get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2534/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2534,
    "url": "https://patches.dpdk.org/api/patches/2534/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1422326164-13697-15-git-send-email-changchun.ouyang@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1422326164-13697-15-git-send-email-changchun.ouyang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1422326164-13697-15-git-send-email-changchun.ouyang@intel.com",
    "date": "2015-01-27T02:35:54",
    "name": "[dpdk-dev,v2,14/24] virtio: Add suport for multiple mac addresses",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "bba26e2a165b2124f6b836f8dc7c62960f7fcc50",
    "submitter": {
        "id": 31,
        "url": "https://patches.dpdk.org/api/people/31/?format=api",
        "name": "Ouyang Changchun",
        "email": "changchun.ouyang@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1422326164-13697-15-git-send-email-changchun.ouyang@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/2534/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/2534/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 3CEDB5A7A;\n\tTue, 27 Jan 2015 03:46:58 +0100 (CET)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 753225A8F\n\tfor <dev@dpdk.org>; Tue, 27 Jan 2015 03:36:58 +0100 (CET)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga103.fm.intel.com with ESMTP; 26 Jan 2015 18:30:40 -0800",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby fmsmga002.fm.intel.com with ESMTP; 26 Jan 2015 18:36:44 -0800",
            "from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com\n\t[10.239.29.89])\n\tby shvmail01.sh.intel.com with ESMTP id t0R2afw6015526;\n\tTue, 27 Jan 2015 10:36:41 +0800",
            "from shecgisg004.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid t0R2admf013828; Tue, 27 Jan 2015 10:36:41 +0800",
            "(from couyang@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t0R2ad2Y013824; \n\tTue, 27 Jan 2015 10:36:39 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.09,471,1418112000\"; d=\"scan'208\";a=\"667998754\"",
        "From": "Ouyang Changchun <changchun.ouyang@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue, 27 Jan 2015 10:35:54 +0800",
        "Message-Id": "<1422326164-13697-15-git-send-email-changchun.ouyang@intel.com>",
        "X-Mailer": "git-send-email 1.7.12.2",
        "In-Reply-To": "<1422326164-13697-1-git-send-email-changchun.ouyang@intel.com>",
        "References": "<1421298930-15210-1-git-send-email-changchun.ouyang@intel.com>\n\t<1422326164-13697-1-git-send-email-changchun.ouyang@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 14/24] virtio: Add suport for multiple mac\n\taddresses",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Virtio support multiple MAC addresses.\n\nSigned-off-by: Stephen Hemminger <stephen@networkplumber.org>\nSigned-off-by: Changchun Ouyang <changchun.ouyang@intel.com>\n---\n lib/librte_pmd_virtio/virtio_ethdev.c | 94 ++++++++++++++++++++++++++++++++++-\n lib/librte_pmd_virtio/virtio_ethdev.h |  3 +-\n lib/librte_pmd_virtio/virtqueue.h     | 34 ++++++++++++-\n 3 files changed, 127 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c b/lib/librte_pmd_virtio/virtio_ethdev.c\nindex 591d692..0e74eea 100644\n--- a/lib/librte_pmd_virtio/virtio_ethdev.c\n+++ b/lib/librte_pmd_virtio/virtio_ethdev.c\n@@ -86,6 +86,10 @@ static void virtio_dev_stats_reset(struct rte_eth_dev *dev);\n static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);\n static int virtio_vlan_filter_set(struct rte_eth_dev *dev,\n \t\t\t\tuint16_t vlan_id, int on);\n+static void virtio_mac_addr_add(struct rte_eth_dev *dev,\n+\t\t\t\tstruct ether_addr *mac_addr,\n+\t\t\t\tuint32_t index, uint32_t vmdq __rte_unused);\n+static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);\n \n static int virtio_dev_queue_stats_mapping_set(\n \t__rte_unused struct rte_eth_dev *eth_dev,\n@@ -503,8 +507,6 @@ static struct eth_dev_ops virtio_eth_dev_ops = {\n \t.stats_get               = virtio_dev_stats_get,\n \t.stats_reset             = virtio_dev_stats_reset,\n \t.link_update             = virtio_dev_link_update,\n-\t.mac_addr_add            = NULL,\n-\t.mac_addr_remove         = NULL,\n \t.rx_queue_setup          = virtio_dev_rx_queue_setup,\n \t/* meaningfull only to multiple queue */\n \t.rx_queue_release        = virtio_dev_rx_queue_release,\n@@ -514,6 +516,8 @@ static struct eth_dev_ops virtio_eth_dev_ops = {\n \t/* collect stats per queue */\n \t.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,\n \t.vlan_filter_set         = virtio_vlan_filter_set,\n+\t.mac_addr_add            = virtio_mac_addr_add,\n+\t.mac_addr_remove         = virtio_mac_addr_remove,\n };\n \n static inline int\n@@ -644,6 +648,92 @@ virtio_get_hwaddr(struct virtio_hw *hw)\n }\n \n static int\n+virtio_mac_table_set(struct virtio_hw *hw,\n+\t\t     const struct virtio_net_ctrl_mac *uc,\n+\t\t     const struct virtio_net_ctrl_mac *mc)\n+{\n+\tstruct virtio_pmd_ctrl ctrl;\n+\tint err, len[2];\n+\n+\tctrl.hdr.class = VIRTIO_NET_CTRL_MAC;\n+\tctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_TABLE_SET;\n+\n+\tlen[0] = uc->entries * ETHER_ADDR_LEN + sizeof(uc->entries);\n+\tmemcpy(ctrl.data, uc, len[0]);\n+\n+\tlen[1] = mc->entries * ETHER_ADDR_LEN + sizeof(mc->entries);\n+\tmemcpy(ctrl.data + len[0], mc, len[1]);\n+\n+\terr = virtio_send_command(hw->cvq, &ctrl, len, 2);\n+\tif (err != 0)\n+\t\tPMD_DRV_LOG(NOTICE, \"mac table set failed: %d\", err);\n+\n+\treturn err;\n+}\n+\n+static void\n+virtio_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,\n+\t\t    uint32_t index, uint32_t vmdq __rte_unused)\n+{\n+\tstruct virtio_hw *hw = dev->data->dev_private;\n+\tconst struct ether_addr *addrs = dev->data->mac_addrs;\n+\tunsigned int i;\n+\tstruct virtio_net_ctrl_mac *uc, *mc;\n+\n+\tif (index >= VIRTIO_MAX_MAC_ADDRS) {\n+\t\tPMD_DRV_LOG(ERR, \"mac address index %u out of range\", index);\n+\t\treturn;\n+\t}\n+\n+\tuc = alloca(VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN + sizeof(uc->entries));\n+\tuc->entries = 0;\n+\tmc = alloca(VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN + sizeof(mc->entries));\n+\tmc->entries = 0;\n+\n+\tfor (i = 0; i < VIRTIO_MAX_MAC_ADDRS; i++) {\n+\t\tconst struct ether_addr *addr\n+\t\t\t= (i == index) ? mac_addr : addrs + i;\n+\t\tstruct virtio_net_ctrl_mac *tbl\n+\t\t\t= is_multicast_ether_addr(addr) ? mc : uc;\n+\n+\t\tmemcpy(&tbl->macs[tbl->entries++], addr, ETHER_ADDR_LEN);\n+\t}\n+\n+\tvirtio_mac_table_set(hw, uc, mc);\n+}\n+\n+static void\n+virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)\n+{\n+\tstruct virtio_hw *hw = dev->data->dev_private;\n+\tstruct ether_addr *addrs = dev->data->mac_addrs;\n+\tstruct virtio_net_ctrl_mac *uc, *mc;\n+\tunsigned int i;\n+\n+\tif (index >= VIRTIO_MAX_MAC_ADDRS) {\n+\t\tPMD_DRV_LOG(ERR, \"mac address index %u out of range\", index);\n+\t\treturn;\n+\t}\n+\n+\tuc = alloca(VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN + sizeof(uc->entries));\n+\tuc->entries = 0;\n+\tmc = alloca(VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN + sizeof(mc->entries));\n+\tmc->entries = 0;\n+\n+\tfor (i = 0; i < VIRTIO_MAX_MAC_ADDRS; i++) {\n+\t\tstruct virtio_net_ctrl_mac *tbl;\n+\n+\t\tif (i == index || is_zero_ether_addr(addrs + i))\n+\t\t\tcontinue;\n+\n+\t\ttbl = is_multicast_ether_addr(addrs + i) ? mc : uc;\n+\t\tmemcpy(&tbl->macs[tbl->entries++], addrs + i, ETHER_ADDR_LEN);\n+\t}\n+\n+\tvirtio_mac_table_set(hw, uc, mc);\n+}\n+\n+static int\n virtio_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)\n {\n \tstruct virtio_hw *hw = dev->data->dev_private;\ndiff --git a/lib/librte_pmd_virtio/virtio_ethdev.h b/lib/librte_pmd_virtio/virtio_ethdev.h\nindex 55c9749..74ac7e0 100644\n--- a/lib/librte_pmd_virtio/virtio_ethdev.h\n+++ b/lib/librte_pmd_virtio/virtio_ethdev.h\n@@ -51,7 +51,7 @@\n \n #define VIRTIO_MAX_RX_QUEUES 128\n #define VIRTIO_MAX_TX_QUEUES 128\n-#define VIRTIO_MAX_MAC_ADDRS 1\n+#define VIRTIO_MAX_MAC_ADDRS 64\n #define VIRTIO_MIN_RX_BUFSIZE 64\n #define VIRTIO_MAX_RX_PKTLEN  9728\n \n@@ -60,6 +60,7 @@\n \t(VIRTIO_NET_F_MAC       | \\\n \tVIRTIO_NET_F_STATUS     | \\\n \tVIRTIO_NET_F_MQ         | \\\n+\tVIRTIO_NET_F_CTRL_MAC_ADDR | \\\n \tVIRTIO_NET_F_CTRL_VQ    | \\\n \tVIRTIO_NET_F_CTRL_RX    | \\\n \tVIRTIO_NET_F_CTRL_VLAN  | \\\ndiff --git a/lib/librte_pmd_virtio/virtqueue.h b/lib/librte_pmd_virtio/virtqueue.h\nindex 5b8a255..d210f4f 100644\n--- a/lib/librte_pmd_virtio/virtqueue.h\n+++ b/lib/librte_pmd_virtio/virtqueue.h\n@@ -99,6 +99,34 @@ enum { VTNET_RQ = 0, VTNET_TQ = 1, VTNET_CQ = 2 };\n #define VIRTIO_NET_CTRL_RX_NOBCAST      5\n \n /**\n+ * Control the MAC\n+ *\n+ * The MAC filter table is managed by the hypervisor, the guest should\n+ * assume the size is infinite.  Filtering should be considered\n+ * non-perfect, ie. based on hypervisor resources, the guest may\n+ * received packets from sources not specified in the filter list.\n+ *\n+ * In addition to the class/cmd header, the TABLE_SET command requires\n+ * two out scatterlists.  Each contains a 4 byte count of entries followed\n+ * by a concatenated byte stream of the ETH_ALEN MAC addresses.  The\n+ * first sg list contains unicast addresses, the second is for multicast.\n+ * This functionality is present if the VIRTIO_NET_F_CTRL_RX feature\n+ * is available.\n+ *\n+ * The ADDR_SET command requests one out scatterlist, it contains a\n+ * 6 bytes MAC address. This functionality is present if the\n+ * VIRTIO_NET_F_CTRL_MAC_ADDR feature is available.\n+ */\n+struct virtio_net_ctrl_mac {\n+\tuint32_t entries;\n+\tuint8_t macs[][ETHER_ADDR_LEN];\n+} __attribute__((__packed__));\n+\n+#define VIRTIO_NET_CTRL_MAC    1\n+ #define VIRTIO_NET_CTRL_MAC_TABLE_SET        0\n+ #define VIRTIO_NET_CTRL_MAC_ADDR_SET         1\n+\n+/**\n  * Control VLAN filtering\n  *\n  * The VLAN filter table is controlled via a simple ADD/DEL interface.\n@@ -121,7 +149,7 @@ typedef uint8_t virtio_net_ctrl_ack;\n #define VIRTIO_NET_OK     0\n #define VIRTIO_NET_ERR    1\n \n-#define VIRTIO_MAX_CTRL_DATA 128\n+#define VIRTIO_MAX_CTRL_DATA 2048\n \n struct virtio_pmd_ctrl {\n \tstruct virtio_net_ctrl_hdr hdr;\n@@ -180,6 +208,10 @@ struct virtqueue {\n #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN        1\n #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX        0x8000\n #endif\n+#ifndef VIRTIO_NET_F_CTRL_MAC_ADDR\n+#define VIRTIO_NET_F_CTRL_MAC_ADDR 0x800000\n+#define VIRTIO_NET_CTRL_MAC_ADDR_SET         1\n+#endif\n \n /**\n  * This is the first element of the scatter-gather list.  If you don't\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "14/24"
    ]
}