diff options
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_main.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 148 |
1 files changed, 75 insertions, 73 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 08efd30..896f283 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -719,8 +719,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, * 60 bytes long. * As a workaround disable TX vlan offloading in such cases. */ - if (unlikely(vlan_tx_tag_present(skb) && - (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60))) { + if (vlan_tx_tag_present(skb) && + (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60)) { skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) goto tx_drop; @@ -785,19 +785,12 @@ 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, bool vf, u32 vf_num) +static int be_vid_config(struct be_adapter *adapter) { - struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf_num]; - u16 vtag[BE_NUM_VLANS_SUPPORTED]; - u16 ntags = 0, i; + u16 vids[BE_NUM_VLANS_SUPPORTED]; + u16 num = 0, i; int status = 0; - if (vf) { - vtag[0] = cpu_to_le16(vf_cfg->vlan_tag); - status = be_cmd_vlan_config(adapter, vf_cfg->if_handle, vtag, - 1, 1, 0); - } - /* No need to further configure vids if in promiscuous mode */ if (adapter->promiscuous) return 0; @@ -808,10 +801,10 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) /* Construct VLAN Table to give to HW */ for (i = 0; i < VLAN_N_VID; i++) if (adapter->vlan_tag[i]) - vtag[ntags++] = cpu_to_le16(i); + vids[num++] = cpu_to_le16(i); status = be_cmd_vlan_config(adapter, adapter->if_handle, - vtag, ntags, 1, 0); + vids, num, 1, 0); /* Set to VLAN promisc mode as setting VLAN filter failed */ if (status) { @@ -840,7 +833,7 @@ static int be_vlan_add_vid(struct net_device *netdev, u16 vid) adapter->vlan_tag[vid] = 1; if (adapter->vlans_added <= (adapter->max_vlans + 1)) - status = be_vid_config(adapter, false, 0); + status = be_vid_config(adapter); if (!status) adapter->vlans_added++; @@ -862,7 +855,7 @@ static int be_vlan_rem_vid(struct net_device *netdev, u16 vid) adapter->vlan_tag[vid] = 0; if (adapter->vlans_added <= adapter->max_vlans) - status = be_vid_config(adapter, false, 0); + status = be_vid_config(adapter); if (!status) adapter->vlans_added--; @@ -889,7 +882,7 @@ static void be_set_rx_mode(struct net_device *netdev) be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); if (adapter->vlans_added) - be_vid_config(adapter, false, 0); + be_vid_config(adapter); } /* Enable multicast promisc if num configured exceeds what we support */ @@ -1056,6 +1049,8 @@ static int be_find_vfs(struct be_adapter *adapter, int vf_state) u16 offset, stride; pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + if (!pos) + return 0; pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset); pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride); @@ -1897,6 +1892,12 @@ static int be_rx_cqs_create(struct be_adapter *adapter) */ adapter->num_rx_qs = (num_irqs(adapter) > 1) ? num_irqs(adapter) + 1 : 1; + if (adapter->num_rx_qs != MAX_RX_QS) { + rtnl_lock(); + netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_qs); + rtnl_unlock(); + } adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; for_all_rx_queues(adapter, rxo, i) { @@ -2543,7 +2544,6 @@ static int be_clear(struct be_adapter *adapter) be_cmd_fw_clean(adapter); be_msix_disable(adapter); - pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0); return 0; } @@ -2601,8 +2601,8 @@ static int be_vf_setup(struct be_adapter *adapter) cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST; for_all_vfs(adapter, vf_cfg, vf) { - status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL, - &vf_cfg->if_handle, NULL, vf + 1); + status = be_cmd_if_create(adapter, cap_flags, en_flags, + &vf_cfg->if_handle, vf + 1); if (status) goto err; } @@ -2642,29 +2642,43 @@ static void be_setup_init(struct be_adapter *adapter) adapter->phy.forced_port_speed = -1; } -static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac) +static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle, + bool *active_mac, u32 *pmac_id) { - u32 pmac_id; - int status; - bool pmac_id_active; + int status = 0; - status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id_active, - &pmac_id, mac); - if (status != 0) - goto do_none; + if (!is_zero_ether_addr(adapter->netdev->perm_addr)) { + memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN); + if (!lancer_chip(adapter) && !be_physfn(adapter)) + *active_mac = true; + else + *active_mac = false; - if (pmac_id_active) { - status = be_cmd_mac_addr_query(adapter, mac, - MAC_ADDRESS_TYPE_NETWORK, - false, adapter->if_handle, pmac_id); + return status; + } - if (!status) - adapter->pmac_id[0] = pmac_id; + if (lancer_chip(adapter)) { + status = be_cmd_get_mac_from_list(adapter, mac, + active_mac, pmac_id, 0); + if (*active_mac) { + status = be_cmd_mac_addr_query(adapter, mac, + MAC_ADDRESS_TYPE_NETWORK, + false, if_handle, + *pmac_id); + } + } else if (be_physfn(adapter)) { + /* For BE3, for PF get permanent MAC */ + status = be_cmd_mac_addr_query(adapter, mac, + MAC_ADDRESS_TYPE_NETWORK, true, + 0, 0); + *active_mac = false; } else { - status = be_cmd_pmac_add(adapter, mac, - adapter->if_handle, &adapter->pmac_id[0], 0); + /* For BE3, for VF get soft MAC assigned by PF*/ + status = be_cmd_mac_addr_query(adapter, mac, + MAC_ADDRESS_TYPE_NETWORK, false, + if_handle, 0); + *active_mac = true; } -do_none: return status; } @@ -2685,12 +2699,12 @@ static int be_get_config(struct be_adapter *adapter) static int be_setup(struct be_adapter *adapter) { - struct net_device *netdev = adapter->netdev; struct device *dev = &adapter->pdev->dev; u32 cap_flags, en_flags; u32 tx_fc, rx_fc; int status; u8 mac[ETH_ALEN]; + bool active_mac; be_setup_init(adapter); @@ -2716,14 +2730,6 @@ static int be_setup(struct be_adapter *adapter) if (status) goto err; - memset(mac, 0, ETH_ALEN); - status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, - true /*permanent */, 0, 0); - if (status) - return status; - memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); - memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); - en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | @@ -2733,27 +2739,29 @@ static int be_setup(struct be_adapter *adapter) cap_flags |= BE_IF_FLAGS_RSS; en_flags |= BE_IF_FLAGS_RSS; } + status = be_cmd_if_create(adapter, cap_flags, en_flags, - netdev->dev_addr, &adapter->if_handle, - &adapter->pmac_id[0], 0); + &adapter->if_handle, 0); if (status != 0) goto err; - /* The VF's permanent mac queried from card is incorrect. - * For BEx: Query the mac configued by the PF using if_handle - * For Lancer: Get and use mac_list to obtain mac address. - */ - if (!be_physfn(adapter)) { - if (lancer_chip(adapter)) - status = be_add_mac_from_list(adapter, mac); - else - status = be_cmd_mac_addr_query(adapter, mac, - MAC_ADDRESS_TYPE_NETWORK, false, - adapter->if_handle, 0); - if (!status) { - memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); - memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); - } + memset(mac, 0, ETH_ALEN); + active_mac = false; + status = be_get_mac_addr(adapter, mac, adapter->if_handle, + &active_mac, &adapter->pmac_id[0]); + if (status != 0) + goto err; + + if (!active_mac) { + status = be_cmd_pmac_add(adapter, mac, adapter->if_handle, + &adapter->pmac_id[0], 0); + if (status != 0) + goto err; + } + + if (is_zero_ether_addr(adapter->netdev->dev_addr)) { + memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); + memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); } status = be_tx_qs_create(adapter); @@ -2762,7 +2770,8 @@ static int be_setup(struct be_adapter *adapter) be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL); - be_vid_config(adapter, false, 0); + if (adapter->vlans_added) + be_vid_config(adapter); be_set_rx_mode(adapter->netdev); @@ -2772,8 +2781,6 @@ static int be_setup(struct be_adapter *adapter) be_cmd_set_flow_control(adapter, adapter->tx_fc, adapter->rx_fc); - pcie_set_readrq(adapter->pdev, 4096); - if (be_physfn(adapter) && num_vfs) { if (adapter->dev_num_vfs) be_vf_setup(adapter); @@ -2787,8 +2794,6 @@ static int be_setup(struct be_adapter *adapter) schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; - - pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1); return 0; err: be_clear(adapter); @@ -3726,10 +3731,7 @@ reschedule: static bool be_reset_required(struct be_adapter *adapter) { - u32 reg; - - pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, ®); - return reg; + return be_find_vfs(adapter, ENABLED) > 0 ? false : true; } static int __devinit be_probe(struct pci_dev *pdev, @@ -3748,7 +3750,7 @@ static int __devinit be_probe(struct pci_dev *pdev, goto disable_dev; pci_set_master(pdev); - netdev = alloc_etherdev_mq(sizeof(struct be_adapter), MAX_TX_QS); + netdev = alloc_etherdev_mqs(sizeof(*adapter), MAX_TX_QS, MAX_RX_QS); if (netdev == NULL) { status = -ENOMEM; goto rel_reg; |