net/mlx4_core: set port QoS attributes
authorAmir Vadai <amirv@mellanox.com>
Wed, 4 Apr 2012 21:33:25 +0000 (21:33 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 5 Apr 2012 09:08:03 +0000 (05:08 -0400)
Adding QoS firmware commands:
- mlx4_en_SET_PORT_PRIO2TC - set UP <=> TC
- mlx4_en_SET_PORT_SCHEDULER - set promised BW, max BW and PG number

Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/en_port.h
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/port.c
include/linux/mlx4/cmd.h
include/linux/mlx4/device.h

index 6934fd7e66ed766c987aff56ffbe6661e5667b3f..745090b49d9efe2792ec010314752473f697eb11 100644 (file)
@@ -39,6 +39,8 @@
 #define SET_PORT_PROMISC_SHIFT 31
 #define SET_PORT_MC_PROMISC_SHIFT      30
 
+#define MLX4_EN_NUM_TC         8
+
 #define VLAN_FLTR_SIZE 128
 struct mlx4_set_vlan_fltr_mbox {
        __be32 entry[VLAN_FLTR_SIZE];
index 2a0ff2cc7182e02bdc69373d3cb0fd3cd32ad1ab..cd56f1aea4b505aad5545b515c534dffe6bef1f1 100644 (file)
 #define DRV_VERSION    "1.1"
 #define DRV_RELDATE    "Dec, 2011"
 
+#define MLX4_NUM_UP            8
+#define MLX4_NUM_TC            8
+#define MLX4_RATELIMIT_UNITS 3 /* 100 Mbps */
+#define MLX4_RATELIMIT_DEFAULT 0xffff
+
+struct mlx4_set_port_prio2tc_context {
+       u8 prio2tc[4];
+};
+
+struct mlx4_port_scheduler_tc_cfg_be {
+       __be16 pg;
+       __be16 bw_precentage;
+       __be16 max_bw_units; /* 3-100Mbps, 4-1Gbps, other values - reserved */
+       __be16 max_bw_value;
+};
+
+struct mlx4_set_port_scheduler_context {
+       struct mlx4_port_scheduler_tc_cfg_be tc[MLX4_NUM_TC];
+};
+
 enum {
        MLX4_HCR_BASE           = 0x80680,
        MLX4_HCR_SIZE           = 0x0001c,
index 77535ff18f1b0ae1e33711ed948ad8bf68fe7ddb..55b12e6bed876df8187b80fc210da9ad5879a13a 100644 (file)
@@ -834,6 +834,68 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
 }
 EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);
 
+int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_set_port_prio2tc_context *context;
+       int err;
+       u32 in_mod;
+       int i;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       context = mailbox->buf;
+       memset(context, 0, sizeof *context);
+
+       for (i = 0; i < MLX4_NUM_UP; i += 2)
+               context->prio2tc[i >> 1] = prio2tc[i] << 4 | prio2tc[i + 1];
+
+       in_mod = MLX4_SET_PORT_PRIO2TC << 8 | port;
+       err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+EXPORT_SYMBOL(mlx4_SET_PORT_PRIO2TC);
+
+int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
+               u8 *pg, u16 *ratelimit)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_set_port_scheduler_context *context;
+       int err;
+       u32 in_mod;
+       int i;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       context = mailbox->buf;
+       memset(context, 0, sizeof *context);
+
+       for (i = 0; i < MLX4_NUM_TC; i++) {
+               struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i];
+               u16 r = ratelimit && ratelimit[i] ? ratelimit[i] :
+                       MLX4_RATELIMIT_DEFAULT;
+
+               tc->pg = htons(pg[i]);
+               tc->bw_precentage = htons(tc_tx_bw[i]);
+
+               tc->max_bw_units = htons(MLX4_RATELIMIT_UNITS);
+               tc->max_bw_value = htons(r);
+       }
+
+       in_mod = MLX4_SET_PORT_SCHEDULER << 8 | port;
+       err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+                      MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+EXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER);
+
 int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
                                struct mlx4_vhcr *vhcr,
                                struct mlx4_cmd_mailbox *inbox,
index 9958ff2cad3c624f7f6c84457dffa71f217d5a44..1f3860a8a1099ea1288cbd618cf160290874068e 100644 (file)
@@ -150,6 +150,10 @@ enum {
        /* statistics commands */
        MLX4_CMD_QUERY_IF_STAT   = 0X54,
        MLX4_CMD_SET_IF_STAT     = 0X55,
+
+       /* set port opcode modifiers */
+       MLX4_SET_PORT_PRIO2TC = 0x8,
+       MLX4_SET_PORT_SCHEDULER  = 0x9,
 };
 
 enum {
index 834c96c5d879d27ca673c144505a1c6a8d505b73..6d028247f79dedef0067482c04cf17b408480fd4 100644 (file)
@@ -628,6 +628,9 @@ int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
                          u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx);
 int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
                           u8 promisc);
+int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc);
+int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
+               u8 *pg, u16 *ratelimit);
 int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
 int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
 void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index);