aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c50
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h10
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c32
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
364enum vf_state { 365enum 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
3751int 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);
3785err:
3786 spin_unlock_bh(&adapter->mcc_lock);
3787 return status;
3788}
3789
3746int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, 3790int 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
1997struct 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
1994int be_pci_fnum_get(struct be_adapter *adapter); 2002int be_pci_fnum_get(struct be_adapter *adapter);
1995int be_fw_wait_ready(struct be_adapter *adapter); 2003int be_fw_wait_ready(struct be_adapter *adapter);
1996int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, 2004int 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);
2113int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain); 2121int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain);
2114int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable); 2122int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable);
2123int 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}
1358static 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
1358static void be_aic_update(struct be_aic_obj *aic, u64 rx_pkts, u64 tx_pkts, 1377static 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