From ee3cb6295144b0adfa75ccaca307643a6998b1e2 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Thu, 1 Jul 2010 03:51:00 +0000 Subject: be2net: changes to properly provide phy details be2net driver is currently not showing correct phy details in certain cases. This patch fixes it. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index b46be490cd2a..1a0d2d037c4e 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -282,6 +282,7 @@ struct be_adapter { int link_speed; u8 port_type; u8 transceiver; + u8 autoneg; u8 generation; /* BladeEngine ASIC generation */ u32 flash_status; struct completion flash_compl; -- cgit v1.2.3 From 344dbf1073d1cea179ed0831547cab2b7ea4ea27 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Fri, 9 Jul 2010 01:43:55 +0000 Subject: be2net: Patch to determine if function is VF while running in guest OS. When driver is loaded in guest OS, the pci variables is_virtfn and is_physfn are both set to 0. This change uses registers in controller to determine the same. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 12 +++++++++++- drivers/net/benet/be_main.c | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 1a0d2d037c4e..f17428caecf1 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -291,9 +291,10 @@ struct be_adapter { u32 vf_if_handle[BE_MAX_VF]; u32 vf_pmac_id[BE_MAX_VF]; u8 base_eq_id; + u8 is_virtfn; }; -#define be_physfn(adapter) (!adapter->pdev->is_virtfn) +#define be_physfn(adapter) (!adapter->is_virtfn) /* BladeEngine Generation numbers */ #define BE_GEN2 2 @@ -393,6 +394,15 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) return val; } +static inline void be_check_sriov_fn_type(struct be_adapter *adapter) +{ + u8 data; + + pci_write_config_byte(adapter->pdev, 0xFE, 0xAA); + pci_read_config_byte(adapter->pdev, 0xFE, &data); + adapter->is_virtfn = (data != 0xAA); +} + extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, bool link_up); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index b63687956f2b..e6ca92334d6d 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1631,6 +1631,7 @@ static void be_sriov_enable(struct be_adapter *adapter) { #ifdef CONFIG_PCI_IOV int status; + be_check_sriov_fn_type(adapter); if (be_physfn(adapter) && num_vfs) { status = pci_enable_sriov(adapter->pdev, num_vfs); adapter->sriov_enabled = status ? false : true; -- cgit v1.2.3 From 9cd9000bdee9131ffd2ce92ca6ef9c86467edd25 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 23 Jul 2010 01:49:04 +0000 Subject: be2net: change to call pmac_del only if necessary If a mac address has not been configured for a VF, there is no need to call be_cmd_pmac_del. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_main.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index f17428caecf1..c730bd64628a 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -221,6 +221,7 @@ struct be_rx_obj { }; #define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ +#define BE_INVALID_PMAC_ID 0xffffffff struct be_adapter { struct pci_dev *pdev; struct net_device *netdev; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index e6ca92334d6d..899881b5aab9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -656,8 +656,9 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) if (!is_valid_ether_addr(mac) || (vf >= num_vfs)) return -EINVAL; - status = be_cmd_pmac_del(adapter, adapter->vf_if_handle[vf], - adapter->vf_pmac_id[vf]); + if (adapter->vf_pmac_id[vf] != BE_INVALID_PMAC_ID) + status = be_cmd_pmac_del(adapter, adapter->vf_if_handle[vf], + adapter->vf_pmac_id[vf]); status = be_cmd_pmac_add(adapter, mac, adapter->vf_if_handle[vf], &adapter->vf_pmac_id[vf]); @@ -1910,6 +1911,7 @@ static int be_setup(struct be_adapter *adapter) "Interface Create failed for VF %d\n", vf); goto if_destroy; } + adapter->vf_pmac_id[vf] = BE_INVALID_PMAC_ID; vf++; } } else if (!be_physfn(adapter)) { -- cgit v1.2.3 From 64600ea5f389858e183d3739776f4667265cc77f Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 23 Jul 2010 01:50:34 +0000 Subject: be2net: add support to get vf config Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 9 ++++++-- drivers/net/benet/be_main.c | 51 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 13 deletions(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index c730bd64628a..a8e95da23f7b 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -220,6 +220,12 @@ struct be_rx_obj { struct be_rx_page_info page_info_tbl[RX_Q_LEN]; }; +struct be_vf_cfg { + unsigned char vf_mac_addr[ETH_ALEN]; + u32 vf_if_handle; + u32 vf_pmac_id; +}; + #define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ #define BE_INVALID_PMAC_ID 0xffffffff struct be_adapter { @@ -289,8 +295,7 @@ struct be_adapter { struct completion flash_compl; bool sriov_enabled; - u32 vf_if_handle[BE_MAX_VF]; - u32 vf_pmac_id[BE_MAX_VF]; + struct be_vf_cfg vf_cfg[BE_MAX_VF]; u8 base_eq_id; u8 is_virtfn; }; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 899881b5aab9..a8c4548e0d60 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -656,18 +656,44 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) if (!is_valid_ether_addr(mac) || (vf >= num_vfs)) return -EINVAL; - if (adapter->vf_pmac_id[vf] != BE_INVALID_PMAC_ID) - status = be_cmd_pmac_del(adapter, adapter->vf_if_handle[vf], - adapter->vf_pmac_id[vf]); + if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) + status = be_cmd_pmac_del(adapter, + adapter->vf_cfg[vf].vf_if_handle, + adapter->vf_cfg[vf].vf_pmac_id); - status = be_cmd_pmac_add(adapter, mac, adapter->vf_if_handle[vf], - &adapter->vf_pmac_id[vf]); - if (!status) + status = be_cmd_pmac_add(adapter, mac, + adapter->vf_cfg[vf].vf_if_handle, + &adapter->vf_cfg[vf].vf_pmac_id); + + if (status) dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", mac, vf); + else + memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN); + return status; } +static int be_get_vf_config(struct net_device *netdev, int vf, + struct ifla_vf_info *vi) +{ + struct be_adapter *adapter = netdev_priv(netdev); + + if (!adapter->sriov_enabled) + return -EPERM; + + if (vf >= num_vfs) + return -EINVAL; + + vi->vf = vf; + vi->tx_rate = 0; + vi->vlan = 0; + vi->qos = 0; + memcpy(&vi->mac, adapter->vf_cfg[vf].vf_mac_addr, ETH_ALEN); + + return 0; +} + static void be_rx_rate_update(struct be_adapter *adapter) { struct be_drvr_stats *stats = drvr_stats(adapter); @@ -1904,14 +1930,15 @@ static int be_setup(struct be_adapter *adapter) cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; status = be_cmd_if_create(adapter, cap_flags, en_flags, - mac, true, &adapter->vf_if_handle[vf], + mac, true, + &adapter->vf_cfg[vf].vf_if_handle, NULL, vf+1); if (status) { dev_err(&adapter->pdev->dev, "Interface Create failed for VF %d\n", vf); goto if_destroy; } - adapter->vf_pmac_id[vf] = BE_INVALID_PMAC_ID; + adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID; vf++; } } else if (!be_physfn(adapter)) { @@ -1945,8 +1972,9 @@ tx_qs_destroy: be_tx_queues_destroy(adapter); if_destroy: for (vf = 0; vf < num_vfs; vf++) - if (adapter->vf_if_handle[vf]) - be_cmd_if_destroy(adapter, adapter->vf_if_handle[vf]); + if (adapter->vf_cfg[vf].vf_if_handle) + be_cmd_if_destroy(adapter, + adapter->vf_cfg[vf].vf_if_handle); be_cmd_if_destroy(adapter, adapter->if_handle); do_none: return status; @@ -2189,7 +2217,8 @@ static struct net_device_ops be_netdev_ops = { .ndo_vlan_rx_register = be_vlan_register, .ndo_vlan_rx_add_vid = be_vlan_add_vid, .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, - .ndo_set_vf_mac = be_set_vf_mac + .ndo_set_vf_mac = be_set_vf_mac, + .ndo_get_vf_config = be_get_vf_config }; static void be_netdev_init(struct net_device *netdev) -- cgit v1.2.3 From 1da87b7fafebb7874622602f79a5fec0425aede7 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 23 Jul 2010 01:51:22 +0000 Subject: be2net: add vlan support for sriov virtual functions Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_main.c | 54 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 8 deletions(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index a8e95da23f7b..f693b9ed68a4 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -224,6 +224,7 @@ struct be_vf_cfg { unsigned char vf_mac_addr[ETH_ALEN]; u32 vf_if_handle; u32 vf_pmac_id; + u16 vf_vlan_tag; }; #define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a8c4548e0d60..46f087e3422b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -552,11 +552,18 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu) * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE. * If the user configures more, place BE in vlan promiscuous mode. */ -static int be_vid_config(struct be_adapter *adapter) +static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) { u16 vtag[BE_NUM_VLANS_SUPPORTED]; u16 ntags = 0, i; int status = 0; + u32 if_handle; + + if (vf) { + if_handle = adapter->vf_cfg[vf_num].vf_if_handle; + vtag[0] = cpu_to_le16(adapter->vf_cfg[vf_num].vf_vlan_tag); + status = be_cmd_vlan_config(adapter, if_handle, vtag, 1, 1, 0); + } if (adapter->vlans_added <= adapter->max_vlans) { /* Construct VLAN Table to give to HW */ @@ -572,6 +579,7 @@ static int be_vid_config(struct be_adapter *adapter) status = be_cmd_vlan_config(adapter, adapter->if_handle, NULL, 0, 1, 1); } + return status; } @@ -592,27 +600,28 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid) { struct be_adapter *adapter = netdev_priv(netdev); + adapter->vlans_added++; if (!be_physfn(adapter)) return; adapter->vlan_tag[vid] = 1; - adapter->vlans_added++; if (adapter->vlans_added <= (adapter->max_vlans + 1)) - be_vid_config(adapter); + be_vid_config(adapter, false, 0); } static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) { struct be_adapter *adapter = netdev_priv(netdev); + adapter->vlans_added--; + vlan_group_set_device(adapter->vlan_grp, vid, NULL); + if (!be_physfn(adapter)) return; adapter->vlan_tag[vid] = 0; - vlan_group_set_device(adapter->vlan_grp, vid, NULL); - adapter->vlans_added--; if (adapter->vlans_added <= adapter->max_vlans) - be_vid_config(adapter); + be_vid_config(adapter, false, 0); } static void be_set_multicast_list(struct net_device *netdev) @@ -687,13 +696,41 @@ static int be_get_vf_config(struct net_device *netdev, int vf, vi->vf = vf; vi->tx_rate = 0; - vi->vlan = 0; + vi->vlan = adapter->vf_cfg[vf].vf_vlan_tag; vi->qos = 0; memcpy(&vi->mac, adapter->vf_cfg[vf].vf_mac_addr, ETH_ALEN); return 0; } +static int be_set_vf_vlan(struct net_device *netdev, + int vf, u16 vlan, u8 qos) +{ + struct be_adapter *adapter = netdev_priv(netdev); + int status = 0; + + if (!adapter->sriov_enabled) + return -EPERM; + + if ((vf >= num_vfs) || (vlan > 4095)) + return -EINVAL; + + if (vlan) { + adapter->vf_cfg[vf].vf_vlan_tag = vlan; + adapter->vlans_added++; + } else { + adapter->vf_cfg[vf].vf_vlan_tag = 0; + adapter->vlans_added--; + } + + status = be_vid_config(adapter, true, vf); + + if (status) + dev_info(&adapter->pdev->dev, + "VLAN %d config on VF %d failed\n", vlan, vf); + return status; +} + static void be_rx_rate_update(struct be_adapter *adapter) { struct be_drvr_stats *stats = drvr_stats(adapter); @@ -1849,7 +1886,7 @@ static int be_open(struct net_device *netdev) be_link_status_update(adapter, link_up); if (be_physfn(adapter)) { - status = be_vid_config(adapter); + status = be_vid_config(adapter, false, 0); if (status) goto err; @@ -2218,6 +2255,7 @@ static struct net_device_ops be_netdev_ops = { .ndo_vlan_rx_add_vid = be_vlan_add_vid, .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, .ndo_set_vf_mac = be_set_vf_mac, + .ndo_set_vf_vlan = be_set_vf_vlan, .ndo_get_vf_config = be_get_vf_config }; -- cgit v1.2.3 From e1d187353fc0597d24cf3169b1bbc1776058e883 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 23 Jul 2010 01:52:13 +0000 Subject: be2net: code to support tx rate configuration on virtual functions Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_cmds.c | 33 +++++++++++++++++++++++++++++++++ drivers/net/benet/be_cmds.h | 18 ++++++++++++++++++ drivers/net/benet/be_main.c | 27 ++++++++++++++++++++++++++- 4 files changed, 78 insertions(+), 1 deletion(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index f693b9ed68a4..8cfe3c4fea04 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -225,6 +225,7 @@ struct be_vf_cfg { u32 vf_if_handle; u32 vf_pmac_id; u16 vf_vlan_tag; + u32 vf_tx_rate; }; #define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 344e062b7f25..408e1f2dd8e8 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1730,3 +1730,36 @@ err: spin_unlock_bh(&adapter->mcc_lock); return status; } + +int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_set_qos *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_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_COMMON_SET_QOS); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_SET_QOS, sizeof(*req)); + + req->hdr.domain = domain; + req->valid_bits = BE_QOS_BITS_NIC; + req->max_bps_nic = bps; + + status = be_mcc_notify_wait(adapter); + +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 912a0586f060..3b69e71d7d03 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -124,6 +124,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_CQ_CREATE 12 #define OPCODE_COMMON_EQ_CREATE 13 #define OPCODE_COMMON_MCC_CREATE 21 +#define OPCODE_COMMON_SET_QOS 28 #define OPCODE_COMMON_SEEPROM_READ 30 #define OPCODE_COMMON_NTWK_RX_FILTER 34 #define OPCODE_COMMON_GET_FW_VERSION 35 @@ -894,6 +895,22 @@ struct be_cmd_resp_get_phy_info { u32 future_use[4]; }; +/*********************** Set QOS ***********************/ + +#define BE_QOS_BITS_NIC 1 + +struct be_cmd_req_set_qos { + struct be_cmd_req_hdr hdr; + u32 valid_bits; + u32 max_bps_nic; + u32 rsvd[7]; +}; + +struct be_cmd_resp_set_qos { + struct be_cmd_resp_hdr hdr; + u32 rsvd; +}; + extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, @@ -974,4 +991,5 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, u8 loopback_type, u8 enable); extern int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd); +extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 46f087e3422b..79adcdd8fc5c 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -695,7 +695,7 @@ static int be_get_vf_config(struct net_device *netdev, int vf, return -EINVAL; vi->vf = vf; - vi->tx_rate = 0; + vi->tx_rate = adapter->vf_cfg[vf].vf_tx_rate; vi->vlan = adapter->vf_cfg[vf].vf_vlan_tag; vi->qos = 0; memcpy(&vi->mac, adapter->vf_cfg[vf].vf_mac_addr, ETH_ALEN); @@ -731,6 +731,30 @@ static int be_set_vf_vlan(struct net_device *netdev, return status; } +static int be_set_vf_tx_rate(struct net_device *netdev, + int vf, int rate) +{ + struct be_adapter *adapter = netdev_priv(netdev); + int status = 0; + + if (!adapter->sriov_enabled) + return -EPERM; + + if ((vf >= num_vfs) || (rate < 0)) + return -EINVAL; + + if (rate > 10000) + rate = 10000; + + adapter->vf_cfg[vf].vf_tx_rate = rate; + status = be_cmd_set_qos(adapter, rate / 10, vf); + + if (status) + dev_info(&adapter->pdev->dev, + "tx rate %d on VF %d failed\n", rate, vf); + return status; +} + static void be_rx_rate_update(struct be_adapter *adapter) { struct be_drvr_stats *stats = drvr_stats(adapter); @@ -2256,6 +2280,7 @@ static struct net_device_ops be_netdev_ops = { .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, .ndo_set_vf_mac = be_set_vf_mac, .ndo_set_vf_vlan = be_set_vf_vlan, + .ndo_set_vf_tx_rate = be_set_vf_tx_rate, .ndo_get_vf_config = be_get_vf_config }; -- cgit v1.2.3 From 3486be29e63a9e8b0b013a9581879d8a48790d20 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 23 Jul 2010 02:04:54 +0000 Subject: be2net: variable name changes This patch changes names of some variables. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 +- drivers/net/benet/be_cmds.c | 4 ++-- drivers/net/benet/be_cmds.h | 2 +- drivers/net/benet/be_main.c | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 8cfe3c4fea04..434bc4bb6652 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -285,7 +285,7 @@ struct be_adapter { u32 port_num; bool promiscuous; bool wol; - u32 cap; + u32 function_mode; u32 rx_fc; /* Rx flow control */ u32 tx_fc; /* Tx flow control */ int link_speed; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 45b6f9050342..6eaf8a3fa5ea 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1258,7 +1258,7 @@ err: } /* Uses mbox */ -int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap) +int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) { struct be_mcc_wrb *wrb; struct be_cmd_req_query_fw_cfg *req; @@ -1279,7 +1279,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap) if (!status) { struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); *port_num = le32_to_cpu(resp->phys_port); - *cap = le32_to_cpu(resp->function_cap); + *mode = le32_to_cpu(resp->function_mode); } spin_unlock(&adapter->mbox_lock); diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 3b69e71d7d03..036531cd200f 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -749,7 +749,7 @@ struct be_cmd_resp_query_fw_cfg { u32 be_config_number; u32 asic_revision; u32 phys_port; - u32 function_cap; + u32 function_mode; u32 rsvd[26]; }; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 79adcdd8fc5c..d5b097d836b9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -963,7 +963,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, /* vlanf could be wrongly set in some cards. * ignore if vtm is not set */ - if ((adapter->cap & 0x400) && !vtm) + if ((adapter->function_mode & 0x400) && !vtm) vlanf = 0; if (unlikely(vlanf)) { @@ -1003,7 +1003,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, /* vlanf could be wrongly set in some cards. * ignore if vtm is not set */ - if ((adapter->cap & 0x400) && !vtm) + if ((adapter->function_mode & 0x400) && !vtm) vlanf = 0; skb = napi_get_frags(&eq_obj->napi); @@ -2500,7 +2500,7 @@ static int be_get_config(struct be_adapter *adapter) return status; status = be_cmd_query_fw_cfg(adapter, - &adapter->port_num, &adapter->cap); + &adapter->port_num, &adapter->function_mode); if (status) return status; @@ -2520,7 +2520,7 @@ static int be_get_config(struct be_adapter *adapter) memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); } - if (adapter->cap & 0x400) + if (adapter->function_mode & 0x400) adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; else adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; -- cgit v1.2.3 From e26198430919927d4c6128b77a35a6a8f735df31 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 23 Jul 2010 02:05:36 +0000 Subject: be2net: bump the driver version number Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 434bc4bb6652..e06369c36dd4 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -33,7 +33,7 @@ #include "be_hw.h" -#define DRV_VER "2.102.147u" +#define DRV_VER "2.103.175u" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" -- cgit v1.2.3 From 7c185276e8d820fa50a678c61abd611ee599920e Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Thu, 29 Jul 2010 06:16:33 +0000 Subject: be2net: add code to dump registers for debug when the BE device becomes unresponsive, dump the registers to help debugging Signed-off-by: Somnath K Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_cmds.c | 1 + drivers/net/benet/be_cmds.h | 1 + drivers/net/benet/be_hw.h | 10 ++++ drivers/net/benet/be_main.c | 127 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index e06369c36dd4..5e6f581c49d4 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -288,6 +288,7 @@ struct be_adapter { u32 function_mode; u32 rx_fc; /* Rx flow control */ u32 tx_fc; /* Tx flow control */ + bool ue_detected; int link_speed; u8 port_type; u8 transceiver; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 6eaf8a3fa5ea..7fd860dcbc80 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -206,6 +206,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) if (msecs > 4000) { dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); + be_dump_ue(adapter); return -1; } diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 036531cd200f..bdc10a28cfda 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -992,4 +992,5 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, extern int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd); extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); +extern void be_dump_ue(struct be_adapter *adapter); diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 06839676e3c4..6c8f9bb8bfe6 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -56,6 +56,16 @@ #define PCICFG_PM_CONTROL_OFFSET 0x44 #define PCICFG_PM_CONTROL_MASK 0x108 /* bits 3 & 8 */ +/********* Online Control Registers *******/ +#define PCICFG_ONLINE0 0xB0 +#define PCICFG_ONLINE1 0xB4 + +/********* UE Status and Mask Registers ***/ +#define PCICFG_UE_STATUS_LOW 0xA0 +#define PCICFG_UE_STATUS_HIGH 0xA4 +#define PCICFG_UE_STATUS_LOW_MASK 0xA8 +#define PCICFG_UE_STATUS_HI_MASK 0xAC + /********* ISR0 Register offset **********/ #define CEV_ISR0_OFFSET 0xC18 #define CEV_ISR_SIZE 4 diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index e72b482c4327..e4a8ae3a1c8d 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -40,6 +40,76 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { 0 } }; MODULE_DEVICE_TABLE(pci, be_dev_ids); +/* UE Status Low CSR */ +static char *ue_status_low_desc[] = { + "CEV", + "CTX", + "DBUF", + "ERX", + "Host", + "MPU", + "NDMA", + "PTC ", + "RDMA ", + "RXF ", + "RXIPS ", + "RXULP0 ", + "RXULP1 ", + "RXULP2 ", + "TIM ", + "TPOST ", + "TPRE ", + "TXIPS ", + "TXULP0 ", + "TXULP1 ", + "UC ", + "WDMA ", + "TXULP2 ", + "HOST1 ", + "P0_OB_LINK ", + "P1_OB_LINK ", + "HOST_GPIO ", + "MBOX ", + "AXGMAC0", + "AXGMAC1", + "JTAG", + "MPU_INTPEND" +}; +/* UE Status High CSR */ +static char *ue_status_hi_desc[] = { + "LPCMEMHOST", + "MGMT_MAC", + "PCS0ONLINE", + "MPU_IRAM", + "PCS1ONLINE", + "PCTL0", + "PCTL1", + "PMEM", + "RR", + "TXPB", + "RXPP", + "XAUI", + "TXP", + "ARM", + "IPC", + "HOST2", + "HOST3", + "HOST4", + "HOST5", + "HOST6", + "HOST7", + "HOST8", + "HOST9", + "NETC" + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown" +}; static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) { @@ -1673,6 +1743,59 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) return 1; } +static inline bool be_detect_ue(struct be_adapter *adapter) +{ + u32 online0 = 0, online1 = 0; + + pci_read_config_dword(adapter->pdev, PCICFG_ONLINE0, &online0); + + pci_read_config_dword(adapter->pdev, PCICFG_ONLINE1, &online1); + + if (!online0 || !online1) { + adapter->ue_detected = true; + dev_err(&adapter->pdev->dev, + "UE Detected!! online0=%d online1=%d\n", + online0, online1); + return true; + } + + return false; +} + +void be_dump_ue(struct be_adapter *adapter) +{ + u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask; + u32 i; + + pci_read_config_dword(adapter->pdev, + PCICFG_UE_STATUS_LOW, &ue_status_lo); + pci_read_config_dword(adapter->pdev, + PCICFG_UE_STATUS_HIGH, &ue_status_hi); + pci_read_config_dword(adapter->pdev, + PCICFG_UE_STATUS_LOW_MASK, &ue_status_lo_mask); + pci_read_config_dword(adapter->pdev, + PCICFG_UE_STATUS_HI_MASK, &ue_status_hi_mask); + + ue_status_lo = (ue_status_lo & (~ue_status_lo_mask)); + ue_status_hi = (ue_status_hi & (~ue_status_hi_mask)); + + if (ue_status_lo) { + for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) { + if (ue_status_lo & 1) + dev_err(&adapter->pdev->dev, + "UE: %s bit set\n", ue_status_low_desc[i]); + } + } + if (ue_status_hi) { + for (i = 0; ue_status_hi; ue_status_hi >>= 1, i++) { + if (ue_status_hi & 1) + dev_err(&adapter->pdev->dev, + "UE: %s bit set\n", ue_status_hi_desc[i]); + } + } + +} + static void be_worker(struct work_struct *work) { struct be_adapter *adapter = @@ -1690,6 +1813,10 @@ static void be_worker(struct work_struct *work) adapter->rx_post_starved = false; be_post_rx_frags(adapter); } + if (!adapter->ue_detected) { + if (be_detect_ue(adapter)) + be_dump_ue(adapter); + } schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); } -- cgit v1.2.3 From 0fc48c37ff3969dde71a43fa7c8f176d4bd90a3e Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Thu, 29 Jul 2010 06:18:58 +0000 Subject: be2net: fix to avoid sending get_stats request if one is already being processed. GET_STATS request uses the same memory region as the response. If a new request for get stats is fired before the response for the previous get_stats request is received, the response will corrupt the new request, causing the f/w to misbehave. Signed-off-by: Somnath K Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_cmds.c | 2 ++ drivers/net/benet/be_main.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net/benet/be.h') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 5e6f581c49d4..99197bd54da5 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -289,6 +289,7 @@ struct be_adapter { u32 rx_fc; /* Rx flow control */ u32 tx_fc; /* Tx flow control */ bool ue_detected; + bool stats_ioctl_sent; int link_speed; u8 port_type; u8 transceiver; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 7fd860dcbc80..3d305494a606 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -75,6 +75,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter, be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); netdev_stats_update(adapter); + adapter->stats_ioctl_sent = false; } } else if ((compl_status != MCC_STATUS_NOT_SUPPORTED) && (compl->tag0 != OPCODE_COMMON_NTWK_MAC_QUERY)) { @@ -951,6 +952,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) sge->len = cpu_to_le32(nonemb_cmd->size); be_mcc_notify(adapter); + adapter->stats_ioctl_sent = true; err: spin_unlock_bh(&adapter->mcc_lock); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index e4a8ae3a1c8d..74e146f470c6 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1801,7 +1801,8 @@ static void be_worker(struct work_struct *work) struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); - be_cmd_get_stats(adapter, &adapter->stats.cmd); + if (!adapter->stats_ioctl_sent) + be_cmd_get_stats(adapter, &adapter->stats.cmd); /* Set EQ delay */ be_rx_eqd_update(adapter); -- cgit v1.2.3