diff options
author | Suresh Reddy <suresh.reddy@emulex.com> | 2014-03-11 09:23:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-12 16:19:47 -0400 |
commit | bdce2ad7964b22c5dbccfa151bb5cbab8f510a99 (patch) | |
tree | c19a3c346b270333c0b60b3f86eee840d9d8dcb4 | |
parent | ecf1f6e1df385d17b9cdebd06edf4d1f00d217a7 (diff) |
be2net: Add link state control for VFs
Add support to control VF's link state by implementing the
ndo_set_vf_link_state() hook.
Signed-off-by: Suresh Reddy <suresh.reddy@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@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 | 50 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 32 |
4 files changed, 88 insertions, 5 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index a91267be715a..d08c7074f99b 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -359,6 +359,7 @@ struct be_vf_cfg { | |||
359 | int pmac_id; | 359 | int pmac_id; |
360 | u16 vlan_tag; | 360 | u16 vlan_tag; |
361 | u32 tx_rate; | 361 | u32 tx_rate; |
362 | u32 plink_tracking; | ||
362 | }; | 363 | }; |
363 | 364 | ||
364 | enum vf_state { | 365 | enum vf_state { |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 72bde5d1c358..ff353d7c3fdf 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -202,8 +202,12 @@ static void be_async_link_state_process(struct be_adapter *adapter, | |||
202 | /* When link status changes, link speed must be re-queried from FW */ | 202 | /* When link status changes, link speed must be re-queried from FW */ |
203 | adapter->phy.link_speed = -1; | 203 | adapter->phy.link_speed = -1; |
204 | 204 | ||
205 | /* Ignore physical link event */ | 205 | /* On BEx the FW does not send a separate link status |
206 | if (lancer_chip(adapter) && | 206 | * notification for physical and logical link. |
207 | * On other chips just process the logical link | ||
208 | * status notification | ||
209 | */ | ||
210 | if (!BEx_chip(adapter) && | ||
207 | !(evt->port_link_status & LOGICAL_LINK_STATUS_MASK)) | 211 | !(evt->port_link_status & LOGICAL_LINK_STATUS_MASK)) |
208 | return; | 212 | return; |
209 | 213 | ||
@@ -211,7 +215,8 @@ static void be_async_link_state_process(struct be_adapter *adapter, | |||
211 | * it may not be received in some cases. | 215 | * it may not be received in some cases. |
212 | */ | 216 | */ |
213 | if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT) | 217 | if (adapter->flags & BE_FLAGS_LINK_STATUS_INIT) |
214 | be_link_status_update(adapter, evt->port_link_status); | 218 | be_link_status_update(adapter, |
219 | evt->port_link_status & LINK_STATUS_MASK); | ||
215 | } | 220 | } |
216 | 221 | ||
217 | /* Grp5 CoS Priority evt */ | 222 | /* Grp5 CoS Priority evt */ |
@@ -3743,6 +3748,45 @@ err: | |||
3743 | return status; | 3748 | return status; |
3744 | } | 3749 | } |
3745 | 3750 | ||
3751 | int be_cmd_set_logical_link_config(struct be_adapter *adapter, | ||
3752 | int link_state, u8 domain) | ||
3753 | { | ||
3754 | struct be_mcc_wrb *wrb; | ||
3755 | struct be_cmd_req_set_ll_link *req; | ||
3756 | int status; | ||
3757 | |||
3758 | if (BEx_chip(adapter) || lancer_chip(adapter)) | ||
3759 | return 0; | ||
3760 | |||
3761 | spin_lock_bh(&adapter->mcc_lock); | ||
3762 | |||
3763 | wrb = wrb_from_mccq(adapter); | ||
3764 | if (!wrb) { | ||
3765 | status = -EBUSY; | ||
3766 | goto err; | ||
3767 | } | ||
3768 | |||
3769 | req = embedded_payload(wrb); | ||
3770 | |||
3771 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
3772 | OPCODE_COMMON_SET_LOGICAL_LINK_CONFIG, | ||
3773 | sizeof(*req), wrb, NULL); | ||
3774 | |||
3775 | req->hdr.version = 1; | ||
3776 | req->hdr.domain = domain; | ||
3777 | |||
3778 | if (link_state == IFLA_VF_LINK_STATE_ENABLE) | ||
3779 | req->link_config |= 1; | ||
3780 | |||
3781 | if (link_state == IFLA_VF_LINK_STATE_AUTO) | ||
3782 | req->link_config |= 1 << PLINK_TRACK_SHIFT; | ||
3783 | |||
3784 | status = be_mcc_notify_wait(adapter); | ||
3785 | err: | ||
3786 | spin_unlock_bh(&adapter->mcc_lock); | ||
3787 | return status; | ||
3788 | } | ||
3789 | |||
3746 | int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, | 3790 | int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, |
3747 | int wrb_payload_size, u16 *cmd_status, u16 *ext_status) | 3791 | int wrb_payload_size, u16 *cmd_status, u16 *ext_status) |
3748 | { | 3792 | { |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index d0ab980f77ea..fda3e8851e17 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -203,6 +203,7 @@ struct be_mcc_mailbox { | |||
203 | #define OPCODE_COMMON_GET_BEACON_STATE 70 | 203 | #define OPCODE_COMMON_GET_BEACON_STATE 70 |
204 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 | 204 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 |
205 | #define OPCODE_COMMON_GET_PORT_NAME 77 | 205 | #define OPCODE_COMMON_GET_PORT_NAME 77 |
206 | #define OPCODE_COMMON_SET_LOGICAL_LINK_CONFIG 80 | ||
206 | #define OPCODE_COMMON_SET_INTERRUPT_ENABLE 89 | 207 | #define OPCODE_COMMON_SET_INTERRUPT_ENABLE 89 |
207 | #define OPCODE_COMMON_SET_FN_PRIVILEGES 100 | 208 | #define OPCODE_COMMON_SET_FN_PRIVILEGES 100 |
208 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 | 209 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 |
@@ -1991,6 +1992,13 @@ struct be_cmd_resp_get_iface_list { | |||
1991 | struct be_if_desc if_desc; | 1992 | struct be_if_desc if_desc; |
1992 | }; | 1993 | }; |
1993 | 1994 | ||
1995 | /*************** Set logical link ********************/ | ||
1996 | #define PLINK_TRACK_SHIFT 8 | ||
1997 | struct be_cmd_req_set_ll_link { | ||
1998 | struct be_cmd_req_hdr hdr; | ||
1999 | u32 link_config; /* Bit 0: UP_DOWN, Bit 9: PLINK */ | ||
2000 | }; | ||
2001 | |||
1994 | int be_pci_fnum_get(struct be_adapter *adapter); | 2002 | int be_pci_fnum_get(struct be_adapter *adapter); |
1995 | int be_fw_wait_ready(struct be_adapter *adapter); | 2003 | int be_fw_wait_ready(struct be_adapter *adapter); |
1996 | int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 2004 | int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, |
@@ -2112,3 +2120,5 @@ int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, | |||
2112 | int vf_num); | 2120 | int vf_num); |
2113 | int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); | 2121 | int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); |
2114 | int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); | 2122 | int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); |
2123 | int be_cmd_set_logical_link_config(struct be_adapter *adapter, | ||
2124 | int link_state, u8 domain); | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 5ba1ea5ec43d..2f02bcbf3164 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -652,7 +652,7 @@ void be_link_status_update(struct be_adapter *adapter, u8 link_status) | |||
652 | adapter->flags |= BE_FLAGS_LINK_STATUS_INIT; | 652 | adapter->flags |= BE_FLAGS_LINK_STATUS_INIT; |
653 | } | 653 | } |
654 | 654 | ||
655 | if ((link_status & LINK_STATUS_MASK) == LINK_UP) | 655 | if (link_status) |
656 | netif_carrier_on(netdev); | 656 | netif_carrier_on(netdev); |
657 | else | 657 | else |
658 | netif_carrier_off(netdev); | 658 | netif_carrier_off(netdev); |
@@ -1288,6 +1288,7 @@ static int be_get_vf_config(struct net_device *netdev, int vf, | |||
1288 | vi->vlan = vf_cfg->vlan_tag & VLAN_VID_MASK; | 1288 | vi->vlan = vf_cfg->vlan_tag & VLAN_VID_MASK; |
1289 | vi->qos = vf_cfg->vlan_tag >> VLAN_PRIO_SHIFT; | 1289 | vi->qos = vf_cfg->vlan_tag >> VLAN_PRIO_SHIFT; |
1290 | memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN); | 1290 | memcpy(&vi->mac, vf_cfg->mac_addr, ETH_ALEN); |
1291 | vi->linkstate = adapter->vf_cfg[vf].plink_tracking; | ||
1291 | 1292 | ||
1292 | return 0; | 1293 | return 0; |
1293 | } | 1294 | } |
@@ -1354,6 +1355,24 @@ static int be_set_vf_tx_rate(struct net_device *netdev, | |||
1354 | adapter->vf_cfg[vf].tx_rate = rate; | 1355 | adapter->vf_cfg[vf].tx_rate = rate; |
1355 | return status; | 1356 | return status; |
1356 | } | 1357 | } |
1358 | static int be_set_vf_link_state(struct net_device *netdev, int vf, | ||
1359 | int link_state) | ||
1360 | { | ||
1361 | struct be_adapter *adapter = netdev_priv(netdev); | ||
1362 | int status; | ||
1363 | |||
1364 | if (!sriov_enabled(adapter)) | ||
1365 | return -EPERM; | ||
1366 | |||
1367 | if (vf >= adapter->num_vfs) | ||
1368 | return -EINVAL; | ||
1369 | |||
1370 | status = be_cmd_set_logical_link_config(adapter, link_state, vf+1); | ||
1371 | if (!status) | ||
1372 | adapter->vf_cfg[vf].plink_tracking = link_state; | ||
1373 | |||
1374 | return status; | ||
1375 | } | ||
1357 | 1376 | ||
1358 | static void be_aic_update(struct be_aic_obj *aic, u64 rx_pkts, u64 tx_pkts, | 1377 | static void be_aic_update(struct be_aic_obj *aic, u64 rx_pkts, u64 tx_pkts, |
1359 | ulong now) | 1378 | ulong now) |
@@ -3109,8 +3128,12 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
3109 | if (!status) | 3128 | if (!status) |
3110 | vf_cfg->tx_rate = lnk_speed; | 3129 | vf_cfg->tx_rate = lnk_speed; |
3111 | 3130 | ||
3112 | if (!old_vfs) | 3131 | if (!old_vfs) { |
3113 | be_cmd_enable_vf(adapter, vf + 1); | 3132 | be_cmd_enable_vf(adapter, vf + 1); |
3133 | be_cmd_set_logical_link_config(adapter, | ||
3134 | IFLA_VF_LINK_STATE_AUTO, | ||
3135 | vf+1); | ||
3136 | } | ||
3114 | } | 3137 | } |
3115 | 3138 | ||
3116 | if (!old_vfs) { | 3139 | if (!old_vfs) { |
@@ -3467,6 +3490,10 @@ static int be_setup(struct be_adapter *adapter) | |||
3467 | be_cmd_set_flow_control(adapter, adapter->tx_fc, | 3490 | be_cmd_set_flow_control(adapter, adapter->tx_fc, |
3468 | adapter->rx_fc); | 3491 | adapter->rx_fc); |
3469 | 3492 | ||
3493 | if (be_physfn(adapter)) | ||
3494 | be_cmd_set_logical_link_config(adapter, | ||
3495 | IFLA_VF_LINK_STATE_AUTO, 0); | ||
3496 | |||
3470 | if (sriov_want(adapter)) { | 3497 | if (sriov_want(adapter)) { |
3471 | if (be_max_vfs(adapter)) | 3498 | if (be_max_vfs(adapter)) |
3472 | be_vf_setup(adapter); | 3499 | be_vf_setup(adapter); |
@@ -4106,6 +4133,7 @@ static const struct net_device_ops be_netdev_ops = { | |||
4106 | .ndo_set_vf_vlan = be_set_vf_vlan, | 4133 | .ndo_set_vf_vlan = be_set_vf_vlan, |
4107 | .ndo_set_vf_tx_rate = be_set_vf_tx_rate, | 4134 | .ndo_set_vf_tx_rate = be_set_vf_tx_rate, |
4108 | .ndo_get_vf_config = be_get_vf_config, | 4135 | .ndo_get_vf_config = be_get_vf_config, |
4136 | .ndo_set_vf_link_state = be_set_vf_link_state, | ||
4109 | #ifdef CONFIG_NET_POLL_CONTROLLER | 4137 | #ifdef CONFIG_NET_POLL_CONTROLLER |
4110 | .ndo_poll_controller = be_netpoll, | 4138 | .ndo_poll_controller = be_netpoll, |
4111 | #endif | 4139 | #endif |