rocker: add change MTU support
authorScott Feldman <sfeldma@gmail.com>
Wed, 8 Jul 2015 23:06:47 +0000 (16:06 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 Jul 2015 07:31:14 +0000 (00:31 -0700)
Implement ndo_change_mtu: on MTU change, reallocate Rx ring bufs and signal
HW of new port MTU value.

Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Tested-by: Simon Horman <simon.horman@netronome.com>
Acked-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/rocker/rocker.c
drivers/net/ethernet/rocker/rocker.h

index 2d8578cade03790782af7e97a1f59f9848301ae6..c0051673c9fad60d7cc5e53c821e4ea46e17de4a 100644 (file)
@@ -1817,6 +1817,30 @@ rocker_cmd_set_port_settings_macaddr_prep(const struct rocker_port *rocker_port,
        return 0;
 }
 
+static int
+rocker_cmd_set_port_settings_mtu_prep(const struct rocker_port *rocker_port,
+                                     struct rocker_desc_info *desc_info,
+                                     void *priv)
+{
+       int mtu = *(int *)priv;
+       struct rocker_tlv *cmd_info;
+
+       if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_TYPE,
+                              ROCKER_TLV_CMD_TYPE_SET_PORT_SETTINGS))
+               return -EMSGSIZE;
+       cmd_info = rocker_tlv_nest_start(desc_info, ROCKER_TLV_CMD_INFO);
+       if (!cmd_info)
+               return -EMSGSIZE;
+       if (rocker_tlv_put_u32(desc_info, ROCKER_TLV_CMD_PORT_SETTINGS_PPORT,
+                              rocker_port->pport))
+               return -EMSGSIZE;
+       if (rocker_tlv_put_u16(desc_info, ROCKER_TLV_CMD_PORT_SETTINGS_MTU,
+                              mtu))
+               return -EMSGSIZE;
+       rocker_tlv_nest_end(desc_info, cmd_info);
+       return 0;
+}
+
 static int
 rocker_cmd_set_port_learning_prep(const struct rocker_port *rocker_port,
                                  struct rocker_desc_info *desc_info,
@@ -1874,6 +1898,14 @@ static int rocker_cmd_set_port_settings_macaddr(struct rocker_port *rocker_port,
                               macaddr, NULL, NULL);
 }
 
+static int rocker_cmd_set_port_settings_mtu(struct rocker_port *rocker_port,
+                                           int mtu)
+{
+       return rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+                              rocker_cmd_set_port_settings_mtu_prep,
+                              &mtu, NULL, NULL);
+}
+
 static int rocker_port_set_learning(struct rocker_port *rocker_port,
                                    enum switchdev_trans trans)
 {
@@ -4152,6 +4184,34 @@ static int rocker_port_set_mac_address(struct net_device *dev, void *p)
        return 0;
 }
 
+static int rocker_port_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct rocker_port *rocker_port = netdev_priv(dev);
+       int running = netif_running(dev);
+       int err;
+
+#define ROCKER_PORT_MIN_MTU    68
+#define ROCKER_PORT_MAX_MTU    9000
+
+       if (new_mtu < ROCKER_PORT_MIN_MTU || new_mtu > ROCKER_PORT_MAX_MTU)
+               return -EINVAL;
+
+       if (running)
+               rocker_port_stop(dev);
+
+       netdev_info(dev, "MTU change from %d to %d\n", dev->mtu, new_mtu);
+       dev->mtu = new_mtu;
+
+       err = rocker_cmd_set_port_settings_mtu(rocker_port, new_mtu);
+       if (err)
+               return err;
+
+       if (running)
+               err = rocker_port_open(dev);
+
+       return err;
+}
+
 static int rocker_port_get_phys_port_name(struct net_device *dev,
                                          char *buf, size_t len)
 {
@@ -4172,6 +4232,7 @@ static const struct net_device_ops rocker_port_netdev_ops = {
        .ndo_stop                       = rocker_port_stop,
        .ndo_start_xmit                 = rocker_port_xmit,
        .ndo_set_mac_address            = rocker_port_set_mac_address,
+       .ndo_change_mtu                 = rocker_port_change_mtu,
        .ndo_bridge_getlink             = switchdev_port_bridge_getlink,
        .ndo_bridge_setlink             = switchdev_port_bridge_setlink,
        .ndo_bridge_dellink             = switchdev_port_bridge_dellink,
index c61fbf968036a3fe4a57f8afbef704bcffa37dc7..08b2c3d961887c65966013d6c077980d37955c32 100644 (file)
@@ -159,6 +159,7 @@ enum {
        ROCKER_TLV_CMD_PORT_SETTINGS_MODE,              /* u8 */
        ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING,          /* u8 */
        ROCKER_TLV_CMD_PORT_SETTINGS_PHYS_NAME,         /* binary */
+       ROCKER_TLV_CMD_PORT_SETTINGS_MTU,               /* u16 */
 
        __ROCKER_TLV_CMD_PORT_SETTINGS_MAX,
        ROCKER_TLV_CMD_PORT_SETTINGS_MAX =