diff options
97 files changed, 851 insertions, 418 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 8ae709e34523..76ae4aa15129 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2966,7 +2966,7 @@ S: Maintained | |||
2966 | F: drivers/net/ethernet/i825xx/eexpress.* | 2966 | F: drivers/net/ethernet/i825xx/eexpress.* |
2967 | 2967 | ||
2968 | ETHERNET BRIDGE | 2968 | ETHERNET BRIDGE |
2969 | M: Stephen Hemminger <shemminger@vyatta.com> | 2969 | M: Stephen Hemminger <stephen@networkplumber.org> |
2970 | L: bridge@lists.linux-foundation.org | 2970 | L: bridge@lists.linux-foundation.org |
2971 | L: netdev@vger.kernel.org | 2971 | L: netdev@vger.kernel.org |
2972 | W: http://www.linuxfoundation.org/en/Net:Bridge | 2972 | W: http://www.linuxfoundation.org/en/Net:Bridge |
@@ -4905,7 +4905,7 @@ S: Maintained | |||
4905 | 4905 | ||
4906 | MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) | 4906 | MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) |
4907 | M: Mirko Lindner <mlindner@marvell.com> | 4907 | M: Mirko Lindner <mlindner@marvell.com> |
4908 | M: Stephen Hemminger <shemminger@vyatta.com> | 4908 | M: Stephen Hemminger <stephen@networkplumber.org> |
4909 | L: netdev@vger.kernel.org | 4909 | L: netdev@vger.kernel.org |
4910 | S: Maintained | 4910 | S: Maintained |
4911 | F: drivers/net/ethernet/marvell/sk* | 4911 | F: drivers/net/ethernet/marvell/sk* |
@@ -5180,7 +5180,7 @@ S: Supported | |||
5180 | F: drivers/infiniband/hw/nes/ | 5180 | F: drivers/infiniband/hw/nes/ |
5181 | 5181 | ||
5182 | NETEM NETWORK EMULATOR | 5182 | NETEM NETWORK EMULATOR |
5183 | M: Stephen Hemminger <shemminger@vyatta.com> | 5183 | M: Stephen Hemminger <stephen@networkplumber.org> |
5184 | L: netem@lists.linux-foundation.org | 5184 | L: netem@lists.linux-foundation.org |
5185 | S: Maintained | 5185 | S: Maintained |
5186 | F: net/sched/sch_netem.c | 5186 | F: net/sched/sch_netem.c |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index b00000e8aef6..33c9a44a9678 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = { | |||
77 | { USB_DEVICE(0x0CF3, 0x311D) }, | 77 | { USB_DEVICE(0x0CF3, 0x311D) }, |
78 | { USB_DEVICE(0x13d3, 0x3375) }, | 78 | { USB_DEVICE(0x13d3, 0x3375) }, |
79 | { USB_DEVICE(0x04CA, 0x3005) }, | 79 | { USB_DEVICE(0x04CA, 0x3005) }, |
80 | { USB_DEVICE(0x04CA, 0x3006) }, | ||
81 | { USB_DEVICE(0x04CA, 0x3008) }, | ||
80 | { USB_DEVICE(0x13d3, 0x3362) }, | 82 | { USB_DEVICE(0x13d3, 0x3362) }, |
81 | { USB_DEVICE(0x0CF3, 0xE004) }, | 83 | { USB_DEVICE(0x0CF3, 0xE004) }, |
82 | { USB_DEVICE(0x0930, 0x0219) }, | 84 | { USB_DEVICE(0x0930, 0x0219) }, |
83 | { USB_DEVICE(0x0489, 0xe057) }, | 85 | { USB_DEVICE(0x0489, 0xe057) }, |
86 | { USB_DEVICE(0x13d3, 0x3393) }, | ||
87 | { USB_DEVICE(0x0489, 0xe04e) }, | ||
88 | { USB_DEVICE(0x0489, 0xe056) }, | ||
84 | 89 | ||
85 | /* Atheros AR5BBU12 with sflash firmware */ | 90 | /* Atheros AR5BBU12 with sflash firmware */ |
86 | { USB_DEVICE(0x0489, 0xE02C) }, | 91 | { USB_DEVICE(0x0489, 0xE02C) }, |
@@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = { | |||
104 | { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, | 109 | { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, |
105 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, | 110 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, |
106 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, | 111 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
112 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, | ||
113 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, | ||
107 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | 114 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, |
108 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | 115 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, |
109 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 116 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
110 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | 117 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, |
118 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | ||
119 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, | ||
120 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, | ||
111 | 121 | ||
112 | /* Atheros AR5BBU22 with sflash firmware */ | 122 | /* Atheros AR5BBU22 with sflash firmware */ |
113 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | 123 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a1d4ede5b892..7e351e345476 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = { | |||
135 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, | 135 | { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, |
136 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, | 136 | { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, |
137 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, | 137 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
138 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, | ||
139 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, | ||
138 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | 140 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, |
139 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | 141 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, |
140 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 142 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
141 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | 143 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, |
144 | { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, | ||
145 | { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, | ||
146 | { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, | ||
142 | 147 | ||
143 | /* Atheros AR5BBU12 with sflash firmware */ | 148 | /* Atheros AR5BBU12 with sflash firmware */ |
144 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | 149 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, |
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 68452b768da2..03a0a01a4054 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c | |||
@@ -248,6 +248,8 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag, | |||
248 | CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l, | 248 | CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l, |
249 | CAPIMSG_CONTROL(data)); | 249 | CAPIMSG_CONTROL(data)); |
250 | l -= 12; | 250 | l -= 12; |
251 | if (l <= 0) | ||
252 | return; | ||
251 | dbgline = kmalloc(3 * l, GFP_ATOMIC); | 253 | dbgline = kmalloc(3 * l, GFP_ATOMIC); |
252 | if (!dbgline) | 254 | if (!dbgline) |
253 | return; | 255 | return; |
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 5233b8f58d77..58607f196c9e 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -960,7 +960,7 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
960 | break; | 960 | break; |
961 | case LEC_ACK_ERROR: | 961 | case LEC_ACK_ERROR: |
962 | netdev_dbg(dev, "ack error\n"); | 962 | netdev_dbg(dev, "ack error\n"); |
963 | cf->data[2] |= (CAN_ERR_PROT_LOC_ACK | | 963 | cf->data[3] |= (CAN_ERR_PROT_LOC_ACK | |
964 | CAN_ERR_PROT_LOC_ACK_DEL); | 964 | CAN_ERR_PROT_LOC_ACK_DEL); |
965 | break; | 965 | break; |
966 | case LEC_BIT1_ERROR: | 966 | case LEC_BIT1_ERROR: |
@@ -973,7 +973,7 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
973 | break; | 973 | break; |
974 | case LEC_CRC_ERROR: | 974 | case LEC_CRC_ERROR: |
975 | netdev_dbg(dev, "CRC error\n"); | 975 | netdev_dbg(dev, "CRC error\n"); |
976 | cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ | | 976 | cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | |
977 | CAN_ERR_PROT_LOC_CRC_DEL); | 977 | CAN_ERR_PROT_LOC_CRC_DEL); |
978 | break; | 978 | break; |
979 | default: | 979 | default: |
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index 7d1748575b1f..5c314a961970 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c | |||
@@ -560,7 +560,7 @@ static void pch_can_error(struct net_device *ndev, u32 status) | |||
560 | stats->rx_errors++; | 560 | stats->rx_errors++; |
561 | break; | 561 | break; |
562 | case PCH_CRC_ERR: | 562 | case PCH_CRC_ERR: |
563 | cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | | 563 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | |
564 | CAN_ERR_PROT_LOC_CRC_DEL; | 564 | CAN_ERR_PROT_LOC_CRC_DEL; |
565 | priv->can.can_stats.bus_error++; | 565 | priv->can.can_stats.bus_error++; |
566 | stats->rx_errors++; | 566 | stats->rx_errors++; |
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f898c6363729..300581b24ff3 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
@@ -746,12 +746,12 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, | |||
746 | } | 746 | } |
747 | if (err_status & HECC_CANES_CRCE) { | 747 | if (err_status & HECC_CANES_CRCE) { |
748 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE); | 748 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE); |
749 | cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ | | 749 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ | |
750 | CAN_ERR_PROT_LOC_CRC_DEL; | 750 | CAN_ERR_PROT_LOC_CRC_DEL; |
751 | } | 751 | } |
752 | if (err_status & HECC_CANES_ACKE) { | 752 | if (err_status & HECC_CANES_ACKE) { |
753 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE); | 753 | hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE); |
754 | cf->data[2] |= CAN_ERR_PROT_LOC_ACK | | 754 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK | |
755 | CAN_ERR_PROT_LOC_ACK_DEL; | 755 | CAN_ERR_PROT_LOC_ACK_DEL; |
756 | } | 756 | } |
757 | } | 757 | } |
diff --git a/drivers/net/ethernet/3com/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c index 66df93638085..ffd8de28a76a 100644 --- a/drivers/net/ethernet/3com/3c574_cs.c +++ b/drivers/net/ethernet/3com/3c574_cs.c | |||
@@ -432,7 +432,7 @@ static int tc574_config(struct pcmcia_device *link) | |||
432 | netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n", | 432 | netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n", |
433 | cardname, dev->base_addr, dev->irq, dev->dev_addr); | 433 | cardname, dev->base_addr, dev->irq, dev->dev_addr); |
434 | netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n", | 434 | netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n", |
435 | 8 << config & Ram_size, | 435 | 8 << (config & Ram_size), |
436 | ram_split[(config & Ram_split) >> Ram_split_shift], | 436 | ram_split[(config & Ram_split) >> Ram_split_shift], |
437 | config & Autoselect ? "autoselect " : ""); | 437 | config & Autoselect ? "autoselect " : ""); |
438 | 438 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 78ea90c40e19..bdb086934cd9 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -1283,14 +1283,26 @@ static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set) | |||
1283 | return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg); | 1283 | return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg); |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | #define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \ | 1286 | static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable) |
1287 | tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ | 1287 | { |
1288 | MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \ | 1288 | u32 val; |
1289 | MII_TG3_AUXCTL_ACTL_TX_6DB) | 1289 | int err; |
1290 | 1290 | ||
1291 | #define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \ | 1291 | err = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val); |
1292 | tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \ | 1292 | |
1293 | MII_TG3_AUXCTL_ACTL_TX_6DB); | 1293 | if (err) |
1294 | return err; | ||
1295 | if (enable) | ||
1296 | |||
1297 | val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA; | ||
1298 | else | ||
1299 | val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA; | ||
1300 | |||
1301 | err = tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, | ||
1302 | val | MII_TG3_AUXCTL_ACTL_TX_6DB); | ||
1303 | |||
1304 | return err; | ||
1305 | } | ||
1294 | 1306 | ||
1295 | static int tg3_bmcr_reset(struct tg3 *tp) | 1307 | static int tg3_bmcr_reset(struct tg3 *tp) |
1296 | { | 1308 | { |
@@ -2223,7 +2235,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp) | |||
2223 | 2235 | ||
2224 | otp = tp->phy_otp; | 2236 | otp = tp->phy_otp; |
2225 | 2237 | ||
2226 | if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) | 2238 | if (tg3_phy_toggle_auxctl_smdsp(tp, true)) |
2227 | return; | 2239 | return; |
2228 | 2240 | ||
2229 | phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT); | 2241 | phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT); |
@@ -2248,7 +2260,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp) | |||
2248 | ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT); | 2260 | ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT); |
2249 | tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy); | 2261 | tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy); |
2250 | 2262 | ||
2251 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2263 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2252 | } | 2264 | } |
2253 | 2265 | ||
2254 | static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) | 2266 | static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) |
@@ -2284,9 +2296,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) | |||
2284 | 2296 | ||
2285 | if (!tp->setlpicnt) { | 2297 | if (!tp->setlpicnt) { |
2286 | if (current_link_up == 1 && | 2298 | if (current_link_up == 1 && |
2287 | !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2299 | !tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2288 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); | 2300 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); |
2289 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2301 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2290 | } | 2302 | } |
2291 | 2303 | ||
2292 | val = tr32(TG3_CPMU_EEE_MODE); | 2304 | val = tr32(TG3_CPMU_EEE_MODE); |
@@ -2302,11 +2314,11 @@ static void tg3_phy_eee_enable(struct tg3 *tp) | |||
2302 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || | 2314 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || |
2303 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | 2315 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || |
2304 | tg3_flag(tp, 57765_CLASS)) && | 2316 | tg3_flag(tp, 57765_CLASS)) && |
2305 | !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2317 | !tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2306 | val = MII_TG3_DSP_TAP26_ALNOKO | | 2318 | val = MII_TG3_DSP_TAP26_ALNOKO | |
2307 | MII_TG3_DSP_TAP26_RMRXSTO; | 2319 | MII_TG3_DSP_TAP26_RMRXSTO; |
2308 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); | 2320 | tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); |
2309 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2321 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2310 | } | 2322 | } |
2311 | 2323 | ||
2312 | val = tr32(TG3_CPMU_EEE_MODE); | 2324 | val = tr32(TG3_CPMU_EEE_MODE); |
@@ -2450,7 +2462,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
2450 | tg3_writephy(tp, MII_CTRL1000, | 2462 | tg3_writephy(tp, MII_CTRL1000, |
2451 | CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); | 2463 | CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER); |
2452 | 2464 | ||
2453 | err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); | 2465 | err = tg3_phy_toggle_auxctl_smdsp(tp, true); |
2454 | if (err) | 2466 | if (err) |
2455 | return err; | 2467 | return err; |
2456 | 2468 | ||
@@ -2471,7 +2483,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
2471 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); | 2483 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); |
2472 | tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); | 2484 | tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); |
2473 | 2485 | ||
2474 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2486 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2475 | 2487 | ||
2476 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); | 2488 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); |
2477 | 2489 | ||
@@ -2572,10 +2584,10 @@ static int tg3_phy_reset(struct tg3 *tp) | |||
2572 | 2584 | ||
2573 | out: | 2585 | out: |
2574 | if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) && | 2586 | if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) && |
2575 | !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2587 | !tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2576 | tg3_phydsp_write(tp, 0x201f, 0x2aaa); | 2588 | tg3_phydsp_write(tp, 0x201f, 0x2aaa); |
2577 | tg3_phydsp_write(tp, 0x000a, 0x0323); | 2589 | tg3_phydsp_write(tp, 0x000a, 0x0323); |
2578 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2590 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2579 | } | 2591 | } |
2580 | 2592 | ||
2581 | if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { | 2593 | if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { |
@@ -2584,14 +2596,14 @@ out: | |||
2584 | } | 2596 | } |
2585 | 2597 | ||
2586 | if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { | 2598 | if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { |
2587 | if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2599 | if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2588 | tg3_phydsp_write(tp, 0x000a, 0x310b); | 2600 | tg3_phydsp_write(tp, 0x000a, 0x310b); |
2589 | tg3_phydsp_write(tp, 0x201f, 0x9506); | 2601 | tg3_phydsp_write(tp, 0x201f, 0x9506); |
2590 | tg3_phydsp_write(tp, 0x401f, 0x14e2); | 2602 | tg3_phydsp_write(tp, 0x401f, 0x14e2); |
2591 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2603 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2592 | } | 2604 | } |
2593 | } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { | 2605 | } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { |
2594 | if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) { | 2606 | if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) { |
2595 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); | 2607 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); |
2596 | if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) { | 2608 | if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) { |
2597 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); | 2609 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); |
@@ -2600,7 +2612,7 @@ out: | |||
2600 | } else | 2612 | } else |
2601 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); | 2613 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); |
2602 | 2614 | ||
2603 | TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 2615 | tg3_phy_toggle_auxctl_smdsp(tp, false); |
2604 | } | 2616 | } |
2605 | } | 2617 | } |
2606 | 2618 | ||
@@ -4009,7 +4021,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) | |||
4009 | tw32(TG3_CPMU_EEE_MODE, | 4021 | tw32(TG3_CPMU_EEE_MODE, |
4010 | tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); | 4022 | tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); |
4011 | 4023 | ||
4012 | err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp); | 4024 | err = tg3_phy_toggle_auxctl_smdsp(tp, true); |
4013 | if (!err) { | 4025 | if (!err) { |
4014 | u32 err2; | 4026 | u32 err2; |
4015 | 4027 | ||
@@ -4042,7 +4054,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) | |||
4042 | MII_TG3_DSP_CH34TP2_HIBW01); | 4054 | MII_TG3_DSP_CH34TP2_HIBW01); |
4043 | } | 4055 | } |
4044 | 4056 | ||
4045 | err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp); | 4057 | err2 = tg3_phy_toggle_auxctl_smdsp(tp, false); |
4046 | if (!err) | 4058 | if (!err) |
4047 | err = err2; | 4059 | err = err2; |
4048 | } | 4060 | } |
@@ -6950,6 +6962,9 @@ static void tg3_poll_controller(struct net_device *dev) | |||
6950 | int i; | 6962 | int i; |
6951 | struct tg3 *tp = netdev_priv(dev); | 6963 | struct tg3 *tp = netdev_priv(dev); |
6952 | 6964 | ||
6965 | if (tg3_irq_sync(tp)) | ||
6966 | return; | ||
6967 | |||
6953 | for (i = 0; i < tp->irq_cnt; i++) | 6968 | for (i = 0; i < tp->irq_cnt; i++) |
6954 | tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]); | 6969 | tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]); |
6955 | } | 6970 | } |
@@ -16367,6 +16382,7 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
16367 | tp->pm_cap = pm_cap; | 16382 | tp->pm_cap = pm_cap; |
16368 | tp->rx_mode = TG3_DEF_RX_MODE; | 16383 | tp->rx_mode = TG3_DEF_RX_MODE; |
16369 | tp->tx_mode = TG3_DEF_TX_MODE; | 16384 | tp->tx_mode = TG3_DEF_TX_MODE; |
16385 | tp->irq_sync = 1; | ||
16370 | 16386 | ||
16371 | if (tg3_debug > 0) | 16387 | if (tg3_debug > 0) |
16372 | tp->msg_enable = tg3_debug; | 16388 | tp->msg_enable = tg3_debug; |
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index b407043ce9b0..f7f02900f650 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c | |||
@@ -548,6 +548,10 @@ static int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p) | |||
548 | return -1; | 548 | return -1; |
549 | } | 549 | } |
550 | 550 | ||
551 | /* All frames should fit into a single buffer */ | ||
552 | if (!(status & RXDESC_FIRST_SEG) || !(status & RXDESC_LAST_SEG)) | ||
553 | return -1; | ||
554 | |||
551 | /* Check if packet has checksum already */ | 555 | /* Check if packet has checksum already */ |
552 | if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) && | 556 | if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) && |
553 | !(ext_status & RXDESC_IP_PAYLOAD_MASK)) | 557 | !(ext_status & RXDESC_IP_PAYLOAD_MASK)) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index f0718e1a8369..c306df7d4568 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -1994,9 +1994,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | |||
1994 | { | 1994 | { |
1995 | const struct port_info *pi = netdev_priv(dev); | 1995 | const struct port_info *pi = netdev_priv(dev); |
1996 | struct adapter *adap = pi->adapter; | 1996 | struct adapter *adap = pi->adapter; |
1997 | 1997 | struct sge_rspq *q; | |
1998 | return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq, | 1998 | int i; |
1999 | c->rx_coalesce_usecs, c->rx_max_coalesced_frames); | 1999 | int r = 0; |
2000 | |||
2001 | for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++) { | ||
2002 | q = &adap->sge.ethrxq[i].rspq; | ||
2003 | r = set_rxq_intr_params(adap, q, c->rx_coalesce_usecs, | ||
2004 | c->rx_max_coalesced_frames); | ||
2005 | if (r) { | ||
2006 | dev_err(&dev->dev, "failed to set coalesce %d\n", r); | ||
2007 | break; | ||
2008 | } | ||
2009 | } | ||
2010 | return r; | ||
2000 | } | 2011 | } |
2001 | 2012 | ||
2002 | static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | 2013 | static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) |
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile index f3a632bf8d96..687c83d1bdab 100644 --- a/drivers/net/ethernet/intel/ixgbe/Makefile +++ b/drivers/net/ethernet/intel/ixgbe/Makefile | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | obj-$(CONFIG_IXGBE) += ixgbe.o | 33 | obj-$(CONFIG_IXGBE) += ixgbe.o |
34 | 34 | ||
35 | ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\ | 35 | ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ |
36 | ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ | 36 | ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ |
37 | ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o | 37 | ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o |
38 | 38 | ||
@@ -40,4 +40,5 @@ ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ | |||
40 | ixgbe_dcb_82599.o ixgbe_dcb_nl.o | 40 | ixgbe_dcb_82599.o ixgbe_dcb_nl.o |
41 | 41 | ||
42 | ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o | 42 | ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o |
43 | ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o | ||
43 | ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o | 44 | ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c index 50aa546b8c7a..3504686d3af5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c | |||
@@ -24,9 +24,6 @@ | |||
24 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 24 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
25 | 25 | ||
26 | *******************************************************************************/ | 26 | *******************************************************************************/ |
27 | |||
28 | #ifdef CONFIG_DEBUG_FS | ||
29 | |||
30 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
31 | #include <linux/module.h> | 28 | #include <linux/module.h> |
32 | 29 | ||
@@ -277,5 +274,3 @@ void ixgbe_dbg_exit(void) | |||
277 | { | 274 | { |
278 | debugfs_remove_recursive(ixgbe_dbg_root); | 275 | debugfs_remove_recursive(ixgbe_dbg_root); |
279 | } | 276 | } |
280 | |||
281 | #endif /* CONFIG_DEBUG_FS */ | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 1a751c9d09c4..bb9256a1b0a9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | |||
@@ -660,11 +660,11 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, | |||
660 | break; | 660 | break; |
661 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | 661 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
662 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; | 662 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; |
663 | tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG; | 663 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; |
664 | break; | 664 | break; |
665 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | 665 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: |
666 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; | 666 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; |
667 | tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG; | 667 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; |
668 | break; | 668 | break; |
669 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | 669 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
670 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | 670 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 2b799f4f1c37..6771b69f40d5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -630,10 +630,15 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
630 | ring->tx_csum++; | 630 | ring->tx_csum++; |
631 | } | 631 | } |
632 | 632 | ||
633 | /* Copy dst mac address to wqe */ | 633 | if (mlx4_is_mfunc(mdev->dev) || priv->validate_loopback) { |
634 | ethh = (struct ethhdr *)skb->data; | 634 | /* Copy dst mac address to wqe. This allows loopback in eSwitch, |
635 | tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); | 635 | * so that VFs and PF can communicate with each other |
636 | tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); | 636 | */ |
637 | ethh = (struct ethhdr *)skb->data; | ||
638 | tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); | ||
639 | tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); | ||
640 | } | ||
641 | |||
637 | /* Handle LSO (TSO) packets */ | 642 | /* Handle LSO (TSO) packets */ |
638 | if (lso_header_size) { | 643 | if (lso_header_size) { |
639 | /* Mark opcode as LSO */ | 644 | /* Mark opcode as LSO */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index e1bafffbc3b1..a6542d75374c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -1790,15 +1790,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) | |||
1790 | int i; | 1790 | int i; |
1791 | 1791 | ||
1792 | if (msi_x) { | 1792 | if (msi_x) { |
1793 | /* In multifunction mode each function gets 2 msi-X vectors | 1793 | nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, |
1794 | * one for data path completions anf the other for asynch events | 1794 | nreq); |
1795 | * or command completions */ | ||
1796 | if (mlx4_is_mfunc(dev)) { | ||
1797 | nreq = 2; | ||
1798 | } else { | ||
1799 | nreq = min_t(int, dev->caps.num_eqs - | ||
1800 | dev->caps.reserved_eqs, nreq); | ||
1801 | } | ||
1802 | 1795 | ||
1803 | entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); | 1796 | entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); |
1804 | if (!entries) | 1797 | if (!entries) |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index bc165f4d0f65..695667d471a1 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | |||
@@ -144,7 +144,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter) | |||
144 | buffrag->length, PCI_DMA_TODEVICE); | 144 | buffrag->length, PCI_DMA_TODEVICE); |
145 | buffrag->dma = 0ULL; | 145 | buffrag->dma = 0ULL; |
146 | } | 146 | } |
147 | for (j = 0; j < cmd_buf->frag_count; j++) { | 147 | for (j = 1; j < cmd_buf->frag_count; j++) { |
148 | buffrag++; | 148 | buffrag++; |
149 | if (buffrag->dma) { | 149 | if (buffrag->dma) { |
150 | pci_unmap_page(adapter->pdev, buffrag->dma, | 150 | pci_unmap_page(adapter->pdev, buffrag->dma, |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 6098fd4adfeb..69e321a65077 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | |||
@@ -1963,10 +1963,12 @@ unwind: | |||
1963 | while (--i >= 0) { | 1963 | while (--i >= 0) { |
1964 | nf = &pbuf->frag_array[i+1]; | 1964 | nf = &pbuf->frag_array[i+1]; |
1965 | pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); | 1965 | pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); |
1966 | nf->dma = 0ULL; | ||
1966 | } | 1967 | } |
1967 | 1968 | ||
1968 | nf = &pbuf->frag_array[0]; | 1969 | nf = &pbuf->frag_array[0]; |
1969 | pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); | 1970 | pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); |
1971 | nf->dma = 0ULL; | ||
1970 | 1972 | ||
1971 | out_err: | 1973 | out_err: |
1972 | return -ENOMEM; | 1974 | return -ENOMEM; |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index ed96f309bca8..11702324a071 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -1826,8 +1826,6 @@ static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) | |||
1826 | 1826 | ||
1827 | if (opts2 & RxVlanTag) | 1827 | if (opts2 & RxVlanTag) |
1828 | __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); | 1828 | __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); |
1829 | |||
1830 | desc->opts2 = 0; | ||
1831 | } | 1829 | } |
1832 | 1830 | ||
1833 | static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) | 1831 | static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) |
@@ -6064,8 +6062,6 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget | |||
6064 | !(status & (RxRWT | RxFOVF)) && | 6062 | !(status & (RxRWT | RxFOVF)) && |
6065 | (dev->features & NETIF_F_RXALL)) | 6063 | (dev->features & NETIF_F_RXALL)) |
6066 | goto process_pkt; | 6064 | goto process_pkt; |
6067 | |||
6068 | rtl8169_mark_to_asic(desc, rx_buf_sz); | ||
6069 | } else { | 6065 | } else { |
6070 | struct sk_buff *skb; | 6066 | struct sk_buff *skb; |
6071 | dma_addr_t addr; | 6067 | dma_addr_t addr; |
@@ -6086,16 +6082,14 @@ process_pkt: | |||
6086 | if (unlikely(rtl8169_fragmented_frame(status))) { | 6082 | if (unlikely(rtl8169_fragmented_frame(status))) { |
6087 | dev->stats.rx_dropped++; | 6083 | dev->stats.rx_dropped++; |
6088 | dev->stats.rx_length_errors++; | 6084 | dev->stats.rx_length_errors++; |
6089 | rtl8169_mark_to_asic(desc, rx_buf_sz); | 6085 | goto release_descriptor; |
6090 | continue; | ||
6091 | } | 6086 | } |
6092 | 6087 | ||
6093 | skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry], | 6088 | skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry], |
6094 | tp, pkt_size, addr); | 6089 | tp, pkt_size, addr); |
6095 | rtl8169_mark_to_asic(desc, rx_buf_sz); | ||
6096 | if (!skb) { | 6090 | if (!skb) { |
6097 | dev->stats.rx_dropped++; | 6091 | dev->stats.rx_dropped++; |
6098 | continue; | 6092 | goto release_descriptor; |
6099 | } | 6093 | } |
6100 | 6094 | ||
6101 | rtl8169_rx_csum(skb, status); | 6095 | rtl8169_rx_csum(skb, status); |
@@ -6111,13 +6105,10 @@ process_pkt: | |||
6111 | tp->rx_stats.bytes += pkt_size; | 6105 | tp->rx_stats.bytes += pkt_size; |
6112 | u64_stats_update_end(&tp->rx_stats.syncp); | 6106 | u64_stats_update_end(&tp->rx_stats.syncp); |
6113 | } | 6107 | } |
6114 | 6108 | release_descriptor: | |
6115 | /* Work around for AMD plateform. */ | 6109 | desc->opts2 = 0; |
6116 | if ((desc->opts2 & cpu_to_le32(0xfffe000)) && | 6110 | wmb(); |
6117 | (tp->mac_version == RTL_GIGA_MAC_VER_05)) { | 6111 | rtl8169_mark_to_asic(desc, rx_buf_sz); |
6118 | desc->opts2 = 0; | ||
6119 | cur_rx++; | ||
6120 | } | ||
6121 | } | 6112 | } |
6122 | 6113 | ||
6123 | count = cur_rx - tp->cur_rx; | 6114 | count = cur_rx - tp->cur_rx; |
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 5fd6f4674326..e6fe0d80d612 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
@@ -84,7 +84,7 @@ struct hv_netvsc_packet { | |||
84 | }; | 84 | }; |
85 | 85 | ||
86 | struct netvsc_device_info { | 86 | struct netvsc_device_info { |
87 | unsigned char mac_adr[6]; | 87 | unsigned char mac_adr[ETH_ALEN]; |
88 | bool link_state; /* 0 - link up, 1 - link down */ | 88 | bool link_state; /* 0 - link up, 1 - link down */ |
89 | int ring_size; | 89 | int ring_size; |
90 | }; | 90 | }; |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index f825a629a699..8264f0ef7692 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -349,7 +349,7 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p) | |||
349 | struct net_device_context *ndevctx = netdev_priv(ndev); | 349 | struct net_device_context *ndevctx = netdev_priv(ndev); |
350 | struct hv_device *hdev = ndevctx->device_ctx; | 350 | struct hv_device *hdev = ndevctx->device_ctx; |
351 | struct sockaddr *addr = p; | 351 | struct sockaddr *addr = p; |
352 | char save_adr[14]; | 352 | char save_adr[ETH_ALEN]; |
353 | unsigned char save_aatype; | 353 | unsigned char save_aatype; |
354 | int err; | 354 | int err; |
355 | 355 | ||
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 81f8f9e31db5..fcbf680c3e62 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -77,6 +77,11 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, | |||
77 | 77 | ||
78 | skb_orphan(skb); | 78 | skb_orphan(skb); |
79 | 79 | ||
80 | /* Before queueing this packet to netif_rx(), | ||
81 | * make sure dst is refcounted. | ||
82 | */ | ||
83 | skb_dst_force(skb); | ||
84 | |||
80 | skb->protocol = eth_type_trans(skb, dev); | 85 | skb->protocol = eth_type_trans(skb, dev); |
81 | 86 | ||
82 | /* it's OK to use per_cpu_ptr() because BHs are off */ | 87 | /* it's OK to use per_cpu_ptr() because BHs are off */ |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 68a43fe602e7..d3fb97d97cbc 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -822,7 +822,10 @@ static int macvlan_changelink(struct net_device *dev, | |||
822 | 822 | ||
823 | static size_t macvlan_get_size(const struct net_device *dev) | 823 | static size_t macvlan_get_size(const struct net_device *dev) |
824 | { | 824 | { |
825 | return nla_total_size(4); | 825 | return (0 |
826 | + nla_total_size(4) /* IFLA_MACVLAN_MODE */ | ||
827 | + nla_total_size(2) /* IFLA_MACVLAN_FLAGS */ | ||
828 | ); | ||
826 | } | 829 | } |
827 | 830 | ||
828 | static int macvlan_fill_info(struct sk_buff *skb, | 831 | static int macvlan_fill_info(struct sk_buff *skb, |
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index d5199cb4caec..b5ddd5077a80 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c | |||
@@ -36,8 +36,9 @@ MODULE_LICENSE("GPL"); | |||
36 | 36 | ||
37 | /* IP101A/G - IP1001 */ | 37 | /* IP101A/G - IP1001 */ |
38 | #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ | 38 | #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ |
39 | #define IP1001_RXPHASE_SEL (1<<0) /* Add delay on RX_CLK */ | ||
40 | #define IP1001_TXPHASE_SEL (1<<1) /* Add delay on TX_CLK */ | ||
39 | #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ | 41 | #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ |
40 | #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ | ||
41 | #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ | 42 | #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ |
42 | #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ | 43 | #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ |
43 | #define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ | 44 | #define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ |
@@ -138,19 +139,24 @@ static int ip1001_config_init(struct phy_device *phydev) | |||
138 | if (c < 0) | 139 | if (c < 0) |
139 | return c; | 140 | return c; |
140 | 141 | ||
141 | /* INTR pin used: speed/link/duplex will cause an interrupt */ | 142 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || |
142 | c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT); | 143 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || |
143 | if (c < 0) | 144 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || |
144 | return c; | 145 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { |
145 | 146 | ||
146 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { | ||
147 | /* Additional delay (2ns) used to adjust RX clock phase | ||
148 | * at RGMII interface */ | ||
149 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); | 147 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); |
150 | if (c < 0) | 148 | if (c < 0) |
151 | return c; | 149 | return c; |
152 | 150 | ||
153 | c |= IP1001_PHASE_SEL_MASK; | 151 | c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL); |
152 | |||
153 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) | ||
154 | c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL); | ||
155 | else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) | ||
156 | c |= IP1001_RXPHASE_SEL; | ||
157 | else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) | ||
158 | c |= IP1001_TXPHASE_SEL; | ||
159 | |||
154 | c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); | 160 | c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); |
155 | if (c < 0) | 161 | if (c < 0) |
156 | return c; | 162 | return c; |
@@ -167,6 +173,11 @@ static int ip101a_g_config_init(struct phy_device *phydev) | |||
167 | if (c < 0) | 173 | if (c < 0) |
168 | return c; | 174 | return c; |
169 | 175 | ||
176 | /* INTR pin used: speed/link/duplex will cause an interrupt */ | ||
177 | c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT); | ||
178 | if (c < 0) | ||
179 | return c; | ||
180 | |||
170 | /* Enable Auto Power Saving mode */ | 181 | /* Enable Auto Power Saving mode */ |
171 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); | 182 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); |
172 | c |= IP101A_G_APS_ON; | 183 | c |= IP101A_G_APS_ON; |
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 5d2a3f215887..22dec9c7ef05 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
@@ -353,15 +353,6 @@ static int m88e1111_config_init(struct phy_device *phydev) | |||
353 | int err; | 353 | int err; |
354 | int temp; | 354 | int temp; |
355 | 355 | ||
356 | /* Enable Fiber/Copper auto selection */ | ||
357 | temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); | ||
358 | temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO; | ||
359 | phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); | ||
360 | |||
361 | temp = phy_read(phydev, MII_BMCR); | ||
362 | temp |= BMCR_RESET; | ||
363 | phy_write(phydev, MII_BMCR, temp); | ||
364 | |||
365 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || | 356 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || |
366 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || | 357 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || |
367 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || | 358 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index af372d0957fe..cc09b67c23bc 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -109,11 +109,11 @@ struct tap_filter { | |||
109 | unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; | 109 | unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | /* 1024 is probably a high enough limit: modern hypervisors seem to support on | 112 | /* DEFAULT_MAX_NUM_RSS_QUEUES were choosed to let the rx/tx queues allocated for |
113 | * the order of 100-200 CPUs so this leaves us some breathing space if we want | 113 | * the netdevice to be fit in one page. So we can make sure the success of |
114 | * to match a queue per guest CPU. | 114 | * memory allocation. TODO: increase the limit. */ |
115 | */ | 115 | #define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES |
116 | #define MAX_TAP_QUEUES 1024 | 116 | #define MAX_TAP_FLOWS 4096 |
117 | 117 | ||
118 | #define TUN_FLOW_EXPIRE (3 * HZ) | 118 | #define TUN_FLOW_EXPIRE (3 * HZ) |
119 | 119 | ||
@@ -185,6 +185,8 @@ struct tun_struct { | |||
185 | unsigned long ageing_time; | 185 | unsigned long ageing_time; |
186 | unsigned int numdisabled; | 186 | unsigned int numdisabled; |
187 | struct list_head disabled; | 187 | struct list_head disabled; |
188 | void *security; | ||
189 | u32 flow_count; | ||
188 | }; | 190 | }; |
189 | 191 | ||
190 | static inline u32 tun_hashfn(u32 rxhash) | 192 | static inline u32 tun_hashfn(u32 rxhash) |
@@ -218,6 +220,7 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun, | |||
218 | e->queue_index = queue_index; | 220 | e->queue_index = queue_index; |
219 | e->tun = tun; | 221 | e->tun = tun; |
220 | hlist_add_head_rcu(&e->hash_link, head); | 222 | hlist_add_head_rcu(&e->hash_link, head); |
223 | ++tun->flow_count; | ||
221 | } | 224 | } |
222 | return e; | 225 | return e; |
223 | } | 226 | } |
@@ -228,6 +231,7 @@ static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e) | |||
228 | e->rxhash, e->queue_index); | 231 | e->rxhash, e->queue_index); |
229 | hlist_del_rcu(&e->hash_link); | 232 | hlist_del_rcu(&e->hash_link); |
230 | kfree_rcu(e, rcu); | 233 | kfree_rcu(e, rcu); |
234 | --tun->flow_count; | ||
231 | } | 235 | } |
232 | 236 | ||
233 | static void tun_flow_flush(struct tun_struct *tun) | 237 | static void tun_flow_flush(struct tun_struct *tun) |
@@ -317,7 +321,8 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, | |||
317 | e->updated = jiffies; | 321 | e->updated = jiffies; |
318 | } else { | 322 | } else { |
319 | spin_lock_bh(&tun->lock); | 323 | spin_lock_bh(&tun->lock); |
320 | if (!tun_flow_find(head, rxhash)) | 324 | if (!tun_flow_find(head, rxhash) && |
325 | tun->flow_count < MAX_TAP_FLOWS) | ||
321 | tun_flow_create(tun, head, rxhash, queue_index); | 326 | tun_flow_create(tun, head, rxhash, queue_index); |
322 | 327 | ||
323 | if (!timer_pending(&tun->flow_gc_timer)) | 328 | if (!timer_pending(&tun->flow_gc_timer)) |
@@ -490,6 +495,10 @@ static int tun_attach(struct tun_struct *tun, struct file *file) | |||
490 | struct tun_file *tfile = file->private_data; | 495 | struct tun_file *tfile = file->private_data; |
491 | int err; | 496 | int err; |
492 | 497 | ||
498 | err = security_tun_dev_attach(tfile->socket.sk, tun->security); | ||
499 | if (err < 0) | ||
500 | goto out; | ||
501 | |||
493 | err = -EINVAL; | 502 | err = -EINVAL; |
494 | if (rtnl_dereference(tfile->tun)) | 503 | if (rtnl_dereference(tfile->tun)) |
495 | goto out; | 504 | goto out; |
@@ -1373,6 +1382,7 @@ static void tun_free_netdev(struct net_device *dev) | |||
1373 | 1382 | ||
1374 | BUG_ON(!(list_empty(&tun->disabled))); | 1383 | BUG_ON(!(list_empty(&tun->disabled))); |
1375 | tun_flow_uninit(tun); | 1384 | tun_flow_uninit(tun); |
1385 | security_tun_dev_free_security(tun->security); | ||
1376 | free_netdev(dev); | 1386 | free_netdev(dev); |
1377 | } | 1387 | } |
1378 | 1388 | ||
@@ -1562,7 +1572,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1562 | 1572 | ||
1563 | if (tun_not_capable(tun)) | 1573 | if (tun_not_capable(tun)) |
1564 | return -EPERM; | 1574 | return -EPERM; |
1565 | err = security_tun_dev_attach(tfile->socket.sk); | 1575 | err = security_tun_dev_open(tun->security); |
1566 | if (err < 0) | 1576 | if (err < 0) |
1567 | return err; | 1577 | return err; |
1568 | 1578 | ||
@@ -1577,6 +1587,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1577 | else { | 1587 | else { |
1578 | char *name; | 1588 | char *name; |
1579 | unsigned long flags = 0; | 1589 | unsigned long flags = 0; |
1590 | int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? | ||
1591 | MAX_TAP_QUEUES : 1; | ||
1580 | 1592 | ||
1581 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 1593 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
1582 | return -EPERM; | 1594 | return -EPERM; |
@@ -1600,8 +1612,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1600 | name = ifr->ifr_name; | 1612 | name = ifr->ifr_name; |
1601 | 1613 | ||
1602 | dev = alloc_netdev_mqs(sizeof(struct tun_struct), name, | 1614 | dev = alloc_netdev_mqs(sizeof(struct tun_struct), name, |
1603 | tun_setup, | 1615 | tun_setup, queues, queues); |
1604 | MAX_TAP_QUEUES, MAX_TAP_QUEUES); | 1616 | |
1605 | if (!dev) | 1617 | if (!dev) |
1606 | return -ENOMEM; | 1618 | return -ENOMEM; |
1607 | 1619 | ||
@@ -1619,7 +1631,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1619 | 1631 | ||
1620 | spin_lock_init(&tun->lock); | 1632 | spin_lock_init(&tun->lock); |
1621 | 1633 | ||
1622 | security_tun_dev_post_create(&tfile->sk); | 1634 | err = security_tun_dev_alloc_security(&tun->security); |
1635 | if (err < 0) | ||
1636 | goto err_free_dev; | ||
1623 | 1637 | ||
1624 | tun_net_init(dev); | 1638 | tun_net_init(dev); |
1625 | 1639 | ||
@@ -1789,10 +1803,14 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) | |||
1789 | 1803 | ||
1790 | if (ifr->ifr_flags & IFF_ATTACH_QUEUE) { | 1804 | if (ifr->ifr_flags & IFF_ATTACH_QUEUE) { |
1791 | tun = tfile->detached; | 1805 | tun = tfile->detached; |
1792 | if (!tun) | 1806 | if (!tun) { |
1793 | ret = -EINVAL; | 1807 | ret = -EINVAL; |
1794 | else | 1808 | goto unlock; |
1795 | ret = tun_attach(tun, file); | 1809 | } |
1810 | ret = security_tun_dev_attach_queue(tun->security); | ||
1811 | if (ret < 0) | ||
1812 | goto unlock; | ||
1813 | ret = tun_attach(tun, file); | ||
1796 | } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { | 1814 | } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { |
1797 | tun = rtnl_dereference(tfile->tun); | 1815 | tun = rtnl_dereference(tfile->tun); |
1798 | if (!tun || !(tun->flags & TUN_TAP_MQ)) | 1816 | if (!tun || !(tun->flags & TUN_TAP_MQ)) |
@@ -1802,6 +1820,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) | |||
1802 | } else | 1820 | } else |
1803 | ret = -EINVAL; | 1821 | ret = -EINVAL; |
1804 | 1822 | ||
1823 | unlock: | ||
1805 | rtnl_unlock(); | 1824 | rtnl_unlock(); |
1806 | return ret; | 1825 | return ret; |
1807 | } | 1826 | } |
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index 42f51c71ec1f..248d2dc765a5 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c | |||
@@ -374,6 +374,21 @@ static const struct driver_info cdc_mbim_info = { | |||
374 | .tx_fixup = cdc_mbim_tx_fixup, | 374 | .tx_fixup = cdc_mbim_tx_fixup, |
375 | }; | 375 | }; |
376 | 376 | ||
377 | /* MBIM and NCM devices should not need a ZLP after NTBs with | ||
378 | * dwNtbOutMaxSize length. This driver_info is for the exceptional | ||
379 | * devices requiring it anyway, allowing them to be supported without | ||
380 | * forcing the performance penalty on all the sane devices. | ||
381 | */ | ||
382 | static const struct driver_info cdc_mbim_info_zlp = { | ||
383 | .description = "CDC MBIM", | ||
384 | .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP, | ||
385 | .bind = cdc_mbim_bind, | ||
386 | .unbind = cdc_mbim_unbind, | ||
387 | .manage_power = cdc_mbim_manage_power, | ||
388 | .rx_fixup = cdc_mbim_rx_fixup, | ||
389 | .tx_fixup = cdc_mbim_tx_fixup, | ||
390 | }; | ||
391 | |||
377 | static const struct usb_device_id mbim_devs[] = { | 392 | static const struct usb_device_id mbim_devs[] = { |
378 | /* This duplicate NCM entry is intentional. MBIM devices can | 393 | /* This duplicate NCM entry is intentional. MBIM devices can |
379 | * be disguised as NCM by default, and this is necessary to | 394 | * be disguised as NCM by default, and this is necessary to |
@@ -385,6 +400,10 @@ static const struct usb_device_id mbim_devs[] = { | |||
385 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), | 400 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), |
386 | .driver_info = (unsigned long)&cdc_mbim_info, | 401 | .driver_info = (unsigned long)&cdc_mbim_info, |
387 | }, | 402 | }, |
403 | /* Sierra Wireless MC7710 need ZLPs */ | ||
404 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68a2, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), | ||
405 | .driver_info = (unsigned long)&cdc_mbim_info_zlp, | ||
406 | }, | ||
388 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), | 407 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), |
389 | .driver_info = (unsigned long)&cdc_mbim_info, | 408 | .driver_info = (unsigned long)&cdc_mbim_info, |
390 | }, | 409 | }, |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 71b6e92b8e9b..9197b2c72ca3 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -435,6 +435,13 @@ advance: | |||
435 | len -= temp; | 435 | len -= temp; |
436 | } | 436 | } |
437 | 437 | ||
438 | /* some buggy devices have an IAD but no CDC Union */ | ||
439 | if (!ctx->union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) { | ||
440 | ctx->control = intf; | ||
441 | ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1); | ||
442 | dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n"); | ||
443 | } | ||
444 | |||
438 | /* check if we got everything */ | 445 | /* check if we got everything */ |
439 | if ((ctx->control == NULL) || (ctx->data == NULL) || | 446 | if ((ctx->control == NULL) || (ctx->data == NULL) || |
440 | ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf)))) | 447 | ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf)))) |
@@ -497,7 +504,8 @@ advance: | |||
497 | error2: | 504 | error2: |
498 | usb_set_intfdata(ctx->control, NULL); | 505 | usb_set_intfdata(ctx->control, NULL); |
499 | usb_set_intfdata(ctx->data, NULL); | 506 | usb_set_intfdata(ctx->data, NULL); |
500 | usb_driver_release_interface(driver, ctx->data); | 507 | if (ctx->data != ctx->control) |
508 | usb_driver_release_interface(driver, ctx->data); | ||
501 | error: | 509 | error: |
502 | cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]); | 510 | cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]); |
503 | dev->data[0] = 0; | 511 | dev->data[0] = 0; |
@@ -1155,6 +1163,20 @@ static const struct driver_info wwan_info = { | |||
1155 | .tx_fixup = cdc_ncm_tx_fixup, | 1163 | .tx_fixup = cdc_ncm_tx_fixup, |
1156 | }; | 1164 | }; |
1157 | 1165 | ||
1166 | /* Same as wwan_info, but with FLAG_NOARP */ | ||
1167 | static const struct driver_info wwan_noarp_info = { | ||
1168 | .description = "Mobile Broadband Network Device (NO ARP)", | ||
1169 | .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET | ||
1170 | | FLAG_WWAN | FLAG_NOARP, | ||
1171 | .bind = cdc_ncm_bind, | ||
1172 | .unbind = cdc_ncm_unbind, | ||
1173 | .check_connect = cdc_ncm_check_connect, | ||
1174 | .manage_power = usbnet_manage_power, | ||
1175 | .status = cdc_ncm_status, | ||
1176 | .rx_fixup = cdc_ncm_rx_fixup, | ||
1177 | .tx_fixup = cdc_ncm_tx_fixup, | ||
1178 | }; | ||
1179 | |||
1158 | static const struct usb_device_id cdc_devs[] = { | 1180 | static const struct usb_device_id cdc_devs[] = { |
1159 | /* Ericsson MBM devices like F5521gw */ | 1181 | /* Ericsson MBM devices like F5521gw */ |
1160 | { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | 1182 | { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
@@ -1194,6 +1216,13 @@ static const struct usb_device_id cdc_devs[] = { | |||
1194 | .driver_info = (unsigned long)&wwan_info, | 1216 | .driver_info = (unsigned long)&wwan_info, |
1195 | }, | 1217 | }, |
1196 | 1218 | ||
1219 | /* Infineon(now Intel) HSPA Modem platform */ | ||
1220 | { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443, | ||
1221 | USB_CLASS_COMM, | ||
1222 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), | ||
1223 | .driver_info = (unsigned long)&wwan_noarp_info, | ||
1224 | }, | ||
1225 | |||
1197 | /* Generic CDC-NCM devices */ | 1226 | /* Generic CDC-NCM devices */ |
1198 | { USB_INTERFACE_INFO(USB_CLASS_COMM, | 1227 | { USB_INTERFACE_INFO(USB_CLASS_COMM, |
1199 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), | 1228 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 3f554c1149f3..d7e99445518e 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
@@ -45,6 +45,12 @@ | |||
45 | #define DM_MCAST_ADDR 0x16 /* 8 bytes */ | 45 | #define DM_MCAST_ADDR 0x16 /* 8 bytes */ |
46 | #define DM_GPR_CTRL 0x1e | 46 | #define DM_GPR_CTRL 0x1e |
47 | #define DM_GPR_DATA 0x1f | 47 | #define DM_GPR_DATA 0x1f |
48 | #define DM_CHIP_ID 0x2c | ||
49 | #define DM_MODE_CTRL 0x91 /* only on dm9620 */ | ||
50 | |||
51 | /* chip id values */ | ||
52 | #define ID_DM9601 0 | ||
53 | #define ID_DM9620 1 | ||
48 | 54 | ||
49 | #define DM_MAX_MCAST 64 | 55 | #define DM_MAX_MCAST 64 |
50 | #define DM_MCAST_SIZE 8 | 56 | #define DM_MCAST_SIZE 8 |
@@ -53,7 +59,6 @@ | |||
53 | #define DM_RX_OVERHEAD 7 /* 3 byte header + 4 byte crc tail */ | 59 | #define DM_RX_OVERHEAD 7 /* 3 byte header + 4 byte crc tail */ |
54 | #define DM_TIMEOUT 1000 | 60 | #define DM_TIMEOUT 1000 |
55 | 61 | ||
56 | |||
57 | static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data) | 62 | static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data) |
58 | { | 63 | { |
59 | int err; | 64 | int err; |
@@ -84,32 +89,23 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data) | |||
84 | 89 | ||
85 | static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) | 90 | static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) |
86 | { | 91 | { |
87 | return usbnet_write_cmd(dev, DM_WRITE_REGS, | 92 | return usbnet_write_cmd(dev, DM_WRITE_REG, |
88 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 93 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
89 | value, reg, NULL, 0); | 94 | value, reg, NULL, 0); |
90 | } | 95 | } |
91 | 96 | ||
92 | static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, | 97 | static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) |
93 | u16 length, void *data) | ||
94 | { | 98 | { |
95 | usbnet_write_cmd_async(dev, DM_WRITE_REGS, | 99 | usbnet_write_cmd_async(dev, DM_WRITE_REGS, |
96 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 100 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
97 | value, reg, data, length); | 101 | 0, reg, data, length); |
98 | } | ||
99 | |||
100 | static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) | ||
101 | { | ||
102 | netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length); | ||
103 | |||
104 | dm_write_async_helper(dev, reg, 0, length, data); | ||
105 | } | 102 | } |
106 | 103 | ||
107 | static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value) | 104 | static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value) |
108 | { | 105 | { |
109 | netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n", | 106 | usbnet_write_cmd_async(dev, DM_WRITE_REG, |
110 | reg, value); | 107 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
111 | 108 | value, reg, NULL, 0); | |
112 | dm_write_async_helper(dev, reg, value, 0, NULL); | ||
113 | } | 109 | } |
114 | 110 | ||
115 | static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value) | 111 | static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value) |
@@ -358,7 +354,7 @@ static const struct net_device_ops dm9601_netdev_ops = { | |||
358 | static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) | 354 | static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) |
359 | { | 355 | { |
360 | int ret; | 356 | int ret; |
361 | u8 mac[ETH_ALEN]; | 357 | u8 mac[ETH_ALEN], id; |
362 | 358 | ||
363 | ret = usbnet_get_endpoints(dev, intf); | 359 | ret = usbnet_get_endpoints(dev, intf); |
364 | if (ret) | 360 | if (ret) |
@@ -399,6 +395,24 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) | |||
399 | __dm9601_set_mac_address(dev); | 395 | __dm9601_set_mac_address(dev); |
400 | } | 396 | } |
401 | 397 | ||
398 | if (dm_read_reg(dev, DM_CHIP_ID, &id) < 0) { | ||
399 | netdev_err(dev->net, "Error reading chip ID\n"); | ||
400 | ret = -ENODEV; | ||
401 | goto out; | ||
402 | } | ||
403 | |||
404 | /* put dm9620 devices in dm9601 mode */ | ||
405 | if (id == ID_DM9620) { | ||
406 | u8 mode; | ||
407 | |||
408 | if (dm_read_reg(dev, DM_MODE_CTRL, &mode) < 0) { | ||
409 | netdev_err(dev->net, "Error reading MODE_CTRL\n"); | ||
410 | ret = -ENODEV; | ||
411 | goto out; | ||
412 | } | ||
413 | dm_write_reg(dev, DM_MODE_CTRL, mode & 0x7f); | ||
414 | } | ||
415 | |||
402 | /* power up phy */ | 416 | /* power up phy */ |
403 | dm_write_reg(dev, DM_GPR_CTRL, 1); | 417 | dm_write_reg(dev, DM_GPR_CTRL, 1); |
404 | dm_write_reg(dev, DM_GPR_DATA, 0); | 418 | dm_write_reg(dev, DM_GPR_DATA, 0); |
@@ -581,6 +595,10 @@ static const struct usb_device_id products[] = { | |||
581 | USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ | 595 | USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ |
582 | .driver_info = (unsigned long)&dm9601_info, | 596 | .driver_info = (unsigned long)&dm9601_info, |
583 | }, | 597 | }, |
598 | { | ||
599 | USB_DEVICE(0x0a46, 0x9620), /* DM9620 USB to Fast Ethernet Adapter */ | ||
600 | .driver_info = (unsigned long)&dm9601_info, | ||
601 | }, | ||
584 | {}, // END | 602 | {}, // END |
585 | }; | 603 | }; |
586 | 604 | ||
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 6a1ca500e612..575a5839ee34 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -433,6 +433,7 @@ static const struct usb_device_id products[] = { | |||
433 | {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ | 433 | {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ |
434 | {QMI_FIXED_INTF(0x19d2, 0x0200, 1)}, | 434 | {QMI_FIXED_INTF(0x19d2, 0x0200, 1)}, |
435 | {QMI_FIXED_INTF(0x19d2, 0x0257, 3)}, /* ZTE MF821 */ | 435 | {QMI_FIXED_INTF(0x19d2, 0x0257, 3)}, /* ZTE MF821 */ |
436 | {QMI_FIXED_INTF(0x19d2, 0x0265, 4)}, /* ONDA MT8205 4G LTE */ | ||
436 | {QMI_FIXED_INTF(0x19d2, 0x0284, 4)}, /* ZTE MF880 */ | 437 | {QMI_FIXED_INTF(0x19d2, 0x0284, 4)}, /* ZTE MF880 */ |
437 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ | 438 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ |
438 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ | 439 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ |
@@ -459,6 +460,7 @@ static const struct usb_device_id products[] = { | |||
459 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 460 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
460 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 461 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
461 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 462 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
463 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | ||
462 | 464 | ||
463 | /* 4. Gobi 1000 devices */ | 465 | /* 4. Gobi 1000 devices */ |
464 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 466 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3d4bf01641b4..f34b2ebee815 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -1448,6 +1448,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1448 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) | 1448 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) |
1449 | strcpy(net->name, "wwan%d"); | 1449 | strcpy(net->name, "wwan%d"); |
1450 | 1450 | ||
1451 | /* devices that cannot do ARP */ | ||
1452 | if ((dev->driver_info->flags & FLAG_NOARP) != 0) | ||
1453 | net->flags |= IFF_NOARP; | ||
1454 | |||
1451 | /* maybe the remote can't receive an Ethernet MTU */ | 1455 | /* maybe the remote can't receive an Ethernet MTU */ |
1452 | if (net->mtu > (dev->hard_mtu - net->hard_header_len)) | 1456 | if (net->mtu > (dev->hard_mtu - net->hard_header_len)) |
1453 | net->mtu = dev->hard_mtu - net->hard_header_len; | 1457 | net->mtu = dev->hard_mtu - net->hard_header_len; |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a6fcf15adc4f..35c00c5ea02a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/scatterlist.h> | 26 | #include <linux/scatterlist.h> |
27 | #include <linux/if_vlan.h> | 27 | #include <linux/if_vlan.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/cpu.h> | ||
29 | 30 | ||
30 | static int napi_weight = 128; | 31 | static int napi_weight = 128; |
31 | module_param(napi_weight, int, 0444); | 32 | module_param(napi_weight, int, 0444); |
@@ -123,6 +124,12 @@ struct virtnet_info { | |||
123 | 124 | ||
124 | /* Does the affinity hint is set for virtqueues? */ | 125 | /* Does the affinity hint is set for virtqueues? */ |
125 | bool affinity_hint_set; | 126 | bool affinity_hint_set; |
127 | |||
128 | /* Per-cpu variable to show the mapping from CPU to virtqueue */ | ||
129 | int __percpu *vq_index; | ||
130 | |||
131 | /* CPU hot plug notifier */ | ||
132 | struct notifier_block nb; | ||
126 | }; | 133 | }; |
127 | 134 | ||
128 | struct skb_vnet_hdr { | 135 | struct skb_vnet_hdr { |
@@ -1013,32 +1020,75 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) | |||
1013 | return 0; | 1020 | return 0; |
1014 | } | 1021 | } |
1015 | 1022 | ||
1016 | static void virtnet_set_affinity(struct virtnet_info *vi, bool set) | 1023 | static void virtnet_clean_affinity(struct virtnet_info *vi, long hcpu) |
1017 | { | 1024 | { |
1018 | int i; | 1025 | int i; |
1026 | int cpu; | ||
1027 | |||
1028 | if (vi->affinity_hint_set) { | ||
1029 | for (i = 0; i < vi->max_queue_pairs; i++) { | ||
1030 | virtqueue_set_affinity(vi->rq[i].vq, -1); | ||
1031 | virtqueue_set_affinity(vi->sq[i].vq, -1); | ||
1032 | } | ||
1033 | |||
1034 | vi->affinity_hint_set = false; | ||
1035 | } | ||
1036 | |||
1037 | i = 0; | ||
1038 | for_each_online_cpu(cpu) { | ||
1039 | if (cpu == hcpu) { | ||
1040 | *per_cpu_ptr(vi->vq_index, cpu) = -1; | ||
1041 | } else { | ||
1042 | *per_cpu_ptr(vi->vq_index, cpu) = | ||
1043 | ++i % vi->curr_queue_pairs; | ||
1044 | } | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | static void virtnet_set_affinity(struct virtnet_info *vi) | ||
1049 | { | ||
1050 | int i; | ||
1051 | int cpu; | ||
1019 | 1052 | ||
1020 | /* In multiqueue mode, when the number of cpu is equal to the number of | 1053 | /* In multiqueue mode, when the number of cpu is equal to the number of |
1021 | * queue pairs, we let the queue pairs to be private to one cpu by | 1054 | * queue pairs, we let the queue pairs to be private to one cpu by |
1022 | * setting the affinity hint to eliminate the contention. | 1055 | * setting the affinity hint to eliminate the contention. |
1023 | */ | 1056 | */ |
1024 | if ((vi->curr_queue_pairs == 1 || | 1057 | if (vi->curr_queue_pairs == 1 || |
1025 | vi->max_queue_pairs != num_online_cpus()) && set) { | 1058 | vi->max_queue_pairs != num_online_cpus()) { |
1026 | if (vi->affinity_hint_set) | 1059 | virtnet_clean_affinity(vi, -1); |
1027 | set = false; | 1060 | return; |
1028 | else | ||
1029 | return; | ||
1030 | } | 1061 | } |
1031 | 1062 | ||
1032 | for (i = 0; i < vi->max_queue_pairs; i++) { | 1063 | i = 0; |
1033 | int cpu = set ? i : -1; | 1064 | for_each_online_cpu(cpu) { |
1034 | virtqueue_set_affinity(vi->rq[i].vq, cpu); | 1065 | virtqueue_set_affinity(vi->rq[i].vq, cpu); |
1035 | virtqueue_set_affinity(vi->sq[i].vq, cpu); | 1066 | virtqueue_set_affinity(vi->sq[i].vq, cpu); |
1067 | *per_cpu_ptr(vi->vq_index, cpu) = i; | ||
1068 | i++; | ||
1036 | } | 1069 | } |
1037 | 1070 | ||
1038 | if (set) | 1071 | vi->affinity_hint_set = true; |
1039 | vi->affinity_hint_set = true; | 1072 | } |
1040 | else | 1073 | |
1041 | vi->affinity_hint_set = false; | 1074 | static int virtnet_cpu_callback(struct notifier_block *nfb, |
1075 | unsigned long action, void *hcpu) | ||
1076 | { | ||
1077 | struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb); | ||
1078 | |||
1079 | switch(action & ~CPU_TASKS_FROZEN) { | ||
1080 | case CPU_ONLINE: | ||
1081 | case CPU_DOWN_FAILED: | ||
1082 | case CPU_DEAD: | ||
1083 | virtnet_set_affinity(vi); | ||
1084 | break; | ||
1085 | case CPU_DOWN_PREPARE: | ||
1086 | virtnet_clean_affinity(vi, (long)hcpu); | ||
1087 | break; | ||
1088 | default: | ||
1089 | break; | ||
1090 | } | ||
1091 | return NOTIFY_OK; | ||
1042 | } | 1092 | } |
1043 | 1093 | ||
1044 | static void virtnet_get_ringparam(struct net_device *dev, | 1094 | static void virtnet_get_ringparam(struct net_device *dev, |
@@ -1082,13 +1132,15 @@ static int virtnet_set_channels(struct net_device *dev, | |||
1082 | if (queue_pairs > vi->max_queue_pairs) | 1132 | if (queue_pairs > vi->max_queue_pairs) |
1083 | return -EINVAL; | 1133 | return -EINVAL; |
1084 | 1134 | ||
1135 | get_online_cpus(); | ||
1085 | err = virtnet_set_queues(vi, queue_pairs); | 1136 | err = virtnet_set_queues(vi, queue_pairs); |
1086 | if (!err) { | 1137 | if (!err) { |
1087 | netif_set_real_num_tx_queues(dev, queue_pairs); | 1138 | netif_set_real_num_tx_queues(dev, queue_pairs); |
1088 | netif_set_real_num_rx_queues(dev, queue_pairs); | 1139 | netif_set_real_num_rx_queues(dev, queue_pairs); |
1089 | 1140 | ||
1090 | virtnet_set_affinity(vi, true); | 1141 | virtnet_set_affinity(vi); |
1091 | } | 1142 | } |
1143 | put_online_cpus(); | ||
1092 | 1144 | ||
1093 | return err; | 1145 | return err; |
1094 | } | 1146 | } |
@@ -1127,12 +1179,19 @@ static int virtnet_change_mtu(struct net_device *dev, int new_mtu) | |||
1127 | 1179 | ||
1128 | /* To avoid contending a lock hold by a vcpu who would exit to host, select the | 1180 | /* To avoid contending a lock hold by a vcpu who would exit to host, select the |
1129 | * txq based on the processor id. | 1181 | * txq based on the processor id. |
1130 | * TODO: handle cpu hotplug. | ||
1131 | */ | 1182 | */ |
1132 | static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb) | 1183 | static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb) |
1133 | { | 1184 | { |
1134 | int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : | 1185 | int txq; |
1135 | smp_processor_id(); | 1186 | struct virtnet_info *vi = netdev_priv(dev); |
1187 | |||
1188 | if (skb_rx_queue_recorded(skb)) { | ||
1189 | txq = skb_get_rx_queue(skb); | ||
1190 | } else { | ||
1191 | txq = *__this_cpu_ptr(vi->vq_index); | ||
1192 | if (txq == -1) | ||
1193 | txq = 0; | ||
1194 | } | ||
1136 | 1195 | ||
1137 | while (unlikely(txq >= dev->real_num_tx_queues)) | 1196 | while (unlikely(txq >= dev->real_num_tx_queues)) |
1138 | txq -= dev->real_num_tx_queues; | 1197 | txq -= dev->real_num_tx_queues; |
@@ -1248,7 +1307,7 @@ static void virtnet_del_vqs(struct virtnet_info *vi) | |||
1248 | { | 1307 | { |
1249 | struct virtio_device *vdev = vi->vdev; | 1308 | struct virtio_device *vdev = vi->vdev; |
1250 | 1309 | ||
1251 | virtnet_set_affinity(vi, false); | 1310 | virtnet_clean_affinity(vi, -1); |
1252 | 1311 | ||
1253 | vdev->config->del_vqs(vdev); | 1312 | vdev->config->del_vqs(vdev); |
1254 | 1313 | ||
@@ -1371,7 +1430,10 @@ static int init_vqs(struct virtnet_info *vi) | |||
1371 | if (ret) | 1430 | if (ret) |
1372 | goto err_free; | 1431 | goto err_free; |
1373 | 1432 | ||
1374 | virtnet_set_affinity(vi, true); | 1433 | get_online_cpus(); |
1434 | virtnet_set_affinity(vi); | ||
1435 | put_online_cpus(); | ||
1436 | |||
1375 | return 0; | 1437 | return 0; |
1376 | 1438 | ||
1377 | err_free: | 1439 | err_free: |
@@ -1453,6 +1515,10 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1453 | if (vi->stats == NULL) | 1515 | if (vi->stats == NULL) |
1454 | goto free; | 1516 | goto free; |
1455 | 1517 | ||
1518 | vi->vq_index = alloc_percpu(int); | ||
1519 | if (vi->vq_index == NULL) | ||
1520 | goto free_stats; | ||
1521 | |||
1456 | mutex_init(&vi->config_lock); | 1522 | mutex_init(&vi->config_lock); |
1457 | vi->config_enable = true; | 1523 | vi->config_enable = true; |
1458 | INIT_WORK(&vi->config_work, virtnet_config_changed_work); | 1524 | INIT_WORK(&vi->config_work, virtnet_config_changed_work); |
@@ -1476,7 +1542,7 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1476 | /* Allocate/initialize the rx/tx queues, and invoke find_vqs */ | 1542 | /* Allocate/initialize the rx/tx queues, and invoke find_vqs */ |
1477 | err = init_vqs(vi); | 1543 | err = init_vqs(vi); |
1478 | if (err) | 1544 | if (err) |
1479 | goto free_stats; | 1545 | goto free_index; |
1480 | 1546 | ||
1481 | netif_set_real_num_tx_queues(dev, 1); | 1547 | netif_set_real_num_tx_queues(dev, 1); |
1482 | netif_set_real_num_rx_queues(dev, 1); | 1548 | netif_set_real_num_rx_queues(dev, 1); |
@@ -1499,6 +1565,13 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1499 | } | 1565 | } |
1500 | } | 1566 | } |
1501 | 1567 | ||
1568 | vi->nb.notifier_call = &virtnet_cpu_callback; | ||
1569 | err = register_hotcpu_notifier(&vi->nb); | ||
1570 | if (err) { | ||
1571 | pr_debug("virtio_net: registering cpu notifier failed\n"); | ||
1572 | goto free_recv_bufs; | ||
1573 | } | ||
1574 | |||
1502 | /* Assume link up if device can't report link status, | 1575 | /* Assume link up if device can't report link status, |
1503 | otherwise get link status from config. */ | 1576 | otherwise get link status from config. */ |
1504 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { | 1577 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { |
@@ -1520,6 +1593,8 @@ free_recv_bufs: | |||
1520 | free_vqs: | 1593 | free_vqs: |
1521 | cancel_delayed_work_sync(&vi->refill); | 1594 | cancel_delayed_work_sync(&vi->refill); |
1522 | virtnet_del_vqs(vi); | 1595 | virtnet_del_vqs(vi); |
1596 | free_index: | ||
1597 | free_percpu(vi->vq_index); | ||
1523 | free_stats: | 1598 | free_stats: |
1524 | free_percpu(vi->stats); | 1599 | free_percpu(vi->stats); |
1525 | free: | 1600 | free: |
@@ -1543,6 +1618,8 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
1543 | { | 1618 | { |
1544 | struct virtnet_info *vi = vdev->priv; | 1619 | struct virtnet_info *vi = vdev->priv; |
1545 | 1620 | ||
1621 | unregister_hotcpu_notifier(&vi->nb); | ||
1622 | |||
1546 | /* Prevent config work handler from accessing the device. */ | 1623 | /* Prevent config work handler from accessing the device. */ |
1547 | mutex_lock(&vi->config_lock); | 1624 | mutex_lock(&vi->config_lock); |
1548 | vi->config_enable = false; | 1625 | vi->config_enable = false; |
@@ -1554,6 +1631,7 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
1554 | 1631 | ||
1555 | flush_work(&vi->config_work); | 1632 | flush_work(&vi->config_work); |
1556 | 1633 | ||
1634 | free_percpu(vi->vq_index); | ||
1557 | free_percpu(vi->stats); | 1635 | free_percpu(vi->stats); |
1558 | free_netdev(vi->dev); | 1636 | free_netdev(vi->dev); |
1559 | } | 1637 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8b0d8dcd7625..56317b0fb6b6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
976 | AR_PHY_CL_TAB_1, | 976 | AR_PHY_CL_TAB_1, |
977 | AR_PHY_CL_TAB_2 }; | 977 | AR_PHY_CL_TAB_2 }; |
978 | 978 | ||
979 | ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); | ||
980 | |||
979 | if (rtt) { | 981 | if (rtt) { |
980 | if (!ar9003_hw_rtt_restore(ah, chan)) | 982 | if (!ar9003_hw_rtt_restore(ah, chan)) |
981 | run_rtt_cal = true; | 983 | run_rtt_cal = true; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index ce19c09fa8e8..3afc24bde6d6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, | |||
586 | ath9k_hw_synth_delay(ah, chan, synthDelay); | 586 | ath9k_hw_synth_delay(ah, chan, synthDelay); |
587 | } | 587 | } |
588 | 588 | ||
589 | static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) | 589 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) |
590 | { | 590 | { |
591 | switch (rx) { | 591 | if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5) |
592 | case 0x5: | ||
593 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | 592 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, |
594 | AR_PHY_SWAP_ALT_CHAIN); | 593 | AR_PHY_SWAP_ALT_CHAIN); |
595 | case 0x3: | 594 | |
596 | case 0x1: | 595 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); |
597 | case 0x2: | 596 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); |
598 | case 0x7: | ||
599 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); | ||
600 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); | ||
601 | break; | ||
602 | default: | ||
603 | break; | ||
604 | } | ||
605 | 597 | ||
606 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) | 598 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) |
607 | REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); | 599 | tx = 3; |
608 | else | ||
609 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); | ||
610 | 600 | ||
611 | if (tx == 0x5) { | 601 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); |
612 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
613 | AR_PHY_SWAP_ALT_CHAIN); | ||
614 | } | ||
615 | } | 602 | } |
616 | 603 | ||
617 | /* | 604 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 86e26a19efda..42794c546a40 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -317,7 +317,6 @@ struct ath_rx { | |||
317 | u32 *rxlink; | 317 | u32 *rxlink; |
318 | u32 num_pkts; | 318 | u32 num_pkts; |
319 | unsigned int rxfilter; | 319 | unsigned int rxfilter; |
320 | spinlock_t rxbuflock; | ||
321 | struct list_head rxbuf; | 320 | struct list_head rxbuf; |
322 | struct ath_descdma rxdma; | 321 | struct ath_descdma rxdma; |
323 | struct ath_buf *rx_bufptr; | 322 | struct ath_buf *rx_bufptr; |
@@ -328,7 +327,6 @@ struct ath_rx { | |||
328 | 327 | ||
329 | int ath_startrecv(struct ath_softc *sc); | 328 | int ath_startrecv(struct ath_softc *sc); |
330 | bool ath_stoprecv(struct ath_softc *sc); | 329 | bool ath_stoprecv(struct ath_softc *sc); |
331 | void ath_flushrecv(struct ath_softc *sc); | ||
332 | u32 ath_calcrxfilter(struct ath_softc *sc); | 330 | u32 ath_calcrxfilter(struct ath_softc *sc); |
333 | int ath_rx_init(struct ath_softc *sc, int nbufs); | 331 | int ath_rx_init(struct ath_softc *sc, int nbufs); |
334 | void ath_rx_cleanup(struct ath_softc *sc); | 332 | void ath_rx_cleanup(struct ath_softc *sc); |
@@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc); | |||
646 | enum sc_op_flags { | 644 | enum sc_op_flags { |
647 | SC_OP_INVALID, | 645 | SC_OP_INVALID, |
648 | SC_OP_BEACONS, | 646 | SC_OP_BEACONS, |
649 | SC_OP_RXFLUSH, | ||
650 | SC_OP_ANI_RUN, | 647 | SC_OP_ANI_RUN, |
651 | SC_OP_PRIM_STA_VIF, | 648 | SC_OP_PRIM_STA_VIF, |
652 | SC_OP_HW_RESET, | 649 | SC_OP_HW_RESET, |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 531fffd801a3..2ca355e94da6 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, | |||
147 | skb->len, DMA_TO_DEVICE); | 147 | skb->len, DMA_TO_DEVICE); |
148 | dev_kfree_skb_any(skb); | 148 | dev_kfree_skb_any(skb); |
149 | bf->bf_buf_addr = 0; | 149 | bf->bf_buf_addr = 0; |
150 | bf->bf_mpdu = NULL; | ||
150 | } | 151 | } |
151 | 152 | ||
152 | skb = ieee80211_beacon_get(hw, vif); | 153 | skb = ieee80211_beacon_get(hw, vif); |
@@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
359 | return; | 360 | return; |
360 | 361 | ||
361 | bf = ath9k_beacon_generate(sc->hw, vif); | 362 | bf = ath9k_beacon_generate(sc->hw, vif); |
362 | WARN_ON(!bf); | ||
363 | 363 | ||
364 | if (sc->beacon.bmisscnt != 0) { | 364 | if (sc->beacon.bmisscnt != 0) { |
365 | ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", | 365 | ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 13ff9edc2401..e585fc827c50 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
861 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); | 861 | RXS_ERR("RX-LENGTH-ERR", rx_len_err); |
862 | RXS_ERR("RX-OOM-ERR", rx_oom_err); | 862 | RXS_ERR("RX-OOM-ERR", rx_oom_err); |
863 | RXS_ERR("RX-RATE-ERR", rx_rate_err); | 863 | RXS_ERR("RX-RATE-ERR", rx_rate_err); |
864 | RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush); | ||
865 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); | 864 | RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err); |
866 | 865 | ||
867 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); | 866 | PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 375c3b46411e..6df2ab62dcb7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -216,7 +216,6 @@ struct ath_tx_stats { | |||
216 | * @rx_oom_err: No. of frames dropped due to OOM issues. | 216 | * @rx_oom_err: No. of frames dropped due to OOM issues. |
217 | * @rx_rate_err: No. of frames dropped due to rate errors. | 217 | * @rx_rate_err: No. of frames dropped due to rate errors. |
218 | * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. | 218 | * @rx_too_many_frags_err: Frames dropped due to too-many-frags received. |
219 | * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH. | ||
220 | * @rx_beacons: No. of beacons received. | 219 | * @rx_beacons: No. of beacons received. |
221 | * @rx_frags: No. of rx-fragements received. | 220 | * @rx_frags: No. of rx-fragements received. |
222 | */ | 221 | */ |
@@ -235,7 +234,6 @@ struct ath_rx_stats { | |||
235 | u32 rx_oom_err; | 234 | u32 rx_oom_err; |
236 | u32 rx_rate_err; | 235 | u32 rx_rate_err; |
237 | u32 rx_too_many_frags_err; | 236 | u32 rx_too_many_frags_err; |
238 | u32 rx_drop_rxflush; | ||
239 | u32 rx_beacons; | 237 | u32 rx_beacons; |
240 | u32 rx_frags; | 238 | u32 rx_frags; |
241 | }; | 239 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 4a9570dfba72..aac4a406a513 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | |||
344 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, | 344 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, |
345 | skb, htc_hdr->endpoint_id, | 345 | skb, htc_hdr->endpoint_id, |
346 | txok); | 346 | txok); |
347 | } else { | ||
348 | kfree_skb(skb); | ||
347 | } | 349 | } |
348 | } | 350 | } |
349 | 351 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7f1a8e91c908..9d26fc56ca56 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); | |||
1066 | int ar9003_paprd_init_table(struct ath_hw *ah); | 1066 | int ar9003_paprd_init_table(struct ath_hw *ah); |
1067 | bool ar9003_paprd_is_done(struct ath_hw *ah); | 1067 | bool ar9003_paprd_is_done(struct ath_hw *ah); |
1068 | bool ar9003_is_paprd_enabled(struct ath_hw *ah); | 1068 | bool ar9003_is_paprd_enabled(struct ath_hw *ah); |
1069 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); | ||
1069 | 1070 | ||
1070 | /* Hardware family op attach helpers */ | 1071 | /* Hardware family op attach helpers */ |
1071 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); | 1072 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index be30a9af1528..dd91f8fdc01c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc) | |||
182 | ath_start_ani(sc); | 182 | ath_start_ani(sc); |
183 | } | 183 | } |
184 | 184 | ||
185 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | 185 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx) |
186 | { | 186 | { |
187 | struct ath_hw *ah = sc->sc_ah; | 187 | struct ath_hw *ah = sc->sc_ah; |
188 | bool ret = true; | 188 | bool ret = true; |
@@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | |||
202 | if (!ath_drain_all_txq(sc, retry_tx)) | 202 | if (!ath_drain_all_txq(sc, retry_tx)) |
203 | ret = false; | 203 | ret = false; |
204 | 204 | ||
205 | if (!flush) { | ||
206 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
207 | ath_rx_tasklet(sc, 1, true); | ||
208 | ath_rx_tasklet(sc, 1, false); | ||
209 | } else { | ||
210 | ath_flushrecv(sc); | ||
211 | } | ||
212 | |||
213 | return ret; | 205 | return ret; |
214 | } | 206 | } |
215 | 207 | ||
@@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
262 | struct ath_common *common = ath9k_hw_common(ah); | 254 | struct ath_common *common = ath9k_hw_common(ah); |
263 | struct ath9k_hw_cal_data *caldata = NULL; | 255 | struct ath9k_hw_cal_data *caldata = NULL; |
264 | bool fastcc = true; | 256 | bool fastcc = true; |
265 | bool flush = false; | ||
266 | int r; | 257 | int r; |
267 | 258 | ||
268 | __ath_cancel_work(sc); | 259 | __ath_cancel_work(sc); |
269 | 260 | ||
261 | tasklet_disable(&sc->intr_tq); | ||
270 | spin_lock_bh(&sc->sc_pcu_lock); | 262 | spin_lock_bh(&sc->sc_pcu_lock); |
271 | 263 | ||
272 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { | 264 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { |
@@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
276 | 268 | ||
277 | if (!hchan) { | 269 | if (!hchan) { |
278 | fastcc = false; | 270 | fastcc = false; |
279 | flush = true; | ||
280 | hchan = ah->curchan; | 271 | hchan = ah->curchan; |
281 | } | 272 | } |
282 | 273 | ||
283 | if (!ath_prepare_reset(sc, retry_tx, flush)) | 274 | if (!ath_prepare_reset(sc, retry_tx)) |
284 | fastcc = false; | 275 | fastcc = false; |
285 | 276 | ||
286 | ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", | 277 | ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", |
@@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
302 | 293 | ||
303 | out: | 294 | out: |
304 | spin_unlock_bh(&sc->sc_pcu_lock); | 295 | spin_unlock_bh(&sc->sc_pcu_lock); |
296 | tasklet_enable(&sc->intr_tq); | ||
297 | |||
305 | return r; | 298 | return r; |
306 | } | 299 | } |
307 | 300 | ||
@@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
804 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); | 797 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); |
805 | } | 798 | } |
806 | 799 | ||
807 | ath_prepare_reset(sc, false, true); | 800 | ath_prepare_reset(sc, false); |
808 | 801 | ||
809 | if (sc->rx.frag) { | 802 | if (sc->rx.frag) { |
810 | dev_kfree_skb_any(sc->rx.frag); | 803 | dev_kfree_skb_any(sc->rx.frag); |
@@ -1833,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new) | |||
1833 | 1826 | ||
1834 | static bool validate_antenna_mask(struct ath_hw *ah, u32 val) | 1827 | static bool validate_antenna_mask(struct ath_hw *ah, u32 val) |
1835 | { | 1828 | { |
1829 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
1830 | return true; | ||
1831 | |||
1836 | switch (val & 0x7) { | 1832 | switch (val & 0x7) { |
1837 | case 0x1: | 1833 | case 0x1: |
1838 | case 0x3: | 1834 | case 0x3: |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index d4df98a938bf..90752f246970 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -254,8 +254,6 @@ rx_init_fail: | |||
254 | 254 | ||
255 | static void ath_edma_start_recv(struct ath_softc *sc) | 255 | static void ath_edma_start_recv(struct ath_softc *sc) |
256 | { | 256 | { |
257 | spin_lock_bh(&sc->rx.rxbuflock); | ||
258 | |||
259 | ath9k_hw_rxena(sc->sc_ah); | 257 | ath9k_hw_rxena(sc->sc_ah); |
260 | 258 | ||
261 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, | 259 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, |
@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc) | |||
267 | ath_opmode_init(sc); | 265 | ath_opmode_init(sc); |
268 | 266 | ||
269 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); | 267 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
270 | |||
271 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
272 | } | 268 | } |
273 | 269 | ||
274 | static void ath_edma_stop_recv(struct ath_softc *sc) | 270 | static void ath_edma_stop_recv(struct ath_softc *sc) |
@@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
285 | int error = 0; | 281 | int error = 0; |
286 | 282 | ||
287 | spin_lock_init(&sc->sc_pcu_lock); | 283 | spin_lock_init(&sc->sc_pcu_lock); |
288 | spin_lock_init(&sc->rx.rxbuflock); | ||
289 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
290 | 284 | ||
291 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + | 285 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + |
292 | sc->sc_ah->caps.rx_status_len; | 286 | sc->sc_ah->caps.rx_status_len; |
@@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc) | |||
447 | return 0; | 441 | return 0; |
448 | } | 442 | } |
449 | 443 | ||
450 | spin_lock_bh(&sc->rx.rxbuflock); | ||
451 | if (list_empty(&sc->rx.rxbuf)) | 444 | if (list_empty(&sc->rx.rxbuf)) |
452 | goto start_recv; | 445 | goto start_recv; |
453 | 446 | ||
@@ -468,26 +461,31 @@ start_recv: | |||
468 | ath_opmode_init(sc); | 461 | ath_opmode_init(sc); |
469 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); | 462 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
470 | 463 | ||
471 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
472 | |||
473 | return 0; | 464 | return 0; |
474 | } | 465 | } |
475 | 466 | ||
467 | static void ath_flushrecv(struct ath_softc *sc) | ||
468 | { | ||
469 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
470 | ath_rx_tasklet(sc, 1, true); | ||
471 | ath_rx_tasklet(sc, 1, false); | ||
472 | } | ||
473 | |||
476 | bool ath_stoprecv(struct ath_softc *sc) | 474 | bool ath_stoprecv(struct ath_softc *sc) |
477 | { | 475 | { |
478 | struct ath_hw *ah = sc->sc_ah; | 476 | struct ath_hw *ah = sc->sc_ah; |
479 | bool stopped, reset = false; | 477 | bool stopped, reset = false; |
480 | 478 | ||
481 | spin_lock_bh(&sc->rx.rxbuflock); | ||
482 | ath9k_hw_abortpcurecv(ah); | 479 | ath9k_hw_abortpcurecv(ah); |
483 | ath9k_hw_setrxfilter(ah, 0); | 480 | ath9k_hw_setrxfilter(ah, 0); |
484 | stopped = ath9k_hw_stopdmarecv(ah, &reset); | 481 | stopped = ath9k_hw_stopdmarecv(ah, &reset); |
485 | 482 | ||
483 | ath_flushrecv(sc); | ||
484 | |||
486 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 485 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
487 | ath_edma_stop_recv(sc); | 486 | ath_edma_stop_recv(sc); |
488 | else | 487 | else |
489 | sc->rx.rxlink = NULL; | 488 | sc->rx.rxlink = NULL; |
490 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
491 | 489 | ||
492 | if (!(ah->ah_flags & AH_UNPLUGGED) && | 490 | if (!(ah->ah_flags & AH_UNPLUGGED) && |
493 | unlikely(!stopped)) { | 491 | unlikely(!stopped)) { |
@@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
499 | return stopped && !reset; | 497 | return stopped && !reset; |
500 | } | 498 | } |
501 | 499 | ||
502 | void ath_flushrecv(struct ath_softc *sc) | ||
503 | { | ||
504 | set_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
505 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
506 | ath_rx_tasklet(sc, 1, true); | ||
507 | ath_rx_tasklet(sc, 1, false); | ||
508 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
509 | } | ||
510 | |||
511 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) | 500 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) |
512 | { | 501 | { |
513 | /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ | 502 | /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */ |
@@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
744 | return NULL; | 733 | return NULL; |
745 | } | 734 | } |
746 | 735 | ||
736 | list_del(&bf->list); | ||
747 | if (!bf->bf_mpdu) | 737 | if (!bf->bf_mpdu) |
748 | return bf; | 738 | return bf; |
749 | 739 | ||
@@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1059 | dma_type = DMA_FROM_DEVICE; | 1049 | dma_type = DMA_FROM_DEVICE; |
1060 | 1050 | ||
1061 | qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; | 1051 | qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; |
1062 | spin_lock_bh(&sc->rx.rxbuflock); | ||
1063 | 1052 | ||
1064 | tsf = ath9k_hw_gettsf64(ah); | 1053 | tsf = ath9k_hw_gettsf64(ah); |
1065 | tsf_lower = tsf & 0xffffffff; | 1054 | tsf_lower = tsf & 0xffffffff; |
1066 | 1055 | ||
1067 | do { | 1056 | do { |
1068 | bool decrypt_error = false; | 1057 | bool decrypt_error = false; |
1069 | /* If handling rx interrupt and flush is in progress => exit */ | ||
1070 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) | ||
1071 | break; | ||
1072 | 1058 | ||
1073 | memset(&rs, 0, sizeof(rs)); | 1059 | memset(&rs, 0, sizeof(rs)); |
1074 | if (edma) | 1060 | if (edma) |
@@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1111 | 1097 | ||
1112 | ath_debug_stat_rx(sc, &rs); | 1098 | ath_debug_stat_rx(sc, &rs); |
1113 | 1099 | ||
1114 | /* | ||
1115 | * If we're asked to flush receive queue, directly | ||
1116 | * chain it back at the queue without processing it. | ||
1117 | */ | ||
1118 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) { | ||
1119 | RX_STAT_INC(rx_drop_rxflush); | ||
1120 | goto requeue_drop_frag; | ||
1121 | } | ||
1122 | |||
1123 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); | 1100 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); |
1124 | 1101 | ||
1125 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; | 1102 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; |
@@ -1254,19 +1231,18 @@ requeue_drop_frag: | |||
1254 | sc->rx.frag = NULL; | 1231 | sc->rx.frag = NULL; |
1255 | } | 1232 | } |
1256 | requeue: | 1233 | requeue: |
1234 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
1235 | if (flush) | ||
1236 | continue; | ||
1237 | |||
1257 | if (edma) { | 1238 | if (edma) { |
1258 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
1259 | ath_rx_edma_buf_link(sc, qtype); | 1239 | ath_rx_edma_buf_link(sc, qtype); |
1260 | } else { | 1240 | } else { |
1261 | list_move_tail(&bf->list, &sc->rx.rxbuf); | ||
1262 | ath_rx_buf_link(sc, bf); | 1241 | ath_rx_buf_link(sc, bf); |
1263 | if (!flush) | 1242 | ath9k_hw_rxena(ah); |
1264 | ath9k_hw_rxena(ah); | ||
1265 | } | 1243 | } |
1266 | } while (1); | 1244 | } while (1); |
1267 | 1245 | ||
1268 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
1269 | |||
1270 | if (!(ah->imask & ATH9K_INT_RXEOL)) { | 1246 | if (!(ah->imask & ATH9K_INT_RXEOL)) { |
1271 | ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | 1247 | ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN); |
1272 | ath9k_hw_set_interrupts(ah); | 1248 | ath9k_hw_set_interrupts(ah); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 1fbd8ecbe2ea..0f71d1d4339d 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -1407,9 +1407,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) | |||
1407 | #endif | 1407 | #endif |
1408 | t->ms = ms; | 1408 | t->ms = ms; |
1409 | t->periodic = (bool) periodic; | 1409 | t->periodic = (bool) periodic; |
1410 | t->set = true; | 1410 | if (!t->set) { |
1411 | 1411 | t->set = true; | |
1412 | atomic_inc(&t->wl->callbacks); | 1412 | atomic_inc(&t->wl->callbacks); |
1413 | } | ||
1413 | 1414 | ||
1414 | ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms)); | 1415 | ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms)); |
1415 | } | 1416 | } |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 7e16d10a7f14..90b8970eadf0 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il) | |||
3958 | 3958 | ||
3959 | memset(&il->staging, 0, sizeof(il->staging)); | 3959 | memset(&il->staging, 0, sizeof(il->staging)); |
3960 | 3960 | ||
3961 | if (!il->vif) { | 3961 | switch (il->iw_mode) { |
3962 | case NL80211_IFTYPE_UNSPECIFIED: | ||
3962 | il->staging.dev_type = RXON_DEV_TYPE_ESS; | 3963 | il->staging.dev_type = RXON_DEV_TYPE_ESS; |
3963 | } else if (il->vif->type == NL80211_IFTYPE_STATION) { | 3964 | break; |
3965 | case NL80211_IFTYPE_STATION: | ||
3964 | il->staging.dev_type = RXON_DEV_TYPE_ESS; | 3966 | il->staging.dev_type = RXON_DEV_TYPE_ESS; |
3965 | il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; | 3967 | il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; |
3966 | } else if (il->vif->type == NL80211_IFTYPE_ADHOC) { | 3968 | break; |
3969 | case NL80211_IFTYPE_ADHOC: | ||
3967 | il->staging.dev_type = RXON_DEV_TYPE_IBSS; | 3970 | il->staging.dev_type = RXON_DEV_TYPE_IBSS; |
3968 | il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; | 3971 | il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; |
3969 | il->staging.filter_flags = | 3972 | il->staging.filter_flags = |
3970 | RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; | 3973 | RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; |
3971 | } else { | 3974 | break; |
3975 | default: | ||
3972 | IL_ERR("Unsupported interface type %d\n", il->vif->type); | 3976 | IL_ERR("Unsupported interface type %d\n", il->vif->type); |
3973 | return; | 3977 | return; |
3974 | } | 3978 | } |
@@ -4550,8 +4554,7 @@ out: | |||
4550 | EXPORT_SYMBOL(il_mac_add_interface); | 4554 | EXPORT_SYMBOL(il_mac_add_interface); |
4551 | 4555 | ||
4552 | static void | 4556 | static void |
4553 | il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, | 4557 | il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif) |
4554 | bool mode_change) | ||
4555 | { | 4558 | { |
4556 | lockdep_assert_held(&il->mutex); | 4559 | lockdep_assert_held(&il->mutex); |
4557 | 4560 | ||
@@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, | |||
4560 | il_force_scan_end(il); | 4563 | il_force_scan_end(il); |
4561 | } | 4564 | } |
4562 | 4565 | ||
4563 | if (!mode_change) | 4566 | il_set_mode(il); |
4564 | il_set_mode(il); | ||
4565 | |||
4566 | } | 4567 | } |
4567 | 4568 | ||
4568 | void | 4569 | void |
@@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
4575 | 4576 | ||
4576 | WARN_ON(il->vif != vif); | 4577 | WARN_ON(il->vif != vif); |
4577 | il->vif = NULL; | 4578 | il->vif = NULL; |
4578 | 4579 | il->iw_mode = NL80211_IFTYPE_UNSPECIFIED; | |
4579 | il_teardown_interface(il, vif, false); | 4580 | il_teardown_interface(il, vif); |
4580 | memset(il->bssid, 0, ETH_ALEN); | 4581 | memset(il->bssid, 0, ETH_ALEN); |
4581 | 4582 | ||
4582 | D_MAC80211("leave\n"); | 4583 | D_MAC80211("leave\n"); |
@@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
4685 | } | 4686 | } |
4686 | 4687 | ||
4687 | /* success */ | 4688 | /* success */ |
4688 | il_teardown_interface(il, vif, true); | ||
4689 | vif->type = newtype; | 4689 | vif->type = newtype; |
4690 | vif->p2p = false; | 4690 | vif->p2p = false; |
4691 | err = il_set_mode(il); | 4691 | il->iw_mode = newtype; |
4692 | WARN_ON(err); | 4692 | il_teardown_interface(il, vif); |
4693 | /* | ||
4694 | * We've switched internally, but submitting to the | ||
4695 | * device may have failed for some reason. Mask this | ||
4696 | * error, because otherwise mac80211 will not switch | ||
4697 | * (and set the interface type back) and we'll be | ||
4698 | * out of sync with it. | ||
4699 | */ | ||
4700 | err = 0; | 4693 | err = 0; |
4701 | 4694 | ||
4702 | out: | 4695 | out: |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a790599fe2c2..31534f7c0548 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -1079,6 +1079,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, | |||
1079 | { | 1079 | { |
1080 | u16 status = le16_to_cpu(tx_resp->status.status); | 1080 | u16 status = le16_to_cpu(tx_resp->status.status); |
1081 | 1081 | ||
1082 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
1083 | |||
1082 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1084 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1083 | info->flags |= iwl_tx_status_to_mac80211(status); | 1085 | info->flags |= iwl_tx_status_to_mac80211(status); |
1084 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | 1086 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index efe525be27dd..cdb11b3964e2 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -1459,7 +1459,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1459 | struct cfg80211_ssid req_ssid; | 1459 | struct cfg80211_ssid req_ssid; |
1460 | int ret, auth_type = 0; | 1460 | int ret, auth_type = 0; |
1461 | struct cfg80211_bss *bss = NULL; | 1461 | struct cfg80211_bss *bss = NULL; |
1462 | u8 is_scanning_required = 0, config_bands = 0; | 1462 | u8 is_scanning_required = 0; |
1463 | 1463 | ||
1464 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); | 1464 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); |
1465 | 1465 | ||
@@ -1478,19 +1478,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1478 | /* disconnect before try to associate */ | 1478 | /* disconnect before try to associate */ |
1479 | mwifiex_deauthenticate(priv, NULL); | 1479 | mwifiex_deauthenticate(priv, NULL); |
1480 | 1480 | ||
1481 | if (channel) { | ||
1482 | if (mode == NL80211_IFTYPE_STATION) { | ||
1483 | if (channel->band == IEEE80211_BAND_2GHZ) | ||
1484 | config_bands = BAND_B | BAND_G | BAND_GN; | ||
1485 | else | ||
1486 | config_bands = BAND_A | BAND_AN; | ||
1487 | |||
1488 | if (!((config_bands | priv->adapter->fw_bands) & | ||
1489 | ~priv->adapter->fw_bands)) | ||
1490 | priv->adapter->config_bands = config_bands; | ||
1491 | } | ||
1492 | } | ||
1493 | |||
1494 | /* As this is new association, clear locally stored | 1481 | /* As this is new association, clear locally stored |
1495 | * keys and security related flags */ | 1482 | * keys and security related flags */ |
1496 | priv->sec_info.wpa_enabled = false; | 1483 | priv->sec_info.wpa_enabled = false; |
@@ -1707,7 +1694,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv, | |||
1707 | 1694 | ||
1708 | if (cfg80211_get_chandef_type(¶ms->chandef) != | 1695 | if (cfg80211_get_chandef_type(¶ms->chandef) != |
1709 | NL80211_CHAN_NO_HT) | 1696 | NL80211_CHAN_NO_HT) |
1710 | config_bands |= BAND_GN; | 1697 | config_bands |= BAND_G | BAND_GN; |
1711 | } else { | 1698 | } else { |
1712 | if (cfg80211_get_chandef_type(¶ms->chandef) == | 1699 | if (cfg80211_get_chandef_type(¶ms->chandef) == |
1713 | NL80211_CHAN_NO_HT) | 1700 | NL80211_CHAN_NO_HT) |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 13fbc4eb1595..b879e1338a54 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -161,7 +161,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) | |||
161 | 161 | ||
162 | if (pdev) { | 162 | if (pdev) { |
163 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); | 163 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); |
164 | if (!card || card->adapter) { | 164 | if (!card || !card->adapter) { |
165 | pr_err("Card or adapter structure is not valid\n"); | 165 | pr_err("Card or adapter structure is not valid\n"); |
166 | return 0; | 166 | return 0; |
167 | } | 167 | } |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 60e88b58039d..f542bb8ccbc8 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -283,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
283 | if (ret) | 283 | if (ret) |
284 | goto done; | 284 | goto done; |
285 | 285 | ||
286 | if (bss_desc) { | ||
287 | u8 config_bands = 0; | ||
288 | |||
289 | if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band) | ||
290 | == HostCmd_SCAN_RADIO_TYPE_BG) | ||
291 | config_bands = BAND_B | BAND_G | BAND_GN; | ||
292 | else | ||
293 | config_bands = BAND_A | BAND_AN; | ||
294 | |||
295 | if (!((config_bands | adapter->fw_bands) & | ||
296 | ~adapter->fw_bands)) | ||
297 | adapter->config_bands = config_bands; | ||
298 | } | ||
299 | |||
286 | ret = mwifiex_check_network_compatibility(priv, bss_desc); | 300 | ret = mwifiex_check_network_compatibility(priv, bss_desc); |
287 | if (ret) | 301 | if (ret) |
288 | goto done; | 302 | goto done; |
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 21b1bbb93a7e..b80bc4612581 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig | |||
@@ -57,12 +57,12 @@ config RTL8192CU | |||
57 | 57 | ||
58 | config RTLWIFI | 58 | config RTLWIFI |
59 | tristate | 59 | tristate |
60 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE | 60 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE |
61 | default m | 61 | default m |
62 | 62 | ||
63 | config RTLWIFI_DEBUG | 63 | config RTLWIFI_DEBUG |
64 | bool "Additional debugging output" | 64 | bool "Additional debugging output" |
65 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE | 65 | depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE |
66 | default y | 66 | default y |
67 | 67 | ||
68 | config RTL8192C_COMMON | 68 | config RTL8192C_COMMON |
diff --git a/include/linux/security.h b/include/linux/security.h index 0f6afc657f77..eee7478cda70 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -989,17 +989,29 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
989 | * tells the LSM to decrement the number of secmark labeling rules loaded | 989 | * tells the LSM to decrement the number of secmark labeling rules loaded |
990 | * @req_classify_flow: | 990 | * @req_classify_flow: |
991 | * Sets the flow's sid to the openreq sid. | 991 | * Sets the flow's sid to the openreq sid. |
992 | * @tun_dev_alloc_security: | ||
993 | * This hook allows a module to allocate a security structure for a TUN | ||
994 | * device. | ||
995 | * @security pointer to a security structure pointer. | ||
996 | * Returns a zero on success, negative values on failure. | ||
997 | * @tun_dev_free_security: | ||
998 | * This hook allows a module to free the security structure for a TUN | ||
999 | * device. | ||
1000 | * @security pointer to the TUN device's security structure | ||
992 | * @tun_dev_create: | 1001 | * @tun_dev_create: |
993 | * Check permissions prior to creating a new TUN device. | 1002 | * Check permissions prior to creating a new TUN device. |
994 | * @tun_dev_post_create: | 1003 | * @tun_dev_attach_queue: |
995 | * This hook allows a module to update or allocate a per-socket security | 1004 | * Check permissions prior to attaching to a TUN device queue. |
996 | * structure. | 1005 | * @security pointer to the TUN device's security structure. |
997 | * @sk contains the newly created sock structure. | ||
998 | * @tun_dev_attach: | 1006 | * @tun_dev_attach: |
999 | * Check permissions prior to attaching to a persistent TUN device. This | 1007 | * This hook can be used by the module to update any security state |
1000 | * hook can also be used by the module to update any security state | ||
1001 | * associated with the TUN device's sock structure. | 1008 | * associated with the TUN device's sock structure. |
1002 | * @sk contains the existing sock structure. | 1009 | * @sk contains the existing sock structure. |
1010 | * @security pointer to the TUN device's security structure. | ||
1011 | * @tun_dev_open: | ||
1012 | * This hook can be used by the module to update any security state | ||
1013 | * associated with the TUN device's security structure. | ||
1014 | * @security pointer to the TUN devices's security structure. | ||
1003 | * | 1015 | * |
1004 | * Security hooks for XFRM operations. | 1016 | * Security hooks for XFRM operations. |
1005 | * | 1017 | * |
@@ -1620,9 +1632,12 @@ struct security_operations { | |||
1620 | void (*secmark_refcount_inc) (void); | 1632 | void (*secmark_refcount_inc) (void); |
1621 | void (*secmark_refcount_dec) (void); | 1633 | void (*secmark_refcount_dec) (void); |
1622 | void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl); | 1634 | void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl); |
1623 | int (*tun_dev_create)(void); | 1635 | int (*tun_dev_alloc_security) (void **security); |
1624 | void (*tun_dev_post_create)(struct sock *sk); | 1636 | void (*tun_dev_free_security) (void *security); |
1625 | int (*tun_dev_attach)(struct sock *sk); | 1637 | int (*tun_dev_create) (void); |
1638 | int (*tun_dev_attach_queue) (void *security); | ||
1639 | int (*tun_dev_attach) (struct sock *sk, void *security); | ||
1640 | int (*tun_dev_open) (void *security); | ||
1626 | #endif /* CONFIG_SECURITY_NETWORK */ | 1641 | #endif /* CONFIG_SECURITY_NETWORK */ |
1627 | 1642 | ||
1628 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1643 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
@@ -2566,9 +2581,12 @@ void security_inet_conn_established(struct sock *sk, | |||
2566 | int security_secmark_relabel_packet(u32 secid); | 2581 | int security_secmark_relabel_packet(u32 secid); |
2567 | void security_secmark_refcount_inc(void); | 2582 | void security_secmark_refcount_inc(void); |
2568 | void security_secmark_refcount_dec(void); | 2583 | void security_secmark_refcount_dec(void); |
2584 | int security_tun_dev_alloc_security(void **security); | ||
2585 | void security_tun_dev_free_security(void *security); | ||
2569 | int security_tun_dev_create(void); | 2586 | int security_tun_dev_create(void); |
2570 | void security_tun_dev_post_create(struct sock *sk); | 2587 | int security_tun_dev_attach_queue(void *security); |
2571 | int security_tun_dev_attach(struct sock *sk); | 2588 | int security_tun_dev_attach(struct sock *sk, void *security); |
2589 | int security_tun_dev_open(void *security); | ||
2572 | 2590 | ||
2573 | #else /* CONFIG_SECURITY_NETWORK */ | 2591 | #else /* CONFIG_SECURITY_NETWORK */ |
2574 | static inline int security_unix_stream_connect(struct sock *sock, | 2592 | static inline int security_unix_stream_connect(struct sock *sock, |
@@ -2733,16 +2751,31 @@ static inline void security_secmark_refcount_dec(void) | |||
2733 | { | 2751 | { |
2734 | } | 2752 | } |
2735 | 2753 | ||
2754 | static inline int security_tun_dev_alloc_security(void **security) | ||
2755 | { | ||
2756 | return 0; | ||
2757 | } | ||
2758 | |||
2759 | static inline void security_tun_dev_free_security(void *security) | ||
2760 | { | ||
2761 | } | ||
2762 | |||
2736 | static inline int security_tun_dev_create(void) | 2763 | static inline int security_tun_dev_create(void) |
2737 | { | 2764 | { |
2738 | return 0; | 2765 | return 0; |
2739 | } | 2766 | } |
2740 | 2767 | ||
2741 | static inline void security_tun_dev_post_create(struct sock *sk) | 2768 | static inline int security_tun_dev_attach_queue(void *security) |
2769 | { | ||
2770 | return 0; | ||
2771 | } | ||
2772 | |||
2773 | static inline int security_tun_dev_attach(struct sock *sk, void *security) | ||
2742 | { | 2774 | { |
2775 | return 0; | ||
2743 | } | 2776 | } |
2744 | 2777 | ||
2745 | static inline int security_tun_dev_attach(struct sock *sk) | 2778 | static inline int security_tun_dev_open(void *security) |
2746 | { | 2779 | { |
2747 | return 0; | 2780 | return 0; |
2748 | } | 2781 | } |
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index bd45eb7bedc8..5de7a220e986 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h | |||
@@ -100,6 +100,7 @@ struct driver_info { | |||
100 | #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ | 100 | #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ |
101 | 101 | ||
102 | #define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */ | 102 | #define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */ |
103 | #define FLAG_NOARP 0x2000 /* device can't do ARP */ | ||
103 | 104 | ||
104 | /* | 105 | /* |
105 | * Indicates to usbnet, that USB driver accumulates multiple IP packets. | 106 | * Indicates to usbnet, that USB driver accumulates multiple IP packets. |
diff --git a/include/net/ip.h b/include/net/ip.h index 0707fb9551aa..a68f838a132c 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -143,6 +143,8 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) | |||
143 | extern int ip4_datagram_connect(struct sock *sk, | 143 | extern int ip4_datagram_connect(struct sock *sk, |
144 | struct sockaddr *uaddr, int addr_len); | 144 | struct sockaddr *uaddr, int addr_len); |
145 | 145 | ||
146 | extern void ip4_datagram_release_cb(struct sock *sk); | ||
147 | |||
146 | struct ip_reply_arg { | 148 | struct ip_reply_arg { |
147 | struct kvec iov[1]; | 149 | struct kvec iov[1]; |
148 | int flags; | 150 | int flags; |
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index d8f5b9f52169..e98aeb3da033 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h | |||
@@ -31,6 +31,8 @@ extern void nf_conntrack_cleanup(struct net *net); | |||
31 | extern int nf_conntrack_proto_init(struct net *net); | 31 | extern int nf_conntrack_proto_init(struct net *net); |
32 | extern void nf_conntrack_proto_fini(struct net *net); | 32 | extern void nf_conntrack_proto_fini(struct net *net); |
33 | 33 | ||
34 | extern void nf_conntrack_cleanup_end(void); | ||
35 | |||
34 | extern bool | 36 | extern bool |
35 | nf_ct_get_tuple(const struct sk_buff *skb, | 37 | nf_ct_get_tuple(const struct sk_buff *skb, |
36 | unsigned int nhoff, | 38 | unsigned int nhoff, |
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 8e1d89d2b1c1..183f97a86bb2 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c | |||
@@ -738,6 +738,7 @@ static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv, | |||
738 | struct arphdr *arphdr; | 738 | struct arphdr *arphdr; |
739 | struct ethhdr *ethhdr; | 739 | struct ethhdr *ethhdr; |
740 | __be32 ip_src, ip_dst; | 740 | __be32 ip_src, ip_dst; |
741 | uint8_t *hw_src, *hw_dst; | ||
741 | uint16_t type = 0; | 742 | uint16_t type = 0; |
742 | 743 | ||
743 | /* pull the ethernet header */ | 744 | /* pull the ethernet header */ |
@@ -777,9 +778,23 @@ static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv, | |||
777 | ip_src = batadv_arp_ip_src(skb, hdr_size); | 778 | ip_src = batadv_arp_ip_src(skb, hdr_size); |
778 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); | 779 | ip_dst = batadv_arp_ip_dst(skb, hdr_size); |
779 | if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) || | 780 | if (ipv4_is_loopback(ip_src) || ipv4_is_multicast(ip_src) || |
780 | ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst)) | 781 | ipv4_is_loopback(ip_dst) || ipv4_is_multicast(ip_dst) || |
782 | ipv4_is_zeronet(ip_src) || ipv4_is_lbcast(ip_src) || | ||
783 | ipv4_is_zeronet(ip_dst) || ipv4_is_lbcast(ip_dst)) | ||
781 | goto out; | 784 | goto out; |
782 | 785 | ||
786 | hw_src = batadv_arp_hw_src(skb, hdr_size); | ||
787 | if (is_zero_ether_addr(hw_src) || is_multicast_ether_addr(hw_src)) | ||
788 | goto out; | ||
789 | |||
790 | /* we don't care about the destination MAC address in ARP requests */ | ||
791 | if (arphdr->ar_op != htons(ARPOP_REQUEST)) { | ||
792 | hw_dst = batadv_arp_hw_dst(skb, hdr_size); | ||
793 | if (is_zero_ether_addr(hw_dst) || | ||
794 | is_multicast_ether_addr(hw_dst)) | ||
795 | goto out; | ||
796 | } | ||
797 | |||
783 | type = ntohs(arphdr->ar_op); | 798 | type = ntohs(arphdr->ar_op); |
784 | out: | 799 | out: |
785 | return type; | 800 | return type; |
@@ -1012,6 +1027,8 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv, | |||
1012 | */ | 1027 | */ |
1013 | ret = !batadv_is_my_client(bat_priv, hw_dst); | 1028 | ret = !batadv_is_my_client(bat_priv, hw_dst); |
1014 | out: | 1029 | out: |
1030 | if (ret) | ||
1031 | kfree_skb(skb); | ||
1015 | /* if ret == false -> packet has to be delivered to the interface */ | 1032 | /* if ret == false -> packet has to be delivered to the interface */ |
1016 | return ret; | 1033 | return ret; |
1017 | } | 1034 | } |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 596660d37c5e..0f78e34220c9 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -2810,14 +2810,6 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2810 | if (conn) { | 2810 | if (conn) { |
2811 | hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); | 2811 | hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); |
2812 | 2812 | ||
2813 | hci_dev_lock(hdev); | ||
2814 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | ||
2815 | !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) | ||
2816 | mgmt_device_connected(hdev, &conn->dst, conn->type, | ||
2817 | conn->dst_type, 0, NULL, 0, | ||
2818 | conn->dev_class); | ||
2819 | hci_dev_unlock(hdev); | ||
2820 | |||
2821 | /* Send to upper protocol */ | 2813 | /* Send to upper protocol */ |
2822 | l2cap_recv_acldata(conn, skb, flags); | 2814 | l2cap_recv_acldata(conn, skb, flags); |
2823 | return; | 2815 | return; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 705078a0cc39..81b44481d0d9 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2688,7 +2688,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2688 | if (ev->opcode != HCI_OP_NOP) | 2688 | if (ev->opcode != HCI_OP_NOP) |
2689 | del_timer(&hdev->cmd_timer); | 2689 | del_timer(&hdev->cmd_timer); |
2690 | 2690 | ||
2691 | if (ev->ncmd) { | 2691 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { |
2692 | atomic_set(&hdev->cmd_cnt, 1); | 2692 | atomic_set(&hdev->cmd_cnt, 1); |
2693 | if (!skb_queue_empty(&hdev->cmd_q)) | 2693 | if (!skb_queue_empty(&hdev->cmd_q)) |
2694 | queue_work(hdev->workqueue, &hdev->cmd_work); | 2694 | queue_work(hdev->workqueue, &hdev->cmd_work); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index b2bcbe2dc328..a7352ff3fd1e 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -931,7 +931,7 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
931 | hid->version = req->version; | 931 | hid->version = req->version; |
932 | hid->country = req->country; | 932 | hid->country = req->country; |
933 | 933 | ||
934 | strncpy(hid->name, req->name, 128); | 934 | strncpy(hid->name, req->name, sizeof(req->name) - 1); |
935 | 935 | ||
936 | snprintf(hid->phys, sizeof(hid->phys), "%pMR", | 936 | snprintf(hid->phys, sizeof(hid->phys), "%pMR", |
937 | &bt_sk(session->ctrl_sock->sk)->src); | 937 | &bt_sk(session->ctrl_sock->sk)->src); |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2c78208d793e..22e658322845 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -3727,6 +3727,17 @@ sendresp: | |||
3727 | static int l2cap_connect_req(struct l2cap_conn *conn, | 3727 | static int l2cap_connect_req(struct l2cap_conn *conn, |
3728 | struct l2cap_cmd_hdr *cmd, u8 *data) | 3728 | struct l2cap_cmd_hdr *cmd, u8 *data) |
3729 | { | 3729 | { |
3730 | struct hci_dev *hdev = conn->hcon->hdev; | ||
3731 | struct hci_conn *hcon = conn->hcon; | ||
3732 | |||
3733 | hci_dev_lock(hdev); | ||
3734 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | ||
3735 | !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) | ||
3736 | mgmt_device_connected(hdev, &hcon->dst, hcon->type, | ||
3737 | hcon->dst_type, 0, NULL, 0, | ||
3738 | hcon->dev_class); | ||
3739 | hci_dev_unlock(hdev); | ||
3740 | |||
3730 | l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0); | 3741 | l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0); |
3731 | return 0; | 3742 | return 0; |
3732 | } | 3743 | } |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 531a93d613d4..57f250c20e39 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -352,7 +352,7 @@ static void __sco_sock_close(struct sock *sk) | |||
352 | 352 | ||
353 | case BT_CONNECTED: | 353 | case BT_CONNECTED: |
354 | case BT_CONFIG: | 354 | case BT_CONFIG: |
355 | if (sco_pi(sk)->conn) { | 355 | if (sco_pi(sk)->conn->hcon) { |
356 | sk->sk_state = BT_DISCONN; | 356 | sk->sk_state = BT_DISCONN; |
357 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); | 357 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); |
358 | hci_conn_put(sco_pi(sk)->conn->hcon); | 358 | hci_conn_put(sco_pi(sk)->conn->hcon); |
diff --git a/net/core/request_sock.c b/net/core/request_sock.c index c31d9e8668c3..4425148d2b51 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c | |||
@@ -186,8 +186,6 @@ void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, | |||
186 | struct fastopen_queue *fastopenq = | 186 | struct fastopen_queue *fastopenq = |
187 | inet_csk(lsk)->icsk_accept_queue.fastopenq; | 187 | inet_csk(lsk)->icsk_accept_queue.fastopenq; |
188 | 188 | ||
189 | BUG_ON(!spin_is_locked(&sk->sk_lock.slock) && !sock_owned_by_user(sk)); | ||
190 | |||
191 | tcp_sk(sk)->fastopen_rsk = NULL; | 189 | tcp_sk(sk)->fastopen_rsk = NULL; |
192 | spin_lock_bh(&fastopenq->lock); | 190 | spin_lock_bh(&fastopenq->lock); |
193 | fastopenq->qlen--; | 191 | fastopenq->qlen--; |
diff --git a/net/core/scm.c b/net/core/scm.c index 57fb1ee6649f..905dcc6ad1e3 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <net/sock.h> | 35 | #include <net/sock.h> |
36 | #include <net/compat.h> | 36 | #include <net/compat.h> |
37 | #include <net/scm.h> | 37 | #include <net/scm.h> |
38 | #include <net/cls_cgroup.h> | ||
38 | 39 | ||
39 | 40 | ||
40 | /* | 41 | /* |
@@ -302,8 +303,10 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
302 | } | 303 | } |
303 | /* Bump the usage count and install the file. */ | 304 | /* Bump the usage count and install the file. */ |
304 | sock = sock_from_file(fp[i], &err); | 305 | sock = sock_from_file(fp[i], &err); |
305 | if (sock) | 306 | if (sock) { |
306 | sock_update_netprioidx(sock->sk, current); | 307 | sock_update_netprioidx(sock->sk, current); |
308 | sock_update_classid(sock->sk, current); | ||
309 | } | ||
307 | fd_install(new_fd, get_file(fp[i])); | 310 | fd_install(new_fd, get_file(fp[i])); |
308 | } | 311 | } |
309 | 312 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3ab989b0de42..a9a2ae3e2213 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1649,7 +1649,7 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) | |||
1649 | 1649 | ||
1650 | static struct page *linear_to_page(struct page *page, unsigned int *len, | 1650 | static struct page *linear_to_page(struct page *page, unsigned int *len, |
1651 | unsigned int *offset, | 1651 | unsigned int *offset, |
1652 | struct sk_buff *skb, struct sock *sk) | 1652 | struct sock *sk) |
1653 | { | 1653 | { |
1654 | struct page_frag *pfrag = sk_page_frag(sk); | 1654 | struct page_frag *pfrag = sk_page_frag(sk); |
1655 | 1655 | ||
@@ -1682,14 +1682,14 @@ static bool spd_can_coalesce(const struct splice_pipe_desc *spd, | |||
1682 | static bool spd_fill_page(struct splice_pipe_desc *spd, | 1682 | static bool spd_fill_page(struct splice_pipe_desc *spd, |
1683 | struct pipe_inode_info *pipe, struct page *page, | 1683 | struct pipe_inode_info *pipe, struct page *page, |
1684 | unsigned int *len, unsigned int offset, | 1684 | unsigned int *len, unsigned int offset, |
1685 | struct sk_buff *skb, bool linear, | 1685 | bool linear, |
1686 | struct sock *sk) | 1686 | struct sock *sk) |
1687 | { | 1687 | { |
1688 | if (unlikely(spd->nr_pages == MAX_SKB_FRAGS)) | 1688 | if (unlikely(spd->nr_pages == MAX_SKB_FRAGS)) |
1689 | return true; | 1689 | return true; |
1690 | 1690 | ||
1691 | if (linear) { | 1691 | if (linear) { |
1692 | page = linear_to_page(page, len, &offset, skb, sk); | 1692 | page = linear_to_page(page, len, &offset, sk); |
1693 | if (!page) | 1693 | if (!page) |
1694 | return true; | 1694 | return true; |
1695 | } | 1695 | } |
@@ -1706,23 +1706,9 @@ static bool spd_fill_page(struct splice_pipe_desc *spd, | |||
1706 | return false; | 1706 | return false; |
1707 | } | 1707 | } |
1708 | 1708 | ||
1709 | static inline void __segment_seek(struct page **page, unsigned int *poff, | ||
1710 | unsigned int *plen, unsigned int off) | ||
1711 | { | ||
1712 | unsigned long n; | ||
1713 | |||
1714 | *poff += off; | ||
1715 | n = *poff / PAGE_SIZE; | ||
1716 | if (n) | ||
1717 | *page = nth_page(*page, n); | ||
1718 | |||
1719 | *poff = *poff % PAGE_SIZE; | ||
1720 | *plen -= off; | ||
1721 | } | ||
1722 | |||
1723 | static bool __splice_segment(struct page *page, unsigned int poff, | 1709 | static bool __splice_segment(struct page *page, unsigned int poff, |
1724 | unsigned int plen, unsigned int *off, | 1710 | unsigned int plen, unsigned int *off, |
1725 | unsigned int *len, struct sk_buff *skb, | 1711 | unsigned int *len, |
1726 | struct splice_pipe_desc *spd, bool linear, | 1712 | struct splice_pipe_desc *spd, bool linear, |
1727 | struct sock *sk, | 1713 | struct sock *sk, |
1728 | struct pipe_inode_info *pipe) | 1714 | struct pipe_inode_info *pipe) |
@@ -1737,23 +1723,19 @@ static bool __splice_segment(struct page *page, unsigned int poff, | |||
1737 | } | 1723 | } |
1738 | 1724 | ||
1739 | /* ignore any bits we already processed */ | 1725 | /* ignore any bits we already processed */ |
1740 | if (*off) { | 1726 | poff += *off; |
1741 | __segment_seek(&page, &poff, &plen, *off); | 1727 | plen -= *off; |
1742 | *off = 0; | 1728 | *off = 0; |
1743 | } | ||
1744 | 1729 | ||
1745 | do { | 1730 | do { |
1746 | unsigned int flen = min(*len, plen); | 1731 | unsigned int flen = min(*len, plen); |
1747 | 1732 | ||
1748 | /* the linear region may spread across several pages */ | 1733 | if (spd_fill_page(spd, pipe, page, &flen, poff, |
1749 | flen = min_t(unsigned int, flen, PAGE_SIZE - poff); | 1734 | linear, sk)) |
1750 | |||
1751 | if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk)) | ||
1752 | return true; | 1735 | return true; |
1753 | 1736 | poff += flen; | |
1754 | __segment_seek(&page, &poff, &plen, flen); | 1737 | plen -= flen; |
1755 | *len -= flen; | 1738 | *len -= flen; |
1756 | |||
1757 | } while (*len && plen); | 1739 | } while (*len && plen); |
1758 | 1740 | ||
1759 | return false; | 1741 | return false; |
@@ -1777,7 +1759,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, | |||
1777 | if (__splice_segment(virt_to_page(skb->data), | 1759 | if (__splice_segment(virt_to_page(skb->data), |
1778 | (unsigned long) skb->data & (PAGE_SIZE - 1), | 1760 | (unsigned long) skb->data & (PAGE_SIZE - 1), |
1779 | skb_headlen(skb), | 1761 | skb_headlen(skb), |
1780 | offset, len, skb, spd, | 1762 | offset, len, spd, |
1781 | skb_head_is_locked(skb), | 1763 | skb_head_is_locked(skb), |
1782 | sk, pipe)) | 1764 | sk, pipe)) |
1783 | return true; | 1765 | return true; |
@@ -1790,7 +1772,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, | |||
1790 | 1772 | ||
1791 | if (__splice_segment(skb_frag_page(f), | 1773 | if (__splice_segment(skb_frag_page(f), |
1792 | f->page_offset, skb_frag_size(f), | 1774 | f->page_offset, skb_frag_size(f), |
1793 | offset, len, skb, spd, false, sk, pipe)) | 1775 | offset, len, spd, false, sk, pipe)) |
1794 | return true; | 1776 | return true; |
1795 | } | 1777 | } |
1796 | 1778 | ||
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index a0d8392491c3..a69b4e4a02b5 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -269,7 +269,11 @@ static void ah_input_done(struct crypto_async_request *base, int err) | |||
269 | skb->network_header += ah_hlen; | 269 | skb->network_header += ah_hlen; |
270 | memcpy(skb_network_header(skb), work_iph, ihl); | 270 | memcpy(skb_network_header(skb), work_iph, ihl); |
271 | __skb_pull(skb, ah_hlen + ihl); | 271 | __skb_pull(skb, ah_hlen + ihl); |
272 | skb_set_transport_header(skb, -ihl); | 272 | |
273 | if (x->props.mode == XFRM_MODE_TUNNEL) | ||
274 | skb_reset_transport_header(skb); | ||
275 | else | ||
276 | skb_set_transport_header(skb, -ihl); | ||
273 | out: | 277 | out: |
274 | kfree(AH_SKB_CB(skb)->tmp); | 278 | kfree(AH_SKB_CB(skb)->tmp); |
275 | xfrm_input_resume(skb, err); | 279 | xfrm_input_resume(skb, err); |
@@ -381,7 +385,10 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) | |||
381 | skb->network_header += ah_hlen; | 385 | skb->network_header += ah_hlen; |
382 | memcpy(skb_network_header(skb), work_iph, ihl); | 386 | memcpy(skb_network_header(skb), work_iph, ihl); |
383 | __skb_pull(skb, ah_hlen + ihl); | 387 | __skb_pull(skb, ah_hlen + ihl); |
384 | skb_set_transport_header(skb, -ihl); | 388 | if (x->props.mode == XFRM_MODE_TUNNEL) |
389 | skb_reset_transport_header(skb); | ||
390 | else | ||
391 | skb_set_transport_header(skb, -ihl); | ||
385 | 392 | ||
386 | err = nexthdr; | 393 | err = nexthdr; |
387 | 394 | ||
@@ -413,9 +420,12 @@ static void ah4_err(struct sk_buff *skb, u32 info) | |||
413 | if (!x) | 420 | if (!x) |
414 | return; | 421 | return; |
415 | 422 | ||
416 | if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) | 423 | if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) { |
424 | atomic_inc(&flow_cache_genid); | ||
425 | rt_genid_bump(net); | ||
426 | |||
417 | ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_AH, 0); | 427 | ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_AH, 0); |
418 | else | 428 | } else |
419 | ipv4_redirect(skb, net, 0, 0, IPPROTO_AH, 0); | 429 | ipv4_redirect(skb, net, 0, 0, IPPROTO_AH, 0); |
420 | xfrm_state_put(x); | 430 | xfrm_state_put(x); |
421 | } | 431 | } |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index 424fafbc8cb0..b28e863fe0a7 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
@@ -85,3 +85,28 @@ out: | |||
85 | return err; | 85 | return err; |
86 | } | 86 | } |
87 | EXPORT_SYMBOL(ip4_datagram_connect); | 87 | EXPORT_SYMBOL(ip4_datagram_connect); |
88 | |||
89 | void ip4_datagram_release_cb(struct sock *sk) | ||
90 | { | ||
91 | const struct inet_sock *inet = inet_sk(sk); | ||
92 | const struct ip_options_rcu *inet_opt; | ||
93 | __be32 daddr = inet->inet_daddr; | ||
94 | struct flowi4 fl4; | ||
95 | struct rtable *rt; | ||
96 | |||
97 | if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0)) | ||
98 | return; | ||
99 | |||
100 | rcu_read_lock(); | ||
101 | inet_opt = rcu_dereference(inet->inet_opt); | ||
102 | if (inet_opt && inet_opt->opt.srr) | ||
103 | daddr = inet_opt->opt.faddr; | ||
104 | rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr, | ||
105 | inet->inet_saddr, inet->inet_dport, | ||
106 | inet->inet_sport, sk->sk_protocol, | ||
107 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if); | ||
108 | if (!IS_ERR(rt)) | ||
109 | __sk_dst_set(sk, &rt->dst); | ||
110 | rcu_read_unlock(); | ||
111 | } | ||
112 | EXPORT_SYMBOL_GPL(ip4_datagram_release_cb); | ||
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index b61e9deb7c7e..3b4f0cd2e63e 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -346,7 +346,10 @@ static int esp_input_done2(struct sk_buff *skb, int err) | |||
346 | 346 | ||
347 | pskb_trim(skb, skb->len - alen - padlen - 2); | 347 | pskb_trim(skb, skb->len - alen - padlen - 2); |
348 | __skb_pull(skb, hlen); | 348 | __skb_pull(skb, hlen); |
349 | skb_set_transport_header(skb, -ihl); | 349 | if (x->props.mode == XFRM_MODE_TUNNEL) |
350 | skb_reset_transport_header(skb); | ||
351 | else | ||
352 | skb_set_transport_header(skb, -ihl); | ||
350 | 353 | ||
351 | err = nexthdr[1]; | 354 | err = nexthdr[1]; |
352 | 355 | ||
@@ -499,9 +502,12 @@ static void esp4_err(struct sk_buff *skb, u32 info) | |||
499 | if (!x) | 502 | if (!x) |
500 | return; | 503 | return; |
501 | 504 | ||
502 | if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) | 505 | if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) { |
506 | atomic_inc(&flow_cache_genid); | ||
507 | rt_genid_bump(net); | ||
508 | |||
503 | ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0); | 509 | ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0); |
504 | else | 510 | } else |
505 | ipv4_redirect(skb, net, 0, 0, IPPROTO_ESP, 0); | 511 | ipv4_redirect(skb, net, 0, 0, IPPROTO_ESP, 0); |
506 | xfrm_state_put(x); | 512 | xfrm_state_put(x); |
507 | } | 513 | } |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 303012adf9e6..e81b1caf2ea2 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -963,8 +963,12 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
963 | ptr--; | 963 | ptr--; |
964 | } | 964 | } |
965 | if (tunnel->parms.o_flags&GRE_CSUM) { | 965 | if (tunnel->parms.o_flags&GRE_CSUM) { |
966 | int offset = skb_transport_offset(skb); | ||
967 | |||
966 | *ptr = 0; | 968 | *ptr = 0; |
967 | *(__sum16 *)ptr = ip_compute_csum((void *)(iph+1), skb->len - sizeof(struct iphdr)); | 969 | *(__sum16 *)ptr = csum_fold(skb_checksum(skb, offset, |
970 | skb->len - offset, | ||
971 | 0)); | ||
968 | } | 972 | } |
969 | } | 973 | } |
970 | 974 | ||
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index d3ab47e19a89..9a46daed2f3c 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -47,9 +47,12 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) | |||
47 | if (!x) | 47 | if (!x) |
48 | return; | 48 | return; |
49 | 49 | ||
50 | if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) | 50 | if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) { |
51 | atomic_inc(&flow_cache_genid); | ||
52 | rt_genid_bump(net); | ||
53 | |||
51 | ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_COMP, 0); | 54 | ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_COMP, 0); |
52 | else | 55 | } else |
53 | ipv4_redirect(skb, net, 0, 0, IPPROTO_COMP, 0); | 56 | ipv4_redirect(skb, net, 0, 0, IPPROTO_COMP, 0); |
54 | xfrm_state_put(x); | 57 | xfrm_state_put(x); |
55 | } | 58 | } |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 8f3d05424a3e..6f9c07268cf6 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -738,6 +738,7 @@ struct proto ping_prot = { | |||
738 | .recvmsg = ping_recvmsg, | 738 | .recvmsg = ping_recvmsg, |
739 | .bind = ping_bind, | 739 | .bind = ping_bind, |
740 | .backlog_rcv = ping_queue_rcv_skb, | 740 | .backlog_rcv = ping_queue_rcv_skb, |
741 | .release_cb = ip4_datagram_release_cb, | ||
741 | .hash = ping_v4_hash, | 742 | .hash = ping_v4_hash, |
742 | .unhash = ping_v4_unhash, | 743 | .unhash = ping_v4_unhash, |
743 | .get_port = ping_v4_get_port, | 744 | .get_port = ping_v4_get_port, |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 73d1e4df4bf6..6f08991409c3 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -894,6 +894,7 @@ struct proto raw_prot = { | |||
894 | .recvmsg = raw_recvmsg, | 894 | .recvmsg = raw_recvmsg, |
895 | .bind = raw_bind, | 895 | .bind = raw_bind, |
896 | .backlog_rcv = raw_rcv_skb, | 896 | .backlog_rcv = raw_rcv_skb, |
897 | .release_cb = ip4_datagram_release_cb, | ||
897 | .hash = raw_hash_sk, | 898 | .hash = raw_hash_sk, |
898 | .unhash = raw_unhash_sk, | 899 | .unhash = raw_unhash_sk, |
899 | .obj_size = sizeof(struct raw_sock), | 900 | .obj_size = sizeof(struct raw_sock), |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 844a9ef60dbd..a0fcc47fee73 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -912,6 +912,9 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) | |||
912 | struct dst_entry *dst = &rt->dst; | 912 | struct dst_entry *dst = &rt->dst; |
913 | struct fib_result res; | 913 | struct fib_result res; |
914 | 914 | ||
915 | if (dst_metric_locked(dst, RTAX_MTU)) | ||
916 | return; | ||
917 | |||
915 | if (dst->dev->mtu < mtu) | 918 | if (dst->dev->mtu < mtu) |
916 | return; | 919 | return; |
917 | 920 | ||
@@ -962,7 +965,7 @@ void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, | |||
962 | } | 965 | } |
963 | EXPORT_SYMBOL_GPL(ipv4_update_pmtu); | 966 | EXPORT_SYMBOL_GPL(ipv4_update_pmtu); |
964 | 967 | ||
965 | void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | 968 | static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) |
966 | { | 969 | { |
967 | const struct iphdr *iph = (const struct iphdr *) skb->data; | 970 | const struct iphdr *iph = (const struct iphdr *) skb->data; |
968 | struct flowi4 fl4; | 971 | struct flowi4 fl4; |
@@ -975,6 +978,53 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
975 | ip_rt_put(rt); | 978 | ip_rt_put(rt); |
976 | } | 979 | } |
977 | } | 980 | } |
981 | |||
982 | void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | ||
983 | { | ||
984 | const struct iphdr *iph = (const struct iphdr *) skb->data; | ||
985 | struct flowi4 fl4; | ||
986 | struct rtable *rt; | ||
987 | struct dst_entry *dst; | ||
988 | bool new = false; | ||
989 | |||
990 | bh_lock_sock(sk); | ||
991 | rt = (struct rtable *) __sk_dst_get(sk); | ||
992 | |||
993 | if (sock_owned_by_user(sk) || !rt) { | ||
994 | __ipv4_sk_update_pmtu(skb, sk, mtu); | ||
995 | goto out; | ||
996 | } | ||
997 | |||
998 | __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); | ||
999 | |||
1000 | if (!__sk_dst_check(sk, 0)) { | ||
1001 | rt = ip_route_output_flow(sock_net(sk), &fl4, sk); | ||
1002 | if (IS_ERR(rt)) | ||
1003 | goto out; | ||
1004 | |||
1005 | new = true; | ||
1006 | } | ||
1007 | |||
1008 | __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); | ||
1009 | |||
1010 | dst = dst_check(&rt->dst, 0); | ||
1011 | if (!dst) { | ||
1012 | if (new) | ||
1013 | dst_release(&rt->dst); | ||
1014 | |||
1015 | rt = ip_route_output_flow(sock_net(sk), &fl4, sk); | ||
1016 | if (IS_ERR(rt)) | ||
1017 | goto out; | ||
1018 | |||
1019 | new = true; | ||
1020 | } | ||
1021 | |||
1022 | if (new) | ||
1023 | __sk_dst_set(sk, &rt->dst); | ||
1024 | |||
1025 | out: | ||
1026 | bh_unlock_sock(sk); | ||
1027 | } | ||
978 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); | 1028 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); |
979 | 1029 | ||
980 | void ipv4_redirect(struct sk_buff *skb, struct net *net, | 1030 | void ipv4_redirect(struct sk_buff *skb, struct net *net, |
@@ -1120,7 +1170,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) | |||
1120 | if (!mtu || time_after_eq(jiffies, rt->dst.expires)) | 1170 | if (!mtu || time_after_eq(jiffies, rt->dst.expires)) |
1121 | mtu = dst_metric_raw(dst, RTAX_MTU); | 1171 | mtu = dst_metric_raw(dst, RTAX_MTU); |
1122 | 1172 | ||
1123 | if (mtu && rt_is_output_route(rt)) | 1173 | if (mtu) |
1124 | return mtu; | 1174 | return mtu; |
1125 | 1175 | ||
1126 | mtu = dst->dev->mtu; | 1176 | mtu = dst->dev->mtu; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 54139fa514e6..70b09ef2463b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -369,11 +369,10 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
369 | * We do take care of PMTU discovery (RFC1191) special case : | 369 | * We do take care of PMTU discovery (RFC1191) special case : |
370 | * we can receive locally generated ICMP messages while socket is held. | 370 | * we can receive locally generated ICMP messages while socket is held. |
371 | */ | 371 | */ |
372 | if (sock_owned_by_user(sk) && | 372 | if (sock_owned_by_user(sk)) { |
373 | type != ICMP_DEST_UNREACH && | 373 | if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) |
374 | code != ICMP_FRAG_NEEDED) | 374 | NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); |
375 | NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); | 375 | } |
376 | |||
377 | if (sk->sk_state == TCP_CLOSE) | 376 | if (sk->sk_state == TCP_CLOSE) |
378 | goto out; | 377 | goto out; |
379 | 378 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 79c8dbe59b54..1f4d405eafba 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1952,6 +1952,7 @@ struct proto udp_prot = { | |||
1952 | .recvmsg = udp_recvmsg, | 1952 | .recvmsg = udp_recvmsg, |
1953 | .sendpage = udp_sendpage, | 1953 | .sendpage = udp_sendpage, |
1954 | .backlog_rcv = __udp_queue_rcv_skb, | 1954 | .backlog_rcv = __udp_queue_rcv_skb, |
1955 | .release_cb = ip4_datagram_release_cb, | ||
1955 | .hash = udp_lib_hash, | 1956 | .hash = udp_lib_hash, |
1956 | .unhash = udp_lib_unhash, | 1957 | .unhash = udp_lib_unhash, |
1957 | .rehash = udp_v4_rehash, | 1958 | .rehash = udp_v4_rehash, |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index ecc35b93314b..384233188ac1 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -472,7 +472,10 @@ static void ah6_input_done(struct crypto_async_request *base, int err) | |||
472 | skb->network_header += ah_hlen; | 472 | skb->network_header += ah_hlen; |
473 | memcpy(skb_network_header(skb), work_iph, hdr_len); | 473 | memcpy(skb_network_header(skb), work_iph, hdr_len); |
474 | __skb_pull(skb, ah_hlen + hdr_len); | 474 | __skb_pull(skb, ah_hlen + hdr_len); |
475 | skb_set_transport_header(skb, -hdr_len); | 475 | if (x->props.mode == XFRM_MODE_TUNNEL) |
476 | skb_reset_transport_header(skb); | ||
477 | else | ||
478 | skb_set_transport_header(skb, -hdr_len); | ||
476 | out: | 479 | out: |
477 | kfree(AH_SKB_CB(skb)->tmp); | 480 | kfree(AH_SKB_CB(skb)->tmp); |
478 | xfrm_input_resume(skb, err); | 481 | xfrm_input_resume(skb, err); |
@@ -593,9 +596,13 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
593 | 596 | ||
594 | skb->network_header += ah_hlen; | 597 | skb->network_header += ah_hlen; |
595 | memcpy(skb_network_header(skb), work_iph, hdr_len); | 598 | memcpy(skb_network_header(skb), work_iph, hdr_len); |
596 | skb->transport_header = skb->network_header; | ||
597 | __skb_pull(skb, ah_hlen + hdr_len); | 599 | __skb_pull(skb, ah_hlen + hdr_len); |
598 | 600 | ||
601 | if (x->props.mode == XFRM_MODE_TUNNEL) | ||
602 | skb_reset_transport_header(skb); | ||
603 | else | ||
604 | skb_set_transport_header(skb, -hdr_len); | ||
605 | |||
599 | err = nexthdr; | 606 | err = nexthdr; |
600 | 607 | ||
601 | out_free: | 608 | out_free: |
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 282f3723ee19..40ffd72243a4 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -300,7 +300,10 @@ static int esp_input_done2(struct sk_buff *skb, int err) | |||
300 | 300 | ||
301 | pskb_trim(skb, skb->len - alen - padlen - 2); | 301 | pskb_trim(skb, skb->len - alen - padlen - 2); |
302 | __skb_pull(skb, hlen); | 302 | __skb_pull(skb, hlen); |
303 | skb_set_transport_header(skb, -hdr_len); | 303 | if (x->props.mode == XFRM_MODE_TUNNEL) |
304 | skb_reset_transport_header(skb); | ||
305 | else | ||
306 | skb_set_transport_header(skb, -hdr_len); | ||
304 | 307 | ||
305 | err = nexthdr[1]; | 308 | err = nexthdr[1]; |
306 | 309 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index b4a9fd51dae7..fff5bdd8b680 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -81,10 +81,22 @@ static inline struct sock *icmpv6_sk(struct net *net) | |||
81 | return net->ipv6.icmp_sk[smp_processor_id()]; | 81 | return net->ipv6.icmp_sk[smp_processor_id()]; |
82 | } | 82 | } |
83 | 83 | ||
84 | static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | ||
85 | u8 type, u8 code, int offset, __be32 info) | ||
86 | { | ||
87 | struct net *net = dev_net(skb->dev); | ||
88 | |||
89 | if (type == ICMPV6_PKT_TOOBIG) | ||
90 | ip6_update_pmtu(skb, net, info, 0, 0); | ||
91 | else if (type == NDISC_REDIRECT) | ||
92 | ip6_redirect(skb, net, 0, 0); | ||
93 | } | ||
94 | |||
84 | static int icmpv6_rcv(struct sk_buff *skb); | 95 | static int icmpv6_rcv(struct sk_buff *skb); |
85 | 96 | ||
86 | static const struct inet6_protocol icmpv6_protocol = { | 97 | static const struct inet6_protocol icmpv6_protocol = { |
87 | .handler = icmpv6_rcv, | 98 | .handler = icmpv6_rcv, |
99 | .err_handler = icmpv6_err, | ||
88 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 100 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
89 | }; | 101 | }; |
90 | 102 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 5552d13ae92f..0c7c03d50dc0 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1213,10 +1213,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1213 | if (dst_allfrag(rt->dst.path)) | 1213 | if (dst_allfrag(rt->dst.path)) |
1214 | cork->flags |= IPCORK_ALLFRAG; | 1214 | cork->flags |= IPCORK_ALLFRAG; |
1215 | cork->length = 0; | 1215 | cork->length = 0; |
1216 | exthdrlen = (opt ? opt->opt_flen : 0) - rt->rt6i_nfheader_len; | 1216 | exthdrlen = (opt ? opt->opt_flen : 0); |
1217 | length += exthdrlen; | 1217 | length += exthdrlen; |
1218 | transhdrlen += exthdrlen; | 1218 | transhdrlen += exthdrlen; |
1219 | dst_exthdrlen = rt->dst.header_len; | 1219 | dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len; |
1220 | } else { | 1220 | } else { |
1221 | rt = (struct rt6_info *)cork->dst; | 1221 | rt = (struct rt6_info *)cork->dst; |
1222 | fl6 = &inet->cork.fl.u.ip6; | 1222 | fl6 = &inet->cork.fl.u.ip6; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 26dcdec9e3a5..8fd154e5f079 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1710,6 +1710,9 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns | |||
1710 | return -EINVAL; | 1710 | return -EINVAL; |
1711 | if (get_user(v, (u32 __user *)optval)) | 1711 | if (get_user(v, (u32 __user *)optval)) |
1712 | return -EFAULT; | 1712 | return -EFAULT; |
1713 | /* "pim6reg%u" should not exceed 16 bytes (IFNAMSIZ) */ | ||
1714 | if (v != RT_TABLE_DEFAULT && v >= 100000000) | ||
1715 | return -EINVAL; | ||
1713 | if (sk == mrt->mroute6_sk) | 1716 | if (sk == mrt->mroute6_sk) |
1714 | return -EBUSY; | 1717 | return -EBUSY; |
1715 | 1718 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 47e0aca614b7..516fbc96feff 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
164 | sta = sta_info_get(sdata, mac_addr); | 164 | sta = sta_info_get(sdata, mac_addr); |
165 | else | 165 | else |
166 | sta = sta_info_get_bss(sdata, mac_addr); | 166 | sta = sta_info_get_bss(sdata, mac_addr); |
167 | if (!sta) { | 167 | /* |
168 | * The ASSOC test makes sure the driver is ready to | ||
169 | * receive the key. When wpa_supplicant has roamed | ||
170 | * using FT, it attempts to set the key before | ||
171 | * association has completed, this rejects that attempt | ||
172 | * so it will set the key again after assocation. | ||
173 | * | ||
174 | * TODO: accept the key if we have a station entry and | ||
175 | * add it to the device after the station. | ||
176 | */ | ||
177 | if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { | ||
168 | ieee80211_key_free(sdata->local, key); | 178 | ieee80211_key_free(sdata->local, key); |
169 | err = -ENOENT; | 179 | err = -ENOENT; |
170 | goto out_unlock; | 180 | goto out_unlock; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8563b9a5cac3..2ed065c09562 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); | |||
1358 | void ieee80211_sched_scan_stopped_work(struct work_struct *work); | 1358 | void ieee80211_sched_scan_stopped_work(struct work_struct *work); |
1359 | 1359 | ||
1360 | /* off-channel helpers */ | 1360 | /* off-channel helpers */ |
1361 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | 1361 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local); |
1362 | bool offchannel_ps_enable); | 1362 | void ieee80211_offchannel_return(struct ieee80211_local *local); |
1363 | void ieee80211_offchannel_return(struct ieee80211_local *local, | ||
1364 | bool offchannel_ps_disable); | ||
1365 | void ieee80211_roc_setup(struct ieee80211_local *local); | 1363 | void ieee80211_roc_setup(struct ieee80211_local *local); |
1366 | void ieee80211_start_next_roc(struct ieee80211_local *local); | 1364 | void ieee80211_start_next_roc(struct ieee80211_local *local); |
1367 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); | 1365 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 47aeee2d8db1..2659e428b80c 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, | |||
215 | skb->priority = 7; | 215 | skb->priority = 7; |
216 | 216 | ||
217 | info->control.vif = &sdata->vif; | 217 | info->control.vif = &sdata->vif; |
218 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | ||
218 | ieee80211_set_qos_hdr(sdata, skb); | 219 | ieee80211_set_qos_hdr(sdata, skb); |
219 | } | 220 | } |
220 | 221 | ||
@@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
246 | return -EAGAIN; | 247 | return -EAGAIN; |
247 | 248 | ||
248 | skb = dev_alloc_skb(local->tx_headroom + | 249 | skb = dev_alloc_skb(local->tx_headroom + |
250 | IEEE80211_ENCRYPT_HEADROOM + | ||
251 | IEEE80211_ENCRYPT_TAILROOM + | ||
249 | hdr_len + | 252 | hdr_len + |
250 | 2 + 15 /* PERR IE */); | 253 | 2 + 15 /* PERR IE */); |
251 | if (!skb) | 254 | if (!skb) |
252 | return -1; | 255 | return -1; |
253 | skb_reserve(skb, local->tx_headroom); | 256 | skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM); |
254 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); | 257 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
255 | memset(mgmt, 0, hdr_len); | 258 | memset(mgmt, 0, hdr_len); |
256 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 259 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index a5379aea7d09..a3ad4c3c80a3 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
102 | ieee80211_sta_reset_conn_monitor(sdata); | 102 | ieee80211_sta_reset_conn_monitor(sdata); |
103 | } | 103 | } |
104 | 104 | ||
105 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | 105 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) |
106 | bool offchannel_ps_enable) | ||
107 | { | 106 | { |
108 | struct ieee80211_sub_if_data *sdata; | 107 | struct ieee80211_sub_if_data *sdata; |
109 | 108 | ||
@@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
134 | 133 | ||
135 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 134 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
136 | netif_tx_stop_all_queues(sdata->dev); | 135 | netif_tx_stop_all_queues(sdata->dev); |
137 | if (offchannel_ps_enable && | 136 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
138 | (sdata->vif.type == NL80211_IFTYPE_STATION) && | ||
139 | sdata->u.mgd.associated) | 137 | sdata->u.mgd.associated) |
140 | ieee80211_offchannel_ps_enable(sdata); | 138 | ieee80211_offchannel_ps_enable(sdata); |
141 | } | 139 | } |
@@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
143 | mutex_unlock(&local->iflist_mtx); | 141 | mutex_unlock(&local->iflist_mtx); |
144 | } | 142 | } |
145 | 143 | ||
146 | void ieee80211_offchannel_return(struct ieee80211_local *local, | 144 | void ieee80211_offchannel_return(struct ieee80211_local *local) |
147 | bool offchannel_ps_disable) | ||
148 | { | 145 | { |
149 | struct ieee80211_sub_if_data *sdata; | 146 | struct ieee80211_sub_if_data *sdata; |
150 | 147 | ||
@@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
163 | continue; | 160 | continue; |
164 | 161 | ||
165 | /* Tell AP we're back */ | 162 | /* Tell AP we're back */ |
166 | if (offchannel_ps_disable && | 163 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
167 | sdata->vif.type == NL80211_IFTYPE_STATION) { | 164 | sdata->u.mgd.associated) |
168 | if (sdata->u.mgd.associated) | 165 | ieee80211_offchannel_ps_disable(sdata); |
169 | ieee80211_offchannel_ps_disable(sdata); | ||
170 | } | ||
171 | 166 | ||
172 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 167 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
173 | /* | 168 | /* |
@@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
385 | local->tmp_channel = NULL; | 380 | local->tmp_channel = NULL; |
386 | ieee80211_hw_config(local, 0); | 381 | ieee80211_hw_config(local, 0); |
387 | 382 | ||
388 | ieee80211_offchannel_return(local, true); | 383 | ieee80211_offchannel_return(local); |
389 | } | 384 | } |
390 | 385 | ||
391 | ieee80211_recalc_idle(local); | 386 | ieee80211_recalc_idle(local); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d59fc6818b1c..bf82e69d0601 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
292 | if (!was_hw_scan) { | 292 | if (!was_hw_scan) { |
293 | ieee80211_configure_filter(local); | 293 | ieee80211_configure_filter(local); |
294 | drv_sw_scan_complete(local); | 294 | drv_sw_scan_complete(local); |
295 | ieee80211_offchannel_return(local, true); | 295 | ieee80211_offchannel_return(local); |
296 | } | 296 | } |
297 | 297 | ||
298 | ieee80211_recalc_idle(local); | 298 | ieee80211_recalc_idle(local); |
@@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
341 | local->next_scan_state = SCAN_DECISION; | 341 | local->next_scan_state = SCAN_DECISION; |
342 | local->scan_channel_idx = 0; | 342 | local->scan_channel_idx = 0; |
343 | 343 | ||
344 | ieee80211_offchannel_stop_vifs(local, true); | 344 | ieee80211_offchannel_stop_vifs(local); |
345 | 345 | ||
346 | ieee80211_configure_filter(local); | 346 | ieee80211_configure_filter(local); |
347 | 347 | ||
@@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
678 | local->scan_channel = NULL; | 678 | local->scan_channel = NULL; |
679 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 679 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
680 | 680 | ||
681 | /* | 681 | /* disable PS */ |
682 | * Re-enable vifs and beaconing. Leave PS | 682 | ieee80211_offchannel_return(local); |
683 | * in off-channel state..will put that back | ||
684 | * on-channel at the end of scanning. | ||
685 | */ | ||
686 | ieee80211_offchannel_return(local, false); | ||
687 | 683 | ||
688 | *next_delay = HZ / 5; | 684 | *next_delay = HZ / 5; |
689 | /* afterwards, resume scan & go to next channel */ | 685 | /* afterwards, resume scan & go to next channel */ |
@@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
693 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, | 689 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, |
694 | unsigned long *next_delay) | 690 | unsigned long *next_delay) |
695 | { | 691 | { |
696 | /* PS already is in off-channel mode */ | 692 | ieee80211_offchannel_stop_vifs(local); |
697 | ieee80211_offchannel_stop_vifs(local, false); | ||
698 | 693 | ||
699 | if (local->ops->flush) { | 694 | if (local->ops->flush) { |
700 | drv_flush(local, false); | 695 | drv_flush(local, false); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e9eadc40c09c..467c1d1b66f2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1673 | chanctx_conf = | 1673 | chanctx_conf = |
1674 | rcu_dereference(tmp_sdata->vif.chanctx_conf); | 1674 | rcu_dereference(tmp_sdata->vif.chanctx_conf); |
1675 | } | 1675 | } |
1676 | if (!chanctx_conf) | ||
1677 | goto fail_rcu; | ||
1678 | 1676 | ||
1679 | chan = chanctx_conf->def.chan; | 1677 | if (chanctx_conf) |
1678 | chan = chanctx_conf->def.chan; | ||
1679 | else if (!local->use_chanctx) | ||
1680 | chan = local->_oper_channel; | ||
1681 | else | ||
1682 | goto fail_rcu; | ||
1680 | 1683 | ||
1681 | /* | 1684 | /* |
1682 | * Frame injection is not allowed if beaconing is not allowed | 1685 | * Frame injection is not allowed if beaconing is not allowed |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 016d95ead930..e4a0c4fb3a7c 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1376,11 +1376,12 @@ void nf_conntrack_cleanup(struct net *net) | |||
1376 | synchronize_net(); | 1376 | synchronize_net(); |
1377 | nf_conntrack_proto_fini(net); | 1377 | nf_conntrack_proto_fini(net); |
1378 | nf_conntrack_cleanup_net(net); | 1378 | nf_conntrack_cleanup_net(net); |
1379 | } | ||
1379 | 1380 | ||
1380 | if (net_eq(net, &init_net)) { | 1381 | void nf_conntrack_cleanup_end(void) |
1381 | RCU_INIT_POINTER(nf_ct_destroy, NULL); | 1382 | { |
1382 | nf_conntrack_cleanup_init_net(); | 1383 | RCU_INIT_POINTER(nf_ct_destroy, NULL); |
1383 | } | 1384 | nf_conntrack_cleanup_init_net(); |
1384 | } | 1385 | } |
1385 | 1386 | ||
1386 | void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls) | 1387 | void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls) |
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 363285d544a1..e7185c684816 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
@@ -575,6 +575,7 @@ static int __init nf_conntrack_standalone_init(void) | |||
575 | static void __exit nf_conntrack_standalone_fini(void) | 575 | static void __exit nf_conntrack_standalone_fini(void) |
576 | { | 576 | { |
577 | unregister_pernet_subsys(&nf_conntrack_net_ops); | 577 | unregister_pernet_subsys(&nf_conntrack_net_ops); |
578 | nf_conntrack_cleanup_end(); | ||
578 | } | 579 | } |
579 | 580 | ||
580 | module_init(nf_conntrack_standalone_init); | 581 | module_init(nf_conntrack_standalone_init); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 8d987c3573fd..7b3a9e5999c0 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -345,19 +345,27 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target, | |||
345 | } | 345 | } |
346 | EXPORT_SYMBOL_GPL(xt_find_revision); | 346 | EXPORT_SYMBOL_GPL(xt_find_revision); |
347 | 347 | ||
348 | static char *textify_hooks(char *buf, size_t size, unsigned int mask) | 348 | static char * |
349 | textify_hooks(char *buf, size_t size, unsigned int mask, uint8_t nfproto) | ||
349 | { | 350 | { |
350 | static const char *const names[] = { | 351 | static const char *const inetbr_names[] = { |
351 | "PREROUTING", "INPUT", "FORWARD", | 352 | "PREROUTING", "INPUT", "FORWARD", |
352 | "OUTPUT", "POSTROUTING", "BROUTING", | 353 | "OUTPUT", "POSTROUTING", "BROUTING", |
353 | }; | 354 | }; |
354 | unsigned int i; | 355 | static const char *const arp_names[] = { |
356 | "INPUT", "FORWARD", "OUTPUT", | ||
357 | }; | ||
358 | const char *const *names; | ||
359 | unsigned int i, max; | ||
355 | char *p = buf; | 360 | char *p = buf; |
356 | bool np = false; | 361 | bool np = false; |
357 | int res; | 362 | int res; |
358 | 363 | ||
364 | names = (nfproto == NFPROTO_ARP) ? arp_names : inetbr_names; | ||
365 | max = (nfproto == NFPROTO_ARP) ? ARRAY_SIZE(arp_names) : | ||
366 | ARRAY_SIZE(inetbr_names); | ||
359 | *p = '\0'; | 367 | *p = '\0'; |
360 | for (i = 0; i < ARRAY_SIZE(names); ++i) { | 368 | for (i = 0; i < max; ++i) { |
361 | if (!(mask & (1 << i))) | 369 | if (!(mask & (1 << i))) |
362 | continue; | 370 | continue; |
363 | res = snprintf(p, size, "%s%s", np ? "/" : "", names[i]); | 371 | res = snprintf(p, size, "%s%s", np ? "/" : "", names[i]); |
@@ -402,8 +410,10 @@ int xt_check_match(struct xt_mtchk_param *par, | |||
402 | pr_err("%s_tables: %s match: used from hooks %s, but only " | 410 | pr_err("%s_tables: %s match: used from hooks %s, but only " |
403 | "valid from %s\n", | 411 | "valid from %s\n", |
404 | xt_prefix[par->family], par->match->name, | 412 | xt_prefix[par->family], par->match->name, |
405 | textify_hooks(used, sizeof(used), par->hook_mask), | 413 | textify_hooks(used, sizeof(used), par->hook_mask, |
406 | textify_hooks(allow, sizeof(allow), par->match->hooks)); | 414 | par->family), |
415 | textify_hooks(allow, sizeof(allow), par->match->hooks, | ||
416 | par->family)); | ||
407 | return -EINVAL; | 417 | return -EINVAL; |
408 | } | 418 | } |
409 | if (par->match->proto && (par->match->proto != proto || inv_proto)) { | 419 | if (par->match->proto && (par->match->proto != proto || inv_proto)) { |
@@ -575,8 +585,10 @@ int xt_check_target(struct xt_tgchk_param *par, | |||
575 | pr_err("%s_tables: %s target: used from hooks %s, but only " | 585 | pr_err("%s_tables: %s target: used from hooks %s, but only " |
576 | "usable from %s\n", | 586 | "usable from %s\n", |
577 | xt_prefix[par->family], par->target->name, | 587 | xt_prefix[par->family], par->target->name, |
578 | textify_hooks(used, sizeof(used), par->hook_mask), | 588 | textify_hooks(used, sizeof(used), par->hook_mask, |
579 | textify_hooks(allow, sizeof(allow), par->target->hooks)); | 589 | par->family), |
590 | textify_hooks(allow, sizeof(allow), par->target->hooks, | ||
591 | par->family)); | ||
580 | return -EINVAL; | 592 | return -EINVAL; |
581 | } | 593 | } |
582 | if (par->target->proto && (par->target->proto != proto || inv_proto)) { | 594 | if (par->target->proto && (par->target->proto != proto || inv_proto)) { |
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 2a0843081840..bde009ed8d3b 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
@@ -109,7 +109,7 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) | |||
109 | struct xt_ct_target_info *info = par->targinfo; | 109 | struct xt_ct_target_info *info = par->targinfo; |
110 | struct nf_conntrack_tuple t; | 110 | struct nf_conntrack_tuple t; |
111 | struct nf_conn *ct; | 111 | struct nf_conn *ct; |
112 | int ret; | 112 | int ret = -EOPNOTSUPP; |
113 | 113 | ||
114 | if (info->flags & ~XT_CT_NOTRACK) | 114 | if (info->flags & ~XT_CT_NOTRACK) |
115 | return -EINVAL; | 115 | return -EINVAL; |
@@ -247,7 +247,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
247 | struct xt_ct_target_info_v1 *info = par->targinfo; | 247 | struct xt_ct_target_info_v1 *info = par->targinfo; |
248 | struct nf_conntrack_tuple t; | 248 | struct nf_conntrack_tuple t; |
249 | struct nf_conn *ct; | 249 | struct nf_conn *ct; |
250 | int ret; | 250 | int ret = -EOPNOTSUPP; |
251 | 251 | ||
252 | if (info->flags & ~XT_CT_NOTRACK) | 252 | if (info->flags & ~XT_CT_NOTRACK) |
253 | return -EINVAL; | 253 | return -EINVAL; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 379c81dee9d1..9bcdbd02d777 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -224,7 +224,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) | |||
224 | 224 | ||
225 | /* Free the outqueue structure and any related pending chunks. | 225 | /* Free the outqueue structure and any related pending chunks. |
226 | */ | 226 | */ |
227 | void sctp_outq_teardown(struct sctp_outq *q) | 227 | static void __sctp_outq_teardown(struct sctp_outq *q) |
228 | { | 228 | { |
229 | struct sctp_transport *transport; | 229 | struct sctp_transport *transport; |
230 | struct list_head *lchunk, *temp; | 230 | struct list_head *lchunk, *temp; |
@@ -277,8 +277,6 @@ void sctp_outq_teardown(struct sctp_outq *q) | |||
277 | sctp_chunk_free(chunk); | 277 | sctp_chunk_free(chunk); |
278 | } | 278 | } |
279 | 279 | ||
280 | q->error = 0; | ||
281 | |||
282 | /* Throw away any leftover control chunks. */ | 280 | /* Throw away any leftover control chunks. */ |
283 | list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { | 281 | list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { |
284 | list_del_init(&chunk->list); | 282 | list_del_init(&chunk->list); |
@@ -286,11 +284,17 @@ void sctp_outq_teardown(struct sctp_outq *q) | |||
286 | } | 284 | } |
287 | } | 285 | } |
288 | 286 | ||
287 | void sctp_outq_teardown(struct sctp_outq *q) | ||
288 | { | ||
289 | __sctp_outq_teardown(q); | ||
290 | sctp_outq_init(q->asoc, q); | ||
291 | } | ||
292 | |||
289 | /* Free the outqueue structure and any related pending chunks. */ | 293 | /* Free the outqueue structure and any related pending chunks. */ |
290 | void sctp_outq_free(struct sctp_outq *q) | 294 | void sctp_outq_free(struct sctp_outq *q) |
291 | { | 295 | { |
292 | /* Throw away leftover chunks. */ | 296 | /* Throw away leftover chunks. */ |
293 | sctp_outq_teardown(q); | 297 | __sctp_outq_teardown(q); |
294 | 298 | ||
295 | /* If we were kmalloc()'d, free the memory. */ | 299 | /* If we were kmalloc()'d, free the memory. */ |
296 | if (q->malloced) | 300 | if (q->malloced) |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 618ec7e216ca..5131fcfedb03 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1779,8 +1779,10 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net, | |||
1779 | 1779 | ||
1780 | /* Update the content of current association. */ | 1780 | /* Update the content of current association. */ |
1781 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); | 1781 | sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); |
1782 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1783 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); | 1782 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); |
1783 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | ||
1784 | SCTP_STATE(SCTP_STATE_ESTABLISHED)); | ||
1785 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); | ||
1784 | return SCTP_DISPOSITION_CONSUME; | 1786 | return SCTP_DISPOSITION_CONSUME; |
1785 | 1787 | ||
1786 | nomem_ev: | 1788 | nomem_ev: |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 043889ac86c0..bf3c6e8fc401 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -366,7 +366,11 @@ int sctp_sysctl_net_register(struct net *net) | |||
366 | 366 | ||
367 | void sctp_sysctl_net_unregister(struct net *net) | 367 | void sctp_sysctl_net_unregister(struct net *net) |
368 | { | 368 | { |
369 | struct ctl_table *table; | ||
370 | |||
371 | table = net->sctp.sysctl_header->ctl_table_arg; | ||
369 | unregister_net_sysctl_table(net->sctp.sysctl_header); | 372 | unregister_net_sysctl_table(net->sctp.sysctl_header); |
373 | kfree(table); | ||
370 | } | 374 | } |
371 | 375 | ||
372 | static struct ctl_table_header * sctp_sysctl_header; | 376 | static struct ctl_table_header * sctp_sysctl_header; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 41eabc46f110..07c585756d2a 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -2656,7 +2656,7 @@ static void xfrm_policy_fini(struct net *net) | |||
2656 | WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir])); | 2656 | WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir])); |
2657 | 2657 | ||
2658 | htab = &net->xfrm.policy_bydst[dir]; | 2658 | htab = &net->xfrm.policy_bydst[dir]; |
2659 | sz = (htab->hmask + 1); | 2659 | sz = (htab->hmask + 1) * sizeof(struct hlist_head); |
2660 | WARN_ON(!hlist_empty(htab->table)); | 2660 | WARN_ON(!hlist_empty(htab->table)); |
2661 | xfrm_hash_free(htab->table, sz); | 2661 | xfrm_hash_free(htab->table, sz); |
2662 | } | 2662 | } |
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 765f6fe951eb..35754cc8a9e5 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
@@ -242,11 +242,13 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq) | |||
242 | u32 diff; | 242 | u32 diff; |
243 | struct xfrm_replay_state_esn *replay_esn = x->replay_esn; | 243 | struct xfrm_replay_state_esn *replay_esn = x->replay_esn; |
244 | u32 seq = ntohl(net_seq); | 244 | u32 seq = ntohl(net_seq); |
245 | u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window; | 245 | u32 pos; |
246 | 246 | ||
247 | if (!replay_esn->replay_window) | 247 | if (!replay_esn->replay_window) |
248 | return; | 248 | return; |
249 | 249 | ||
250 | pos = (replay_esn->seq - 1) % replay_esn->replay_window; | ||
251 | |||
250 | if (seq > replay_esn->seq) { | 252 | if (seq > replay_esn->seq) { |
251 | diff = seq - replay_esn->seq; | 253 | diff = seq - replay_esn->seq; |
252 | 254 | ||
diff --git a/security/capability.c b/security/capability.c index 0fe5a026aef8..579775088967 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -709,16 +709,31 @@ static void cap_req_classify_flow(const struct request_sock *req, | |||
709 | { | 709 | { |
710 | } | 710 | } |
711 | 711 | ||
712 | static int cap_tun_dev_alloc_security(void **security) | ||
713 | { | ||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | static void cap_tun_dev_free_security(void *security) | ||
718 | { | ||
719 | } | ||
720 | |||
712 | static int cap_tun_dev_create(void) | 721 | static int cap_tun_dev_create(void) |
713 | { | 722 | { |
714 | return 0; | 723 | return 0; |
715 | } | 724 | } |
716 | 725 | ||
717 | static void cap_tun_dev_post_create(struct sock *sk) | 726 | static int cap_tun_dev_attach_queue(void *security) |
727 | { | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | static int cap_tun_dev_attach(struct sock *sk, void *security) | ||
718 | { | 732 | { |
733 | return 0; | ||
719 | } | 734 | } |
720 | 735 | ||
721 | static int cap_tun_dev_attach(struct sock *sk) | 736 | static int cap_tun_dev_open(void *security) |
722 | { | 737 | { |
723 | return 0; | 738 | return 0; |
724 | } | 739 | } |
@@ -1050,8 +1065,11 @@ void __init security_fixup_ops(struct security_operations *ops) | |||
1050 | set_to_cap_if_null(ops, secmark_refcount_inc); | 1065 | set_to_cap_if_null(ops, secmark_refcount_inc); |
1051 | set_to_cap_if_null(ops, secmark_refcount_dec); | 1066 | set_to_cap_if_null(ops, secmark_refcount_dec); |
1052 | set_to_cap_if_null(ops, req_classify_flow); | 1067 | set_to_cap_if_null(ops, req_classify_flow); |
1068 | set_to_cap_if_null(ops, tun_dev_alloc_security); | ||
1069 | set_to_cap_if_null(ops, tun_dev_free_security); | ||
1053 | set_to_cap_if_null(ops, tun_dev_create); | 1070 | set_to_cap_if_null(ops, tun_dev_create); |
1054 | set_to_cap_if_null(ops, tun_dev_post_create); | 1071 | set_to_cap_if_null(ops, tun_dev_open); |
1072 | set_to_cap_if_null(ops, tun_dev_attach_queue); | ||
1055 | set_to_cap_if_null(ops, tun_dev_attach); | 1073 | set_to_cap_if_null(ops, tun_dev_attach); |
1056 | #endif /* CONFIG_SECURITY_NETWORK */ | 1074 | #endif /* CONFIG_SECURITY_NETWORK */ |
1057 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1075 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
diff --git a/security/security.c b/security/security.c index daa97f4ac9d1..7b88c6aeaed4 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1254,24 +1254,42 @@ void security_secmark_refcount_dec(void) | |||
1254 | } | 1254 | } |
1255 | EXPORT_SYMBOL(security_secmark_refcount_dec); | 1255 | EXPORT_SYMBOL(security_secmark_refcount_dec); |
1256 | 1256 | ||
1257 | int security_tun_dev_alloc_security(void **security) | ||
1258 | { | ||
1259 | return security_ops->tun_dev_alloc_security(security); | ||
1260 | } | ||
1261 | EXPORT_SYMBOL(security_tun_dev_alloc_security); | ||
1262 | |||
1263 | void security_tun_dev_free_security(void *security) | ||
1264 | { | ||
1265 | security_ops->tun_dev_free_security(security); | ||
1266 | } | ||
1267 | EXPORT_SYMBOL(security_tun_dev_free_security); | ||
1268 | |||
1257 | int security_tun_dev_create(void) | 1269 | int security_tun_dev_create(void) |
1258 | { | 1270 | { |
1259 | return security_ops->tun_dev_create(); | 1271 | return security_ops->tun_dev_create(); |
1260 | } | 1272 | } |
1261 | EXPORT_SYMBOL(security_tun_dev_create); | 1273 | EXPORT_SYMBOL(security_tun_dev_create); |
1262 | 1274 | ||
1263 | void security_tun_dev_post_create(struct sock *sk) | 1275 | int security_tun_dev_attach_queue(void *security) |
1264 | { | 1276 | { |
1265 | return security_ops->tun_dev_post_create(sk); | 1277 | return security_ops->tun_dev_attach_queue(security); |
1266 | } | 1278 | } |
1267 | EXPORT_SYMBOL(security_tun_dev_post_create); | 1279 | EXPORT_SYMBOL(security_tun_dev_attach_queue); |
1268 | 1280 | ||
1269 | int security_tun_dev_attach(struct sock *sk) | 1281 | int security_tun_dev_attach(struct sock *sk, void *security) |
1270 | { | 1282 | { |
1271 | return security_ops->tun_dev_attach(sk); | 1283 | return security_ops->tun_dev_attach(sk, security); |
1272 | } | 1284 | } |
1273 | EXPORT_SYMBOL(security_tun_dev_attach); | 1285 | EXPORT_SYMBOL(security_tun_dev_attach); |
1274 | 1286 | ||
1287 | int security_tun_dev_open(void *security) | ||
1288 | { | ||
1289 | return security_ops->tun_dev_open(security); | ||
1290 | } | ||
1291 | EXPORT_SYMBOL(security_tun_dev_open); | ||
1292 | |||
1275 | #endif /* CONFIG_SECURITY_NETWORK */ | 1293 | #endif /* CONFIG_SECURITY_NETWORK */ |
1276 | 1294 | ||
1277 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1295 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 61a53367d029..ef26e9611ffb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4399,6 +4399,24 @@ static void selinux_req_classify_flow(const struct request_sock *req, | |||
4399 | fl->flowi_secid = req->secid; | 4399 | fl->flowi_secid = req->secid; |
4400 | } | 4400 | } |
4401 | 4401 | ||
4402 | static int selinux_tun_dev_alloc_security(void **security) | ||
4403 | { | ||
4404 | struct tun_security_struct *tunsec; | ||
4405 | |||
4406 | tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL); | ||
4407 | if (!tunsec) | ||
4408 | return -ENOMEM; | ||
4409 | tunsec->sid = current_sid(); | ||
4410 | |||
4411 | *security = tunsec; | ||
4412 | return 0; | ||
4413 | } | ||
4414 | |||
4415 | static void selinux_tun_dev_free_security(void *security) | ||
4416 | { | ||
4417 | kfree(security); | ||
4418 | } | ||
4419 | |||
4402 | static int selinux_tun_dev_create(void) | 4420 | static int selinux_tun_dev_create(void) |
4403 | { | 4421 | { |
4404 | u32 sid = current_sid(); | 4422 | u32 sid = current_sid(); |
@@ -4414,8 +4432,17 @@ static int selinux_tun_dev_create(void) | |||
4414 | NULL); | 4432 | NULL); |
4415 | } | 4433 | } |
4416 | 4434 | ||
4417 | static void selinux_tun_dev_post_create(struct sock *sk) | 4435 | static int selinux_tun_dev_attach_queue(void *security) |
4418 | { | 4436 | { |
4437 | struct tun_security_struct *tunsec = security; | ||
4438 | |||
4439 | return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET, | ||
4440 | TUN_SOCKET__ATTACH_QUEUE, NULL); | ||
4441 | } | ||
4442 | |||
4443 | static int selinux_tun_dev_attach(struct sock *sk, void *security) | ||
4444 | { | ||
4445 | struct tun_security_struct *tunsec = security; | ||
4419 | struct sk_security_struct *sksec = sk->sk_security; | 4446 | struct sk_security_struct *sksec = sk->sk_security; |
4420 | 4447 | ||
4421 | /* we don't currently perform any NetLabel based labeling here and it | 4448 | /* we don't currently perform any NetLabel based labeling here and it |
@@ -4425,20 +4452,19 @@ static void selinux_tun_dev_post_create(struct sock *sk) | |||
4425 | * cause confusion to the TUN user that had no idea network labeling | 4452 | * cause confusion to the TUN user that had no idea network labeling |
4426 | * protocols were being used */ | 4453 | * protocols were being used */ |
4427 | 4454 | ||
4428 | /* see the comments in selinux_tun_dev_create() about why we don't use | 4455 | sksec->sid = tunsec->sid; |
4429 | * the sockcreate SID here */ | ||
4430 | |||
4431 | sksec->sid = current_sid(); | ||
4432 | sksec->sclass = SECCLASS_TUN_SOCKET; | 4456 | sksec->sclass = SECCLASS_TUN_SOCKET; |
4457 | |||
4458 | return 0; | ||
4433 | } | 4459 | } |
4434 | 4460 | ||
4435 | static int selinux_tun_dev_attach(struct sock *sk) | 4461 | static int selinux_tun_dev_open(void *security) |
4436 | { | 4462 | { |
4437 | struct sk_security_struct *sksec = sk->sk_security; | 4463 | struct tun_security_struct *tunsec = security; |
4438 | u32 sid = current_sid(); | 4464 | u32 sid = current_sid(); |
4439 | int err; | 4465 | int err; |
4440 | 4466 | ||
4441 | err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, | 4467 | err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET, |
4442 | TUN_SOCKET__RELABELFROM, NULL); | 4468 | TUN_SOCKET__RELABELFROM, NULL); |
4443 | if (err) | 4469 | if (err) |
4444 | return err; | 4470 | return err; |
@@ -4446,8 +4472,7 @@ static int selinux_tun_dev_attach(struct sock *sk) | |||
4446 | TUN_SOCKET__RELABELTO, NULL); | 4472 | TUN_SOCKET__RELABELTO, NULL); |
4447 | if (err) | 4473 | if (err) |
4448 | return err; | 4474 | return err; |
4449 | 4475 | tunsec->sid = sid; | |
4450 | sksec->sid = sid; | ||
4451 | 4476 | ||
4452 | return 0; | 4477 | return 0; |
4453 | } | 4478 | } |
@@ -5642,9 +5667,12 @@ static struct security_operations selinux_ops = { | |||
5642 | .secmark_refcount_inc = selinux_secmark_refcount_inc, | 5667 | .secmark_refcount_inc = selinux_secmark_refcount_inc, |
5643 | .secmark_refcount_dec = selinux_secmark_refcount_dec, | 5668 | .secmark_refcount_dec = selinux_secmark_refcount_dec, |
5644 | .req_classify_flow = selinux_req_classify_flow, | 5669 | .req_classify_flow = selinux_req_classify_flow, |
5670 | .tun_dev_alloc_security = selinux_tun_dev_alloc_security, | ||
5671 | .tun_dev_free_security = selinux_tun_dev_free_security, | ||
5645 | .tun_dev_create = selinux_tun_dev_create, | 5672 | .tun_dev_create = selinux_tun_dev_create, |
5646 | .tun_dev_post_create = selinux_tun_dev_post_create, | 5673 | .tun_dev_attach_queue = selinux_tun_dev_attach_queue, |
5647 | .tun_dev_attach = selinux_tun_dev_attach, | 5674 | .tun_dev_attach = selinux_tun_dev_attach, |
5675 | .tun_dev_open = selinux_tun_dev_open, | ||
5648 | 5676 | ||
5649 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 5677 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
5650 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 5678 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index df2de54a958d..14d04e63b1f0 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
@@ -150,6 +150,6 @@ struct security_class_mapping secclass_map[] = { | |||
150 | NULL } }, | 150 | NULL } }, |
151 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, | 151 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, |
152 | { "tun_socket", | 152 | { "tun_socket", |
153 | { COMMON_SOCK_PERMS, NULL } }, | 153 | { COMMON_SOCK_PERMS, "attach_queue", NULL } }, |
154 | { NULL } | 154 | { NULL } |
155 | }; | 155 | }; |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 26c7eee1c309..aa47bcabb5f6 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -110,6 +110,10 @@ struct sk_security_struct { | |||
110 | u16 sclass; /* sock security class */ | 110 | u16 sclass; /* sock security class */ |
111 | }; | 111 | }; |
112 | 112 | ||
113 | struct tun_security_struct { | ||
114 | u32 sid; /* SID for the tun device sockets */ | ||
115 | }; | ||
116 | |||
113 | struct key_security_struct { | 117 | struct key_security_struct { |
114 | u32 sid; /* SID of key */ | 118 | u32 sid; /* SID of key */ |
115 | }; | 119 | }; |