diff options
author | Ajit Khaparde <ajit.khaparde@emulex.com> | 2012-03-18 02:23:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-03-19 16:52:17 -0400 |
commit | f1f3ee1bcc996e21f122442fd8c34de51622c76a (patch) | |
tree | dd7dadc565c33a09133a46dfd2ec5ac1ecee6d6e | |
parent | 456d9c962bb5824423fa93277c8f7f5b2e3d5e1c (diff) |
be2net: fix programming of VLAN tags for VF
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 83 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 55 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 23 |
4 files changed, 157 insertions, 5 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 03fc3dbe3872..9576ac002c23 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -303,6 +303,7 @@ struct be_vf_cfg { | |||
303 | unsigned char mac_addr[ETH_ALEN]; | 303 | unsigned char mac_addr[ETH_ALEN]; |
304 | int if_handle; | 304 | int if_handle; |
305 | int pmac_id; | 305 | int pmac_id; |
306 | u16 def_vid; | ||
306 | u16 vlan_tag; | 307 | u16 vlan_tag; |
307 | u32 tx_rate; | 308 | u32 tx_rate; |
308 | }; | 309 | }; |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index d72c2b46963c..67b030d72df1 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -2419,6 +2419,89 @@ err: | |||
2419 | return status; | 2419 | return status; |
2420 | } | 2420 | } |
2421 | 2421 | ||
2422 | int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, | ||
2423 | u32 domain, u16 intf_id) | ||
2424 | { | ||
2425 | struct be_mcc_wrb *wrb; | ||
2426 | struct be_cmd_req_set_hsw_config *req; | ||
2427 | void *ctxt; | ||
2428 | int status; | ||
2429 | |||
2430 | spin_lock_bh(&adapter->mcc_lock); | ||
2431 | |||
2432 | wrb = wrb_from_mccq(adapter); | ||
2433 | if (!wrb) { | ||
2434 | status = -EBUSY; | ||
2435 | goto err; | ||
2436 | } | ||
2437 | |||
2438 | req = embedded_payload(wrb); | ||
2439 | ctxt = &req->context; | ||
2440 | |||
2441 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2442 | OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req), wrb, NULL); | ||
2443 | |||
2444 | req->hdr.domain = domain; | ||
2445 | AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id); | ||
2446 | if (pvid) { | ||
2447 | AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1); | ||
2448 | AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid); | ||
2449 | } | ||
2450 | |||
2451 | be_dws_cpu_to_le(req->context, sizeof(req->context)); | ||
2452 | status = be_mcc_notify_wait(adapter); | ||
2453 | |||
2454 | err: | ||
2455 | spin_unlock_bh(&adapter->mcc_lock); | ||
2456 | return status; | ||
2457 | } | ||
2458 | |||
2459 | /* Get Hyper switch config */ | ||
2460 | int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, | ||
2461 | u32 domain, u16 intf_id) | ||
2462 | { | ||
2463 | struct be_mcc_wrb *wrb; | ||
2464 | struct be_cmd_req_get_hsw_config *req; | ||
2465 | void *ctxt; | ||
2466 | int status; | ||
2467 | u16 vid; | ||
2468 | |||
2469 | spin_lock_bh(&adapter->mcc_lock); | ||
2470 | |||
2471 | wrb = wrb_from_mccq(adapter); | ||
2472 | if (!wrb) { | ||
2473 | status = -EBUSY; | ||
2474 | goto err; | ||
2475 | } | ||
2476 | |||
2477 | req = embedded_payload(wrb); | ||
2478 | ctxt = &req->context; | ||
2479 | |||
2480 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2481 | OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req), wrb, NULL); | ||
2482 | |||
2483 | req->hdr.domain = domain; | ||
2484 | AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt, | ||
2485 | intf_id); | ||
2486 | AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1); | ||
2487 | be_dws_cpu_to_le(req->context, sizeof(req->context)); | ||
2488 | |||
2489 | status = be_mcc_notify_wait(adapter); | ||
2490 | if (!status) { | ||
2491 | struct be_cmd_resp_get_hsw_config *resp = | ||
2492 | embedded_payload(wrb); | ||
2493 | be_dws_le_to_cpu(&resp->context, | ||
2494 | sizeof(resp->context)); | ||
2495 | vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context, | ||
2496 | pvid, &resp->context); | ||
2497 | *pvid = le16_to_cpu(vid); | ||
2498 | } | ||
2499 | |||
2500 | err: | ||
2501 | spin_unlock_bh(&adapter->mcc_lock); | ||
2502 | return status; | ||
2503 | } | ||
2504 | |||
2422 | int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter) | 2505 | int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter) |
2423 | { | 2506 | { |
2424 | struct be_mcc_wrb *wrb; | 2507 | struct be_mcc_wrb *wrb; |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 345d49eeadc8..d5b680c56af0 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -191,6 +191,8 @@ struct be_mcc_mailbox { | |||
191 | #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 | 191 | #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 |
192 | #define OPCODE_COMMON_GET_MAC_LIST 147 | 192 | #define OPCODE_COMMON_GET_MAC_LIST 147 |
193 | #define OPCODE_COMMON_SET_MAC_LIST 148 | 193 | #define OPCODE_COMMON_SET_MAC_LIST 148 |
194 | #define OPCODE_COMMON_GET_HSW_CONFIG 152 | ||
195 | #define OPCODE_COMMON_SET_HSW_CONFIG 153 | ||
194 | #define OPCODE_COMMON_READ_OBJECT 171 | 196 | #define OPCODE_COMMON_READ_OBJECT 171 |
195 | #define OPCODE_COMMON_WRITE_OBJECT 172 | 197 | #define OPCODE_COMMON_WRITE_OBJECT 172 |
196 | 198 | ||
@@ -1413,6 +1415,55 @@ struct be_cmd_req_set_mac_list { | |||
1413 | struct macaddr mac[BE_MAX_MAC]; | 1415 | struct macaddr mac[BE_MAX_MAC]; |
1414 | } __packed; | 1416 | } __packed; |
1415 | 1417 | ||
1418 | /*********************** HSW Config ***********************/ | ||
1419 | struct amap_set_hsw_context { | ||
1420 | u8 interface_id[16]; | ||
1421 | u8 rsvd0[14]; | ||
1422 | u8 pvid_valid; | ||
1423 | u8 rsvd1; | ||
1424 | u8 rsvd2[16]; | ||
1425 | u8 pvid[16]; | ||
1426 | u8 rsvd3[32]; | ||
1427 | u8 rsvd4[32]; | ||
1428 | u8 rsvd5[32]; | ||
1429 | } __packed; | ||
1430 | |||
1431 | struct be_cmd_req_set_hsw_config { | ||
1432 | struct be_cmd_req_hdr hdr; | ||
1433 | u8 context[sizeof(struct amap_set_hsw_context) / 8]; | ||
1434 | } __packed; | ||
1435 | |||
1436 | struct be_cmd_resp_set_hsw_config { | ||
1437 | struct be_cmd_resp_hdr hdr; | ||
1438 | u32 rsvd; | ||
1439 | }; | ||
1440 | |||
1441 | struct amap_get_hsw_req_context { | ||
1442 | u8 interface_id[16]; | ||
1443 | u8 rsvd0[14]; | ||
1444 | u8 pvid_valid; | ||
1445 | u8 pport; | ||
1446 | } __packed; | ||
1447 | |||
1448 | struct amap_get_hsw_resp_context { | ||
1449 | u8 rsvd1[16]; | ||
1450 | u8 pvid[16]; | ||
1451 | u8 rsvd2[32]; | ||
1452 | u8 rsvd3[32]; | ||
1453 | u8 rsvd4[32]; | ||
1454 | } __packed; | ||
1455 | |||
1456 | struct be_cmd_req_get_hsw_config { | ||
1457 | struct be_cmd_req_hdr hdr; | ||
1458 | u8 context[sizeof(struct amap_get_hsw_req_context) / 8]; | ||
1459 | } __packed; | ||
1460 | |||
1461 | struct be_cmd_resp_get_hsw_config { | ||
1462 | struct be_cmd_resp_hdr hdr; | ||
1463 | u8 context[sizeof(struct amap_get_hsw_resp_context) / 8]; | ||
1464 | u32 rsvd; | ||
1465 | }; | ||
1466 | |||
1416 | /*************** HW Stats Get v1 **********************************/ | 1467 | /*************** HW Stats Get v1 **********************************/ |
1417 | #define BE_TXP_SW_SZ 48 | 1468 | #define BE_TXP_SW_SZ 48 |
1418 | struct be_port_rxf_stats_v1 { | 1469 | struct be_port_rxf_stats_v1 { |
@@ -1617,5 +1668,9 @@ extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, | |||
1617 | bool *pmac_id_active, u32 *pmac_id, u8 *mac); | 1668 | bool *pmac_id_active, u32 *pmac_id, u8 *mac); |
1618 | extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, | 1669 | extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, |
1619 | u8 mac_count, u32 domain); | 1670 | u8 mac_count, u32 domain); |
1671 | extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, | ||
1672 | u32 domain, u16 intf_id); | ||
1673 | extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, | ||
1674 | u32 domain, u16 intf_id); | ||
1620 | extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter); | 1675 | extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter); |
1621 | 1676 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 1c84bc81b8f1..528a886bc2cd 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -978,14 +978,21 @@ static int be_set_vf_vlan(struct net_device *netdev, | |||
978 | return -EINVAL; | 978 | return -EINVAL; |
979 | 979 | ||
980 | if (vlan) { | 980 | if (vlan) { |
981 | adapter->vf_cfg[vf].vlan_tag = vlan; | 981 | if (adapter->vf_cfg[vf].vlan_tag != vlan) { |
982 | adapter->vlans_added++; | 982 | /* If this is new value, program it. Else skip. */ |
983 | adapter->vf_cfg[vf].vlan_tag = vlan; | ||
984 | |||
985 | status = be_cmd_set_hsw_config(adapter, vlan, | ||
986 | vf + 1, adapter->vf_cfg[vf].if_handle); | ||
987 | } | ||
983 | } else { | 988 | } else { |
989 | /* Reset Transparent Vlan Tagging. */ | ||
984 | adapter->vf_cfg[vf].vlan_tag = 0; | 990 | adapter->vf_cfg[vf].vlan_tag = 0; |
985 | adapter->vlans_added--; | 991 | vlan = adapter->vf_cfg[vf].def_vid; |
992 | status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, | ||
993 | adapter->vf_cfg[vf].if_handle); | ||
986 | } | 994 | } |
987 | 995 | ||
988 | status = be_vid_config(adapter, true, vf); | ||
989 | 996 | ||
990 | if (status) | 997 | if (status) |
991 | dev_info(&adapter->pdev->dev, | 998 | dev_info(&adapter->pdev->dev, |
@@ -2525,7 +2532,7 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
2525 | { | 2532 | { |
2526 | struct be_vf_cfg *vf_cfg; | 2533 | struct be_vf_cfg *vf_cfg; |
2527 | u32 cap_flags, en_flags, vf; | 2534 | u32 cap_flags, en_flags, vf; |
2528 | u16 lnk_speed; | 2535 | u16 def_vlan, lnk_speed; |
2529 | int status; | 2536 | int status; |
2530 | 2537 | ||
2531 | be_vf_setup_init(adapter); | 2538 | be_vf_setup_init(adapter); |
@@ -2549,6 +2556,12 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
2549 | if (status) | 2556 | if (status) |
2550 | goto err; | 2557 | goto err; |
2551 | vf_cfg->tx_rate = lnk_speed * 10; | 2558 | vf_cfg->tx_rate = lnk_speed * 10; |
2559 | |||
2560 | status = be_cmd_get_hsw_config(adapter, &def_vlan, | ||
2561 | vf + 1, vf_cfg->if_handle); | ||
2562 | if (status) | ||
2563 | goto err; | ||
2564 | vf_cfg->def_vid = def_vlan; | ||
2552 | } | 2565 | } |
2553 | return 0; | 2566 | return 0; |
2554 | err: | 2567 | err: |