diff options
36 files changed, 1032 insertions, 336 deletions
diff --git a/Documentation/devicetree/bindings/net/nfc/st21nfca.txt b/Documentation/devicetree/bindings/net/nfc/st21nfca.txt index e4faa2e8dfeb..7bb2e213d6f9 100644 --- a/Documentation/devicetree/bindings/net/nfc/st21nfca.txt +++ b/Documentation/devicetree/bindings/net/nfc/st21nfca.txt | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | * STMicroelectronics SAS. ST21NFCA NFC Controller | 1 | * STMicroelectronics SAS. ST21NFCA NFC Controller |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: Should be "st,st21nfca_i2c". | 4 | - compatible: Should be "st,st21nfca-i2c". |
| 5 | - clock-frequency: I²C work frequency. | 5 | - clock-frequency: I²C work frequency. |
| 6 | - reg: address on the bus | 6 | - reg: address on the bus |
| 7 | - interrupt-parent: phandle for the interrupt gpio controller | 7 | - interrupt-parent: phandle for the interrupt gpio controller |
| @@ -11,6 +11,10 @@ Required properties: | |||
| 11 | Optional SoC Specific Properties: | 11 | Optional SoC Specific Properties: |
| 12 | - pinctrl-names: Contains only one value - "default". | 12 | - pinctrl-names: Contains only one value - "default". |
| 13 | - pintctrl-0: Specifies the pin control groups used for this controller. | 13 | - pintctrl-0: Specifies the pin control groups used for this controller. |
| 14 | - ese-present: Specifies that an ese is physically connected to the nfc | ||
| 15 | controller. | ||
| 16 | - uicc-present: Specifies that the uicc swp signal can be physically | ||
| 17 | connected to the nfc controller. | ||
| 14 | 18 | ||
| 15 | Example (for ARM-based BeagleBoard xM with ST21NFCA on I2C2): | 19 | Example (for ARM-based BeagleBoard xM with ST21NFCA on I2C2): |
| 16 | 20 | ||
| @@ -20,7 +24,7 @@ Example (for ARM-based BeagleBoard xM with ST21NFCA on I2C2): | |||
| 20 | 24 | ||
| 21 | st21nfca: st21nfca@1 { | 25 | st21nfca: st21nfca@1 { |
| 22 | 26 | ||
| 23 | compatible = "st,st21nfca_i2c"; | 27 | compatible = "st,st21nfca-i2c"; |
| 24 | 28 | ||
| 25 | reg = <0x01>; | 29 | reg = <0x01>; |
| 26 | clock-frequency = <400000>; | 30 | clock-frequency = <400000>; |
| @@ -29,5 +33,8 @@ Example (for ARM-based BeagleBoard xM with ST21NFCA on I2C2): | |||
| 29 | interrupts = <2 IRQ_TYPE_LEVEL_LOW>; | 33 | interrupts = <2 IRQ_TYPE_LEVEL_LOW>; |
| 30 | 34 | ||
| 31 | enable-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>; | 35 | enable-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>; |
| 36 | |||
| 37 | ese-present; | ||
| 38 | uicc-present; | ||
| 32 | }; | 39 | }; |
| 33 | }; | 40 | }; |
diff --git a/Documentation/devicetree/bindings/net/nfc/st21nfcb.txt b/Documentation/devicetree/bindings/net/nfc/st21nfcb.txt index 9005608cbbd1..bb237072dbe9 100644 --- a/Documentation/devicetree/bindings/net/nfc/st21nfcb.txt +++ b/Documentation/devicetree/bindings/net/nfc/st21nfcb.txt | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | * STMicroelectronics SAS. ST21NFCB NFC Controller | 1 | * STMicroelectronics SAS. ST21NFCB NFC Controller |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: Should be "st,st21nfcb_i2c". | 4 | - compatible: Should be "st,st21nfcb-i2c". |
| 5 | - clock-frequency: I²C work frequency. | 5 | - clock-frequency: I²C work frequency. |
| 6 | - reg: address on the bus | 6 | - reg: address on the bus |
| 7 | - interrupt-parent: phandle for the interrupt gpio controller | 7 | - interrupt-parent: phandle for the interrupt gpio controller |
| @@ -20,7 +20,7 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on I2C2): | |||
| 20 | 20 | ||
| 21 | st21nfcb: st21nfcb@8 { | 21 | st21nfcb: st21nfcb@8 { |
| 22 | 22 | ||
| 23 | compatible = "st,st21nfcb_i2c"; | 23 | compatible = "st,st21nfcb-i2c"; |
| 24 | 24 | ||
| 25 | reg = <0x08>; | 25 | reg = <0x08>; |
| 26 | clock-frequency = <400000>; | 26 | clock-frequency = <400000>; |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 93ff846e96f1..43df78882e48 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
| @@ -764,7 +764,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
| 764 | u32 *tx_queues, *rx_queues; | 764 | u32 *tx_queues, *rx_queues; |
| 765 | unsigned short mode, poll_mode; | 765 | unsigned short mode, poll_mode; |
| 766 | 766 | ||
| 767 | if (!np || !of_device_is_available(np)) | 767 | if (!np) |
| 768 | return -ENODEV; | 768 | return -ENODEV; |
| 769 | 769 | ||
| 770 | if (of_device_is_compatible(np, "fsl,etsec2")) { | 770 | if (of_device_is_compatible(np, "fsl,etsec2")) { |
diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c index 525214ef5984..c02b81bcfffb 100644 --- a/drivers/net/ethernet/hisilicon/hip04_eth.c +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c | |||
| @@ -567,10 +567,11 @@ static irqreturn_t hip04_mac_interrupt(int irq, void *dev_id) | |||
| 567 | writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT); | 567 | writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT); |
| 568 | 568 | ||
| 569 | if (unlikely(ists & DEF_INT_ERR)) { | 569 | if (unlikely(ists & DEF_INT_ERR)) { |
| 570 | if (ists & (RCV_NOBUF | RCV_DROP)) | 570 | if (ists & (RCV_NOBUF | RCV_DROP)) { |
| 571 | stats->rx_errors++; | 571 | stats->rx_errors++; |
| 572 | stats->rx_dropped++; | 572 | stats->rx_dropped++; |
| 573 | netdev_err(ndev, "rx drop\n"); | 573 | netdev_err(ndev, "rx drop\n"); |
| 574 | } | ||
| 574 | if (ists & TX_DROP) { | 575 | if (ists & TX_DROP) { |
| 575 | stats->tx_dropped++; | 576 | stats->tx_dropped++; |
| 576 | netdev_err(ndev, "tx drop\n"); | 577 | netdev_err(ndev, "tx drop\n"); |
diff --git a/drivers/nfc/microread/microread.c b/drivers/nfc/microread/microread.c index 963a4a5dc88e..f454dc68cc03 100644 --- a/drivers/nfc/microread/microread.c +++ b/drivers/nfc/microread/microread.c | |||
| @@ -557,10 +557,11 @@ exit: | |||
| 557 | pr_err("Failed to handle discovered target err=%d\n", r); | 557 | pr_err("Failed to handle discovered target err=%d\n", r); |
| 558 | } | 558 | } |
| 559 | 559 | ||
| 560 | static int microread_event_received(struct nfc_hci_dev *hdev, u8 gate, | 560 | static int microread_event_received(struct nfc_hci_dev *hdev, u8 pipe, |
| 561 | u8 event, struct sk_buff *skb) | 561 | u8 event, struct sk_buff *skb) |
| 562 | { | 562 | { |
| 563 | int r; | 563 | int r; |
| 564 | u8 gate = hdev->pipes[pipe].gate; | ||
| 564 | u8 mode; | 565 | u8 mode; |
| 565 | 566 | ||
| 566 | pr_info("Microread received event 0x%x to gate 0x%x\n", event, gate); | 567 | pr_info("Microread received event 0x%x to gate 0x%x\n", event, gate); |
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index fc02e8d6a193..cdde745b96bd 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c | |||
| @@ -24,11 +24,13 @@ | |||
| 24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
| 25 | #include <linux/of_gpio.h> | 25 | #include <linux/of_gpio.h> |
| 26 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
| 27 | #include <linux/acpi.h> | ||
| 27 | #include <linux/miscdevice.h> | 28 | #include <linux/miscdevice.h> |
| 28 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
| 29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
| 30 | #include <linux/nfc.h> | 31 | #include <linux/nfc.h> |
| 31 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
| 33 | #include <linux/gpio/consumer.h> | ||
| 32 | #include <linux/platform_data/pn544.h> | 34 | #include <linux/platform_data/pn544.h> |
| 33 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
| 34 | 36 | ||
| @@ -41,6 +43,11 @@ | |||
| 41 | #define PN544_I2C_FRAME_HEADROOM 1 | 43 | #define PN544_I2C_FRAME_HEADROOM 1 |
| 42 | #define PN544_I2C_FRAME_TAILROOM 2 | 44 | #define PN544_I2C_FRAME_TAILROOM 2 |
| 43 | 45 | ||
| 46 | /* GPIO names */ | ||
| 47 | #define PN544_GPIO_NAME_IRQ "pn544_irq" | ||
| 48 | #define PN544_GPIO_NAME_FW "pn544_fw" | ||
| 49 | #define PN544_GPIO_NAME_EN "pn544_en" | ||
| 50 | |||
| 44 | /* framing in HCI mode */ | 51 | /* framing in HCI mode */ |
| 45 | #define PN544_HCI_I2C_LLC_LEN 1 | 52 | #define PN544_HCI_I2C_LLC_LEN 1 |
| 46 | #define PN544_HCI_I2C_LLC_CRC 2 | 53 | #define PN544_HCI_I2C_LLC_CRC 2 |
| @@ -58,6 +65,13 @@ static struct i2c_device_id pn544_hci_i2c_id_table[] = { | |||
| 58 | 65 | ||
| 59 | MODULE_DEVICE_TABLE(i2c, pn544_hci_i2c_id_table); | 66 | MODULE_DEVICE_TABLE(i2c, pn544_hci_i2c_id_table); |
| 60 | 67 | ||
| 68 | static const struct acpi_device_id pn544_hci_i2c_acpi_match[] = { | ||
| 69 | {"NXP5440", 0}, | ||
| 70 | {} | ||
| 71 | }; | ||
| 72 | |||
| 73 | MODULE_DEVICE_TABLE(acpi, pn544_hci_i2c_acpi_match); | ||
| 74 | |||
| 61 | #define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c" | 75 | #define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c" |
| 62 | 76 | ||
| 63 | /* | 77 | /* |
| @@ -195,18 +209,19 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) | |||
| 195 | nfc_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n"); | 209 | nfc_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n"); |
| 196 | 210 | ||
| 197 | /* Disable fw download */ | 211 | /* Disable fw download */ |
| 198 | gpio_set_value(phy->gpio_fw, 0); | 212 | gpio_set_value_cansleep(phy->gpio_fw, 0); |
| 199 | 213 | ||
| 200 | for (polarity = 0; polarity < 2; polarity++) { | 214 | for (polarity = 0; polarity < 2; polarity++) { |
| 201 | phy->en_polarity = polarity; | 215 | phy->en_polarity = polarity; |
| 202 | retry = 3; | 216 | retry = 3; |
| 203 | while (retry--) { | 217 | while (retry--) { |
| 204 | /* power off */ | 218 | /* power off */ |
| 205 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | 219 | gpio_set_value_cansleep(phy->gpio_en, |
| 220 | !phy->en_polarity); | ||
| 206 | usleep_range(10000, 15000); | 221 | usleep_range(10000, 15000); |
| 207 | 222 | ||
| 208 | /* power on */ | 223 | /* power on */ |
| 209 | gpio_set_value(phy->gpio_en, phy->en_polarity); | 224 | gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity); |
| 210 | usleep_range(10000, 15000); | 225 | usleep_range(10000, 15000); |
| 211 | 226 | ||
| 212 | /* send reset */ | 227 | /* send reset */ |
| @@ -225,13 +240,14 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) | |||
| 225 | "Could not detect nfc_en polarity, fallback to active high\n"); | 240 | "Could not detect nfc_en polarity, fallback to active high\n"); |
| 226 | 241 | ||
| 227 | out: | 242 | out: |
| 228 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | 243 | gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity); |
| 229 | } | 244 | } |
| 230 | 245 | ||
| 231 | static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) | 246 | static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) |
| 232 | { | 247 | { |
| 233 | gpio_set_value(phy->gpio_fw, run_mode == PN544_FW_MODE ? 1 : 0); | 248 | gpio_set_value_cansleep(phy->gpio_fw, |
| 234 | gpio_set_value(phy->gpio_en, phy->en_polarity); | 249 | run_mode == PN544_FW_MODE ? 1 : 0); |
| 250 | gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity); | ||
| 235 | usleep_range(10000, 15000); | 251 | usleep_range(10000, 15000); |
| 236 | 252 | ||
| 237 | phy->run_mode = run_mode; | 253 | phy->run_mode = run_mode; |
| @@ -254,14 +270,14 @@ static void pn544_hci_i2c_disable(void *phy_id) | |||
| 254 | { | 270 | { |
| 255 | struct pn544_i2c_phy *phy = phy_id; | 271 | struct pn544_i2c_phy *phy = phy_id; |
| 256 | 272 | ||
| 257 | gpio_set_value(phy->gpio_fw, 0); | 273 | gpio_set_value_cansleep(phy->gpio_fw, 0); |
| 258 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | 274 | gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity); |
| 259 | usleep_range(10000, 15000); | 275 | usleep_range(10000, 15000); |
| 260 | 276 | ||
| 261 | gpio_set_value(phy->gpio_en, phy->en_polarity); | 277 | gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity); |
| 262 | usleep_range(10000, 15000); | 278 | usleep_range(10000, 15000); |
| 263 | 279 | ||
| 264 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | 280 | gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity); |
| 265 | usleep_range(10000, 15000); | 281 | usleep_range(10000, 15000); |
| 266 | 282 | ||
| 267 | phy->powered = 0; | 283 | phy->powered = 0; |
| @@ -859,6 +875,90 @@ exit_state_wait_secure_write_answer: | |||
| 859 | } | 875 | } |
| 860 | } | 876 | } |
| 861 | 877 | ||
| 878 | static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client) | ||
| 879 | { | ||
| 880 | struct pn544_i2c_phy *phy = i2c_get_clientdata(client); | ||
| 881 | const struct acpi_device_id *id; | ||
| 882 | struct gpio_desc *gpiod_en, *gpiod_irq, *gpiod_fw; | ||
| 883 | struct device *dev; | ||
| 884 | int ret; | ||
| 885 | |||
| 886 | if (!client) | ||
| 887 | return -EINVAL; | ||
| 888 | |||
| 889 | dev = &client->dev; | ||
| 890 | |||
| 891 | /* Match the struct device against a given list of ACPI IDs */ | ||
| 892 | id = acpi_match_device(dev->driver->acpi_match_table, dev); | ||
| 893 | |||
| 894 | if (!id) | ||
| 895 | return -ENODEV; | ||
| 896 | |||
| 897 | /* Get EN GPIO from ACPI */ | ||
| 898 | gpiod_en = devm_gpiod_get_index(dev, PN544_GPIO_NAME_EN, 1); | ||
| 899 | if (IS_ERR(gpiod_en)) { | ||
| 900 | nfc_err(dev, | ||
| 901 | "Unable to get EN GPIO\n"); | ||
| 902 | return -ENODEV; | ||
| 903 | } | ||
| 904 | |||
| 905 | phy->gpio_en = desc_to_gpio(gpiod_en); | ||
| 906 | |||
| 907 | /* Configuration EN GPIO */ | ||
| 908 | ret = gpiod_direction_output(gpiod_en, 0); | ||
| 909 | if (ret) { | ||
| 910 | nfc_err(dev, "Fail EN pin direction\n"); | ||
| 911 | return ret; | ||
| 912 | } | ||
| 913 | |||
| 914 | /* Get FW GPIO from ACPI */ | ||
| 915 | gpiod_fw = devm_gpiod_get_index(dev, PN544_GPIO_NAME_FW, 2); | ||
| 916 | if (IS_ERR(gpiod_fw)) { | ||
| 917 | nfc_err(dev, | ||
| 918 | "Unable to get FW GPIO\n"); | ||
| 919 | return -ENODEV; | ||
| 920 | } | ||
| 921 | |||
| 922 | phy->gpio_fw = desc_to_gpio(gpiod_fw); | ||
| 923 | |||
| 924 | /* Configuration FW GPIO */ | ||
| 925 | ret = gpiod_direction_output(gpiod_fw, 0); | ||
| 926 | if (ret) { | ||
| 927 | nfc_err(dev, "Fail FW pin direction\n"); | ||
| 928 | return ret; | ||
| 929 | } | ||
| 930 | |||
| 931 | /* Get IRQ GPIO */ | ||
| 932 | gpiod_irq = devm_gpiod_get_index(dev, PN544_GPIO_NAME_IRQ, 0); | ||
| 933 | if (IS_ERR(gpiod_irq)) { | ||
| 934 | nfc_err(dev, | ||
| 935 | "Unable to get IRQ GPIO\n"); | ||
| 936 | return -ENODEV; | ||
| 937 | } | ||
| 938 | |||
| 939 | phy->gpio_irq = desc_to_gpio(gpiod_irq); | ||
| 940 | |||
| 941 | /* Configure IRQ GPIO */ | ||
| 942 | ret = gpiod_direction_input(gpiod_irq); | ||
| 943 | if (ret) { | ||
| 944 | nfc_err(dev, "Fail IRQ pin direction\n"); | ||
| 945 | return ret; | ||
| 946 | } | ||
| 947 | |||
| 948 | /* Map the pin to an IRQ */ | ||
| 949 | ret = gpiod_to_irq(gpiod_irq); | ||
| 950 | if (ret < 0) { | ||
| 951 | nfc_err(dev, "Fail pin IRQ mapping\n"); | ||
| 952 | return ret; | ||
| 953 | } | ||
| 954 | |||
| 955 | nfc_info(dev, "GPIO resource, no:%d irq:%d\n", | ||
| 956 | desc_to_gpio(gpiod_irq), ret); | ||
| 957 | client->irq = ret; | ||
| 958 | |||
| 959 | return 0; | ||
| 960 | } | ||
| 961 | |||
| 862 | #ifdef CONFIG_OF | 962 | #ifdef CONFIG_OF |
| 863 | 963 | ||
| 864 | static int pn544_hci_i2c_of_request_resources(struct i2c_client *client) | 964 | static int pn544_hci_i2c_of_request_resources(struct i2c_client *client) |
| @@ -884,7 +984,7 @@ static int pn544_hci_i2c_of_request_resources(struct i2c_client *client) | |||
| 884 | phy->gpio_en = ret; | 984 | phy->gpio_en = ret; |
| 885 | 985 | ||
| 886 | /* Configuration of EN GPIO */ | 986 | /* Configuration of EN GPIO */ |
| 887 | ret = gpio_request(phy->gpio_en, "pn544_en"); | 987 | ret = gpio_request(phy->gpio_en, PN544_GPIO_NAME_EN); |
| 888 | if (ret) { | 988 | if (ret) { |
| 889 | nfc_err(&client->dev, "Fail EN pin\n"); | 989 | nfc_err(&client->dev, "Fail EN pin\n"); |
| 890 | goto err_dt; | 990 | goto err_dt; |
| @@ -906,7 +1006,7 @@ static int pn544_hci_i2c_of_request_resources(struct i2c_client *client) | |||
| 906 | phy->gpio_fw = ret; | 1006 | phy->gpio_fw = ret; |
| 907 | 1007 | ||
| 908 | /* Configuration of FW GPIO */ | 1008 | /* Configuration of FW GPIO */ |
| 909 | ret = gpio_request(phy->gpio_fw, "pn544_fw"); | 1009 | ret = gpio_request(phy->gpio_fw, PN544_GPIO_NAME_FW); |
| 910 | if (ret) { | 1010 | if (ret) { |
| 911 | nfc_err(&client->dev, "Fail FW pin\n"); | 1011 | nfc_err(&client->dev, "Fail FW pin\n"); |
| 912 | goto err_gpio_en; | 1012 | goto err_gpio_en; |
| @@ -1001,6 +1101,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, | |||
| 1001 | phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); | 1101 | phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); |
| 1002 | phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); | 1102 | phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); |
| 1003 | phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); | 1103 | phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); |
| 1104 | /* Using ACPI */ | ||
| 1105 | } else if (ACPI_HANDLE(&client->dev)) { | ||
| 1106 | r = pn544_hci_i2c_acpi_request_resources(client); | ||
| 1107 | if (r) { | ||
| 1108 | nfc_err(&client->dev, | ||
| 1109 | "Cannot get ACPI data\n"); | ||
| 1110 | return r; | ||
| 1111 | } | ||
| 1004 | } else { | 1112 | } else { |
| 1005 | nfc_err(&client->dev, "No platform data\n"); | 1113 | nfc_err(&client->dev, "No platform data\n"); |
| 1006 | return -EINVAL; | 1114 | return -EINVAL; |
| @@ -1080,6 +1188,7 @@ static struct i2c_driver pn544_hci_i2c_driver = { | |||
| 1080 | .name = PN544_HCI_I2C_DRIVER_NAME, | 1188 | .name = PN544_HCI_I2C_DRIVER_NAME, |
| 1081 | .owner = THIS_MODULE, | 1189 | .owner = THIS_MODULE, |
| 1082 | .of_match_table = of_match_ptr(of_pn544_i2c_match), | 1190 | .of_match_table = of_match_ptr(of_pn544_i2c_match), |
| 1191 | .acpi_match_table = ACPI_PTR(pn544_hci_i2c_acpi_match), | ||
| 1083 | }, | 1192 | }, |
| 1084 | .probe = pn544_hci_i2c_probe, | 1193 | .probe = pn544_hci_i2c_probe, |
| 1085 | .id_table = pn544_hci_i2c_id_table, | 1194 | .id_table = pn544_hci_i2c_id_table, |
diff --git a/drivers/nfc/pn544/pn544.c b/drivers/nfc/pn544/pn544.c index 9c8051d20cea..12e819ddf17a 100644 --- a/drivers/nfc/pn544/pn544.c +++ b/drivers/nfc/pn544/pn544.c | |||
| @@ -724,10 +724,11 @@ static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, | |||
| 724 | * <= 0: driver handled the event, skb consumed | 724 | * <= 0: driver handled the event, skb consumed |
| 725 | * 1: driver does not handle the event, please do standard processing | 725 | * 1: driver does not handle the event, please do standard processing |
| 726 | */ | 726 | */ |
| 727 | static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event, | 727 | static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, |
| 728 | struct sk_buff *skb) | 728 | struct sk_buff *skb) |
| 729 | { | 729 | { |
| 730 | struct sk_buff *rgb_skb = NULL; | 730 | struct sk_buff *rgb_skb = NULL; |
| 731 | u8 gate = hdev->pipes[pipe].gate; | ||
| 731 | int r; | 732 | int r; |
| 732 | 733 | ||
| 733 | pr_debug("hci event %d\n", event); | 734 | pr_debug("hci event %d\n", event); |
diff --git a/drivers/nfc/st21nfca/Makefile b/drivers/nfc/st21nfca/Makefile index 7d688f97aa27..97edab4bbdf8 100644 --- a/drivers/nfc/st21nfca/Makefile +++ b/drivers/nfc/st21nfca/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for ST21NFCA HCI based NFC driver | 2 | # Makefile for ST21NFCA HCI based NFC driver |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | st21nfca_hci-objs = st21nfca.o st21nfca_dep.o | 5 | st21nfca_hci-objs = st21nfca.o st21nfca_dep.o st21nfca_se.o |
| 6 | obj-$(CONFIG_NFC_ST21NFCA) += st21nfca_hci.o | 6 | obj-$(CONFIG_NFC_ST21NFCA) += st21nfca_hci.o |
| 7 | 7 | ||
| 8 | st21nfca_i2c-objs = i2c.o | 8 | st21nfca_i2c-objs = i2c.o |
diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 05722085a59f..a32143951616 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c | |||
| @@ -74,6 +74,8 @@ struct st21nfca_i2c_phy { | |||
| 74 | unsigned int gpio_ena; | 74 | unsigned int gpio_ena; |
| 75 | unsigned int irq_polarity; | 75 | unsigned int irq_polarity; |
| 76 | 76 | ||
| 77 | struct st21nfca_se_status se_status; | ||
| 78 | |||
| 77 | struct sk_buff *pending_skb; | 79 | struct sk_buff *pending_skb; |
| 78 | int current_read_len; | 80 | int current_read_len; |
| 79 | /* | 81 | /* |
| @@ -537,6 +539,11 @@ static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) | |||
| 537 | 539 | ||
| 538 | phy->irq_polarity = irq_get_trigger_type(client->irq); | 540 | phy->irq_polarity = irq_get_trigger_type(client->irq); |
| 539 | 541 | ||
| 542 | phy->se_status.is_ese_present = | ||
| 543 | of_property_read_bool(pp, "ese-present"); | ||
| 544 | phy->se_status.is_uicc_present = | ||
| 545 | of_property_read_bool(pp, "uicc-present"); | ||
| 546 | |||
| 540 | return 0; | 547 | return 0; |
| 541 | } | 548 | } |
| 542 | #else | 549 | #else |
| @@ -571,6 +578,9 @@ static int st21nfca_hci_i2c_request_resources(struct i2c_client *client) | |||
| 571 | } | 578 | } |
| 572 | } | 579 | } |
| 573 | 580 | ||
| 581 | phy->se_status.is_ese_present = pdata->is_ese_present; | ||
| 582 | phy->se_status.is_uicc_present = pdata->is_uicc_present; | ||
| 583 | |||
| 574 | return 0; | 584 | return 0; |
| 575 | } | 585 | } |
| 576 | 586 | ||
| @@ -591,11 +601,8 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, | |||
| 591 | 601 | ||
| 592 | phy = devm_kzalloc(&client->dev, sizeof(struct st21nfca_i2c_phy), | 602 | phy = devm_kzalloc(&client->dev, sizeof(struct st21nfca_i2c_phy), |
| 593 | GFP_KERNEL); | 603 | GFP_KERNEL); |
| 594 | if (!phy) { | 604 | if (!phy) |
| 595 | nfc_err(&client->dev, | ||
| 596 | "Cannot allocate memory for st21nfca i2c phy.\n"); | ||
| 597 | return -ENOMEM; | 605 | return -ENOMEM; |
| 598 | } | ||
| 599 | 606 | ||
| 600 | phy->i2c_dev = client; | 607 | phy->i2c_dev = client; |
| 601 | phy->pending_skb = alloc_skb(ST21NFCA_HCI_LLC_MAX_SIZE * 2, GFP_KERNEL); | 608 | phy->pending_skb = alloc_skb(ST21NFCA_HCI_LLC_MAX_SIZE * 2, GFP_KERNEL); |
| @@ -641,8 +648,11 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, | |||
| 641 | } | 648 | } |
| 642 | 649 | ||
| 643 | return st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, | 650 | return st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, |
| 644 | ST21NFCA_FRAME_HEADROOM, ST21NFCA_FRAME_TAILROOM, | 651 | ST21NFCA_FRAME_HEADROOM, |
| 645 | ST21NFCA_HCI_LLC_MAX_PAYLOAD, &phy->hdev); | 652 | ST21NFCA_FRAME_TAILROOM, |
| 653 | ST21NFCA_HCI_LLC_MAX_PAYLOAD, | ||
| 654 | &phy->hdev, | ||
| 655 | &phy->se_status); | ||
| 646 | } | 656 | } |
| 647 | 657 | ||
| 648 | static int st21nfca_hci_i2c_remove(struct i2c_client *client) | 658 | static int st21nfca_hci_i2c_remove(struct i2c_client *client) |
| @@ -661,6 +671,7 @@ static int st21nfca_hci_i2c_remove(struct i2c_client *client) | |||
| 661 | 671 | ||
| 662 | #ifdef CONFIG_OF | 672 | #ifdef CONFIG_OF |
| 663 | static const struct of_device_id of_st21nfca_i2c_match[] = { | 673 | static const struct of_device_id of_st21nfca_i2c_match[] = { |
| 674 | { .compatible = "st,st21nfca-i2c", }, | ||
| 664 | { .compatible = "st,st21nfca_i2c", }, | 675 | { .compatible = "st,st21nfca_i2c", }, |
| 665 | {} | 676 | {} |
| 666 | }; | 677 | }; |
diff --git a/drivers/nfc/st21nfca/st21nfca.c b/drivers/nfc/st21nfca/st21nfca.c index f2596c8d68b0..24d3d240d5f4 100644 --- a/drivers/nfc/st21nfca/st21nfca.c +++ b/drivers/nfc/st21nfca/st21nfca.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #include "st21nfca.h" | 24 | #include "st21nfca.h" |
| 25 | #include "st21nfca_dep.h" | 25 | #include "st21nfca_dep.h" |
| 26 | #include "st21nfca_se.h" | ||
| 26 | 27 | ||
| 27 | #define DRIVER_DESC "HCI NFC driver for ST21NFCA" | 28 | #define DRIVER_DESC "HCI NFC driver for ST21NFCA" |
| 28 | 29 | ||
| @@ -62,7 +63,6 @@ | |||
| 62 | #define ST21NFCA_RF_CARD_F_DATARATE 0x08 | 63 | #define ST21NFCA_RF_CARD_F_DATARATE 0x08 |
| 63 | #define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01 | 64 | #define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01 |
| 64 | 65 | ||
| 65 | #define ST21NFCA_DEVICE_MGNT_GATE 0x01 | ||
| 66 | #define ST21NFCA_DEVICE_MGNT_PIPE 0x02 | 66 | #define ST21NFCA_DEVICE_MGNT_PIPE 0x02 |
| 67 | 67 | ||
| 68 | #define ST21NFCA_DM_GETINFO 0x13 | 68 | #define ST21NFCA_DM_GETINFO 0x13 |
| @@ -78,6 +78,11 @@ | |||
| 78 | 78 | ||
| 79 | #define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/ | 79 | #define ST21NFCA_NFC_MODE 0x03 /* NFC_MODE parameter*/ |
| 80 | 80 | ||
| 81 | #define ST21NFCA_EVT_HOT_PLUG 0x03 | ||
| 82 | #define ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(x) (x->data[0] & 0x80) | ||
| 83 | |||
| 84 | #define ST21NFCA_SE_TO_PIPES 2000 | ||
| 85 | |||
| 81 | static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES); | 86 | static DECLARE_BITMAP(dev_mask, ST21NFCA_NUM_DEVICES); |
| 82 | 87 | ||
| 83 | static struct nfc_hci_gate st21nfca_gates[] = { | 88 | static struct nfc_hci_gate st21nfca_gates[] = { |
| @@ -92,6 +97,10 @@ static struct nfc_hci_gate st21nfca_gates[] = { | |||
| 92 | {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, | 97 | {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, |
| 93 | {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, | 98 | {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, |
| 94 | {ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE}, | 99 | {ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE}, |
| 100 | |||
| 101 | /* Secure element pipes are created by secure element host */ | ||
| 102 | {ST21NFCA_CONNECTIVITY_GATE, NFC_HCI_DO_NOT_CREATE_PIPE}, | ||
| 103 | {ST21NFCA_APDU_READER_GATE, NFC_HCI_DO_NOT_CREATE_PIPE}, | ||
| 95 | }; | 104 | }; |
| 96 | 105 | ||
| 97 | struct st21nfca_pipe_info { | 106 | struct st21nfca_pipe_info { |
| @@ -118,18 +127,6 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
| 118 | NFC_HCI_TERMINAL_HOST_ID, 0 | 127 | NFC_HCI_TERMINAL_HOST_ID, 0 |
| 119 | }; | 128 | }; |
| 120 | 129 | ||
| 121 | skb_pipe_list = alloc_skb(ST21NFCA_HCI_LLC_MAX_SIZE, GFP_KERNEL); | ||
| 122 | if (!skb_pipe_list) { | ||
| 123 | r = -ENOMEM; | ||
| 124 | goto free_list; | ||
| 125 | } | ||
| 126 | |||
| 127 | skb_pipe_info = alloc_skb(ST21NFCA_HCI_LLC_MAX_SIZE, GFP_KERNEL); | ||
| 128 | if (!skb_pipe_info) { | ||
| 129 | r = -ENOMEM; | ||
| 130 | goto free_info; | ||
| 131 | } | ||
| 132 | |||
| 133 | /* On ST21NFCA device pipes number are dynamics | 130 | /* On ST21NFCA device pipes number are dynamics |
| 134 | * A maximum of 16 pipes can be created at the same time | 131 | * A maximum of 16 pipes can be created at the same time |
| 135 | * If pipes are already created, hci_dev_up will fail. | 132 | * If pipes are already created, hci_dev_up will fail. |
| @@ -148,7 +145,8 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
| 148 | * Pipe can be closed and need to be open. | 145 | * Pipe can be closed and need to be open. |
| 149 | */ | 146 | */ |
| 150 | r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, | 147 | r = nfc_hci_connect_gate(hdev, NFC_HCI_HOST_CONTROLLER_ID, |
| 151 | ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DEVICE_MGNT_PIPE); | 148 | ST21NFCA_DEVICE_MGNT_GATE, |
| 149 | ST21NFCA_DEVICE_MGNT_PIPE); | ||
| 152 | if (r < 0) | 150 | if (r < 0) |
| 153 | goto free_info; | 151 | goto free_info; |
| 154 | 152 | ||
| @@ -179,17 +177,28 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
| 179 | * - destination gid (1byte) | 177 | * - destination gid (1byte) |
| 180 | */ | 178 | */ |
| 181 | info = (struct st21nfca_pipe_info *) skb_pipe_info->data; | 179 | info = (struct st21nfca_pipe_info *) skb_pipe_info->data; |
| 180 | if (info->dst_gate_id == ST21NFCA_APDU_READER_GATE && | ||
| 181 | info->src_host_id != ST21NFCA_ESE_HOST_ID) { | ||
| 182 | pr_err("Unexpected apdu_reader pipe on host %x\n", | ||
| 183 | info->src_host_id); | ||
| 184 | continue; | ||
| 185 | } | ||
| 186 | |||
| 182 | for (j = 0; (j < ARRAY_SIZE(st21nfca_gates)) && | 187 | for (j = 0; (j < ARRAY_SIZE(st21nfca_gates)) && |
| 183 | (st21nfca_gates[j].gate != info->dst_gate_id); | 188 | (st21nfca_gates[j].gate != info->dst_gate_id) ; j++) |
| 184 | j++) | ||
| 185 | ; | 189 | ; |
| 186 | 190 | ||
| 187 | if (j < ARRAY_SIZE(st21nfca_gates) && | 191 | if (j < ARRAY_SIZE(st21nfca_gates) && |
| 188 | st21nfca_gates[j].gate == info->dst_gate_id && | 192 | st21nfca_gates[j].gate == info->dst_gate_id && |
| 189 | ST21NFCA_DM_IS_PIPE_OPEN(info->pipe_state)) { | 193 | ST21NFCA_DM_IS_PIPE_OPEN(info->pipe_state)) { |
| 190 | st21nfca_gates[j].pipe = pipe_info[2]; | 194 | st21nfca_gates[j].pipe = pipe_info[2]; |
| 195 | |||
| 191 | hdev->gate2pipe[st21nfca_gates[j].gate] = | 196 | hdev->gate2pipe[st21nfca_gates[j].gate] = |
| 192 | st21nfca_gates[j].pipe; | 197 | st21nfca_gates[j].pipe; |
| 198 | hdev->pipes[st21nfca_gates[j].pipe].gate = | ||
| 199 | st21nfca_gates[j].gate; | ||
| 200 | hdev->pipes[st21nfca_gates[j].pipe].dest_host = | ||
| 201 | info->src_host_id; | ||
| 193 | } | 202 | } |
| 194 | } | 203 | } |
| 195 | 204 | ||
| @@ -199,7 +208,7 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
| 199 | */ | 208 | */ |
| 200 | if (skb_pipe_list->len + 3 < ARRAY_SIZE(st21nfca_gates)) { | 209 | if (skb_pipe_list->len + 3 < ARRAY_SIZE(st21nfca_gates)) { |
| 201 | for (i = skb_pipe_list->len + 3; | 210 | for (i = skb_pipe_list->len + 3; |
| 202 | i < ARRAY_SIZE(st21nfca_gates); i++) { | 211 | i < ARRAY_SIZE(st21nfca_gates) - 2; i++) { |
| 203 | r = nfc_hci_connect_gate(hdev, | 212 | r = nfc_hci_connect_gate(hdev, |
| 204 | NFC_HCI_HOST_CONTROLLER_ID, | 213 | NFC_HCI_HOST_CONTROLLER_ID, |
| 205 | st21nfca_gates[i].gate, | 214 | st21nfca_gates[i].gate, |
| @@ -212,7 +221,6 @@ static int st21nfca_hci_load_session(struct nfc_hci_dev *hdev) | |||
| 212 | memcpy(hdev->init_data.gates, st21nfca_gates, sizeof(st21nfca_gates)); | 221 | memcpy(hdev->init_data.gates, st21nfca_gates, sizeof(st21nfca_gates)); |
| 213 | free_info: | 222 | free_info: |
| 214 | kfree_skb(skb_pipe_info); | 223 | kfree_skb(skb_pipe_info); |
| 215 | free_list: | ||
| 216 | kfree_skb(skb_pipe_list); | 224 | kfree_skb(skb_pipe_list); |
| 217 | return r; | 225 | return r; |
| 218 | } | 226 | } |
| @@ -257,16 +265,33 @@ out: | |||
| 257 | 265 | ||
| 258 | static int st21nfca_hci_ready(struct nfc_hci_dev *hdev) | 266 | static int st21nfca_hci_ready(struct nfc_hci_dev *hdev) |
| 259 | { | 267 | { |
| 268 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 260 | struct sk_buff *skb; | 269 | struct sk_buff *skb; |
| 261 | 270 | ||
| 262 | u8 param; | 271 | u8 param; |
| 272 | u8 white_list[2]; | ||
| 273 | int wl_size = 0; | ||
| 263 | int r; | 274 | int r; |
| 264 | 275 | ||
| 265 | param = NFC_HCI_UICC_HOST_ID; | 276 | if (info->se_status->is_ese_present && |
| 266 | r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, | 277 | info->se_status->is_uicc_present) { |
| 267 | NFC_HCI_ADMIN_WHITELIST, ¶m, 1); | 278 | white_list[wl_size++] = NFC_HCI_UICC_HOST_ID; |
| 268 | if (r < 0) | 279 | white_list[wl_size++] = ST21NFCA_ESE_HOST_ID; |
| 269 | return r; | 280 | } else if (!info->se_status->is_ese_present && |
| 281 | info->se_status->is_uicc_present) { | ||
| 282 | white_list[wl_size++] = NFC_HCI_UICC_HOST_ID; | ||
| 283 | } else if (info->se_status->is_ese_present && | ||
| 284 | !info->se_status->is_uicc_present) { | ||
| 285 | white_list[wl_size++] = ST21NFCA_ESE_HOST_ID; | ||
| 286 | } | ||
| 287 | |||
| 288 | if (wl_size) { | ||
| 289 | r = nfc_hci_set_param(hdev, NFC_HCI_ADMIN_GATE, | ||
| 290 | NFC_HCI_ADMIN_WHITELIST, | ||
| 291 | (u8 *) &white_list, wl_size); | ||
| 292 | if (r < 0) | ||
| 293 | return r; | ||
| 294 | } | ||
| 270 | 295 | ||
| 271 | /* Set NFC_MODE in device management gate to enable */ | 296 | /* Set NFC_MODE in device management gate to enable */ |
| 272 | r = nfc_hci_get_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, | 297 | r = nfc_hci_get_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, |
| @@ -274,8 +299,9 @@ static int st21nfca_hci_ready(struct nfc_hci_dev *hdev) | |||
| 274 | if (r < 0) | 299 | if (r < 0) |
| 275 | return r; | 300 | return r; |
| 276 | 301 | ||
| 277 | if (skb->data[0] == 0) { | 302 | param = skb->data[0]; |
| 278 | kfree_skb(skb); | 303 | kfree_skb(skb); |
| 304 | if (param == 0) { | ||
| 279 | param = 1; | 305 | param = 1; |
| 280 | 306 | ||
| 281 | r = nfc_hci_set_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, | 307 | r = nfc_hci_set_param(hdev, ST21NFCA_DEVICE_MGNT_GATE, |
| @@ -417,9 +443,12 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev, | |||
| 417 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, | 443 | r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE, |
| 418 | ST21NFCA_RF_CARD_F_DATARATE, | 444 | ST21NFCA_RF_CARD_F_DATARATE, |
| 419 | param, 1); | 445 | param, 1); |
| 420 | if (r < 0) | 446 | if (r < 0) { |
| 447 | kfree_skb(datarate_skb); | ||
| 421 | return r; | 448 | return r; |
| 449 | } | ||
| 422 | } | 450 | } |
| 451 | kfree_skb(datarate_skb); | ||
| 423 | 452 | ||
| 424 | /* | 453 | /* |
| 425 | * Configure sens_res | 454 | * Configure sens_res |
| @@ -673,15 +702,15 @@ static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev, | |||
| 673 | struct nfc_target *target) | 702 | struct nfc_target *target) |
| 674 | { | 703 | { |
| 675 | int r; | 704 | int r; |
| 676 | struct sk_buff *nfcid2_skb = NULL, *nfcid1_skb; | 705 | struct sk_buff *nfcid_skb = NULL; |
| 677 | 706 | ||
| 678 | if (gate == ST21NFCA_RF_READER_F_GATE) { | 707 | if (gate == ST21NFCA_RF_READER_F_GATE) { |
| 679 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE, | 708 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE, |
| 680 | ST21NFCA_RF_READER_F_NFCID2, &nfcid2_skb); | 709 | ST21NFCA_RF_READER_F_NFCID2, &nfcid_skb); |
| 681 | if (r < 0) | 710 | if (r < 0) |
| 682 | goto exit; | 711 | goto exit; |
| 683 | 712 | ||
| 684 | if (nfcid2_skb->len > NFC_SENSF_RES_MAXSIZE) { | 713 | if (nfcid_skb->len > NFC_SENSF_RES_MAXSIZE) { |
| 685 | r = -EPROTO; | 714 | r = -EPROTO; |
| 686 | goto exit; | 715 | goto exit; |
| 687 | } | 716 | } |
| @@ -693,11 +722,11 @@ static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev, | |||
| 693 | * - After the reception of SEL_RES with NFCIP-1 compliant bit | 722 | * - After the reception of SEL_RES with NFCIP-1 compliant bit |
| 694 | * set for type A frame NFCID1 will be updated | 723 | * set for type A frame NFCID1 will be updated |
| 695 | */ | 724 | */ |
| 696 | if (nfcid2_skb->len > 0) { | 725 | if (nfcid_skb->len > 0) { |
| 697 | /* P2P in type F */ | 726 | /* P2P in type F */ |
| 698 | memcpy(target->sensf_res, nfcid2_skb->data, | 727 | memcpy(target->sensf_res, nfcid_skb->data, |
| 699 | nfcid2_skb->len); | 728 | nfcid_skb->len); |
| 700 | target->sensf_res_len = nfcid2_skb->len; | 729 | target->sensf_res_len = nfcid_skb->len; |
| 701 | /* NFC Forum Digital Protocol Table 44 */ | 730 | /* NFC Forum Digital Protocol Table 44 */ |
| 702 | if (target->sensf_res[0] == 0x01 && | 731 | if (target->sensf_res[0] == 0x01 && |
| 703 | target->sensf_res[1] == 0xfe) | 732 | target->sensf_res[1] == 0xfe) |
| @@ -707,27 +736,28 @@ static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev, | |||
| 707 | target->supported_protocols = | 736 | target->supported_protocols = |
| 708 | NFC_PROTO_FELICA_MASK; | 737 | NFC_PROTO_FELICA_MASK; |
| 709 | } else { | 738 | } else { |
| 739 | kfree_skb(nfcid_skb); | ||
| 710 | /* P2P in type A */ | 740 | /* P2P in type A */ |
| 711 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE, | 741 | r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE, |
| 712 | ST21NFCA_RF_READER_F_NFCID1, | 742 | ST21NFCA_RF_READER_F_NFCID1, |
| 713 | &nfcid1_skb); | 743 | &nfcid_skb); |
| 714 | if (r < 0) | 744 | if (r < 0) |
| 715 | goto exit; | 745 | goto exit; |
| 716 | 746 | ||
| 717 | if (nfcid1_skb->len > NFC_NFCID1_MAXSIZE) { | 747 | if (nfcid_skb->len > NFC_NFCID1_MAXSIZE) { |
| 718 | r = -EPROTO; | 748 | r = -EPROTO; |
| 719 | goto exit; | 749 | goto exit; |
| 720 | } | 750 | } |
| 721 | memcpy(target->sensf_res, nfcid1_skb->data, | 751 | memcpy(target->sensf_res, nfcid_skb->data, |
| 722 | nfcid1_skb->len); | 752 | nfcid_skb->len); |
| 723 | target->sensf_res_len = nfcid1_skb->len; | 753 | target->sensf_res_len = nfcid_skb->len; |
| 724 | target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; | 754 | target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; |
| 725 | } | 755 | } |
| 726 | target->hci_reader_gate = ST21NFCA_RF_READER_F_GATE; | 756 | target->hci_reader_gate = ST21NFCA_RF_READER_F_GATE; |
| 727 | } | 757 | } |
| 728 | r = 1; | 758 | r = 1; |
| 729 | exit: | 759 | exit: |
| 730 | kfree_skb(nfcid2_skb); | 760 | kfree_skb(nfcid_skb); |
| 731 | return r; | 761 | return r; |
| 732 | } | 762 | } |
| 733 | 763 | ||
| @@ -829,24 +859,82 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev, | |||
| 829 | } | 859 | } |
| 830 | } | 860 | } |
| 831 | 861 | ||
| 862 | static void st21nfca_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, | ||
| 863 | struct sk_buff *skb) | ||
| 864 | { | ||
| 865 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 866 | u8 gate = hdev->pipes[pipe].gate; | ||
| 867 | |||
| 868 | pr_debug("cmd: %x\n", cmd); | ||
| 869 | |||
| 870 | switch (cmd) { | ||
| 871 | case NFC_HCI_ANY_OPEN_PIPE: | ||
| 872 | if (gate != ST21NFCA_APDU_READER_GATE && | ||
| 873 | hdev->pipes[pipe].dest_host != NFC_HCI_UICC_HOST_ID) | ||
| 874 | info->se_info.count_pipes++; | ||
| 875 | |||
| 876 | if (info->se_info.count_pipes == info->se_info.expected_pipes) { | ||
| 877 | del_timer_sync(&info->se_info.se_active_timer); | ||
| 878 | info->se_info.se_active = false; | ||
| 879 | info->se_info.count_pipes = 0; | ||
| 880 | complete(&info->se_info.req_completion); | ||
| 881 | } | ||
| 882 | break; | ||
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | static int st21nfca_admin_event_received(struct nfc_hci_dev *hdev, u8 event, | ||
| 887 | struct sk_buff *skb) | ||
| 888 | { | ||
| 889 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 890 | |||
| 891 | pr_debug("admin event: %x\n", event); | ||
| 892 | |||
| 893 | switch (event) { | ||
| 894 | case ST21NFCA_EVT_HOT_PLUG: | ||
| 895 | if (info->se_info.se_active) { | ||
| 896 | if (!ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(skb)) { | ||
| 897 | del_timer_sync(&info->se_info.se_active_timer); | ||
| 898 | info->se_info.se_active = false; | ||
| 899 | complete(&info->se_info.req_completion); | ||
| 900 | } else { | ||
| 901 | mod_timer(&info->se_info.se_active_timer, | ||
| 902 | jiffies + | ||
| 903 | msecs_to_jiffies(ST21NFCA_SE_TO_PIPES)); | ||
| 904 | } | ||
| 905 | } | ||
| 906 | break; | ||
| 907 | } | ||
| 908 | kfree_skb(skb); | ||
| 909 | return 0; | ||
| 910 | } | ||
| 911 | |||
| 832 | /* | 912 | /* |
| 833 | * Returns: | 913 | * Returns: |
| 834 | * <= 0: driver handled the event, skb consumed | 914 | * <= 0: driver handled the event, skb consumed |
| 835 | * 1: driver does not handle the event, please do standard processing | 915 | * 1: driver does not handle the event, please do standard processing |
| 836 | */ | 916 | */ |
| 837 | static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, | 917 | static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, |
| 838 | u8 event, struct sk_buff *skb) | 918 | u8 event, struct sk_buff *skb) |
| 839 | { | 919 | { |
| 920 | u8 gate = hdev->pipes[pipe].gate; | ||
| 921 | u8 host = hdev->pipes[pipe].dest_host; | ||
| 922 | |||
| 840 | pr_debug("hci event: %d gate: %x\n", event, gate); | 923 | pr_debug("hci event: %d gate: %x\n", event, gate); |
| 841 | 924 | ||
| 842 | switch (gate) { | 925 | switch (gate) { |
| 926 | case NFC_HCI_ADMIN_GATE: | ||
| 927 | return st21nfca_admin_event_received(hdev, event, skb); | ||
| 843 | case ST21NFCA_RF_CARD_F_GATE: | 928 | case ST21NFCA_RF_CARD_F_GATE: |
| 844 | return st21nfca_dep_event_received(hdev, event, skb); | 929 | return st21nfca_dep_event_received(hdev, event, skb); |
| 930 | case ST21NFCA_CONNECTIVITY_GATE: | ||
| 931 | return st21nfca_connectivity_event_received(hdev, host, | ||
| 932 | event, skb); | ||
| 933 | case ST21NFCA_APDU_READER_GATE: | ||
| 934 | return st21nfca_apdu_reader_event_received(hdev, event, skb); | ||
| 845 | default: | 935 | default: |
| 846 | return 1; | 936 | return 1; |
| 847 | } | 937 | } |
| 848 | kfree_skb(skb); | ||
| 849 | return 0; | ||
| 850 | } | 938 | } |
| 851 | 939 | ||
| 852 | static struct nfc_hci_ops st21nfca_hci_ops = { | 940 | static struct nfc_hci_ops st21nfca_hci_ops = { |
| @@ -865,11 +953,17 @@ static struct nfc_hci_ops st21nfca_hci_ops = { | |||
| 865 | .tm_send = st21nfca_hci_tm_send, | 953 | .tm_send = st21nfca_hci_tm_send, |
| 866 | .check_presence = st21nfca_hci_check_presence, | 954 | .check_presence = st21nfca_hci_check_presence, |
| 867 | .event_received = st21nfca_hci_event_received, | 955 | .event_received = st21nfca_hci_event_received, |
| 956 | .cmd_received = st21nfca_hci_cmd_received, | ||
| 957 | .discover_se = st21nfca_hci_discover_se, | ||
| 958 | .enable_se = st21nfca_hci_enable_se, | ||
| 959 | .disable_se = st21nfca_hci_disable_se, | ||
| 960 | .se_io = st21nfca_hci_se_io, | ||
| 868 | }; | 961 | }; |
| 869 | 962 | ||
| 870 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | 963 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, |
| 871 | char *llc_name, int phy_headroom, int phy_tailroom, | 964 | char *llc_name, int phy_headroom, int phy_tailroom, |
| 872 | int phy_payload, struct nfc_hci_dev **hdev) | 965 | int phy_payload, struct nfc_hci_dev **hdev, |
| 966 | struct st21nfca_se_status *se_status) | ||
| 873 | { | 967 | { |
| 874 | struct st21nfca_hci_info *info; | 968 | struct st21nfca_hci_info *info; |
| 875 | int r = 0; | 969 | int r = 0; |
| @@ -929,6 +1023,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | |||
| 929 | goto err_alloc_hdev; | 1023 | goto err_alloc_hdev; |
| 930 | } | 1024 | } |
| 931 | 1025 | ||
| 1026 | info->se_status = se_status; | ||
| 1027 | |||
| 932 | nfc_hci_set_clientdata(info->hdev, info); | 1028 | nfc_hci_set_clientdata(info->hdev, info); |
| 933 | 1029 | ||
| 934 | r = nfc_hci_register_device(info->hdev); | 1030 | r = nfc_hci_register_device(info->hdev); |
| @@ -937,6 +1033,7 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | |||
| 937 | 1033 | ||
| 938 | *hdev = info->hdev; | 1034 | *hdev = info->hdev; |
| 939 | st21nfca_dep_init(info->hdev); | 1035 | st21nfca_dep_init(info->hdev); |
| 1036 | st21nfca_se_init(info->hdev); | ||
| 940 | 1037 | ||
| 941 | return 0; | 1038 | return 0; |
| 942 | 1039 | ||
| @@ -955,6 +1052,7 @@ void st21nfca_hci_remove(struct nfc_hci_dev *hdev) | |||
| 955 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | 1052 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); |
| 956 | 1053 | ||
| 957 | st21nfca_dep_deinit(hdev); | 1054 | st21nfca_dep_deinit(hdev); |
| 1055 | st21nfca_se_deinit(hdev); | ||
| 958 | nfc_hci_unregister_device(hdev); | 1056 | nfc_hci_unregister_device(hdev); |
| 959 | nfc_hci_free_device(hdev); | 1057 | nfc_hci_free_device(hdev); |
| 960 | kfree(info); | 1058 | kfree(info); |
diff --git a/drivers/nfc/st21nfca/st21nfca.h b/drivers/nfc/st21nfca/st21nfca.h index 7c2a85292230..15a78d330a9f 100644 --- a/drivers/nfc/st21nfca/st21nfca.h +++ b/drivers/nfc/st21nfca/st21nfca.h | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <net/nfc/hci.h> | 20 | #include <net/nfc/hci.h> |
| 21 | 21 | ||
| 22 | #include "st21nfca_dep.h" | 22 | #include "st21nfca_dep.h" |
| 23 | #include "st21nfca_se.h" | ||
| 23 | 24 | ||
| 24 | #define HCI_MODE 0 | 25 | #define HCI_MODE 0 |
| 25 | 26 | ||
| @@ -51,9 +52,15 @@ | |||
| 51 | 52 | ||
| 52 | #define ST21NFCA_NUM_DEVICES 256 | 53 | #define ST21NFCA_NUM_DEVICES 256 |
| 53 | 54 | ||
| 55 | struct st21nfca_se_status { | ||
| 56 | bool is_ese_present; | ||
| 57 | bool is_uicc_present; | ||
| 58 | }; | ||
| 59 | |||
| 54 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, | 60 | int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, |
| 55 | char *llc_name, int phy_headroom, int phy_tailroom, | 61 | char *llc_name, int phy_headroom, int phy_tailroom, |
| 56 | int phy_payload, struct nfc_hci_dev **hdev); | 62 | int phy_payload, struct nfc_hci_dev **hdev, |
| 63 | struct st21nfca_se_status *se_status); | ||
| 57 | void st21nfca_hci_remove(struct nfc_hci_dev *hdev); | 64 | void st21nfca_hci_remove(struct nfc_hci_dev *hdev); |
| 58 | 65 | ||
| 59 | enum st21nfca_state { | 66 | enum st21nfca_state { |
| @@ -66,6 +73,7 @@ struct st21nfca_hci_info { | |||
| 66 | void *phy_id; | 73 | void *phy_id; |
| 67 | 74 | ||
| 68 | struct nfc_hci_dev *hdev; | 75 | struct nfc_hci_dev *hdev; |
| 76 | struct st21nfca_se_status *se_status; | ||
| 69 | 77 | ||
| 70 | enum st21nfca_state state; | 78 | enum st21nfca_state state; |
| 71 | 79 | ||
| @@ -76,13 +84,16 @@ struct st21nfca_hci_info { | |||
| 76 | void *async_cb_context; | 84 | void *async_cb_context; |
| 77 | 85 | ||
| 78 | struct st21nfca_dep_info dep_info; | 86 | struct st21nfca_dep_info dep_info; |
| 87 | struct st21nfca_se_info se_info; | ||
| 79 | }; | 88 | }; |
| 80 | 89 | ||
| 81 | /* Reader RF commands */ | 90 | /* Reader RF commands */ |
| 82 | #define ST21NFCA_WR_XCHG_DATA 0x10 | 91 | #define ST21NFCA_WR_XCHG_DATA 0x10 |
| 83 | |||
| 84 | #define ST21NFCA_RF_READER_F_GATE 0x14 | ||
| 85 | 92 | ||
| 86 | #define ST21NFCA_RF_CARD_F_GATE 0x24 | 93 | #define ST21NFCA_DEVICE_MGNT_GATE 0x01 |
| 94 | #define ST21NFCA_RF_READER_F_GATE 0x14 | ||
| 95 | #define ST21NFCA_RF_CARD_F_GATE 0x24 | ||
| 96 | #define ST21NFCA_APDU_READER_GATE 0xf0 | ||
| 97 | #define ST21NFCA_CONNECTIVITY_GATE 0x41 | ||
| 87 | 98 | ||
| 88 | #endif /* __LOCAL_ST21NFCA_H_ */ | 99 | #endif /* __LOCAL_ST21NFCA_H_ */ |
diff --git a/drivers/nfc/st21nfca/st21nfca_se.c b/drivers/nfc/st21nfca/st21nfca_se.c new file mode 100644 index 000000000000..9b93d3904ab5 --- /dev/null +++ b/drivers/nfc/st21nfca/st21nfca_se.c | |||
| @@ -0,0 +1,390 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <net/nfc/hci.h> | ||
| 18 | |||
| 19 | #include "st21nfca.h" | ||
| 20 | #include "st21nfca_se.h" | ||
| 21 | |||
| 22 | #define ST21NFCA_EVT_UICC_ACTIVATE 0x10 | ||
| 23 | #define ST21NFCA_EVT_UICC_DEACTIVATE 0x13 | ||
| 24 | #define ST21NFCA_EVT_SE_HARD_RESET 0x20 | ||
| 25 | #define ST21NFCA_EVT_SE_SOFT_RESET 0x11 | ||
| 26 | #define ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER 0x21 | ||
| 27 | #define ST21NFCA_EVT_SE_ACTIVATE 0x22 | ||
| 28 | #define ST21NFCA_EVT_SE_DEACTIVATE 0x23 | ||
| 29 | |||
| 30 | #define ST21NFCA_EVT_TRANSMIT_DATA 0x10 | ||
| 31 | #define ST21NFCA_EVT_WTX_REQUEST 0x11 | ||
| 32 | |||
| 33 | #define ST21NFCA_EVT_CONNECTIVITY 0x10 | ||
| 34 | #define ST21NFCA_EVT_TRANSACTION 0x12 | ||
| 35 | |||
| 36 | #define ST21NFCA_ESE_HOST_ID 0xc0 | ||
| 37 | |||
| 38 | #define ST21NFCA_SE_TO_HOT_PLUG 1000 | ||
| 39 | /* Connectivity pipe only */ | ||
| 40 | #define ST21NFCA_SE_COUNT_PIPE_UICC 0x01 | ||
| 41 | /* Connectivity + APDU Reader pipe */ | ||
| 42 | #define ST21NFCA_SE_COUNT_PIPE_EMBEDDED 0x02 | ||
| 43 | |||
| 44 | #define ST21NFCA_SE_MODE_OFF 0x00 | ||
| 45 | #define ST21NFCA_SE_MODE_ON 0x01 | ||
| 46 | |||
| 47 | #define ST21NFCA_PARAM_ATR 0x01 | ||
| 48 | #define ST21NFCA_ATR_DEFAULT_BWI 0x04 | ||
| 49 | |||
| 50 | /* | ||
| 51 | * WT = 2^BWI/10[s], convert into msecs and add a secure | ||
| 52 | * room by increasing by 2 this timeout | ||
| 53 | */ | ||
| 54 | #define ST21NFCA_BWI_TO_TIMEOUT(x) ((1 << x) * 200) | ||
| 55 | #define ST21NFCA_ATR_GET_Y_FROM_TD(x) (x >> 4) | ||
| 56 | |||
| 57 | /* If TA is present bit 0 is set */ | ||
| 58 | #define ST21NFCA_ATR_TA_PRESENT(x) (x & 0x01) | ||
| 59 | /* If TB is present bit 1 is set */ | ||
| 60 | #define ST21NFCA_ATR_TB_PRESENT(x) (x & 0x02) | ||
| 61 | |||
| 62 | static u8 st21nfca_se_get_bwi(struct nfc_hci_dev *hdev) | ||
| 63 | { | ||
| 64 | int i; | ||
| 65 | u8 td; | ||
| 66 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 67 | |||
| 68 | /* Bits 8 to 5 of the first TB for T=1 encode BWI from zero to nine */ | ||
| 69 | for (i = 1; i < ST21NFCA_ESE_MAX_LENGTH; i++) { | ||
| 70 | td = ST21NFCA_ATR_GET_Y_FROM_TD(info->se_info.atr[i]); | ||
| 71 | if (ST21NFCA_ATR_TA_PRESENT(td)) | ||
| 72 | i++; | ||
| 73 | if (ST21NFCA_ATR_TB_PRESENT(td)) { | ||
| 74 | i++; | ||
| 75 | return info->se_info.atr[i] >> 4; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | return ST21NFCA_ATR_DEFAULT_BWI; | ||
| 79 | } | ||
| 80 | |||
| 81 | static void st21nfca_se_get_atr(struct nfc_hci_dev *hdev) | ||
| 82 | { | ||
| 83 | int r; | ||
| 84 | struct sk_buff *skb; | ||
| 85 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 86 | |||
| 87 | r = nfc_hci_get_param(hdev, ST21NFCA_APDU_READER_GATE, | ||
| 88 | ST21NFCA_PARAM_ATR, &skb); | ||
| 89 | if (r < 0) | ||
| 90 | return; | ||
| 91 | |||
| 92 | if (skb->len <= ST21NFCA_ESE_MAX_LENGTH) { | ||
| 93 | memcpy(info->se_info.atr, skb->data, skb->len); | ||
| 94 | info->se_info.wt_timeout = | ||
| 95 | ST21NFCA_BWI_TO_TIMEOUT(st21nfca_se_get_bwi(hdev)); | ||
| 96 | } | ||
| 97 | kfree_skb(skb); | ||
| 98 | } | ||
| 99 | |||
| 100 | static int st21nfca_hci_control_se(struct nfc_hci_dev *hdev, u32 se_idx, | ||
| 101 | u8 state) | ||
| 102 | { | ||
| 103 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 104 | int r; | ||
| 105 | struct sk_buff *sk_host_list; | ||
| 106 | u8 se_event, host_id; | ||
| 107 | |||
| 108 | switch (se_idx) { | ||
| 109 | case NFC_HCI_UICC_HOST_ID: | ||
| 110 | se_event = (state == ST21NFCA_SE_MODE_ON ? | ||
| 111 | ST21NFCA_EVT_UICC_ACTIVATE : | ||
| 112 | ST21NFCA_EVT_UICC_DEACTIVATE); | ||
| 113 | |||
| 114 | info->se_info.count_pipes = 0; | ||
| 115 | info->se_info.expected_pipes = ST21NFCA_SE_COUNT_PIPE_UICC; | ||
| 116 | break; | ||
| 117 | case ST21NFCA_ESE_HOST_ID: | ||
| 118 | se_event = (state == ST21NFCA_SE_MODE_ON ? | ||
| 119 | ST21NFCA_EVT_SE_ACTIVATE : | ||
| 120 | ST21NFCA_EVT_SE_DEACTIVATE); | ||
| 121 | |||
| 122 | info->se_info.count_pipes = 0; | ||
| 123 | info->se_info.expected_pipes = ST21NFCA_SE_COUNT_PIPE_EMBEDDED; | ||
| 124 | break; | ||
| 125 | default: | ||
| 126 | return -EINVAL; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* | ||
| 130 | * Wait for an EVT_HOT_PLUG in order to | ||
| 131 | * retrieve a relevant host list. | ||
| 132 | */ | ||
| 133 | reinit_completion(&info->se_info.req_completion); | ||
| 134 | r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, se_event, | ||
| 135 | NULL, 0); | ||
| 136 | if (r < 0) | ||
| 137 | return r; | ||
| 138 | |||
| 139 | mod_timer(&info->se_info.se_active_timer, jiffies + | ||
| 140 | msecs_to_jiffies(ST21NFCA_SE_TO_HOT_PLUG)); | ||
| 141 | info->se_info.se_active = true; | ||
| 142 | |||
| 143 | /* Ignore return value and check in any case the host_list */ | ||
| 144 | wait_for_completion_interruptible(&info->se_info.req_completion); | ||
| 145 | |||
| 146 | r = nfc_hci_get_param(hdev, NFC_HCI_ADMIN_GATE, | ||
| 147 | NFC_HCI_ADMIN_HOST_LIST, | ||
| 148 | &sk_host_list); | ||
| 149 | if (r < 0) | ||
| 150 | return r; | ||
| 151 | |||
| 152 | host_id = sk_host_list->data[sk_host_list->len - 1]; | ||
| 153 | kfree_skb(sk_host_list); | ||
| 154 | |||
| 155 | if (state == ST21NFCA_SE_MODE_ON && host_id == se_idx) | ||
| 156 | return se_idx; | ||
| 157 | else if (state == ST21NFCA_SE_MODE_OFF && host_id != se_idx) | ||
| 158 | return se_idx; | ||
| 159 | |||
| 160 | return -1; | ||
| 161 | } | ||
| 162 | |||
| 163 | int st21nfca_hci_discover_se(struct nfc_hci_dev *hdev) | ||
| 164 | { | ||
| 165 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 166 | int se_count = 0; | ||
| 167 | |||
| 168 | if (info->se_status->is_uicc_present) { | ||
| 169 | nfc_add_se(hdev->ndev, NFC_HCI_UICC_HOST_ID, NFC_SE_UICC); | ||
| 170 | se_count++; | ||
| 171 | } | ||
| 172 | |||
| 173 | if (info->se_status->is_ese_present) { | ||
| 174 | nfc_add_se(hdev->ndev, ST21NFCA_ESE_HOST_ID, NFC_SE_EMBEDDED); | ||
| 175 | se_count++; | ||
| 176 | } | ||
| 177 | |||
| 178 | return !se_count; | ||
| 179 | } | ||
| 180 | EXPORT_SYMBOL(st21nfca_hci_discover_se); | ||
| 181 | |||
| 182 | int st21nfca_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx) | ||
| 183 | { | ||
| 184 | int r; | ||
| 185 | |||
| 186 | /* | ||
| 187 | * According to upper layer, se_idx == NFC_SE_UICC when | ||
| 188 | * info->se_status->is_uicc_enable is true should never happen. | ||
| 189 | * Same for eSE. | ||
| 190 | */ | ||
| 191 | r = st21nfca_hci_control_se(hdev, se_idx, ST21NFCA_SE_MODE_ON); | ||
| 192 | |||
| 193 | if (r == ST21NFCA_ESE_HOST_ID) { | ||
| 194 | st21nfca_se_get_atr(hdev); | ||
| 195 | r = nfc_hci_send_event(hdev, ST21NFCA_APDU_READER_GATE, | ||
| 196 | ST21NFCA_EVT_SE_SOFT_RESET, NULL, 0); | ||
| 197 | if (r < 0) | ||
| 198 | return r; | ||
| 199 | } else if (r < 0) { | ||
| 200 | /* | ||
| 201 | * The activation tentative failed, the secure element | ||
| 202 | * is not connected. Remove from the list. | ||
| 203 | */ | ||
| 204 | nfc_remove_se(hdev->ndev, se_idx); | ||
| 205 | return r; | ||
| 206 | } | ||
| 207 | |||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | EXPORT_SYMBOL(st21nfca_hci_enable_se); | ||
| 211 | |||
| 212 | int st21nfca_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx) | ||
| 213 | { | ||
| 214 | int r; | ||
| 215 | |||
| 216 | /* | ||
| 217 | * According to upper layer, se_idx == NFC_SE_UICC when | ||
| 218 | * info->se_status->is_uicc_enable is true should never happen | ||
| 219 | * Same for eSE. | ||
| 220 | */ | ||
| 221 | r = st21nfca_hci_control_se(hdev, se_idx, ST21NFCA_SE_MODE_OFF); | ||
| 222 | if (r < 0) | ||
| 223 | return r; | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | EXPORT_SYMBOL(st21nfca_hci_disable_se); | ||
| 228 | |||
| 229 | int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, | ||
| 230 | u8 *apdu, size_t apdu_length, | ||
| 231 | se_io_cb_t cb, void *cb_context) | ||
| 232 | { | ||
| 233 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 234 | |||
| 235 | pr_debug("se_io %x\n", se_idx); | ||
| 236 | |||
| 237 | switch (se_idx) { | ||
| 238 | case ST21NFCA_ESE_HOST_ID: | ||
| 239 | info->se_info.cb = cb; | ||
| 240 | info->se_info.cb_context = cb_context; | ||
| 241 | mod_timer(&info->se_info.bwi_timer, jiffies + | ||
| 242 | msecs_to_jiffies(info->se_info.wt_timeout)); | ||
| 243 | info->se_info.bwi_active = true; | ||
| 244 | return nfc_hci_send_event(hdev, ST21NFCA_APDU_READER_GATE, | ||
| 245 | ST21NFCA_EVT_TRANSMIT_DATA, | ||
| 246 | apdu, apdu_length); | ||
| 247 | default: | ||
| 248 | return -ENODEV; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | EXPORT_SYMBOL(st21nfca_hci_se_io); | ||
| 252 | |||
| 253 | static void st21nfca_se_wt_timeout(unsigned long data) | ||
| 254 | { | ||
| 255 | /* | ||
| 256 | * No answer from the secure element | ||
| 257 | * within the defined timeout. | ||
| 258 | * Let's send a reset request as recovery procedure. | ||
| 259 | * According to the situation, we first try to send a software reset | ||
| 260 | * to the secure element. If the next command is still not | ||
| 261 | * answering in time, we send to the CLF a secure element hardware | ||
| 262 | * reset request. | ||
| 263 | */ | ||
| 264 | /* hardware reset managed through VCC_UICC_OUT power supply */ | ||
| 265 | u8 param = 0x01; | ||
| 266 | struct st21nfca_hci_info *info = (struct st21nfca_hci_info *) data; | ||
| 267 | |||
| 268 | pr_debug("\n"); | ||
| 269 | |||
| 270 | info->se_info.bwi_active = false; | ||
| 271 | |||
| 272 | if (!info->se_info.xch_error) { | ||
| 273 | info->se_info.xch_error = true; | ||
| 274 | nfc_hci_send_event(info->hdev, ST21NFCA_APDU_READER_GATE, | ||
| 275 | ST21NFCA_EVT_SE_SOFT_RESET, NULL, 0); | ||
| 276 | } else { | ||
| 277 | info->se_info.xch_error = false; | ||
| 278 | nfc_hci_send_event(info->hdev, ST21NFCA_DEVICE_MGNT_GATE, | ||
| 279 | ST21NFCA_EVT_SE_HARD_RESET, ¶m, 1); | ||
| 280 | } | ||
| 281 | info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME); | ||
| 282 | } | ||
| 283 | |||
| 284 | static void st21nfca_se_activation_timeout(unsigned long data) | ||
| 285 | { | ||
| 286 | struct st21nfca_hci_info *info = (struct st21nfca_hci_info *) data; | ||
| 287 | |||
| 288 | pr_debug("\n"); | ||
| 289 | |||
| 290 | info->se_info.se_active = false; | ||
| 291 | |||
| 292 | complete(&info->se_info.req_completion); | ||
| 293 | } | ||
| 294 | |||
| 295 | /* | ||
| 296 | * Returns: | ||
| 297 | * <= 0: driver handled the event, skb consumed | ||
| 298 | * 1: driver does not handle the event, please do standard processing | ||
| 299 | */ | ||
| 300 | int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, | ||
| 301 | u8 event, struct sk_buff *skb) | ||
| 302 | { | ||
| 303 | int r = 0; | ||
| 304 | |||
| 305 | pr_debug("connectivity gate event: %x\n", event); | ||
| 306 | |||
| 307 | switch (event) { | ||
| 308 | case ST21NFCA_EVT_CONNECTIVITY: | ||
| 309 | break; | ||
| 310 | case ST21NFCA_EVT_TRANSACTION: | ||
| 311 | break; | ||
| 312 | default: | ||
| 313 | return 1; | ||
| 314 | } | ||
| 315 | kfree_skb(skb); | ||
| 316 | return r; | ||
| 317 | } | ||
| 318 | EXPORT_SYMBOL(st21nfca_connectivity_event_received); | ||
| 319 | |||
| 320 | int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, | ||
| 321 | u8 event, struct sk_buff *skb) | ||
| 322 | { | ||
| 323 | int r = 0; | ||
| 324 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 325 | |||
| 326 | pr_debug("apdu reader gate event: %x\n", event); | ||
| 327 | |||
| 328 | switch (event) { | ||
| 329 | case ST21NFCA_EVT_TRANSMIT_DATA: | ||
| 330 | del_timer_sync(&info->se_info.bwi_timer); | ||
| 331 | info->se_info.bwi_active = false; | ||
| 332 | r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, | ||
| 333 | ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); | ||
| 334 | if (r < 0) | ||
| 335 | goto exit; | ||
| 336 | |||
| 337 | info->se_info.cb(info->se_info.cb_context, | ||
| 338 | skb->data, skb->len, 0); | ||
| 339 | break; | ||
| 340 | case ST21NFCA_EVT_WTX_REQUEST: | ||
| 341 | mod_timer(&info->se_info.bwi_timer, jiffies + | ||
| 342 | msecs_to_jiffies(info->se_info.wt_timeout)); | ||
| 343 | break; | ||
| 344 | } | ||
| 345 | |||
| 346 | exit: | ||
| 347 | kfree_skb(skb); | ||
| 348 | return r; | ||
| 349 | } | ||
| 350 | EXPORT_SYMBOL(st21nfca_apdu_reader_event_received); | ||
| 351 | |||
| 352 | void st21nfca_se_init(struct nfc_hci_dev *hdev) | ||
| 353 | { | ||
| 354 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 355 | |||
| 356 | init_completion(&info->se_info.req_completion); | ||
| 357 | /* initialize timers */ | ||
| 358 | init_timer(&info->se_info.bwi_timer); | ||
| 359 | info->se_info.bwi_timer.data = (unsigned long)info; | ||
| 360 | info->se_info.bwi_timer.function = st21nfca_se_wt_timeout; | ||
| 361 | info->se_info.bwi_active = false; | ||
| 362 | |||
| 363 | init_timer(&info->se_info.se_active_timer); | ||
| 364 | info->se_info.se_active_timer.data = (unsigned long)info; | ||
| 365 | info->se_info.se_active_timer.function = st21nfca_se_activation_timeout; | ||
| 366 | info->se_info.se_active = false; | ||
| 367 | |||
| 368 | info->se_info.count_pipes = 0; | ||
| 369 | info->se_info.expected_pipes = 0; | ||
| 370 | |||
| 371 | info->se_info.xch_error = false; | ||
| 372 | |||
| 373 | info->se_info.wt_timeout = | ||
| 374 | ST21NFCA_BWI_TO_TIMEOUT(ST21NFCA_ATR_DEFAULT_BWI); | ||
| 375 | } | ||
| 376 | EXPORT_SYMBOL(st21nfca_se_init); | ||
| 377 | |||
| 378 | void st21nfca_se_deinit(struct nfc_hci_dev *hdev) | ||
| 379 | { | ||
| 380 | struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); | ||
| 381 | |||
| 382 | if (info->se_info.bwi_active) | ||
| 383 | del_timer_sync(&info->se_info.bwi_timer); | ||
| 384 | if (info->se_info.se_active) | ||
| 385 | del_timer_sync(&info->se_info.se_active_timer); | ||
| 386 | |||
| 387 | info->se_info.bwi_active = false; | ||
| 388 | info->se_info.se_active = false; | ||
| 389 | } | ||
| 390 | EXPORT_SYMBOL(st21nfca_se_deinit); | ||
diff --git a/drivers/nfc/st21nfca/st21nfca_se.h b/drivers/nfc/st21nfca/st21nfca_se.h new file mode 100644 index 000000000000..b172cfcaeb90 --- /dev/null +++ b/drivers/nfc/st21nfca/st21nfca_se.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __ST21NFCA_SE_H | ||
| 18 | #define __ST21NFCA_SE_H | ||
| 19 | |||
| 20 | #include <linux/skbuff.h> | ||
| 21 | #include <linux/workqueue.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * ref ISO7816-3 chap 8.1. the initial character TS is followed by a | ||
| 25 | * sequence of at most 32 characters. | ||
| 26 | */ | ||
| 27 | #define ST21NFCA_ESE_MAX_LENGTH 33 | ||
| 28 | #define ST21NFCA_ESE_HOST_ID 0xc0 | ||
| 29 | |||
| 30 | struct st21nfca_se_info { | ||
| 31 | u8 atr[ST21NFCA_ESE_MAX_LENGTH]; | ||
| 32 | struct completion req_completion; | ||
| 33 | |||
| 34 | struct timer_list bwi_timer; | ||
| 35 | int wt_timeout; /* in msecs */ | ||
| 36 | bool bwi_active; | ||
| 37 | |||
| 38 | struct timer_list se_active_timer; | ||
| 39 | bool se_active; | ||
| 40 | int expected_pipes; | ||
| 41 | int count_pipes; | ||
| 42 | |||
| 43 | bool xch_error; | ||
| 44 | |||
| 45 | se_io_cb_t cb; | ||
| 46 | void *cb_context; | ||
| 47 | }; | ||
| 48 | |||
| 49 | int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, | ||
| 50 | u8 event, struct sk_buff *skb); | ||
| 51 | int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, | ||
| 52 | u8 event, struct sk_buff *skb); | ||
| 53 | |||
| 54 | int st21nfca_hci_discover_se(struct nfc_hci_dev *hdev); | ||
| 55 | int st21nfca_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx); | ||
| 56 | int st21nfca_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx); | ||
| 57 | int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, | ||
| 58 | u8 *apdu, size_t apdu_length, | ||
| 59 | se_io_cb_t cb, void *cb_context); | ||
| 60 | |||
| 61 | void st21nfca_se_init(struct nfc_hci_dev *hdev); | ||
| 62 | void st21nfca_se_deinit(struct nfc_hci_dev *hdev); | ||
| 63 | #endif /* __ST21NFCA_SE_H */ | ||
diff --git a/drivers/nfc/st21nfcb/i2c.c b/drivers/nfc/st21nfcb/i2c.c index 01ba865863ee..eb886932d972 100644 --- a/drivers/nfc/st21nfcb/i2c.c +++ b/drivers/nfc/st21nfcb/i2c.c | |||
| @@ -199,7 +199,7 @@ static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id) | |||
| 199 | struct sk_buff *skb = NULL; | 199 | struct sk_buff *skb = NULL; |
| 200 | int r; | 200 | int r; |
| 201 | 201 | ||
| 202 | if (!phy || irq != phy->i2c_dev->irq) { | 202 | if (!phy || !phy->ndlc || irq != phy->i2c_dev->irq) { |
| 203 | WARN_ON_ONCE(1); | 203 | WARN_ON_ONCE(1); |
| 204 | return IRQ_NONE; | 204 | return IRQ_NONE; |
| 205 | } | 205 | } |
| @@ -343,18 +343,22 @@ static int st21nfcb_nci_i2c_probe(struct i2c_client *client, | |||
| 343 | return -ENODEV; | 343 | return -ENODEV; |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | r = ndlc_probe(phy, &i2c_phy_ops, &client->dev, | ||
| 347 | ST21NFCB_FRAME_HEADROOM, ST21NFCB_FRAME_TAILROOM, | ||
| 348 | &phy->ndlc); | ||
| 349 | if (r < 0) { | ||
| 350 | nfc_err(&client->dev, "Unable to register ndlc layer\n"); | ||
| 351 | return r; | ||
| 352 | } | ||
| 353 | |||
| 346 | r = devm_request_threaded_irq(&client->dev, client->irq, NULL, | 354 | r = devm_request_threaded_irq(&client->dev, client->irq, NULL, |
| 347 | st21nfcb_nci_irq_thread_fn, | 355 | st21nfcb_nci_irq_thread_fn, |
| 348 | phy->irq_polarity | IRQF_ONESHOT, | 356 | phy->irq_polarity | IRQF_ONESHOT, |
| 349 | ST21NFCB_NCI_DRIVER_NAME, phy); | 357 | ST21NFCB_NCI_DRIVER_NAME, phy); |
| 350 | if (r < 0) { | 358 | if (r < 0) |
| 351 | nfc_err(&client->dev, "Unable to register IRQ handler\n"); | 359 | nfc_err(&client->dev, "Unable to register IRQ handler\n"); |
| 352 | return r; | ||
| 353 | } | ||
| 354 | 360 | ||
| 355 | return ndlc_probe(phy, &i2c_phy_ops, &client->dev, | 361 | return r; |
| 356 | ST21NFCB_FRAME_HEADROOM, ST21NFCB_FRAME_TAILROOM, | ||
| 357 | &phy->ndlc); | ||
| 358 | } | 362 | } |
| 359 | 363 | ||
| 360 | static int st21nfcb_nci_i2c_remove(struct i2c_client *client) | 364 | static int st21nfcb_nci_i2c_remove(struct i2c_client *client) |
| @@ -373,6 +377,7 @@ static int st21nfcb_nci_i2c_remove(struct i2c_client *client) | |||
| 373 | 377 | ||
| 374 | #ifdef CONFIG_OF | 378 | #ifdef CONFIG_OF |
| 375 | static const struct of_device_id of_st21nfcb_i2c_match[] = { | 379 | static const struct of_device_id of_st21nfcb_i2c_match[] = { |
| 380 | { .compatible = "st,st21nfcb-i2c", }, | ||
| 376 | { .compatible = "st,st21nfcb_i2c", }, | 381 | { .compatible = "st,st21nfcb_i2c", }, |
| 377 | {} | 382 | {} |
| 378 | }; | 383 | }; |
diff --git a/drivers/nfc/st21nfcb/ndlc.c b/drivers/nfc/st21nfcb/ndlc.c index bac50e805f1d..5fbf59d2138c 100644 --- a/drivers/nfc/st21nfcb/ndlc.c +++ b/drivers/nfc/st21nfcb/ndlc.c | |||
| @@ -138,7 +138,7 @@ static void llt_ndlc_requeue_data_pending(struct llt_ndlc *ndlc) | |||
| 138 | default: | 138 | default: |
| 139 | pr_err("UNKNOWN Packet Control Byte=%d\n", pcb); | 139 | pr_err("UNKNOWN Packet Control Byte=%d\n", pcb); |
| 140 | kfree_skb(skb); | 140 | kfree_skb(skb); |
| 141 | break; | 141 | continue; |
| 142 | } | 142 | } |
| 143 | skb_queue_head(&ndlc->send_q, skb); | 143 | skb_queue_head(&ndlc->send_q, skb); |
| 144 | } | 144 | } |
| @@ -297,6 +297,5 @@ void ndlc_remove(struct llt_ndlc *ndlc) | |||
| 297 | skb_queue_purge(&ndlc->send_q); | 297 | skb_queue_purge(&ndlc->send_q); |
| 298 | 298 | ||
| 299 | st21nfcb_nci_remove(ndlc->ndev); | 299 | st21nfcb_nci_remove(ndlc->ndev); |
| 300 | kfree(ndlc); | ||
| 301 | } | 300 | } |
| 302 | EXPORT_SYMBOL(ndlc_remove); | 301 | EXPORT_SYMBOL(ndlc_remove); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 642d426a668f..3d37c6eb1732 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -1514,6 +1514,8 @@ struct net_device { | |||
| 1514 | struct list_head napi_list; | 1514 | struct list_head napi_list; |
| 1515 | struct list_head unreg_list; | 1515 | struct list_head unreg_list; |
| 1516 | struct list_head close_list; | 1516 | struct list_head close_list; |
| 1517 | struct list_head ptype_all; | ||
| 1518 | struct list_head ptype_specific; | ||
| 1517 | 1519 | ||
| 1518 | struct { | 1520 | struct { |
| 1519 | struct list_head upper; | 1521 | struct list_head upper; |
diff --git a/include/linux/platform_data/st21nfca.h b/include/linux/platform_data/st21nfca.h index 5087fff96d86..cc2bdafb0c69 100644 --- a/include/linux/platform_data/st21nfca.h +++ b/include/linux/platform_data/st21nfca.h | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | struct st21nfca_nfc_platform_data { | 26 | struct st21nfca_nfc_platform_data { |
| 27 | unsigned int gpio_ena; | 27 | unsigned int gpio_ena; |
| 28 | unsigned int irq_polarity; | 28 | unsigned int irq_polarity; |
| 29 | bool is_ese_present; | ||
| 30 | bool is_uicc_present; | ||
| 29 | }; | 31 | }; |
| 30 | 32 | ||
| 31 | #endif /* _ST21NFCA_HCI_H_ */ | 33 | #endif /* _ST21NFCA_HCI_H_ */ |
diff --git a/include/linux/platform_data/st21nfcb.h b/include/linux/platform_data/st21nfcb.h index c3b432f5b63e..b023373d9874 100644 --- a/include/linux/platform_data/st21nfcb.h +++ b/include/linux/platform_data/st21nfcb.h | |||
| @@ -19,8 +19,6 @@ | |||
| 19 | #ifndef _ST21NFCB_NCI_H_ | 19 | #ifndef _ST21NFCB_NCI_H_ |
| 20 | #define _ST21NFCB_NCI_H_ | 20 | #define _ST21NFCB_NCI_H_ |
| 21 | 21 | ||
| 22 | #include <linux/i2c.h> | ||
| 23 | |||
| 24 | #define ST21NFCB_NCI_DRIVER_NAME "st21nfcb_nci" | 22 | #define ST21NFCB_NCI_DRIVER_NAME "st21nfcb_nci" |
| 25 | 23 | ||
| 26 | struct st21nfcb_nfc_platform_data { | 24 | struct st21nfcb_nfc_platform_data { |
| @@ -28,4 +26,4 @@ struct st21nfcb_nfc_platform_data { | |||
| 28 | unsigned int irq_polarity; | 26 | unsigned int irq_polarity; |
| 29 | }; | 27 | }; |
| 30 | 28 | ||
| 31 | #endif /* _ST21NFCA_HCI_H_ */ | 29 | #endif /* _ST21NFCB_NCI_H_ */ |
diff --git a/include/net/geneve.h b/include/net/geneve.h index 03aa2adb5bab..14fb8d3390b4 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h | |||
| @@ -90,7 +90,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
| 90 | struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, | 90 | struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, |
| 91 | __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, | 91 | __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, |
| 92 | __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, | 92 | __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, |
| 93 | bool xnet); | 93 | bool csum, bool xnet); |
| 94 | #endif /*ifdef CONFIG_INET */ | 94 | #endif /*ifdef CONFIG_INET */ |
| 95 | 95 | ||
| 96 | #endif /*ifdef__NET_GENEVE_H */ | 96 | #endif /*ifdef__NET_GENEVE_H */ |
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h index 14bd0e1c47fa..ab672b537dd4 100644 --- a/include/net/nfc/hci.h +++ b/include/net/nfc/hci.h | |||
| @@ -51,8 +51,10 @@ struct nfc_hci_ops { | |||
| 51 | int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb); | 51 | int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb); |
| 52 | int (*check_presence)(struct nfc_hci_dev *hdev, | 52 | int (*check_presence)(struct nfc_hci_dev *hdev, |
| 53 | struct nfc_target *target); | 53 | struct nfc_target *target); |
| 54 | int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, | 54 | int (*event_received)(struct nfc_hci_dev *hdev, u8 pipe, u8 event, |
| 55 | struct sk_buff *skb); | 55 | struct sk_buff *skb); |
| 56 | void (*cmd_received)(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, | ||
| 57 | struct sk_buff *skb); | ||
| 56 | int (*fw_download)(struct nfc_hci_dev *hdev, const char *firmware_name); | 58 | int (*fw_download)(struct nfc_hci_dev *hdev, const char *firmware_name); |
| 57 | int (*discover_se)(struct nfc_hci_dev *dev); | 59 | int (*discover_se)(struct nfc_hci_dev *dev); |
| 58 | int (*enable_se)(struct nfc_hci_dev *dev, u32 se_idx); | 60 | int (*enable_se)(struct nfc_hci_dev *dev, u32 se_idx); |
| @@ -63,8 +65,10 @@ struct nfc_hci_ops { | |||
| 63 | }; | 65 | }; |
| 64 | 66 | ||
| 65 | /* Pipes */ | 67 | /* Pipes */ |
| 66 | #define NFC_HCI_INVALID_PIPE 0x80 | ||
| 67 | #define NFC_HCI_DO_NOT_CREATE_PIPE 0x81 | 68 | #define NFC_HCI_DO_NOT_CREATE_PIPE 0x81 |
| 69 | #define NFC_HCI_INVALID_PIPE 0x80 | ||
| 70 | #define NFC_HCI_INVALID_GATE 0xFF | ||
| 71 | #define NFC_HCI_INVALID_HOST 0x80 | ||
| 68 | #define NFC_HCI_LINK_MGMT_PIPE 0x00 | 72 | #define NFC_HCI_LINK_MGMT_PIPE 0x00 |
| 69 | #define NFC_HCI_ADMIN_PIPE 0x01 | 73 | #define NFC_HCI_ADMIN_PIPE 0x01 |
| 70 | 74 | ||
| @@ -73,7 +77,13 @@ struct nfc_hci_gate { | |||
| 73 | u8 pipe; | 77 | u8 pipe; |
| 74 | }; | 78 | }; |
| 75 | 79 | ||
| 80 | struct nfc_hci_pipe { | ||
| 81 | u8 gate; | ||
| 82 | u8 dest_host; | ||
| 83 | }; | ||
| 84 | |||
| 76 | #define NFC_HCI_MAX_CUSTOM_GATES 50 | 85 | #define NFC_HCI_MAX_CUSTOM_GATES 50 |
| 86 | #define NFC_HCI_MAX_PIPES 127 | ||
| 77 | struct nfc_hci_init_data { | 87 | struct nfc_hci_init_data { |
| 78 | u8 gate_count; | 88 | u8 gate_count; |
| 79 | struct nfc_hci_gate gates[NFC_HCI_MAX_CUSTOM_GATES]; | 89 | struct nfc_hci_gate gates[NFC_HCI_MAX_CUSTOM_GATES]; |
| @@ -125,6 +135,7 @@ struct nfc_hci_dev { | |||
| 125 | void *clientdata; | 135 | void *clientdata; |
| 126 | 136 | ||
| 127 | u8 gate2pipe[NFC_HCI_MAX_GATES]; | 137 | u8 gate2pipe[NFC_HCI_MAX_GATES]; |
| 138 | struct nfc_hci_pipe pipes[NFC_HCI_MAX_PIPES]; | ||
| 128 | 139 | ||
| 129 | u8 sw_romlib; | 140 | u8 sw_romlib; |
| 130 | u8 sw_patch; | 141 | u8 sw_patch; |
| @@ -167,6 +178,8 @@ void *nfc_hci_get_clientdata(struct nfc_hci_dev *hdev); | |||
| 167 | void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err); | 178 | void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err); |
| 168 | 179 | ||
| 169 | int nfc_hci_result_to_errno(u8 result); | 180 | int nfc_hci_result_to_errno(u8 result); |
| 181 | void nfc_hci_reset_pipes(struct nfc_hci_dev *dev); | ||
| 182 | void nfc_hci_reset_pipes_per_host(struct nfc_hci_dev *hdev, u8 host); | ||
| 170 | 183 | ||
| 171 | /* Host IDs */ | 184 | /* Host IDs */ |
| 172 | #define NFC_HCI_HOST_CONTROLLER_ID 0x00 | 185 | #define NFC_HCI_HOST_CONTROLLER_ID 0x00 |
| @@ -219,6 +232,12 @@ int nfc_hci_result_to_errno(u8 result); | |||
| 219 | #define NFC_HCI_EVT_POST_DATA 0x02 | 232 | #define NFC_HCI_EVT_POST_DATA 0x02 |
| 220 | #define NFC_HCI_EVT_HOT_PLUG 0x03 | 233 | #define NFC_HCI_EVT_HOT_PLUG 0x03 |
| 221 | 234 | ||
| 235 | /* Generic commands */ | ||
| 236 | #define NFC_HCI_ANY_SET_PARAMETER 0x01 | ||
| 237 | #define NFC_HCI_ANY_GET_PARAMETER 0x02 | ||
| 238 | #define NFC_HCI_ANY_OPEN_PIPE 0x03 | ||
| 239 | #define NFC_HCI_ANY_CLOSE_PIPE 0x04 | ||
| 240 | |||
| 222 | /* Reader RF gates events */ | 241 | /* Reader RF gates events */ |
| 223 | #define NFC_HCI_EVT_READER_REQUESTED 0x10 | 242 | #define NFC_HCI_EVT_READER_REQUESTED 0x10 |
| 224 | #define NFC_HCI_EVT_END_OPERATION 0x11 | 243 | #define NFC_HCI_EVT_END_OPERATION 0x11 |
| @@ -249,8 +268,6 @@ int nfc_hci_send_cmd(struct nfc_hci_dev *hdev, u8 gate, u8 cmd, | |||
| 249 | int nfc_hci_send_cmd_async(struct nfc_hci_dev *hdev, u8 gate, u8 cmd, | 268 | int nfc_hci_send_cmd_async(struct nfc_hci_dev *hdev, u8 gate, u8 cmd, |
| 250 | const u8 *param, size_t param_len, | 269 | const u8 *param, size_t param_len, |
| 251 | data_exchange_cb_t cb, void *cb_context); | 270 | data_exchange_cb_t cb, void *cb_context); |
| 252 | int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response, | ||
| 253 | const u8 *param, size_t param_len); | ||
| 254 | int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, | 271 | int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, |
| 255 | const u8 *param, size_t param_len); | 272 | const u8 *param, size_t param_len); |
| 256 | int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate); | 273 | int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate); |
diff --git a/include/net/sock.h b/include/net/sock.h index 2210fec65669..15341499786c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -1374,29 +1374,6 @@ void sk_prot_clear_portaddr_nulls(struct sock *sk, int size); | |||
| 1374 | #define SOCK_BINDADDR_LOCK 4 | 1374 | #define SOCK_BINDADDR_LOCK 4 |
| 1375 | #define SOCK_BINDPORT_LOCK 8 | 1375 | #define SOCK_BINDPORT_LOCK 8 |
| 1376 | 1376 | ||
| 1377 | /* sock_iocb: used to kick off async processing of socket ios */ | ||
| 1378 | struct sock_iocb { | ||
| 1379 | struct list_head list; | ||
| 1380 | |||
| 1381 | int flags; | ||
| 1382 | int size; | ||
| 1383 | struct socket *sock; | ||
| 1384 | struct sock *sk; | ||
| 1385 | struct scm_cookie *scm; | ||
| 1386 | struct msghdr *msg, async_msg; | ||
| 1387 | struct kiocb *kiocb; | ||
| 1388 | }; | ||
| 1389 | |||
| 1390 | static inline struct sock_iocb *kiocb_to_siocb(struct kiocb *iocb) | ||
| 1391 | { | ||
| 1392 | return (struct sock_iocb *)iocb->private; | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | static inline struct kiocb *siocb_to_kiocb(struct sock_iocb *si) | ||
| 1396 | { | ||
| 1397 | return si->kiocb; | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | struct socket_alloc { | 1377 | struct socket_alloc { |
| 1401 | struct socket socket; | 1378 | struct socket socket; |
| 1402 | struct inode vfs_inode; | 1379 | struct inode vfs_inode; |
diff --git a/net/core/dev.c b/net/core/dev.c index 7f028d441e98..1d564d68e31a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -371,9 +371,10 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev) | |||
| 371 | static inline struct list_head *ptype_head(const struct packet_type *pt) | 371 | static inline struct list_head *ptype_head(const struct packet_type *pt) |
| 372 | { | 372 | { |
| 373 | if (pt->type == htons(ETH_P_ALL)) | 373 | if (pt->type == htons(ETH_P_ALL)) |
| 374 | return &ptype_all; | 374 | return pt->dev ? &pt->dev->ptype_all : &ptype_all; |
| 375 | else | 375 | else |
| 376 | return &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK]; | 376 | return pt->dev ? &pt->dev->ptype_specific : |
| 377 | &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK]; | ||
| 377 | } | 378 | } |
| 378 | 379 | ||
| 379 | /** | 380 | /** |
| @@ -1734,6 +1735,23 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
| 1734 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 1735 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
| 1735 | } | 1736 | } |
| 1736 | 1737 | ||
| 1738 | static inline void deliver_ptype_list_skb(struct sk_buff *skb, | ||
| 1739 | struct packet_type **pt, | ||
| 1740 | struct net_device *dev, __be16 type, | ||
| 1741 | struct list_head *ptype_list) | ||
| 1742 | { | ||
| 1743 | struct packet_type *ptype, *pt_prev = *pt; | ||
| 1744 | |||
| 1745 | list_for_each_entry_rcu(ptype, ptype_list, list) { | ||
| 1746 | if (ptype->type != type) | ||
| 1747 | continue; | ||
| 1748 | if (pt_prev) | ||
| 1749 | deliver_skb(skb, pt_prev, dev); | ||
| 1750 | pt_prev = ptype; | ||
| 1751 | } | ||
| 1752 | *pt = pt_prev; | ||
| 1753 | } | ||
| 1754 | |||
| 1737 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) | 1755 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) |
| 1738 | { | 1756 | { |
| 1739 | if (!ptype->af_packet_priv || !skb->sk) | 1757 | if (!ptype->af_packet_priv || !skb->sk) |
| @@ -1757,45 +1775,54 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
| 1757 | struct packet_type *ptype; | 1775 | struct packet_type *ptype; |
| 1758 | struct sk_buff *skb2 = NULL; | 1776 | struct sk_buff *skb2 = NULL; |
| 1759 | struct packet_type *pt_prev = NULL; | 1777 | struct packet_type *pt_prev = NULL; |
| 1778 | struct list_head *ptype_list = &ptype_all; | ||
| 1760 | 1779 | ||
| 1761 | rcu_read_lock(); | 1780 | rcu_read_lock(); |
| 1762 | list_for_each_entry_rcu(ptype, &ptype_all, list) { | 1781 | again: |
| 1782 | list_for_each_entry_rcu(ptype, ptype_list, list) { | ||
| 1763 | /* Never send packets back to the socket | 1783 | /* Never send packets back to the socket |
| 1764 | * they originated from - MvS (miquels@drinkel.ow.org) | 1784 | * they originated from - MvS (miquels@drinkel.ow.org) |
| 1765 | */ | 1785 | */ |
| 1766 | if ((ptype->dev == dev || !ptype->dev) && | 1786 | if (skb_loop_sk(ptype, skb)) |
| 1767 | (!skb_loop_sk(ptype, skb))) { | 1787 | continue; |
| 1768 | if (pt_prev) { | ||
| 1769 | deliver_skb(skb2, pt_prev, skb->dev); | ||
| 1770 | pt_prev = ptype; | ||
| 1771 | continue; | ||
| 1772 | } | ||
| 1773 | 1788 | ||
| 1774 | skb2 = skb_clone(skb, GFP_ATOMIC); | 1789 | if (pt_prev) { |
| 1775 | if (!skb2) | 1790 | deliver_skb(skb2, pt_prev, skb->dev); |
| 1776 | break; | 1791 | pt_prev = ptype; |
| 1792 | continue; | ||
| 1793 | } | ||
| 1777 | 1794 | ||
| 1778 | net_timestamp_set(skb2); | 1795 | /* need to clone skb, done only once */ |
| 1796 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 1797 | if (!skb2) | ||
| 1798 | goto out_unlock; | ||
| 1779 | 1799 | ||
| 1780 | /* skb->nh should be correctly | 1800 | net_timestamp_set(skb2); |
| 1781 | set by sender, so that the second statement is | ||
| 1782 | just protection against buggy protocols. | ||
| 1783 | */ | ||
| 1784 | skb_reset_mac_header(skb2); | ||
| 1785 | |||
| 1786 | if (skb_network_header(skb2) < skb2->data || | ||
| 1787 | skb_network_header(skb2) > skb_tail_pointer(skb2)) { | ||
| 1788 | net_crit_ratelimited("protocol %04x is buggy, dev %s\n", | ||
| 1789 | ntohs(skb2->protocol), | ||
| 1790 | dev->name); | ||
| 1791 | skb_reset_network_header(skb2); | ||
| 1792 | } | ||
| 1793 | 1801 | ||
| 1794 | skb2->transport_header = skb2->network_header; | 1802 | /* skb->nh should be correctly |
| 1795 | skb2->pkt_type = PACKET_OUTGOING; | 1803 | * set by sender, so that the second statement is |
| 1796 | pt_prev = ptype; | 1804 | * just protection against buggy protocols. |
| 1805 | */ | ||
| 1806 | skb_reset_mac_header(skb2); | ||
| 1807 | |||
| 1808 | if (skb_network_header(skb2) < skb2->data || | ||
| 1809 | skb_network_header(skb2) > skb_tail_pointer(skb2)) { | ||
| 1810 | net_crit_ratelimited("protocol %04x is buggy, dev %s\n", | ||
| 1811 | ntohs(skb2->protocol), | ||
| 1812 | dev->name); | ||
| 1813 | skb_reset_network_header(skb2); | ||
| 1797 | } | 1814 | } |
| 1815 | |||
| 1816 | skb2->transport_header = skb2->network_header; | ||
| 1817 | skb2->pkt_type = PACKET_OUTGOING; | ||
| 1818 | pt_prev = ptype; | ||
| 1819 | } | ||
| 1820 | |||
| 1821 | if (ptype_list == &ptype_all) { | ||
| 1822 | ptype_list = &dev->ptype_all; | ||
| 1823 | goto again; | ||
| 1798 | } | 1824 | } |
| 1825 | out_unlock: | ||
| 1799 | if (pt_prev) | 1826 | if (pt_prev) |
| 1800 | pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); | 1827 | pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); |
| 1801 | rcu_read_unlock(); | 1828 | rcu_read_unlock(); |
| @@ -2617,7 +2644,7 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
| 2617 | unsigned int len; | 2644 | unsigned int len; |
| 2618 | int rc; | 2645 | int rc; |
| 2619 | 2646 | ||
| 2620 | if (!list_empty(&ptype_all)) | 2647 | if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) |
| 2621 | dev_queue_xmit_nit(skb, dev); | 2648 | dev_queue_xmit_nit(skb, dev); |
| 2622 | 2649 | ||
| 2623 | len = skb->len; | 2650 | len = skb->len; |
| @@ -3615,7 +3642,6 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc) | |||
| 3615 | struct packet_type *ptype, *pt_prev; | 3642 | struct packet_type *ptype, *pt_prev; |
| 3616 | rx_handler_func_t *rx_handler; | 3643 | rx_handler_func_t *rx_handler; |
| 3617 | struct net_device *orig_dev; | 3644 | struct net_device *orig_dev; |
| 3618 | struct net_device *null_or_dev; | ||
| 3619 | bool deliver_exact = false; | 3645 | bool deliver_exact = false; |
| 3620 | int ret = NET_RX_DROP; | 3646 | int ret = NET_RX_DROP; |
| 3621 | __be16 type; | 3647 | __be16 type; |
| @@ -3658,11 +3684,15 @@ another_round: | |||
| 3658 | goto skip_taps; | 3684 | goto skip_taps; |
| 3659 | 3685 | ||
| 3660 | list_for_each_entry_rcu(ptype, &ptype_all, list) { | 3686 | list_for_each_entry_rcu(ptype, &ptype_all, list) { |
| 3661 | if (!ptype->dev || ptype->dev == skb->dev) { | 3687 | if (pt_prev) |
| 3662 | if (pt_prev) | 3688 | ret = deliver_skb(skb, pt_prev, orig_dev); |
| 3663 | ret = deliver_skb(skb, pt_prev, orig_dev); | 3689 | pt_prev = ptype; |
| 3664 | pt_prev = ptype; | 3690 | } |
| 3665 | } | 3691 | |
| 3692 | list_for_each_entry_rcu(ptype, &skb->dev->ptype_all, list) { | ||
| 3693 | if (pt_prev) | ||
| 3694 | ret = deliver_skb(skb, pt_prev, orig_dev); | ||
| 3695 | pt_prev = ptype; | ||
| 3666 | } | 3696 | } |
| 3667 | 3697 | ||
| 3668 | skip_taps: | 3698 | skip_taps: |
| @@ -3718,19 +3748,21 @@ ncls: | |||
| 3718 | skb->vlan_tci = 0; | 3748 | skb->vlan_tci = 0; |
| 3719 | } | 3749 | } |
| 3720 | 3750 | ||
| 3751 | type = skb->protocol; | ||
| 3752 | |||
| 3721 | /* deliver only exact match when indicated */ | 3753 | /* deliver only exact match when indicated */ |
| 3722 | null_or_dev = deliver_exact ? skb->dev : NULL; | 3754 | if (likely(!deliver_exact)) { |
| 3755 | deliver_ptype_list_skb(skb, &pt_prev, orig_dev, type, | ||
| 3756 | &ptype_base[ntohs(type) & | ||
| 3757 | PTYPE_HASH_MASK]); | ||
| 3758 | } | ||
| 3723 | 3759 | ||
| 3724 | type = skb->protocol; | 3760 | deliver_ptype_list_skb(skb, &pt_prev, orig_dev, type, |
| 3725 | list_for_each_entry_rcu(ptype, | 3761 | &orig_dev->ptype_specific); |
| 3726 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { | 3762 | |
| 3727 | if (ptype->type == type && | 3763 | if (unlikely(skb->dev != orig_dev)) { |
| 3728 | (ptype->dev == null_or_dev || ptype->dev == skb->dev || | 3764 | deliver_ptype_list_skb(skb, &pt_prev, orig_dev, type, |
| 3729 | ptype->dev == orig_dev)) { | 3765 | &skb->dev->ptype_specific); |
| 3730 | if (pt_prev) | ||
| 3731 | ret = deliver_skb(skb, pt_prev, orig_dev); | ||
| 3732 | pt_prev = ptype; | ||
| 3733 | } | ||
| 3734 | } | 3766 | } |
| 3735 | 3767 | ||
| 3736 | if (pt_prev) { | 3768 | if (pt_prev) { |
| @@ -6579,6 +6611,8 @@ void netdev_run_todo(void) | |||
| 6579 | 6611 | ||
| 6580 | /* paranoia */ | 6612 | /* paranoia */ |
| 6581 | BUG_ON(netdev_refcnt_read(dev)); | 6613 | BUG_ON(netdev_refcnt_read(dev)); |
| 6614 | BUG_ON(!list_empty(&dev->ptype_all)); | ||
| 6615 | BUG_ON(!list_empty(&dev->ptype_specific)); | ||
| 6582 | WARN_ON(rcu_access_pointer(dev->ip_ptr)); | 6616 | WARN_ON(rcu_access_pointer(dev->ip_ptr)); |
| 6583 | WARN_ON(rcu_access_pointer(dev->ip6_ptr)); | 6617 | WARN_ON(rcu_access_pointer(dev->ip6_ptr)); |
| 6584 | WARN_ON(dev->dn_ptr); | 6618 | WARN_ON(dev->dn_ptr); |
| @@ -6761,6 +6795,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
| 6761 | INIT_LIST_HEAD(&dev->adj_list.lower); | 6795 | INIT_LIST_HEAD(&dev->adj_list.lower); |
| 6762 | INIT_LIST_HEAD(&dev->all_adj_list.upper); | 6796 | INIT_LIST_HEAD(&dev->all_adj_list.upper); |
| 6763 | INIT_LIST_HEAD(&dev->all_adj_list.lower); | 6797 | INIT_LIST_HEAD(&dev->all_adj_list.lower); |
| 6798 | INIT_LIST_HEAD(&dev->ptype_all); | ||
| 6799 | INIT_LIST_HEAD(&dev->ptype_specific); | ||
| 6764 | dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; | 6800 | dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; |
| 6765 | setup(dev); | 6801 | setup(dev); |
| 6766 | 6802 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 07447d1665e6..fedd7ab4085a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -2148,7 +2148,7 @@ replay: | |||
| 2148 | dev->ifindex = ifm->ifi_index; | 2148 | dev->ifindex = ifm->ifi_index; |
| 2149 | 2149 | ||
| 2150 | if (ops->newlink) { | 2150 | if (ops->newlink) { |
| 2151 | err = ops->newlink(net, dev, tb, data); | 2151 | err = ops->newlink(link_net ? : net, dev, tb, data); |
| 2152 | /* Drivers should call free_netdev() in ->destructor | 2152 | /* Drivers should call free_netdev() in ->destructor |
| 2153 | * and unregister it on failure after registration | 2153 | * and unregister it on failure after registration |
| 2154 | * so that device could be finally freed in rtnl_unlock. | 2154 | * so that device could be finally freed in rtnl_unlock. |
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 93e51199e44b..5a4828ba05ad 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
| @@ -107,13 +107,13 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
| 107 | struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, | 107 | struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, |
| 108 | __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, | 108 | __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, |
| 109 | __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, | 109 | __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, |
| 110 | bool xnet) | 110 | bool csum, bool xnet) |
| 111 | { | 111 | { |
| 112 | struct genevehdr *gnvh; | 112 | struct genevehdr *gnvh; |
| 113 | int min_headroom; | 113 | int min_headroom; |
| 114 | int err; | 114 | int err; |
| 115 | 115 | ||
| 116 | skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); | 116 | skb = udp_tunnel_handle_offloads(skb, csum); |
| 117 | if (IS_ERR(skb)) | 117 | if (IS_ERR(skb)) |
| 118 | return PTR_ERR(skb); | 118 | return PTR_ERR(skb); |
| 119 | 119 | ||
| @@ -138,7 +138,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
| 138 | 138 | ||
| 139 | return udp_tunnel_xmit_skb(rt, skb, src, dst, | 139 | return udp_tunnel_xmit_skb(rt, skb, src, dst, |
| 140 | tos, ttl, df, src_port, dst_port, xnet, | 140 | tos, ttl, df, src_port, dst_port, xnet, |
| 141 | gs->sock->sk->sk_no_check_tx); | 141 | !csum); |
| 142 | } | 142 | } |
| 143 | EXPORT_SYMBOL_GPL(geneve_xmit_skb); | 143 | EXPORT_SYMBOL_GPL(geneve_xmit_skb); |
| 144 | 144 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 2197af00673a..a36777b7cfb6 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -695,7 +695,7 @@ static void netlink_ring_setup_skb(struct sk_buff *skb, struct sock *sk, | |||
| 695 | 695 | ||
| 696 | static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, | 696 | static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, |
| 697 | u32 dst_portid, u32 dst_group, | 697 | u32 dst_portid, u32 dst_group, |
| 698 | struct sock_iocb *siocb) | 698 | struct scm_cookie *scm) |
| 699 | { | 699 | { |
| 700 | struct netlink_sock *nlk = nlk_sk(sk); | 700 | struct netlink_sock *nlk = nlk_sk(sk); |
| 701 | struct netlink_ring *ring; | 701 | struct netlink_ring *ring; |
| @@ -741,7 +741,7 @@ static int netlink_mmap_sendmsg(struct sock *sk, struct msghdr *msg, | |||
| 741 | 741 | ||
| 742 | NETLINK_CB(skb).portid = nlk->portid; | 742 | NETLINK_CB(skb).portid = nlk->portid; |
| 743 | NETLINK_CB(skb).dst_group = dst_group; | 743 | NETLINK_CB(skb).dst_group = dst_group; |
| 744 | NETLINK_CB(skb).creds = siocb->scm->creds; | 744 | NETLINK_CB(skb).creds = scm->creds; |
| 745 | 745 | ||
| 746 | err = security_netlink_send(sk, skb); | 746 | err = security_netlink_send(sk, skb); |
| 747 | if (err) { | 747 | if (err) { |
| @@ -820,7 +820,7 @@ static void netlink_ring_set_copied(struct sock *sk, struct sk_buff *skb) | |||
| 820 | #define netlink_tx_is_mmaped(sk) false | 820 | #define netlink_tx_is_mmaped(sk) false |
| 821 | #define netlink_mmap sock_no_mmap | 821 | #define netlink_mmap sock_no_mmap |
| 822 | #define netlink_poll datagram_poll | 822 | #define netlink_poll datagram_poll |
| 823 | #define netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, siocb) 0 | 823 | #define netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, scm) 0 |
| 824 | #endif /* CONFIG_NETLINK_MMAP */ | 824 | #endif /* CONFIG_NETLINK_MMAP */ |
| 825 | 825 | ||
| 826 | static void netlink_skb_destructor(struct sk_buff *skb) | 826 | static void netlink_skb_destructor(struct sk_buff *skb) |
| @@ -2259,7 +2259,6 @@ static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) | |||
| 2259 | static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | 2259 | static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, |
| 2260 | struct msghdr *msg, size_t len) | 2260 | struct msghdr *msg, size_t len) |
| 2261 | { | 2261 | { |
| 2262 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
| 2263 | struct sock *sk = sock->sk; | 2262 | struct sock *sk = sock->sk; |
| 2264 | struct netlink_sock *nlk = nlk_sk(sk); | 2263 | struct netlink_sock *nlk = nlk_sk(sk); |
| 2265 | DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name); | 2264 | DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name); |
| @@ -2273,10 +2272,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2273 | if (msg->msg_flags&MSG_OOB) | 2272 | if (msg->msg_flags&MSG_OOB) |
| 2274 | return -EOPNOTSUPP; | 2273 | return -EOPNOTSUPP; |
| 2275 | 2274 | ||
| 2276 | if (NULL == siocb->scm) | 2275 | err = scm_send(sock, msg, &scm, true); |
| 2277 | siocb->scm = &scm; | ||
| 2278 | |||
| 2279 | err = scm_send(sock, msg, siocb->scm, true); | ||
| 2280 | if (err < 0) | 2276 | if (err < 0) |
| 2281 | return err; | 2277 | return err; |
| 2282 | 2278 | ||
| @@ -2305,7 +2301,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2305 | if (netlink_tx_is_mmaped(sk) && | 2301 | if (netlink_tx_is_mmaped(sk) && |
| 2306 | msg->msg_iter.iov->iov_base == NULL) { | 2302 | msg->msg_iter.iov->iov_base == NULL) { |
| 2307 | err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, | 2303 | err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, |
| 2308 | siocb); | 2304 | &scm); |
| 2309 | goto out; | 2305 | goto out; |
| 2310 | } | 2306 | } |
| 2311 | 2307 | ||
| @@ -2319,7 +2315,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2319 | 2315 | ||
| 2320 | NETLINK_CB(skb).portid = nlk->portid; | 2316 | NETLINK_CB(skb).portid = nlk->portid; |
| 2321 | NETLINK_CB(skb).dst_group = dst_group; | 2317 | NETLINK_CB(skb).dst_group = dst_group; |
| 2322 | NETLINK_CB(skb).creds = siocb->scm->creds; | 2318 | NETLINK_CB(skb).creds = scm.creds; |
| 2323 | NETLINK_CB(skb).flags = netlink_skb_flags; | 2319 | NETLINK_CB(skb).flags = netlink_skb_flags; |
| 2324 | 2320 | ||
| 2325 | err = -EFAULT; | 2321 | err = -EFAULT; |
| @@ -2341,7 +2337,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2341 | err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT); | 2337 | err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT); |
| 2342 | 2338 | ||
| 2343 | out: | 2339 | out: |
| 2344 | scm_destroy(siocb->scm); | 2340 | scm_destroy(&scm); |
| 2345 | return err; | 2341 | return err; |
| 2346 | } | 2342 | } |
| 2347 | 2343 | ||
| @@ -2349,7 +2345,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2349 | struct msghdr *msg, size_t len, | 2345 | struct msghdr *msg, size_t len, |
| 2350 | int flags) | 2346 | int flags) |
| 2351 | { | 2347 | { |
| 2352 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
| 2353 | struct scm_cookie scm; | 2348 | struct scm_cookie scm; |
| 2354 | struct sock *sk = sock->sk; | 2349 | struct sock *sk = sock->sk; |
| 2355 | struct netlink_sock *nlk = nlk_sk(sk); | 2350 | struct netlink_sock *nlk = nlk_sk(sk); |
| @@ -2412,11 +2407,8 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2412 | if (nlk->flags & NETLINK_RECV_PKTINFO) | 2407 | if (nlk->flags & NETLINK_RECV_PKTINFO) |
| 2413 | netlink_cmsg_recv_pktinfo(msg, skb); | 2408 | netlink_cmsg_recv_pktinfo(msg, skb); |
| 2414 | 2409 | ||
| 2415 | if (NULL == siocb->scm) { | 2410 | memset(&scm, 0, sizeof(scm)); |
| 2416 | memset(&scm, 0, sizeof(scm)); | 2411 | scm.creds = *NETLINK_CREDS(skb); |
| 2417 | siocb->scm = &scm; | ||
| 2418 | } | ||
| 2419 | siocb->scm->creds = *NETLINK_CREDS(skb); | ||
| 2420 | if (flags & MSG_TRUNC) | 2412 | if (flags & MSG_TRUNC) |
| 2421 | copied = data_skb->len; | 2413 | copied = data_skb->len; |
| 2422 | 2414 | ||
| @@ -2431,7 +2423,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2431 | } | 2423 | } |
| 2432 | } | 2424 | } |
| 2433 | 2425 | ||
| 2434 | scm_recv(sock, msg, siocb->scm, flags); | 2426 | scm_recv(sock, msg, &scm, flags); |
| 2435 | out: | 2427 | out: |
| 2436 | netlink_rcv_wake(sk); | 2428 | netlink_rcv_wake(sk); |
| 2437 | return err ? : copied; | 2429 | return err ? : copied; |
diff --git a/net/nfc/core.c b/net/nfc/core.c index 819b87702b70..7f1b6351755c 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
| @@ -555,7 +555,6 @@ EXPORT_SYMBOL(nfc_find_se); | |||
| 555 | 555 | ||
| 556 | int nfc_enable_se(struct nfc_dev *dev, u32 se_idx) | 556 | int nfc_enable_se(struct nfc_dev *dev, u32 se_idx) |
| 557 | { | 557 | { |
| 558 | |||
| 559 | struct nfc_se *se; | 558 | struct nfc_se *se; |
| 560 | int rc; | 559 | int rc; |
| 561 | 560 | ||
| @@ -605,7 +604,6 @@ error: | |||
| 605 | 604 | ||
| 606 | int nfc_disable_se(struct nfc_dev *dev, u32 se_idx) | 605 | int nfc_disable_se(struct nfc_dev *dev, u32 se_idx) |
| 607 | { | 606 | { |
| 608 | |||
| 609 | struct nfc_se *se; | 607 | struct nfc_se *se; |
| 610 | int rc; | 608 | int rc; |
| 611 | 609 | ||
diff --git a/net/nfc/hci/command.c b/net/nfc/hci/command.c index 91df487aa0a9..844673cb7c18 100644 --- a/net/nfc/hci/command.c +++ b/net/nfc/hci/command.c | |||
| @@ -116,23 +116,6 @@ int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, | |||
| 116 | } | 116 | } |
| 117 | EXPORT_SYMBOL(nfc_hci_send_event); | 117 | EXPORT_SYMBOL(nfc_hci_send_event); |
| 118 | 118 | ||
| 119 | int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response, | ||
| 120 | const u8 *param, size_t param_len) | ||
| 121 | { | ||
| 122 | u8 pipe; | ||
| 123 | |||
| 124 | pr_debug("\n"); | ||
| 125 | |||
| 126 | pipe = hdev->gate2pipe[gate]; | ||
| 127 | if (pipe == NFC_HCI_INVALID_PIPE) | ||
| 128 | return -EADDRNOTAVAIL; | ||
| 129 | |||
| 130 | return nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE, | ||
| 131 | response, param, param_len, NULL, NULL, | ||
| 132 | 0); | ||
| 133 | } | ||
| 134 | EXPORT_SYMBOL(nfc_hci_send_response); | ||
| 135 | |||
| 136 | /* | 119 | /* |
| 137 | * Execute an hci command sent to gate. | 120 | * Execute an hci command sent to gate. |
| 138 | * skb will contain response data if success. skb can be NULL if you are not | 121 | * skb will contain response data if success. skb can be NULL if you are not |
| @@ -331,7 +314,7 @@ int nfc_hci_disconnect_all_gates(struct nfc_hci_dev *hdev) | |||
| 331 | if (r < 0) | 314 | if (r < 0) |
| 332 | return r; | 315 | return r; |
| 333 | 316 | ||
| 334 | memset(hdev->gate2pipe, NFC_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe)); | 317 | nfc_hci_reset_pipes(hdev); |
| 335 | 318 | ||
| 336 | return 0; | 319 | return 0; |
| 337 | } | 320 | } |
| @@ -345,7 +328,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, | |||
| 345 | 328 | ||
| 346 | pr_debug("\n"); | 329 | pr_debug("\n"); |
| 347 | 330 | ||
| 348 | if (hdev->gate2pipe[dest_gate] == NFC_HCI_DO_NOT_CREATE_PIPE) | 331 | if (pipe == NFC_HCI_DO_NOT_CREATE_PIPE) |
| 349 | return 0; | 332 | return 0; |
| 350 | 333 | ||
| 351 | if (hdev->gate2pipe[dest_gate] != NFC_HCI_INVALID_PIPE) | 334 | if (hdev->gate2pipe[dest_gate] != NFC_HCI_INVALID_PIPE) |
| @@ -380,6 +363,8 @@ open_pipe: | |||
| 380 | return r; | 363 | return r; |
| 381 | } | 364 | } |
| 382 | 365 | ||
| 366 | hdev->pipes[pipe].gate = dest_gate; | ||
| 367 | hdev->pipes[pipe].dest_host = dest_host; | ||
| 383 | hdev->gate2pipe[dest_gate] = pipe; | 368 | hdev->gate2pipe[dest_gate] = pipe; |
| 384 | 369 | ||
| 385 | return 0; | 370 | return 0; |
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index ef50e7716c4a..6e061da2258a 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c | |||
| @@ -46,6 +46,32 @@ int nfc_hci_result_to_errno(u8 result) | |||
| 46 | } | 46 | } |
| 47 | EXPORT_SYMBOL(nfc_hci_result_to_errno); | 47 | EXPORT_SYMBOL(nfc_hci_result_to_errno); |
| 48 | 48 | ||
| 49 | void nfc_hci_reset_pipes(struct nfc_hci_dev *hdev) | ||
| 50 | { | ||
| 51 | int i = 0; | ||
| 52 | |||
| 53 | for (i = 0; i < NFC_HCI_MAX_PIPES; i++) { | ||
| 54 | hdev->pipes[i].gate = NFC_HCI_INVALID_GATE; | ||
| 55 | hdev->pipes[i].dest_host = NFC_HCI_INVALID_HOST; | ||
| 56 | } | ||
| 57 | memset(hdev->gate2pipe, NFC_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe)); | ||
| 58 | } | ||
| 59 | EXPORT_SYMBOL(nfc_hci_reset_pipes); | ||
| 60 | |||
| 61 | void nfc_hci_reset_pipes_per_host(struct nfc_hci_dev *hdev, u8 host) | ||
| 62 | { | ||
| 63 | int i = 0; | ||
| 64 | |||
| 65 | for (i = 0; i < NFC_HCI_MAX_PIPES; i++) { | ||
| 66 | if (hdev->pipes[i].dest_host != host) | ||
| 67 | continue; | ||
| 68 | |||
| 69 | hdev->pipes[i].gate = NFC_HCI_INVALID_GATE; | ||
| 70 | hdev->pipes[i].dest_host = NFC_HCI_INVALID_HOST; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | EXPORT_SYMBOL(nfc_hci_reset_pipes_per_host); | ||
| 74 | |||
| 49 | static void nfc_hci_msg_tx_work(struct work_struct *work) | 75 | static void nfc_hci_msg_tx_work(struct work_struct *work) |
| 50 | { | 76 | { |
| 51 | struct nfc_hci_dev *hdev = container_of(work, struct nfc_hci_dev, | 77 | struct nfc_hci_dev *hdev = container_of(work, struct nfc_hci_dev, |
| @@ -167,48 +193,69 @@ exit: | |||
| 167 | void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, | 193 | void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, |
| 168 | struct sk_buff *skb) | 194 | struct sk_buff *skb) |
| 169 | { | 195 | { |
| 170 | int r = 0; | 196 | u8 gate = hdev->pipes[pipe].gate; |
| 171 | u8 gate = nfc_hci_pipe2gate(hdev, pipe); | 197 | u8 status = NFC_HCI_ANY_OK; |
| 172 | u8 local_gate, new_pipe; | 198 | struct hci_create_pipe_resp *create_info; |
| 173 | u8 gate_opened = 0x00; | 199 | struct hci_delete_pipe_noti *delete_info; |
| 200 | struct hci_all_pipe_cleared_noti *cleared_info; | ||
| 174 | 201 | ||
| 175 | pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd); | 202 | pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd); |
| 176 | 203 | ||
| 177 | switch (cmd) { | 204 | switch (cmd) { |
| 178 | case NFC_HCI_ADM_NOTIFY_PIPE_CREATED: | 205 | case NFC_HCI_ADM_NOTIFY_PIPE_CREATED: |
| 179 | if (skb->len != 5) { | 206 | if (skb->len != 5) { |
| 180 | r = -EPROTO; | 207 | status = NFC_HCI_ANY_E_NOK; |
| 181 | break; | 208 | goto exit; |
| 182 | } | 209 | } |
| 210 | create_info = (struct hci_create_pipe_resp *)skb->data; | ||
| 183 | 211 | ||
| 184 | local_gate = skb->data[3]; | 212 | /* Save the new created pipe and bind with local gate, |
| 185 | new_pipe = skb->data[4]; | ||
| 186 | nfc_hci_send_response(hdev, gate, NFC_HCI_ANY_OK, NULL, 0); | ||
| 187 | |||
| 188 | /* save the new created pipe and bind with local gate, | ||
| 189 | * the description for skb->data[3] is destination gate id | 213 | * the description for skb->data[3] is destination gate id |
| 190 | * but since we received this cmd from host controller, we | 214 | * but since we received this cmd from host controller, we |
| 191 | * are the destination and it is our local gate | 215 | * are the destination and it is our local gate |
| 192 | */ | 216 | */ |
| 193 | hdev->gate2pipe[local_gate] = new_pipe; | 217 | hdev->gate2pipe[create_info->dest_gate] = create_info->pipe; |
| 218 | hdev->pipes[create_info->pipe].gate = create_info->dest_gate; | ||
| 219 | hdev->pipes[create_info->pipe].dest_host = | ||
| 220 | create_info->src_host; | ||
| 194 | break; | 221 | break; |
| 195 | case NFC_HCI_ANY_OPEN_PIPE: | 222 | case NFC_HCI_ANY_OPEN_PIPE: |
| 196 | /* if the pipe is already created, we allow remote host to | 223 | if (gate == NFC_HCI_INVALID_GATE) { |
| 197 | * open it | 224 | status = NFC_HCI_ANY_E_NOK; |
| 198 | */ | 225 | goto exit; |
| 199 | if (gate != 0xff) | 226 | } |
| 200 | nfc_hci_send_response(hdev, gate, NFC_HCI_ANY_OK, | 227 | break; |
| 201 | &gate_opened, 1); | 228 | case NFC_HCI_ADM_NOTIFY_PIPE_DELETED: |
| 229 | if (skb->len != 1) { | ||
| 230 | status = NFC_HCI_ANY_E_NOK; | ||
| 231 | goto exit; | ||
| 232 | } | ||
| 233 | delete_info = (struct hci_delete_pipe_noti *)skb->data; | ||
| 234 | |||
| 235 | hdev->pipes[delete_info->pipe].gate = NFC_HCI_INVALID_GATE; | ||
| 236 | hdev->pipes[delete_info->pipe].dest_host = NFC_HCI_INVALID_HOST; | ||
| 202 | break; | 237 | break; |
| 203 | case NFC_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: | 238 | case NFC_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: |
| 204 | nfc_hci_send_response(hdev, gate, NFC_HCI_ANY_OK, NULL, 0); | 239 | if (skb->len != 1) { |
| 240 | status = NFC_HCI_ANY_E_NOK; | ||
| 241 | goto exit; | ||
| 242 | } | ||
| 243 | cleared_info = (struct hci_all_pipe_cleared_noti *)skb->data; | ||
| 244 | |||
| 245 | nfc_hci_reset_pipes_per_host(hdev, cleared_info->host); | ||
| 205 | break; | 246 | break; |
| 206 | default: | 247 | default: |
| 207 | pr_info("Discarded unknown cmd %x to gate %x\n", cmd, gate); | 248 | pr_info("Discarded unknown cmd %x to gate %x\n", cmd, gate); |
| 208 | r = -EINVAL; | ||
| 209 | break; | 249 | break; |
| 210 | } | 250 | } |
| 211 | 251 | ||
| 252 | if (hdev->ops->cmd_received) | ||
| 253 | hdev->ops->cmd_received(hdev, pipe, cmd, skb); | ||
| 254 | |||
| 255 | exit: | ||
| 256 | nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE, | ||
| 257 | status, NULL, 0, NULL, NULL, 0); | ||
| 258 | |||
| 212 | kfree_skb(skb); | 259 | kfree_skb(skb); |
| 213 | } | 260 | } |
| 214 | 261 | ||
| @@ -330,15 +377,15 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, | |||
| 330 | struct sk_buff *skb) | 377 | struct sk_buff *skb) |
| 331 | { | 378 | { |
| 332 | int r = 0; | 379 | int r = 0; |
| 333 | u8 gate = nfc_hci_pipe2gate(hdev, pipe); | 380 | u8 gate = hdev->pipes[pipe].gate; |
| 334 | 381 | ||
| 335 | if (gate == 0xff) { | 382 | if (gate == NFC_HCI_INVALID_GATE) { |
| 336 | pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); | 383 | pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); |
| 337 | goto exit; | 384 | goto exit; |
| 338 | } | 385 | } |
| 339 | 386 | ||
| 340 | if (hdev->ops->event_received) { | 387 | if (hdev->ops->event_received) { |
| 341 | r = hdev->ops->event_received(hdev, gate, event, skb); | 388 | r = hdev->ops->event_received(hdev, pipe, event, skb); |
| 342 | if (r <= 0) | 389 | if (r <= 0) |
| 343 | goto exit_noskb; | 390 | goto exit_noskb; |
| 344 | } | 391 | } |
| @@ -573,7 +620,7 @@ static int hci_dev_down(struct nfc_dev *nfc_dev) | |||
| 573 | if (hdev->ops->close) | 620 | if (hdev->ops->close) |
| 574 | hdev->ops->close(hdev); | 621 | hdev->ops->close(hdev); |
| 575 | 622 | ||
| 576 | memset(hdev->gate2pipe, NFC_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe)); | 623 | nfc_hci_reset_pipes(hdev); |
| 577 | 624 | ||
| 578 | return 0; | 625 | return 0; |
| 579 | } | 626 | } |
| @@ -932,7 +979,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(struct nfc_hci_ops *ops, | |||
| 932 | 979 | ||
| 933 | nfc_set_drvdata(hdev->ndev, hdev); | 980 | nfc_set_drvdata(hdev->ndev, hdev); |
| 934 | 981 | ||
| 935 | memset(hdev->gate2pipe, NFC_HCI_INVALID_PIPE, sizeof(hdev->gate2pipe)); | 982 | nfc_hci_reset_pipes(hdev); |
| 936 | 983 | ||
| 937 | hdev->quirks = quirks; | 984 | hdev->quirks = quirks; |
| 938 | 985 | ||
diff --git a/net/nfc/hci/hci.h b/net/nfc/hci/hci.h index c3d2e2c1394c..ab4c8e80b1ad 100644 --- a/net/nfc/hci/hci.h +++ b/net/nfc/hci/hci.h | |||
| @@ -65,6 +65,14 @@ struct hci_create_pipe_resp { | |||
| 65 | u8 pipe; | 65 | u8 pipe; |
| 66 | } __packed; | 66 | } __packed; |
| 67 | 67 | ||
| 68 | struct hci_delete_pipe_noti { | ||
| 69 | u8 pipe; | ||
| 70 | } __packed; | ||
| 71 | |||
| 72 | struct hci_all_pipe_cleared_noti { | ||
| 73 | u8 host; | ||
| 74 | } __packed; | ||
| 75 | |||
| 68 | #define NFC_HCI_FRAGMENT 0x7f | 76 | #define NFC_HCI_FRAGMENT 0x7f |
| 69 | 77 | ||
| 70 | #define HCP_HEADER(type, instr) ((((type) & 0x03) << 6) | ((instr) & 0x3f)) | 78 | #define HCP_HEADER(type, instr) ((((type) & 0x03) << 6) | ((instr) & 0x3f)) |
| @@ -77,8 +85,6 @@ int nfc_hci_hcp_message_tx(struct nfc_hci_dev *hdev, u8 pipe, | |||
| 77 | data_exchange_cb_t cb, void *cb_context, | 85 | data_exchange_cb_t cb, void *cb_context, |
| 78 | unsigned long completion_delay); | 86 | unsigned long completion_delay); |
| 79 | 87 | ||
| 80 | u8 nfc_hci_pipe2gate(struct nfc_hci_dev *hdev, u8 pipe); | ||
| 81 | |||
| 82 | void nfc_hci_hcp_message_rx(struct nfc_hci_dev *hdev, u8 pipe, u8 type, | 88 | void nfc_hci_hcp_message_rx(struct nfc_hci_dev *hdev, u8 pipe, u8 type, |
| 83 | u8 instruction, struct sk_buff *skb); | 89 | u8 instruction, struct sk_buff *skb); |
| 84 | 90 | ||
diff --git a/net/nfc/hci/hcp.c b/net/nfc/hci/hcp.c index e9de1514656e..1fe725d66085 100644 --- a/net/nfc/hci/hcp.c +++ b/net/nfc/hci/hcp.c | |||
| @@ -124,17 +124,6 @@ out_skb_err: | |||
| 124 | return err; | 124 | return err; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | u8 nfc_hci_pipe2gate(struct nfc_hci_dev *hdev, u8 pipe) | ||
| 128 | { | ||
| 129 | int gate; | ||
| 130 | |||
| 131 | for (gate = 0; gate < NFC_HCI_MAX_GATES; gate++) | ||
| 132 | if (hdev->gate2pipe[gate] == pipe) | ||
| 133 | return gate; | ||
| 134 | |||
| 135 | return 0xff; | ||
| 136 | } | ||
| 137 | |||
| 138 | /* | 127 | /* |
| 139 | * Receive hcp message for pipe, with type and cmd. | 128 | * Receive hcp message for pipe, with type and cmd. |
| 140 | * skb contains optional message data only. | 129 | * skb contains optional message data only. |
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index 7ca3d454ff3b..bf02fd5808c9 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c | |||
| @@ -212,7 +212,7 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 212 | tun_key->ipv4_dst, tun_key->ipv4_tos, | 212 | tun_key->ipv4_dst, tun_key->ipv4_tos, |
| 213 | tun_key->ipv4_ttl, df, sport, dport, | 213 | tun_key->ipv4_ttl, df, sport, dport, |
| 214 | tun_key->tun_flags, vni, opts_len, opts, | 214 | tun_key->tun_flags, vni, opts_len, opts, |
| 215 | false); | 215 | !!(tun_key->tun_flags & TUNNEL_CSUM), false); |
| 216 | if (err < 0) | 216 | if (err < 0) |
| 217 | ip_rt_put(rt); | 217 | ip_rt_put(rt); |
| 218 | return err; | 218 | return err; |
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 3cc983bf444a..ff07d4062d60 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c | |||
| @@ -74,7 +74,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, | |||
| 74 | __be64 key; | 74 | __be64 key; |
| 75 | __be16 flags; | 75 | __be16 flags; |
| 76 | 76 | ||
| 77 | flags = TUNNEL_KEY; | 77 | flags = TUNNEL_KEY | (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0); |
| 78 | vxlan_port = vxlan_vport(vport); | 78 | vxlan_port = vxlan_vport(vport); |
| 79 | if (vxlan_port->exts & VXLAN_F_GBP) | 79 | if (vxlan_port->exts & VXLAN_F_GBP) |
| 80 | flags |= TUNNEL_VXLAN_OPT; | 80 | flags |= TUNNEL_VXLAN_OPT; |
| @@ -230,6 +230,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 230 | __be16 src_port; | 230 | __be16 src_port; |
| 231 | __be16 df; | 231 | __be16 df; |
| 232 | int err; | 232 | int err; |
| 233 | u32 vxflags; | ||
| 233 | 234 | ||
| 234 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { | 235 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { |
| 235 | err = -EINVAL; | 236 | err = -EINVAL; |
| @@ -251,11 +252,13 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 251 | src_port = udp_flow_src_port(net, skb, 0, 0, true); | 252 | src_port = udp_flow_src_port(net, skb, 0, 0, true); |
| 252 | md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8); | 253 | md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8); |
| 253 | md.gbp = vxlan_ext_gbp(skb); | 254 | md.gbp = vxlan_ext_gbp(skb); |
| 255 | vxflags = vxlan_port->exts | | ||
| 256 | (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0); | ||
| 254 | 257 | ||
| 255 | err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst, | 258 | err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst, |
| 256 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, | 259 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, |
| 257 | src_port, dst_port, | 260 | src_port, dst_port, |
| 258 | &md, false, vxlan_port->exts); | 261 | &md, false, vxflags); |
| 259 | if (err < 0) | 262 | if (err < 0) |
| 260 | ip_rt_put(rt); | 263 | ip_rt_put(rt); |
| 261 | return err; | 264 | return err; |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 7a57f66e654a..899d0319f2b2 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
| @@ -713,7 +713,7 @@ config NET_ACT_BPF | |||
| 713 | config NET_ACT_CONNMARK | 713 | config NET_ACT_CONNMARK |
| 714 | tristate "Netfilter Connection Mark Retriever" | 714 | tristate "Netfilter Connection Mark Retriever" |
| 715 | depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES | 715 | depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES |
| 716 | depends on NF_CONNTRACK_MARK | 716 | depends on NF_CONNTRACK && NF_CONNTRACK_MARK |
| 717 | ---help--- | 717 | ---help--- |
| 718 | Say Y here to allow retrieving of conn mark | 718 | Say Y here to allow retrieving of conn mark |
| 719 | 719 | ||
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 9b05924cc386..2a50f5c62070 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * net/sched/sch_fq.c Fair Queue Packet Scheduler (per flow pacing) | 2 | * net/sched/sch_fq.c Fair Queue Packet Scheduler (per flow pacing) |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2013 Eric Dumazet <edumazet@google.com> | 4 | * Copyright (C) 2013-2015 Eric Dumazet <edumazet@google.com> |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
| @@ -471,7 +471,7 @@ begin: | |||
| 471 | goto out; | 471 | goto out; |
| 472 | 472 | ||
| 473 | rate = q->flow_max_rate; | 473 | rate = q->flow_max_rate; |
| 474 | if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT) | 474 | if (skb->sk) |
| 475 | rate = min(skb->sk->sk_pacing_rate, rate); | 475 | rate = min(skb->sk->sk_pacing_rate, rate); |
| 476 | 476 | ||
| 477 | if (rate != ~0U) { | 477 | if (rate != ~0U) { |
diff --git a/net/socket.c b/net/socket.c index 3acd35f144d6..3326d67482ac 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -613,13 +613,6 @@ EXPORT_SYMBOL(__sock_tx_timestamp); | |||
| 613 | static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, | 613 | static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, |
| 614 | struct msghdr *msg, size_t size) | 614 | struct msghdr *msg, size_t size) |
| 615 | { | 615 | { |
| 616 | struct sock_iocb *si = kiocb_to_siocb(iocb); | ||
| 617 | |||
| 618 | si->sock = sock; | ||
| 619 | si->scm = NULL; | ||
| 620 | si->msg = msg; | ||
| 621 | si->size = size; | ||
| 622 | |||
| 623 | return sock->ops->sendmsg(iocb, sock, msg, size); | 616 | return sock->ops->sendmsg(iocb, sock, msg, size); |
| 624 | } | 617 | } |
| 625 | 618 | ||
| @@ -635,11 +628,9 @@ static int do_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
| 635 | size_t size, bool nosec) | 628 | size_t size, bool nosec) |
| 636 | { | 629 | { |
| 637 | struct kiocb iocb; | 630 | struct kiocb iocb; |
| 638 | struct sock_iocb siocb; | ||
| 639 | int ret; | 631 | int ret; |
| 640 | 632 | ||
| 641 | init_sync_kiocb(&iocb, NULL); | 633 | init_sync_kiocb(&iocb, NULL); |
| 642 | iocb.private = &siocb; | ||
| 643 | ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : | 634 | ret = nosec ? __sock_sendmsg_nosec(&iocb, sock, msg, size) : |
| 644 | __sock_sendmsg(&iocb, sock, msg, size); | 635 | __sock_sendmsg(&iocb, sock, msg, size); |
| 645 | if (-EIOCBQUEUED == ret) | 636 | if (-EIOCBQUEUED == ret) |
| @@ -756,14 +747,6 @@ EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); | |||
| 756 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, | 747 | static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, |
| 757 | struct msghdr *msg, size_t size, int flags) | 748 | struct msghdr *msg, size_t size, int flags) |
| 758 | { | 749 | { |
| 759 | struct sock_iocb *si = kiocb_to_siocb(iocb); | ||
| 760 | |||
| 761 | si->sock = sock; | ||
| 762 | si->scm = NULL; | ||
| 763 | si->msg = msg; | ||
| 764 | si->size = size; | ||
| 765 | si->flags = flags; | ||
| 766 | |||
| 767 | return sock->ops->recvmsg(iocb, sock, msg, size, flags); | 750 | return sock->ops->recvmsg(iocb, sock, msg, size, flags); |
| 768 | } | 751 | } |
| 769 | 752 | ||
| @@ -779,11 +762,9 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg, | |||
| 779 | size_t size, int flags) | 762 | size_t size, int flags) |
| 780 | { | 763 | { |
| 781 | struct kiocb iocb; | 764 | struct kiocb iocb; |
| 782 | struct sock_iocb siocb; | ||
| 783 | int ret; | 765 | int ret; |
| 784 | 766 | ||
| 785 | init_sync_kiocb(&iocb, NULL); | 767 | init_sync_kiocb(&iocb, NULL); |
| 786 | iocb.private = &siocb; | ||
| 787 | ret = __sock_recvmsg(&iocb, sock, msg, size, flags); | 768 | ret = __sock_recvmsg(&iocb, sock, msg, size, flags); |
| 788 | if (-EIOCBQUEUED == ret) | 769 | if (-EIOCBQUEUED == ret) |
| 789 | ret = wait_on_sync_kiocb(&iocb); | 770 | ret = wait_on_sync_kiocb(&iocb); |
| @@ -795,11 +776,9 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, | |||
| 795 | size_t size, int flags) | 776 | size_t size, int flags) |
| 796 | { | 777 | { |
| 797 | struct kiocb iocb; | 778 | struct kiocb iocb; |
| 798 | struct sock_iocb siocb; | ||
| 799 | int ret; | 779 | int ret; |
| 800 | 780 | ||
| 801 | init_sync_kiocb(&iocb, NULL); | 781 | init_sync_kiocb(&iocb, NULL); |
| 802 | iocb.private = &siocb; | ||
| 803 | ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags); | 782 | ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags); |
| 804 | if (-EIOCBQUEUED == ret) | 783 | if (-EIOCBQUEUED == ret) |
| 805 | ret = wait_on_sync_kiocb(&iocb); | 784 | ret = wait_on_sync_kiocb(&iocb); |
| @@ -866,14 +845,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
| 866 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); | 845 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); |
| 867 | } | 846 | } |
| 868 | 847 | ||
| 869 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, | ||
| 870 | struct sock_iocb *siocb) | ||
| 871 | { | ||
| 872 | siocb->kiocb = iocb; | ||
| 873 | iocb->private = siocb; | ||
| 874 | return siocb; | ||
| 875 | } | ||
| 876 | |||
| 877 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | 848 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, |
| 878 | struct file *file, const struct iovec *iov, | 849 | struct file *file, const struct iovec *iov, |
| 879 | unsigned long nr_segs) | 850 | unsigned long nr_segs) |
| @@ -893,7 +864,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | |||
| 893 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | 864 | static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
| 894 | unsigned long nr_segs, loff_t pos) | 865 | unsigned long nr_segs, loff_t pos) |
| 895 | { | 866 | { |
| 896 | struct sock_iocb siocb, *x; | 867 | struct msghdr msg; |
| 897 | 868 | ||
| 898 | if (pos != 0) | 869 | if (pos != 0) |
| 899 | return -ESPIPE; | 870 | return -ESPIPE; |
| @@ -901,11 +872,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 901 | if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */ | 872 | if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */ |
| 902 | return 0; | 873 | return 0; |
| 903 | 874 | ||
| 904 | 875 | return do_sock_read(&msg, iocb, iocb->ki_filp, iov, nr_segs); | |
| 905 | x = alloc_sock_iocb(iocb, &siocb); | ||
| 906 | if (!x) | ||
| 907 | return -ENOMEM; | ||
| 908 | return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); | ||
| 909 | } | 876 | } |
| 910 | 877 | ||
| 911 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, | 878 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, |
| @@ -929,16 +896,12 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, | |||
| 929 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | 896 | static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, |
| 930 | unsigned long nr_segs, loff_t pos) | 897 | unsigned long nr_segs, loff_t pos) |
| 931 | { | 898 | { |
| 932 | struct sock_iocb siocb, *x; | 899 | struct msghdr msg; |
| 933 | 900 | ||
| 934 | if (pos != 0) | 901 | if (pos != 0) |
| 935 | return -ESPIPE; | 902 | return -ESPIPE; |
| 936 | 903 | ||
| 937 | x = alloc_sock_iocb(iocb, &siocb); | 904 | return do_sock_write(&msg, iocb, iocb->ki_filp, iov, nr_segs); |
| 938 | if (!x) | ||
| 939 | return -ENOMEM; | ||
| 940 | |||
| 941 | return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs); | ||
| 942 | } | 905 | } |
| 943 | 906 | ||
| 944 | /* | 907 | /* |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 8e1b10274b02..526b6edab018 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -1445,7 +1445,6 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, | |||
| 1445 | static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | 1445 | static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, |
| 1446 | struct msghdr *msg, size_t len) | 1446 | struct msghdr *msg, size_t len) |
| 1447 | { | 1447 | { |
| 1448 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
| 1449 | struct sock *sk = sock->sk; | 1448 | struct sock *sk = sock->sk; |
| 1450 | struct net *net = sock_net(sk); | 1449 | struct net *net = sock_net(sk); |
| 1451 | struct unix_sock *u = unix_sk(sk); | 1450 | struct unix_sock *u = unix_sk(sk); |
| @@ -1456,14 +1455,12 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1456 | unsigned int hash; | 1455 | unsigned int hash; |
| 1457 | struct sk_buff *skb; | 1456 | struct sk_buff *skb; |
| 1458 | long timeo; | 1457 | long timeo; |
| 1459 | struct scm_cookie tmp_scm; | 1458 | struct scm_cookie scm; |
| 1460 | int max_level; | 1459 | int max_level; |
| 1461 | int data_len = 0; | 1460 | int data_len = 0; |
| 1462 | 1461 | ||
| 1463 | if (NULL == siocb->scm) | ||
| 1464 | siocb->scm = &tmp_scm; | ||
| 1465 | wait_for_unix_gc(); | 1462 | wait_for_unix_gc(); |
| 1466 | err = scm_send(sock, msg, siocb->scm, false); | 1463 | err = scm_send(sock, msg, &scm, false); |
| 1467 | if (err < 0) | 1464 | if (err < 0) |
| 1468 | return err; | 1465 | return err; |
| 1469 | 1466 | ||
| @@ -1507,11 +1504,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1507 | if (skb == NULL) | 1504 | if (skb == NULL) |
| 1508 | goto out; | 1505 | goto out; |
| 1509 | 1506 | ||
| 1510 | err = unix_scm_to_skb(siocb->scm, skb, true); | 1507 | err = unix_scm_to_skb(&scm, skb, true); |
| 1511 | if (err < 0) | 1508 | if (err < 0) |
| 1512 | goto out_free; | 1509 | goto out_free; |
| 1513 | max_level = err + 1; | 1510 | max_level = err + 1; |
| 1514 | unix_get_secdata(siocb->scm, skb); | 1511 | unix_get_secdata(&scm, skb); |
| 1515 | 1512 | ||
| 1516 | skb_put(skb, len - data_len); | 1513 | skb_put(skb, len - data_len); |
| 1517 | skb->data_len = data_len; | 1514 | skb->data_len = data_len; |
| @@ -1606,7 +1603,7 @@ restart: | |||
| 1606 | unix_state_unlock(other); | 1603 | unix_state_unlock(other); |
| 1607 | other->sk_data_ready(other); | 1604 | other->sk_data_ready(other); |
| 1608 | sock_put(other); | 1605 | sock_put(other); |
| 1609 | scm_destroy(siocb->scm); | 1606 | scm_destroy(&scm); |
| 1610 | return len; | 1607 | return len; |
| 1611 | 1608 | ||
| 1612 | out_unlock: | 1609 | out_unlock: |
| @@ -1616,7 +1613,7 @@ out_free: | |||
| 1616 | out: | 1613 | out: |
| 1617 | if (other) | 1614 | if (other) |
| 1618 | sock_put(other); | 1615 | sock_put(other); |
| 1619 | scm_destroy(siocb->scm); | 1616 | scm_destroy(&scm); |
| 1620 | return err; | 1617 | return err; |
| 1621 | } | 1618 | } |
| 1622 | 1619 | ||
| @@ -1628,21 +1625,18 @@ out: | |||
| 1628 | static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | 1625 | static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, |
| 1629 | struct msghdr *msg, size_t len) | 1626 | struct msghdr *msg, size_t len) |
| 1630 | { | 1627 | { |
| 1631 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | ||
| 1632 | struct sock *sk = sock->sk; | 1628 | struct sock *sk = sock->sk; |
| 1633 | struct sock *other = NULL; | 1629 | struct sock *other = NULL; |
| 1634 | int err, size; | 1630 | int err, size; |
| 1635 | struct sk_buff *skb; | 1631 | struct sk_buff *skb; |
| 1636 | int sent = 0; | 1632 | int sent = 0; |
| 1637 | struct scm_cookie tmp_scm; | 1633 | struct scm_cookie scm; |
| 1638 | bool fds_sent = false; | 1634 | bool fds_sent = false; |
| 1639 | int max_level; | 1635 | int max_level; |
| 1640 | int data_len; | 1636 | int data_len; |
| 1641 | 1637 | ||
| 1642 | if (NULL == siocb->scm) | ||
| 1643 | siocb->scm = &tmp_scm; | ||
| 1644 | wait_for_unix_gc(); | 1638 | wait_for_unix_gc(); |
| 1645 | err = scm_send(sock, msg, siocb->scm, false); | 1639 | err = scm_send(sock, msg, &scm, false); |
| 1646 | if (err < 0) | 1640 | if (err < 0) |
| 1647 | return err; | 1641 | return err; |
| 1648 | 1642 | ||
| @@ -1683,7 +1677,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1683 | goto out_err; | 1677 | goto out_err; |
| 1684 | 1678 | ||
| 1685 | /* Only send the fds in the first buffer */ | 1679 | /* Only send the fds in the first buffer */ |
| 1686 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); | 1680 | err = unix_scm_to_skb(&scm, skb, !fds_sent); |
| 1687 | if (err < 0) { | 1681 | if (err < 0) { |
| 1688 | kfree_skb(skb); | 1682 | kfree_skb(skb); |
| 1689 | goto out_err; | 1683 | goto out_err; |
| @@ -1715,8 +1709,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1715 | sent += size; | 1709 | sent += size; |
| 1716 | } | 1710 | } |
| 1717 | 1711 | ||
| 1718 | scm_destroy(siocb->scm); | 1712 | scm_destroy(&scm); |
| 1719 | siocb->scm = NULL; | ||
| 1720 | 1713 | ||
| 1721 | return sent; | 1714 | return sent; |
| 1722 | 1715 | ||
| @@ -1728,8 +1721,7 @@ pipe_err: | |||
| 1728 | send_sig(SIGPIPE, current, 0); | 1721 | send_sig(SIGPIPE, current, 0); |
| 1729 | err = -EPIPE; | 1722 | err = -EPIPE; |
| 1730 | out_err: | 1723 | out_err: |
| 1731 | scm_destroy(siocb->scm); | 1724 | scm_destroy(&scm); |
| 1732 | siocb->scm = NULL; | ||
| 1733 | return sent ? : err; | 1725 | return sent ? : err; |
| 1734 | } | 1726 | } |
| 1735 | 1727 | ||
| @@ -1778,8 +1770,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1778 | struct msghdr *msg, size_t size, | 1770 | struct msghdr *msg, size_t size, |
| 1779 | int flags) | 1771 | int flags) |
| 1780 | { | 1772 | { |
| 1781 | struct sock_iocb *siocb = kiocb_to_siocb(iocb); | 1773 | struct scm_cookie scm; |
| 1782 | struct scm_cookie tmp_scm; | ||
| 1783 | struct sock *sk = sock->sk; | 1774 | struct sock *sk = sock->sk; |
| 1784 | struct unix_sock *u = unix_sk(sk); | 1775 | struct unix_sock *u = unix_sk(sk); |
| 1785 | int noblock = flags & MSG_DONTWAIT; | 1776 | int noblock = flags & MSG_DONTWAIT; |
| @@ -1831,16 +1822,14 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1831 | if (sock_flag(sk, SOCK_RCVTSTAMP)) | 1822 | if (sock_flag(sk, SOCK_RCVTSTAMP)) |
| 1832 | __sock_recv_timestamp(msg, sk, skb); | 1823 | __sock_recv_timestamp(msg, sk, skb); |
| 1833 | 1824 | ||
| 1834 | if (!siocb->scm) { | 1825 | memset(&scm, 0, sizeof(scm)); |
| 1835 | siocb->scm = &tmp_scm; | 1826 | |
| 1836 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1827 | scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
| 1837 | } | 1828 | unix_set_secdata(&scm, skb); |
| 1838 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); | ||
| 1839 | unix_set_secdata(siocb->scm, skb); | ||
| 1840 | 1829 | ||
| 1841 | if (!(flags & MSG_PEEK)) { | 1830 | if (!(flags & MSG_PEEK)) { |
| 1842 | if (UNIXCB(skb).fp) | 1831 | if (UNIXCB(skb).fp) |
| 1843 | unix_detach_fds(siocb->scm, skb); | 1832 | unix_detach_fds(&scm, skb); |
| 1844 | 1833 | ||
| 1845 | sk_peek_offset_bwd(sk, skb->len); | 1834 | sk_peek_offset_bwd(sk, skb->len); |
| 1846 | } else { | 1835 | } else { |
| @@ -1860,11 +1849,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1860 | sk_peek_offset_fwd(sk, size); | 1849 | sk_peek_offset_fwd(sk, size); |
| 1861 | 1850 | ||
| 1862 | if (UNIXCB(skb).fp) | 1851 | if (UNIXCB(skb).fp) |
| 1863 | siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); | 1852 | scm.fp = scm_fp_dup(UNIXCB(skb).fp); |
| 1864 | } | 1853 | } |
| 1865 | err = (flags & MSG_TRUNC) ? skb->len - skip : size; | 1854 | err = (flags & MSG_TRUNC) ? skb->len - skip : size; |
| 1866 | 1855 | ||
| 1867 | scm_recv(sock, msg, siocb->scm, flags); | 1856 | scm_recv(sock, msg, &scm, flags); |
| 1868 | 1857 | ||
| 1869 | out_free: | 1858 | out_free: |
| 1870 | skb_free_datagram(sk, skb); | 1859 | skb_free_datagram(sk, skb); |
| @@ -1915,8 +1904,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1915 | struct msghdr *msg, size_t size, | 1904 | struct msghdr *msg, size_t size, |
| 1916 | int flags) | 1905 | int flags) |
| 1917 | { | 1906 | { |
| 1918 | struct sock_iocb *siocb = kiocb_to_siocb(iocb); | 1907 | struct scm_cookie scm; |
| 1919 | struct scm_cookie tmp_scm; | ||
| 1920 | struct sock *sk = sock->sk; | 1908 | struct sock *sk = sock->sk; |
| 1921 | struct unix_sock *u = unix_sk(sk); | 1909 | struct unix_sock *u = unix_sk(sk); |
| 1922 | DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); | 1910 | DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name); |
| @@ -1943,10 +1931,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1943 | * while sleeps in memcpy_tomsg | 1931 | * while sleeps in memcpy_tomsg |
| 1944 | */ | 1932 | */ |
| 1945 | 1933 | ||
| 1946 | if (!siocb->scm) { | 1934 | memset(&scm, 0, sizeof(scm)); |
| 1947 | siocb->scm = &tmp_scm; | ||
| 1948 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | ||
| 1949 | } | ||
| 1950 | 1935 | ||
| 1951 | err = mutex_lock_interruptible(&u->readlock); | 1936 | err = mutex_lock_interruptible(&u->readlock); |
| 1952 | if (unlikely(err)) { | 1937 | if (unlikely(err)) { |
| @@ -2012,13 +1997,13 @@ again: | |||
| 2012 | 1997 | ||
| 2013 | if (check_creds) { | 1998 | if (check_creds) { |
| 2014 | /* Never glue messages from different writers */ | 1999 | /* Never glue messages from different writers */ |
| 2015 | if ((UNIXCB(skb).pid != siocb->scm->pid) || | 2000 | if ((UNIXCB(skb).pid != scm.pid) || |
| 2016 | !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) || | 2001 | !uid_eq(UNIXCB(skb).uid, scm.creds.uid) || |
| 2017 | !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid)) | 2002 | !gid_eq(UNIXCB(skb).gid, scm.creds.gid)) |
| 2018 | break; | 2003 | break; |
| 2019 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { | 2004 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { |
| 2020 | /* Copy credentials */ | 2005 | /* Copy credentials */ |
| 2021 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); | 2006 | scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
| 2022 | check_creds = 1; | 2007 | check_creds = 1; |
| 2023 | } | 2008 | } |
| 2024 | 2009 | ||
| @@ -2045,7 +2030,7 @@ again: | |||
| 2045 | sk_peek_offset_bwd(sk, chunk); | 2030 | sk_peek_offset_bwd(sk, chunk); |
| 2046 | 2031 | ||
| 2047 | if (UNIXCB(skb).fp) | 2032 | if (UNIXCB(skb).fp) |
| 2048 | unix_detach_fds(siocb->scm, skb); | 2033 | unix_detach_fds(&scm, skb); |
| 2049 | 2034 | ||
| 2050 | if (unix_skb_len(skb)) | 2035 | if (unix_skb_len(skb)) |
| 2051 | break; | 2036 | break; |
| @@ -2053,13 +2038,13 @@ again: | |||
| 2053 | skb_unlink(skb, &sk->sk_receive_queue); | 2038 | skb_unlink(skb, &sk->sk_receive_queue); |
| 2054 | consume_skb(skb); | 2039 | consume_skb(skb); |
| 2055 | 2040 | ||
| 2056 | if (siocb->scm->fp) | 2041 | if (scm.fp) |
| 2057 | break; | 2042 | break; |
| 2058 | } else { | 2043 | } else { |
| 2059 | /* It is questionable, see note in unix_dgram_recvmsg. | 2044 | /* It is questionable, see note in unix_dgram_recvmsg. |
| 2060 | */ | 2045 | */ |
| 2061 | if (UNIXCB(skb).fp) | 2046 | if (UNIXCB(skb).fp) |
| 2062 | siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); | 2047 | scm.fp = scm_fp_dup(UNIXCB(skb).fp); |
| 2063 | 2048 | ||
| 2064 | sk_peek_offset_fwd(sk, chunk); | 2049 | sk_peek_offset_fwd(sk, chunk); |
| 2065 | 2050 | ||
| @@ -2068,7 +2053,7 @@ again: | |||
| 2068 | } while (size); | 2053 | } while (size); |
| 2069 | 2054 | ||
| 2070 | mutex_unlock(&u->readlock); | 2055 | mutex_unlock(&u->readlock); |
| 2071 | scm_recv(sock, msg, siocb->scm, flags); | 2056 | scm_recv(sock, msg, &scm, flags); |
| 2072 | out: | 2057 | out: |
| 2073 | return copied ? : err; | 2058 | return copied ? : err; |
| 2074 | } | 2059 | } |
