Merge tag 'master-2014-12-15' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
authorDavid S. Miller <davem@davemloft.net>
Tue, 16 Dec 2014 20:16:48 +0000 (15:16 -0500)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 Dec 2014 20:16:48 +0000 (15:16 -0500)
John W. Linville says:

====================
pull request: wireless 2014-12-16

Please pull this batch of fixes intended for the 3.19 stream!

For the Bluetooth bits, Johan says:

"The patches consist of:

 - Coccinelle warning fix
 - hci_dev_lock/unlock fixes
 - Fixes for pending mgmt command handling
 - Fixes for properly following the force_lesc_support switch
 - Fix for a Microsoft branded Broadcom adapter
 - New device id for Atheros AR3012
 - Fix for BR/EDR Secure Connections enabling"

Along with that...

Brian Norris avoids leaking some kernel memory contents via printk in brcmsmac.

Julia Lawall corrects some misspellings in a few drivers.

Larry Finger gives us one more rtlwifi fix to correct a porting oversight.

Wei Yongjun fixes a sparse warning in rtlwifi.

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
20 files changed:
Documentation/networking/fib_trie.txt
drivers/net/dsa/Kconfig
drivers/net/ethernet/broadcom/Kconfig
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/cirrus/cs89x0.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/fw.h
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/smsc/Kconfig
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
drivers/net/macvtap.c
drivers/net/phy/Kconfig
drivers/net/phy/Makefile
drivers/net/phy/fixed.c [deleted file]
drivers/net/phy/fixed_phy.c [new file with mode: 0644]
drivers/net/tun.c
include/linux/phy_fixed.h
include/uapi/linux/if_tun.h
net/ipv4/ip_gre.c
net/rds/message.c

index 0723db7..fe71938 100644 (file)
@@ -73,8 +73,8 @@ trie_leaf_remove()
 
 trie_rebalance()
        The key function for the dynamic trie after any change in the trie
-       it is run to optimize and reorganize. Tt will walk the trie upwards 
-       towards the root from a given tnode, doing a resize() at each step 
+       it is run to optimize and reorganize. It will walk the trie upwards
+       towards the root from a given tnode, doing a resize() at each step
        to implement level compression.
 
 resize()
index 7cf8f4a..48e62a3 100644 (file)
@@ -59,7 +59,7 @@ config NET_DSA_BCM_SF2
        depends on HAS_IOMEM
        select NET_DSA
        select NET_DSA_TAG_BRCM
-       select FIXED_PHY if NET_DSA_BCM_SF2=y
+       select FIXED_PHY
        select BCM7XXX_PHY
        select MDIO_BCM_UNIMAC
        ---help---
index 888247a..41a3c98 100644 (file)
@@ -64,7 +64,7 @@ config BCMGENET
        tristate "Broadcom GENET internal MAC support"
        select MII
        select PHYLIB
-       select FIXED_PHY if BCMGENET=y
+       select FIXED_PHY
        select BCM7XXX_PHY
        help
          This driver supports the built-in Ethernet MACs found in the
@@ -155,7 +155,7 @@ config SYSTEMPORT
        depends on OF
        select MII
        select PHYLIB
-       select FIXED_PHY if SYSTEMPORT=y
+       select FIXED_PHY
        help
          This driver supports the built-in Ethernet MACs found in the
          Broadcom BCM7xxx Set Top Box family chipset using an internal
index 06dea3d..3767271 100644 (file)
@@ -2160,7 +2160,7 @@ static int __init macb_probe(struct platform_device *pdev)
        int err = -ENXIO;
        const char *mac;
        void __iomem *mem;
-       unsigned int hw_q, queue_mask, q, num_queues, q_irq = 0;
+       unsigned int hw_q, queue_mask, q, num_queues;
        struct clk *pclk, *hclk, *tx_clk;
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2235,11 +2235,11 @@ static int __init macb_probe(struct platform_device *pdev)
         * register mapping but we don't want to test the queue index then
         * compute the corresponding register offset at run time.
         */
-       for (hw_q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) {
+       for (hw_q = 0, q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) {
                if (!(queue_mask & (1 << hw_q)))
                        continue;
 
-               queue = &bp->queues[q_irq];
+               queue = &bp->queues[q];
                queue->bp = bp;
                if (hw_q) {
                        queue->ISR  = GEM_ISR(hw_q - 1);
@@ -2261,18 +2261,18 @@ static int __init macb_probe(struct platform_device *pdev)
                 * must remove the optional gaps that could exist in the
                 * hardware queue mask.
                 */
-               queue->irq = platform_get_irq(pdev, q_irq);
+               queue->irq = platform_get_irq(pdev, q);
                err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt,
                                       0, dev->name, queue);
                if (err) {
                        dev_err(&pdev->dev,
                                "Unable to request IRQ %d (error %d)\n",
                                queue->irq, err);
-                       goto err_out_free_irq;
+                       goto err_out_free_netdev;
                }
 
                INIT_WORK(&queue->tx_error_task, macb_tx_error_task);
-               q_irq++;
+               q++;
        }
        dev->irq = bp->queues[0].irq;
 
@@ -2350,7 +2350,7 @@ static int __init macb_probe(struct platform_device *pdev)
        err = register_netdev(dev);
        if (err) {
                dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
-               goto err_out_free_irq;
+               goto err_out_free_netdev;
        }
 
        err = macb_mii_init(bp);
@@ -2373,9 +2373,7 @@ static int __init macb_probe(struct platform_device *pdev)
 
 err_out_unregister_netdev:
        unregister_netdev(dev);
-err_out_free_irq:
-       for (q = 0, queue = bp->queues; q < q_irq; ++q, ++queue)
-               devm_free_irq(&pdev->dev, queue->irq, queue);
+err_out_free_netdev:
        free_netdev(dev);
 err_out_disable_clocks:
        if (!IS_ERR(tx_clk))
@@ -2392,8 +2390,6 @@ static int __exit macb_remove(struct platform_device *pdev)
 {
        struct net_device *dev;
        struct macb *bp;
-       struct macb_queue *queue;
-       unsigned int q;
 
        dev = platform_get_drvdata(pdev);
 
@@ -2405,14 +2401,11 @@ static int __exit macb_remove(struct platform_device *pdev)
                kfree(bp->mii_bus->irq);
                mdiobus_free(bp->mii_bus);
                unregister_netdev(dev);
-               queue = bp->queues;
-               for (q = 0; q < bp->num_queues; ++q, ++queue)
-                       devm_free_irq(&pdev->dev, queue->irq, queue);
-               free_netdev(dev);
                if (!IS_ERR(bp->tx_clk))
                        clk_disable_unprepare(bp->tx_clk);
                clk_disable_unprepare(bp->hclk);
                clk_disable_unprepare(bp->pclk);
+               free_netdev(dev);
        }
 
        return 0;
index b242792..d1c025f 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
+#include <linux/jiffies.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -238,13 +239,13 @@ writereg(struct net_device *dev, u16 regno, u16 value)
 static int __init
 wait_eeprom_ready(struct net_device *dev)
 {
-       int timeout = jiffies;
+       unsigned long timeout = jiffies;
        /* check to see if the EEPROM is ready,
         * a timeout is used just in case EEPROM is ready when
         * SI_BUSY in the PP_SelfST is clear
         */
        while (readreg(dev, PP_SelfST) & SI_BUSY)
-               if (jiffies - timeout >= 40)
+               if (time_after_eq(jiffies, timeout + 40))
                        return -1;
        return 0;
 }
@@ -485,7 +486,7 @@ control_dc_dc(struct net_device *dev, int on_not_off)
 {
        struct net_local *lp = netdev_priv(dev);
        unsigned int selfcontrol;
-       int timenow = jiffies;
+       unsigned long timenow = jiffies;
        /* control the DC to DC convertor in the SelfControl register.
         * Note: This is hooked up to a general purpose pin, might not
         * always be a DC to DC convertor.
@@ -499,7 +500,7 @@ control_dc_dc(struct net_device *dev, int on_not_off)
        writereg(dev, PP_SelfCTL, selfcontrol);
 
        /* Wait for the DC/DC converter to power up - 500ms */
-       while (jiffies - timenow < HZ)
+       while (time_before(jiffies, timenow + HZ))
                ;
 }
 
@@ -514,7 +515,7 @@ send_test_pkt(struct net_device *dev)
                0, 0,           /* DSAP=0 & SSAP=0 fields */
                0xf3, 0         /* Control (Test Req + P bit set) */
        };
-       long timenow = jiffies;
+       unsigned long timenow = jiffies;
 
        writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);
 
@@ -525,10 +526,10 @@ send_test_pkt(struct net_device *dev)
        iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT);
 
        /* Test to see if the chip has allocated memory for the packet */
-       while (jiffies - timenow < 5)
+       while (time_before(jiffies, timenow + 5))
                if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW)
                        break;
-       if (jiffies - timenow >= 5)
+       if (time_after_eq(jiffies, timenow + 5))
                return 0;       /* this shouldn't happen */
 
        /* Write the contents of the packet */
@@ -536,7 +537,7 @@ send_test_pkt(struct net_device *dev)
 
        cs89_dbg(1, debug, "Sending test packet ");
        /* wait a couple of jiffies for packet to be received */
-       for (timenow = jiffies; jiffies - timenow < 3;)
+       for (timenow = jiffies; time_before(jiffies, timenow + 3);)
                ;
        if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
                cs89_dbg(1, cont, "succeeded\n");
@@ -556,7 +557,7 @@ static int
 detect_tp(struct net_device *dev)
 {
        struct net_local *lp = netdev_priv(dev);
-       int timenow = jiffies;
+       unsigned long timenow = jiffies;
        int fdx;
 
        cs89_dbg(1, debug, "%s: Attempting TP\n", dev->name);
@@ -574,7 +575,7 @@ detect_tp(struct net_device *dev)
        /* Delay for the hardware to work out if the TP cable is present
         * - 150ms
         */
-       for (timenow = jiffies; jiffies - timenow < 15;)
+       for (timenow = jiffies; time_before(jiffies, timenow + 15);)
                ;
        if ((readreg(dev, PP_LineST) & LINK_OK) == 0)
                return DETECTED_NONE;
@@ -618,7 +619,7 @@ detect_tp(struct net_device *dev)
                if ((lp->auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
                        pr_info("%s: negotiating duplex...\n", dev->name);
                        while (readreg(dev, PP_AutoNegST) & AUTO_NEG_BUSY) {
-                               if (jiffies - timenow > 4000) {
+                               if (time_after(jiffies, timenow + 4000)) {
                                        pr_err("**** Full / half duplex auto-negotiation timed out ****\n");
                                        break;
                                }
@@ -1271,7 +1272,7 @@ static void __init reset_chip(struct net_device *dev)
 {
 #if !defined(CONFIG_MACH_MX31ADS)
        struct net_local *lp = netdev_priv(dev);
-       int reset_start_time;
+       unsigned long reset_start_time;
 
        writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
 
@@ -1294,7 +1295,7 @@ static void __init reset_chip(struct net_device *dev)
        /* Wait until the chip is reset */
        reset_start_time = jiffies;
        while ((readreg(dev, PP_SelfST) & INIT_DONE) == 0 &&
-              jiffies - reset_start_time < 2)
+              time_before(jiffies, reset_start_time + 2))
                ;
 #endif /* !CONFIG_MACH_MX31ADS */
 }
index ef3b95b..51807bb 100644 (file)
@@ -787,11 +787,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size))
                        field = 3;
                dev_cap->bf_regs_per_page = 1 << (field & 0x3f);
-               mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n",
-                        dev_cap->bf_reg_size, dev_cap->bf_regs_per_page);
        } else {
                dev_cap->bf_reg_size = 0;
-               mlx4_dbg(dev, "BlueFlame not available\n");
        }
 
        MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SG_SQ_OFFSET);
@@ -902,9 +899,6 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                        goto out;
        }
 
-       mlx4_dbg(dev, "Base MM extensions: flags %08x, rsvd L_Key %08x\n",
-                dev_cap->bmme_flags, dev_cap->reserved_lkey);
-
        /*
         * Each UAR has 4 EQ doorbells; so if a UAR is reserved, then
         * we can't use any EQs whose doorbell falls on that page,
@@ -916,6 +910,21 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        else
                dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SYS_EQS;
 
+out:
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+
+void mlx4_dev_cap_dump(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
+{
+       if (dev_cap->bf_reg_size > 0)
+               mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n",
+                        dev_cap->bf_reg_size, dev_cap->bf_regs_per_page);
+       else
+               mlx4_dbg(dev, "BlueFlame not available\n");
+
+       mlx4_dbg(dev, "Base MM extensions: flags %08x, rsvd L_Key %08x\n",
+                dev_cap->bmme_flags, dev_cap->reserved_lkey);
        mlx4_dbg(dev, "Max ICM size %lld MB\n",
                 (unsigned long long) dev_cap->max_icm_sz >> 20);
        mlx4_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n",
@@ -949,13 +958,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                 dev_cap->dmfs_high_rate_qpn_base);
        mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n",
                 dev_cap->dmfs_high_rate_qpn_range);
-
        dump_dev_cap_flags(dev, dev_cap->flags);
        dump_dev_cap_flags2(dev, dev_cap->flags2);
-
-out:
-       mlx4_free_cmd_mailbox(dev, mailbox);
-       return err;
 }
 
 int mlx4_QUERY_PORT(struct mlx4_dev *dev, int port, struct mlx4_port_cap *port_cap)
index 794e282..62562b6 100644 (file)
@@ -224,6 +224,7 @@ struct mlx4_set_ib_param {
        u32 cap_mask;
 };
 
+void mlx4_dev_cap_dump(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap);
 int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap);
 int mlx4_QUERY_PORT(struct mlx4_dev *dev, int port, struct mlx4_port_cap *port_cap);
 int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port,
index e25436b..b935bf3 100644 (file)
@@ -305,6 +305,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n");
                return err;
        }
+       mlx4_dev_cap_dump(dev, dev_cap);
 
        if (dev_cap->min_page_sz > PAGE_SIZE) {
                mlx4_err(dev, "HCA minimum page size of %d bigger than kernel PAGE_SIZE of %ld, aborting\n",
@@ -2488,41 +2489,42 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev,
                             u8 total_vfs, int existing_vfs)
 {
        u64 dev_flags = dev->flags;
+       int err = 0;
 
-       dev->dev_vfs = kzalloc(
-                       total_vfs * sizeof(*dev->dev_vfs),
-                       GFP_KERNEL);
+       atomic_inc(&pf_loading);
+       if (dev->flags &  MLX4_FLAG_SRIOV) {
+               if (existing_vfs != total_vfs) {
+                       mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n",
+                                existing_vfs, total_vfs);
+                       total_vfs = existing_vfs;
+               }
+       }
+
+       dev->dev_vfs = kzalloc(total_vfs * sizeof(*dev->dev_vfs), GFP_KERNEL);
        if (NULL == dev->dev_vfs) {
                mlx4_err(dev, "Failed to allocate memory for VFs\n");
                goto disable_sriov;
-       } else if (!(dev->flags &  MLX4_FLAG_SRIOV)) {
-               int err = 0;
-
-               atomic_inc(&pf_loading);
-               if (existing_vfs) {
-                       if (existing_vfs != total_vfs)
-                               mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n",
-                                        existing_vfs, total_vfs);
-               } else {
-                       mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs);
-                       err = pci_enable_sriov(pdev, total_vfs);
-               }
-               if (err) {
-                       mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n",
-                                err);
-                       atomic_dec(&pf_loading);
-                       goto disable_sriov;
-               } else {
-                       mlx4_warn(dev, "Running in master mode\n");
-                       dev_flags |= MLX4_FLAG_SRIOV |
-                               MLX4_FLAG_MASTER;
-                       dev_flags &= ~MLX4_FLAG_SLAVE;
-                       dev->num_vfs = total_vfs;
-               }
+       }
+
+       if (!(dev->flags &  MLX4_FLAG_SRIOV)) {
+               mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs);
+               err = pci_enable_sriov(pdev, total_vfs);
+       }
+       if (err) {
+               mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n",
+                        err);
+               goto disable_sriov;
+       } else {
+               mlx4_warn(dev, "Running in master mode\n");
+               dev_flags |= MLX4_FLAG_SRIOV |
+                       MLX4_FLAG_MASTER;
+               dev_flags &= ~MLX4_FLAG_SLAVE;
+               dev->num_vfs = total_vfs;
        }
        return dev_flags;
 
 disable_sriov:
+       atomic_dec(&pf_loading);
        dev->num_vfs = 0;
        kfree(dev->dev_vfs);
        return dev_flags & ~MLX4_FLAG_MASTER;
@@ -2606,8 +2608,10 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
                }
 
                if (total_vfs) {
-                       existing_vfs = pci_num_vf(pdev);
                        dev->flags = MLX4_FLAG_MASTER;
+                       existing_vfs = pci_num_vf(pdev);
+                       if (existing_vfs)
+                               dev->flags |= MLX4_FLAG_SRIOV;
                        dev->num_vfs = total_vfs;
                }
        }
@@ -2643,6 +2647,7 @@ slave_start:
        }
 
        if (mlx4_is_master(dev)) {
+               /* when we hit the goto slave_start below, dev_cap already initialized */
                if (!dev_cap) {
                        dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL);
 
@@ -2849,6 +2854,7 @@ slave_start:
        if (mlx4_is_master(dev) && dev->num_vfs)
                atomic_dec(&pf_loading);
 
+       kfree(dev_cap);
        return 0;
 
 err_port:
index 6279268..9468e64 100644 (file)
@@ -39,7 +39,7 @@ config SMC91X
        select CRC32
        select MII
        depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \
-                   MN10300 || COLDFIRE || ARM64 || XTENSA || NIOS2)
+                   MN10300 || COLDFIRE || ARM64 || XTENSA || NIOS2) && (!OF || GPIOLIB)
        ---help---
          This is a driver for SMC's 91x series of Ethernet chipsets,
          including the SMC91C94 and the SMC91C111. Say Y if you want it
index 0e13775..056b358 100644 (file)
@@ -309,16 +309,16 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
 
        if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
                const char *rs;
-               dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
 
                err = of_property_read_string(np, "st,tx-retime-src", &rs);
-               if (err < 0)
+               if (err < 0) {
                        dev_warn(dev, "Use internal clock source\n");
-
-               if (!strcasecmp(rs, "clk_125"))
+                       dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
+               } else if (!strcasecmp(rs, "clk_125")) {
                        dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
-               else if (!strcasecmp(rs, "txclk"))
+               } else if (!strcasecmp(rs, "txclk")) {
                        dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
+               }
 
                dwmac->speed = SPEED_1000;
        }
index 60f7ee5..7df2217 100644 (file)
@@ -46,16 +46,18 @@ struct macvtap_queue {
        struct list_head next;
 };
 
-#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_VNET_LE | IFF_MULTI_QUEUE)
+#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE)
+
+#define MACVTAP_VNET_LE 0x80000000
 
 static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
 {
-       return __virtio16_to_cpu(q->flags & IFF_VNET_LE, val);
+       return __virtio16_to_cpu(q->flags & MACVTAP_VNET_LE, val);
 }
 
 static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val)
 {
-       return __cpu_to_virtio16(q->flags & IFF_VNET_LE, val);
+       return __cpu_to_virtio16(q->flags & MACVTAP_VNET_LE, val);
 }
 
 static struct proto macvtap_proto = {
@@ -999,7 +1001,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
        void __user *argp = (void __user *)arg;
        struct ifreq __user *ifr = argp;
        unsigned int __user *up = argp;
-       unsigned int u;
+       unsigned short u;
        int __user *sp = argp;
        int s;
        int ret;
@@ -1014,7 +1016,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
                if ((u & ~MACVTAP_FEATURES) != (IFF_NO_PI | IFF_TAP))
                        ret = -EINVAL;
                else
-                       q->flags = u;
+                       q->flags = (q->flags & ~MACVTAP_FEATURES) | u;
 
                return ret;
 
@@ -1027,8 +1029,9 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
                }
 
                ret = 0;
+               u = q->flags;
                if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) ||
-                   put_user(q->flags, &ifr->ifr_flags))
+                   put_user(u, &ifr->ifr_flags))
                        ret = -EFAULT;
                macvtap_put_vlan(vlan);
                rtnl_unlock();
@@ -1069,6 +1072,21 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
                q->vnet_hdr_sz = s;
                return 0;
 
+       case TUNGETVNETLE:
+               s = !!(q->flags & MACVTAP_VNET_LE);
+               if (put_user(s, sp))
+                       return -EFAULT;
+               return 0;
+
+       case TUNSETVNETLE:
+               if (get_user(s, sp))
+                       return -EFAULT;
+               if (s)
+                       q->flags |= MACVTAP_VNET_LE;
+               else
+                       q->flags &= ~MACVTAP_VNET_LE;
+               return 0;
+
        case TUNSETOFFLOAD:
                /* let the user check for future flags */
                if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
index b4b0f80..a3c251b 100644 (file)
@@ -119,8 +119,8 @@ config MICREL_PHY
          Supports the KSZ9021, VSC8201, KS8001 PHYs.
 
 config FIXED_PHY
-       bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
-       depends on PHYLIB=y
+       tristate "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
+       depends on PHYLIB
        ---help---
          Adds the platform "fixed" MDIO Bus to cover the boards that use
          PHYs that are not connected to the real MDIO bus.
index eb3b18b..501ea76 100644 (file)
@@ -17,7 +17,7 @@ obj-$(CONFIG_BCM87XX_PHY)     += bcm87xx.o
 obj-$(CONFIG_ICPLUS_PHY)       += icplus.o
 obj-$(CONFIG_REALTEK_PHY)      += realtek.o
 obj-$(CONFIG_LSI_ET1011C_PHY)  += et1011c.o
-obj-$(CONFIG_FIXED_PHY)                += fixed.o
+obj-$(CONFIG_FIXED_PHY)                += fixed_phy.o
 obj-$(CONFIG_MDIO_BITBANG)     += mdio-bitbang.o
 obj-$(CONFIG_MDIO_GPIO)                += mdio-gpio.o
 obj-$(CONFIG_NATIONAL_PHY)     += national.o
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
deleted file mode 100644 (file)
index 3ad0e6e..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
- *
- * Author: Vitaly Bordug <vbordug@ru.mvista.com>
- *         Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * Copyright (c) 2006-2007 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/list.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/phy_fixed.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-
-#define MII_REGS_NUM 29
-
-struct fixed_mdio_bus {
-       int irqs[PHY_MAX_ADDR];
-       struct mii_bus *mii_bus;
-       struct list_head phys;
-};
-
-struct fixed_phy {
-       int addr;
-       u16 regs[MII_REGS_NUM];
-       struct phy_device *phydev;
-       struct fixed_phy_status status;
-       int (*link_update)(struct net_device *, struct fixed_phy_status *);
-       struct list_head node;
-};
-
-static struct platform_device *pdev;
-static struct fixed_mdio_bus platform_fmb = {
-       .phys = LIST_HEAD_INIT(platform_fmb.phys),
-};
-
-static int fixed_phy_update_regs(struct fixed_phy *fp)
-{
-       u16 bmsr = BMSR_ANEGCAPABLE;
-       u16 bmcr = 0;
-       u16 lpagb = 0;
-       u16 lpa = 0;
-
-       if (fp->status.duplex) {
-               bmcr |= BMCR_FULLDPLX;
-
-               switch (fp->status.speed) {
-               case 1000:
-                       bmsr |= BMSR_ESTATEN;
-                       bmcr |= BMCR_SPEED1000;
-                       lpagb |= LPA_1000FULL;
-                       break;
-               case 100:
-                       bmsr |= BMSR_100FULL;
-                       bmcr |= BMCR_SPEED100;
-                       lpa |= LPA_100FULL;
-                       break;
-               case 10:
-                       bmsr |= BMSR_10FULL;
-                       lpa |= LPA_10FULL;
-                       break;
-               default:
-                       pr_warn("fixed phy: unknown speed\n");
-                       return -EINVAL;
-               }
-       } else {
-               switch (fp->status.speed) {
-               case 1000:
-                       bmsr |= BMSR_ESTATEN;
-                       bmcr |= BMCR_SPEED1000;
-                       lpagb |= LPA_1000HALF;
-                       break;
-               case 100:
-                       bmsr |= BMSR_100HALF;
-                       bmcr |= BMCR_SPEED100;
-                       lpa |= LPA_100HALF;
-                       break;
-               case 10:
-                       bmsr |= BMSR_10HALF;
-                       lpa |= LPA_10HALF;
-                       break;
-               default:
-                       pr_warn("fixed phy: unknown speed\n");
-                       return -EINVAL;
-               }
-       }
-
-       if (fp->status.link)
-               bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
-
-       if (fp->status.pause)
-               lpa |= LPA_PAUSE_CAP;
-
-       if (fp->status.asym_pause)
-               lpa |= LPA_PAUSE_ASYM;
-
-       fp->regs[MII_PHYSID1] = 0;
-       fp->regs[MII_PHYSID2] = 0;
-
-       fp->regs[MII_BMSR] = bmsr;
-       fp->regs[MII_BMCR] = bmcr;
-       fp->regs[MII_LPA] = lpa;
-       fp->regs[MII_STAT1000] = lpagb;
-
-       return 0;
-}
-
-static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
-{
-       struct fixed_mdio_bus *fmb = bus->priv;
-       struct fixed_phy *fp;
-
-       if (reg_num >= MII_REGS_NUM)
-               return -1;
-
-       /* We do not support emulating Clause 45 over Clause 22 register reads
-        * return an error instead of bogus data.
-        */
-       switch (reg_num) {
-       case MII_MMD_CTRL:
-       case MII_MMD_DATA:
-               return -1;
-       default:
-               break;
-       }
-
-       list_for_each_entry(fp, &fmb->phys, node) {
-               if (fp->addr == phy_addr) {
-                       /* Issue callback if user registered it. */
-                       if (fp->link_update) {
-                               fp->link_update(fp->phydev->attached_dev,
-                                               &fp->status);
-                               fixed_phy_update_regs(fp);
-                       }
-                       return fp->regs[reg_num];
-               }
-       }
-
-       return 0xFFFF;
-}
-
-static int fixed_mdio_write(struct mii_bus *bus, int phy_addr, int reg_num,
-                           u16 val)
-{
-       return 0;
-}
-
-/*
- * If something weird is required to be done with link/speed,
- * network driver is able to assign a function to implement this.
- * May be useful for PHY's that need to be software-driven.
- */
-int fixed_phy_set_link_update(struct phy_device *phydev,
-                             int (*link_update)(struct net_device *,
-                                                struct fixed_phy_status *))
-{
-       struct fixed_mdio_bus *fmb = &platform_fmb;
-       struct fixed_phy *fp;
-
-       if (!link_update || !phydev || !phydev->bus)
-               return -EINVAL;
-
-       list_for_each_entry(fp, &fmb->phys, node) {
-               if (fp->addr == phydev->addr) {
-                       fp->link_update = link_update;
-                       fp->phydev = phydev;
-                       return 0;
-               }
-       }
-
-       return -ENOENT;
-}
-EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
-
-int fixed_phy_add(unsigned int irq, int phy_addr,
-                 struct fixed_phy_status *status)
-{
-       int ret;
-       struct fixed_mdio_bus *fmb = &platform_fmb;
-       struct fixed_phy *fp;
-
-       fp = kzalloc(sizeof(*fp), GFP_KERNEL);
-       if (!fp)
-               return -ENOMEM;
-
-       memset(fp->regs, 0xFF,  sizeof(fp->regs[0]) * MII_REGS_NUM);
-
-       fmb->irqs[phy_addr] = irq;
-
-       fp->addr = phy_addr;
-       fp->status = *status;
-
-       ret = fixed_phy_update_regs(fp);
-       if (ret)
-               goto err_regs;
-
-       list_add_tail(&fp->node, &fmb->phys);
-
-       return 0;
-
-err_regs:
-       kfree(fp);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(fixed_phy_add);
-
-void fixed_phy_del(int phy_addr)
-{
-       struct fixed_mdio_bus *fmb = &platform_fmb;
-       struct fixed_phy *fp, *tmp;
-
-       list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
-               if (fp->addr == phy_addr) {
-                       list_del(&fp->node);
-                       kfree(fp);
-                       return;
-               }
-       }
-}
-EXPORT_SYMBOL_GPL(fixed_phy_del);
-
-static int phy_fixed_addr;
-static DEFINE_SPINLOCK(phy_fixed_addr_lock);
-
-struct phy_device *fixed_phy_register(unsigned int irq,
-                                     struct fixed_phy_status *status,
-                                     struct device_node *np)
-{
-       struct fixed_mdio_bus *fmb = &platform_fmb;
-       struct phy_device *phy;
-       int phy_addr;
-       int ret;
-
-       /* Get the next available PHY address, up to PHY_MAX_ADDR */
-       spin_lock(&phy_fixed_addr_lock);
-       if (phy_fixed_addr == PHY_MAX_ADDR) {
-               spin_unlock(&phy_fixed_addr_lock);
-               return ERR_PTR(-ENOSPC);
-       }
-       phy_addr = phy_fixed_addr++;
-       spin_unlock(&phy_fixed_addr_lock);
-
-       ret = fixed_phy_add(PHY_POLL, phy_addr, status);
-       if (ret < 0)
-               return ERR_PTR(ret);
-
-       phy = get_phy_device(fmb->mii_bus, phy_addr, false);
-       if (!phy || IS_ERR(phy)) {
-               fixed_phy_del(phy_addr);
-               return ERR_PTR(-EINVAL);
-       }
-
-       of_node_get(np);
-       phy->dev.of_node = np;
-
-       ret = phy_device_register(phy);
-       if (ret) {
-               phy_device_free(phy);
-               of_node_put(np);
-               fixed_phy_del(phy_addr);
-               return ERR_PTR(ret);
-       }
-
-       return phy;
-}
-EXPORT_SYMBOL_GPL(fixed_phy_register);
-
-static int __init fixed_mdio_bus_init(void)
-{
-       struct fixed_mdio_bus *fmb = &platform_fmb;
-       int ret;
-
-       pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
-       if (IS_ERR(pdev)) {
-               ret = PTR_ERR(pdev);
-               goto err_pdev;
-       }
-
-       fmb->mii_bus = mdiobus_alloc();
-       if (fmb->mii_bus == NULL) {
-               ret = -ENOMEM;
-               goto err_mdiobus_reg;
-       }
-
-       snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
-       fmb->mii_bus->name = "Fixed MDIO Bus";
-       fmb->mii_bus->priv = fmb;
-       fmb->mii_bus->parent = &pdev->dev;
-       fmb->mii_bus->read = &fixed_mdio_read;
-       fmb->mii_bus->write = &fixed_mdio_write;
-       fmb->mii_bus->irq = fmb->irqs;
-
-       ret = mdiobus_register(fmb->mii_bus);
-       if (ret)
-               goto err_mdiobus_alloc;
-
-       return 0;
-
-err_mdiobus_alloc:
-       mdiobus_free(fmb->mii_bus);
-err_mdiobus_reg:
-       platform_device_unregister(pdev);
-err_pdev:
-       return ret;
-}
-module_init(fixed_mdio_bus_init);
-
-static void __exit fixed_mdio_bus_exit(void)
-{
-       struct fixed_mdio_bus *fmb = &platform_fmb;
-       struct fixed_phy *fp, *tmp;
-
-       mdiobus_unregister(fmb->mii_bus);
-       mdiobus_free(fmb->mii_bus);
-       platform_device_unregister(pdev);
-
-       list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
-               list_del(&fp->node);
-               kfree(fp);
-       }
-}
-module_exit(fixed_mdio_bus_exit);
-
-MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
-MODULE_AUTHOR("Vitaly Bordug");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c
new file mode 100644 (file)
index 0000000..3ad0e6e
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
+ *
+ * Author: Vitaly Bordug <vbordug@ru.mvista.com>
+ *         Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * Copyright (c) 2006-2007 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#define MII_REGS_NUM 29
+
+struct fixed_mdio_bus {
+       int irqs[PHY_MAX_ADDR];
+       struct mii_bus *mii_bus;
+       struct list_head phys;
+};
+
+struct fixed_phy {
+       int addr;
+       u16 regs[MII_REGS_NUM];
+       struct phy_device *phydev;
+       struct fixed_phy_status status;
+       int (*link_update)(struct net_device *, struct fixed_phy_status *);
+       struct list_head node;
+};
+
+static struct platform_device *pdev;
+static struct fixed_mdio_bus platform_fmb = {
+       .phys = LIST_HEAD_INIT(platform_fmb.phys),
+};
+
+static int fixed_phy_update_regs(struct fixed_phy *fp)
+{
+       u16 bmsr = BMSR_ANEGCAPABLE;
+       u16 bmcr = 0;
+       u16 lpagb = 0;
+       u16 lpa = 0;
+
+       if (fp->status.duplex) {
+               bmcr |= BMCR_FULLDPLX;
+
+               switch (fp->status.speed) {
+               case 1000:
+                       bmsr |= BMSR_ESTATEN;
+                       bmcr |= BMCR_SPEED1000;
+                       lpagb |= LPA_1000FULL;
+                       break;
+               case 100:
+                       bmsr |= BMSR_100FULL;
+                       bmcr |= BMCR_SPEED100;
+                       lpa |= LPA_100FULL;
+                       break;
+               case 10:
+                       bmsr |= BMSR_10FULL;
+                       lpa |= LPA_10FULL;
+                       break;
+               default:
+                       pr_warn("fixed phy: unknown speed\n");
+                       return -EINVAL;
+               }
+       } else {
+               switch (fp->status.speed) {
+               case 1000:
+                       bmsr |= BMSR_ESTATEN;
+                       bmcr |= BMCR_SPEED1000;
+                       lpagb |= LPA_1000HALF;
+                       break;
+               case 100:
+                       bmsr |= BMSR_100HALF;
+                       bmcr |= BMCR_SPEED100;
+                       lpa |= LPA_100HALF;
+                       break;
+               case 10:
+                       bmsr |= BMSR_10HALF;
+                       lpa |= LPA_10HALF;
+                       break;
+               default:
+                       pr_warn("fixed phy: unknown speed\n");
+                       return -EINVAL;
+               }
+       }
+
+       if (fp->status.link)
+               bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
+
+       if (fp->status.pause)
+               lpa |= LPA_PAUSE_CAP;
+
+       if (fp->status.asym_pause)
+               lpa |= LPA_PAUSE_ASYM;
+
+       fp->regs[MII_PHYSID1] = 0;
+       fp->regs[MII_PHYSID2] = 0;
+
+       fp->regs[MII_BMSR] = bmsr;
+       fp->regs[MII_BMCR] = bmcr;
+       fp->regs[MII_LPA] = lpa;
+       fp->regs[MII_STAT1000] = lpagb;
+
+       return 0;
+}
+
+static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
+{
+       struct fixed_mdio_bus *fmb = bus->priv;
+       struct fixed_phy *fp;
+
+       if (reg_num >= MII_REGS_NUM)
+               return -1;
+
+       /* We do not support emulating Clause 45 over Clause 22 register reads
+        * return an error instead of bogus data.
+        */
+       switch (reg_num) {
+       case MII_MMD_CTRL:
+       case MII_MMD_DATA:
+               return -1;
+       default:
+               break;
+       }
+
+       list_for_each_entry(fp, &fmb->phys, node) {
+               if (fp->addr == phy_addr) {
+                       /* Issue callback if user registered it. */
+                       if (fp->link_update) {
+                               fp->link_update(fp->phydev->attached_dev,
+                                               &fp->status);
+                               fixed_phy_update_regs(fp);
+                       }
+                       return fp->regs[reg_num];
+               }
+       }
+
+       return 0xFFFF;
+}
+
+static int fixed_mdio_write(struct mii_bus *bus, int phy_addr, int reg_num,
+                           u16 val)
+{
+       return 0;
+}
+
+/*
+ * If something weird is required to be done with link/speed,
+ * network driver is able to assign a function to implement this.
+ * May be useful for PHY's that need to be software-driven.
+ */
+int fixed_phy_set_link_update(struct phy_device *phydev,
+                             int (*link_update)(struct net_device *,
+                                                struct fixed_phy_status *))
+{
+       struct fixed_mdio_bus *fmb = &platform_fmb;
+       struct fixed_phy *fp;
+
+       if (!link_update || !phydev || !phydev->bus)
+               return -EINVAL;
+
+       list_for_each_entry(fp, &fmb->phys, node) {
+               if (fp->addr == phydev->addr) {
+                       fp->link_update = link_update;
+                       fp->phydev = phydev;
+                       return 0;
+               }
+       }
+
+       return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
+
+int fixed_phy_add(unsigned int irq, int phy_addr,
+                 struct fixed_phy_status *status)
+{
+       int ret;
+       struct fixed_mdio_bus *fmb = &platform_fmb;
+       struct fixed_phy *fp;
+
+       fp = kzalloc(sizeof(*fp), GFP_KERNEL);
+       if (!fp)
+               return -ENOMEM;
+
+       memset(fp->regs, 0xFF,  sizeof(fp->regs[0]) * MII_REGS_NUM);
+
+       fmb->irqs[phy_addr] = irq;
+
+       fp->addr = phy_addr;
+       fp->status = *status;
+
+       ret = fixed_phy_update_regs(fp);
+       if (ret)
+               goto err_regs;
+
+       list_add_tail(&fp->node, &fmb->phys);
+
+       return 0;
+
+err_regs:
+       kfree(fp);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(fixed_phy_add);
+
+void fixed_phy_del(int phy_addr)
+{
+       struct fixed_mdio_bus *fmb = &platform_fmb;
+       struct fixed_phy *fp, *tmp;
+
+       list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
+               if (fp->addr == phy_addr) {
+                       list_del(&fp->node);
+                       kfree(fp);
+                       return;
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(fixed_phy_del);
+
+static int phy_fixed_addr;
+static DEFINE_SPINLOCK(phy_fixed_addr_lock);
+
+struct phy_device *fixed_phy_register(unsigned int irq,
+                                     struct fixed_phy_status *status,
+                                     struct device_node *np)
+{
+       struct fixed_mdio_bus *fmb = &platform_fmb;
+       struct phy_device *phy;
+       int phy_addr;
+       int ret;
+
+       /* Get the next available PHY address, up to PHY_MAX_ADDR */
+       spin_lock(&phy_fixed_addr_lock);
+       if (phy_fixed_addr == PHY_MAX_ADDR) {
+               spin_unlock(&phy_fixed_addr_lock);
+               return ERR_PTR(-ENOSPC);
+       }
+       phy_addr = phy_fixed_addr++;
+       spin_unlock(&phy_fixed_addr_lock);
+
+       ret = fixed_phy_add(PHY_POLL, phy_addr, status);
+       if (ret < 0)
+               return ERR_PTR(ret);
+
+       phy = get_phy_device(fmb->mii_bus, phy_addr, false);
+       if (!phy || IS_ERR(phy)) {
+               fixed_phy_del(phy_addr);
+               return ERR_PTR(-EINVAL);
+       }
+
+       of_node_get(np);
+       phy->dev.of_node = np;
+
+       ret = phy_device_register(phy);
+       if (ret) {
+               phy_device_free(phy);
+               of_node_put(np);
+               fixed_phy_del(phy_addr);
+               return ERR_PTR(ret);
+       }
+
+       return phy;
+}
+EXPORT_SYMBOL_GPL(fixed_phy_register);
+
+static int __init fixed_mdio_bus_init(void)
+{
+       struct fixed_mdio_bus *fmb = &platform_fmb;
+       int ret;
+
+       pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
+       if (IS_ERR(pdev)) {
+               ret = PTR_ERR(pdev);
+               goto err_pdev;
+       }
+
+       fmb->mii_bus = mdiobus_alloc();
+       if (fmb->mii_bus == NULL) {
+               ret = -ENOMEM;
+               goto err_mdiobus_reg;
+       }
+
+       snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
+       fmb->mii_bus->name = "Fixed MDIO Bus";
+       fmb->mii_bus->priv = fmb;
+       fmb->mii_bus->parent = &pdev->dev;
+       fmb->mii_bus->read = &fixed_mdio_read;
+       fmb->mii_bus->write = &fixed_mdio_write;
+       fmb->mii_bus->irq = fmb->irqs;
+
+       ret = mdiobus_register(fmb->mii_bus);
+       if (ret)
+               goto err_mdiobus_alloc;
+
+       return 0;
+
+err_mdiobus_alloc:
+       mdiobus_free(fmb->mii_bus);
+err_mdiobus_reg:
+       platform_device_unregister(pdev);
+err_pdev:
+       return ret;
+}
+module_init(fixed_mdio_bus_init);
+
+static void __exit fixed_mdio_bus_exit(void)
+{
+       struct fixed_mdio_bus *fmb = &platform_fmb;
+       struct fixed_phy *fp, *tmp;
+
+       mdiobus_unregister(fmb->mii_bus);
+       mdiobus_free(fmb->mii_bus);
+       platform_device_unregister(pdev);
+
+       list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
+               list_del(&fp->node);
+               kfree(fp);
+       }
+}
+module_exit(fixed_mdio_bus_exit);
+
+MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
+MODULE_AUTHOR("Vitaly Bordug");
+MODULE_LICENSE("GPL");
index a5cbf67..8c8dc16 100644 (file)
@@ -110,9 +110,11 @@ do {                                                               \
  * overload it to mean fasync when stored there.
  */
 #define TUN_FASYNC     IFF_ATTACH_QUEUE
+/* High bits in flags field are unused. */
+#define TUN_VNET_LE     0x80000000
 
 #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \
-                     IFF_VNET_LE | IFF_MULTI_QUEUE)
+                     IFF_MULTI_QUEUE)
 #define GOODCOPY_LEN 128
 
 #define FLT_EXACT_COUNT 8
@@ -208,12 +210,12 @@ struct tun_struct {
 
 static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
 {
-       return __virtio16_to_cpu(tun->flags & IFF_VNET_LE, val);
+       return __virtio16_to_cpu(tun->flags & TUN_VNET_LE, val);
 }
 
 static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val)
 {
-       return __cpu_to_virtio16(tun->flags & IFF_VNET_LE, val);
+       return __cpu_to_virtio16(tun->flags & TUN_VNET_LE, val);
 }
 
 static inline u32 tun_hashfn(u32 rxhash)
@@ -1843,6 +1845,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
        int sndbuf;
        int vnet_hdr_sz;
        unsigned int ifindex;
+       int le;
        int ret;
 
        if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) {
@@ -2042,6 +2045,23 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
                tun->vnet_hdr_sz = vnet_hdr_sz;
                break;
 
+       case TUNGETVNETLE:
+               le = !!(tun->flags & TUN_VNET_LE);
+               if (put_user(le, (int __user *)argp))
+                       ret = -EFAULT;
+               break;
+
+       case TUNSETVNETLE:
+               if (get_user(le, (int __user *)argp)) {
+                       ret = -EFAULT;
+                       break;
+               }
+               if (le)
+                       tun->flags |= TUN_VNET_LE;
+               else
+                       tun->flags &= ~TUN_VNET_LE;
+               break;
+
        case TUNATTACHFILTER:
                /* Can be set only for TAPs */
                ret = -EINVAL;
index f2ca1b4..7e75bfe 100644 (file)
@@ -11,7 +11,7 @@ struct fixed_phy_status {
 
 struct device_node;
 
-#ifdef CONFIG_FIXED_PHY
+#if IS_ENABLED(CONFIG_FIXED_PHY)
 extern int fixed_phy_add(unsigned int irq, int phy_id,
                         struct fixed_phy_status *status);
 extern struct phy_device *fixed_phy_register(unsigned int irq,
index 18b2403..50ae243 100644 (file)
@@ -48,6 +48,8 @@
 #define TUNSETQUEUE  _IOW('T', 217, int)
 #define TUNSETIFINDEX  _IOW('T', 218, unsigned int)
 #define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
+#define TUNSETVNETLE _IOW('T', 220, int)
+#define TUNGETVNETLE _IOR('T', 221, int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN                0x0001
@@ -57,7 +59,6 @@
 #define IFF_ONE_QUEUE  0x2000
 #define IFF_VNET_HDR   0x4000
 #define IFF_TUN_EXCL   0x8000
-#define IFF_VNET_LE    0x10000
 #define IFF_MULTI_QUEUE 0x0100
 #define IFF_ATTACH_QUEUE 0x0200
 #define IFF_DETACH_QUEUE 0x0400
index ac84912..4f4bf5b 100644 (file)
@@ -252,10 +252,6 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
        struct ip_tunnel *tunnel = netdev_priv(dev);
        const struct iphdr *tnl_params;
 
-       skb = gre_handle_offloads(skb, !!(tunnel->parms.o_flags&TUNNEL_CSUM));
-       if (IS_ERR(skb))
-               goto out;
-
        if (dev->header_ops) {
                /* Need space for new headers */
                if (skb_cow_head(skb, dev->needed_headroom -
@@ -268,6 +264,7 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
                 * to gre header.
                 */
                skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
+               skb_reset_mac_header(skb);
        } else {
                if (skb_cow_head(skb, dev->needed_headroom))
                        goto free_skb;
@@ -275,6 +272,10 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
                tnl_params = &tunnel->parms.iph;
        }
 
+       skb = gre_handle_offloads(skb, !!(tunnel->parms.o_flags&TUNNEL_CSUM));
+       if (IS_ERR(skb))
+               goto out;
+
        __gre_xmit(skb, dev, tnl_params, skb->protocol);
 
        return NETDEV_TX_OK;
index ff22022..5a21e6f 100644 (file)
@@ -325,7 +325,8 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
        copied = 0;
 
        while (iov_iter_count(to) && copied < len) {
-               to_copy = min(iov_iter_count(to), sg->length - vec_off);
+               to_copy = min_t(unsigned long, iov_iter_count(to),
+                               sg->length - vec_off);
                to_copy = min_t(unsigned long, to_copy, len - copied);
 
                rds_stats_add(s_copy_to_user, to_copy);