be2net: allow VFs to program MAC and VLAN filters
authorSathya Perla <sathya.perla@emulex.com>
Tue, 23 Jul 2013 09:55:00 +0000 (15:25 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 Jul 2013 22:41:52 +0000 (15:41 -0700)
In the current design VFs were not allowed to program MAC/VLAN filters.
Only the PF driver was allowed to configure/provision MAC and transparent
VLANs to a VF. Change this to support MAC/VLAN filtering on a VF by a VM.

Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_main.c

index 632c0d323867f143540b75cb64adcc7f1d9841fe..5d37601df03ffd0fb2812696fcf69672d01683fc 100644 (file)
@@ -2606,6 +2606,38 @@ err:
        return status;
 }
 
+/* Set privilege(s) for a function */
+int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
+                            u32 domain)
+{
+       struct be_mcc_wrb *wrb;
+       struct be_cmd_req_set_fn_privileges *req;
+       int status;
+
+       spin_lock_bh(&adapter->mcc_lock);
+
+       wrb = wrb_from_mccq(adapter);
+       if (!wrb) {
+               status = -EBUSY;
+               goto err;
+       }
+
+       req = embedded_payload(wrb);
+       be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+                              OPCODE_COMMON_SET_FN_PRIVILEGES, sizeof(*req),
+                              wrb, NULL);
+       req->hdr.domain = domain;
+       if (lancer_chip(adapter))
+               req->privileges_lancer = cpu_to_le32(privileges);
+       else
+               req->privileges = cpu_to_le32(privileges);
+
+       status = be_mcc_notify_wait(adapter);
+err:
+       spin_unlock_bh(&adapter->mcc_lock);
+       return status;
+}
+
 /* pmac_id_valid: true => pmac_id is supplied and MAC address is requested.
  * pmac_id_valid: false => pmac_id or MAC address is requested.
  *               If pmac_id is returned, pmac_id_valid is returned as true
index 7ecca3b591a6625bd909e252c5e29443e914764c..671a89d84f98ebc046a714ddcc1f5ed51b6cc205 100644 (file)
@@ -202,6 +202,7 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_READ_TRANSRECV_DATA              73
 #define OPCODE_COMMON_GET_PORT_NAME                    77
 #define OPCODE_COMMON_SET_INTERRUPT_ENABLE             89
+#define OPCODE_COMMON_SET_FN_PRIVILEGES                        100
 #define OPCODE_COMMON_GET_PHY_DETAILS                  102
 #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP          103
 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES   121
@@ -1474,6 +1475,11 @@ struct be_cmd_resp_get_fn_privileges {
        u32 privilege_mask;
 };
 
+struct be_cmd_req_set_fn_privileges {
+       struct be_cmd_req_hdr hdr;
+       u32 privileges;         /* Used by BE3, SH-R */
+       u32 privileges_lancer;  /* Used by Lancer */
+};
 
 /******************** GET/SET_MACLIST  **************************/
 #define BE_MAX_MAC                     64
@@ -1921,6 +1927,8 @@ extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
 extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
 extern int be_cmd_get_fn_privileges(struct be_adapter *adapter,
                                    u32 *privilege, u32 domain);
+extern int be_cmd_set_fn_privileges(struct be_adapter *adapter,
+                                   u32 privileges, u32 vf_num);
 extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
                                    bool *pmac_id_active, u32 *pmac_id,
                                    u8 domain);
index 29e7870e0b35750158805075bfef94535f1674c5..858bb473bd42c45cce55c3df9f29d379e329c1f7 100644 (file)
@@ -2880,6 +2880,7 @@ static int be_vf_setup(struct be_adapter *adapter)
        u16 def_vlan, lnk_speed;
        int status, old_vfs, vf;
        struct device *dev = &adapter->pdev->dev;
+       u32 privileges;
 
        old_vfs = pci_num_vf(adapter->pdev);
        if (old_vfs) {
@@ -2923,6 +2924,18 @@ static int be_vf_setup(struct be_adapter *adapter)
        }
 
        for_all_vfs(adapter, vf_cfg, vf) {
+               /* Allow VFs to programs MAC/VLAN filters */
+               status = be_cmd_get_fn_privileges(adapter, &privileges, vf + 1);
+               if (!status && !(privileges & BE_PRIV_FILTMGMT)) {
+                       status = be_cmd_set_fn_privileges(adapter,
+                                                         privileges |
+                                                         BE_PRIV_FILTMGMT,
+                                                         vf + 1);
+                       if (!status)
+                               dev_info(dev, "VF%d has FILTMGMT privilege\n",
+                                        vf);
+               }
+
                /* BE3 FW, by default, caps VF TX-rate to 100mbps.
                 * Allow full available bandwidth
                 */