diff options
Diffstat (limited to 'drivers/net/cxgb4vf/cxgb4vf_main.c')
| -rw-r--r-- | drivers/net/cxgb4vf/cxgb4vf_main.c | 116 |
1 files changed, 72 insertions, 44 deletions
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 555ecc5a2e93..d887a76cd39d 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
| @@ -753,7 +753,9 @@ static int cxgb4vf_open(struct net_device *dev) | |||
| 753 | if (err) | 753 | if (err) |
| 754 | return err; | 754 | return err; |
| 755 | set_bit(pi->port_id, &adapter->open_device_map); | 755 | set_bit(pi->port_id, &adapter->open_device_map); |
| 756 | link_start(dev); | 756 | err = link_start(dev); |
| 757 | if (err) | ||
| 758 | return err; | ||
| 757 | netif_tx_start_all_queues(dev); | 759 | netif_tx_start_all_queues(dev); |
| 758 | return 0; | 760 | return 0; |
| 759 | } | 761 | } |
| @@ -814,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev) | |||
| 814 | } | 816 | } |
| 815 | 817 | ||
| 816 | /* | 818 | /* |
| 817 | * Collect up to maxaddrs worth of a netdevice's unicast addresses into an | 819 | * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting |
| 818 | * array of addrss pointers and return the number collected. | 820 | * at a specified offset within the list, into an array of addrss pointers and |
| 821 | * return the number collected. | ||
| 819 | */ | 822 | */ |
| 820 | static inline int collect_netdev_uc_list_addrs(const struct net_device *dev, | 823 | static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev, |
| 821 | const u8 **addr, | 824 | const u8 **addr, |
| 822 | unsigned int maxaddrs) | 825 | unsigned int offset, |
| 826 | unsigned int maxaddrs) | ||
| 823 | { | 827 | { |
| 828 | unsigned int index = 0; | ||
| 824 | unsigned int naddr = 0; | 829 | unsigned int naddr = 0; |
| 825 | const struct netdev_hw_addr *ha; | 830 | const struct netdev_hw_addr *ha; |
| 826 | 831 | ||
| 827 | for_each_dev_addr(dev, ha) { | 832 | for_each_dev_addr(dev, ha) |
| 828 | addr[naddr++] = ha->addr; | 833 | if (index++ >= offset) { |
| 829 | if (naddr >= maxaddrs) | 834 | addr[naddr++] = ha->addr; |
| 830 | break; | 835 | if (naddr >= maxaddrs) |
| 831 | } | 836 | break; |
| 837 | } | ||
| 832 | return naddr; | 838 | return naddr; |
| 833 | } | 839 | } |
| 834 | 840 | ||
| 835 | /* | 841 | /* |
| 836 | * Collect up to maxaddrs worth of a netdevice's multicast addresses into an | 842 | * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting |
| 837 | * array of addrss pointers and return the number collected. | 843 | * at a specified offset within the list, into an array of addrss pointers and |
| 844 | * return the number collected. | ||
| 838 | */ | 845 | */ |
| 839 | static inline int collect_netdev_mc_list_addrs(const struct net_device *dev, | 846 | static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev, |
| 840 | const u8 **addr, | 847 | const u8 **addr, |
| 841 | unsigned int maxaddrs) | 848 | unsigned int offset, |
| 849 | unsigned int maxaddrs) | ||
| 842 | { | 850 | { |
| 851 | unsigned int index = 0; | ||
| 843 | unsigned int naddr = 0; | 852 | unsigned int naddr = 0; |
| 844 | const struct netdev_hw_addr *ha; | 853 | const struct netdev_hw_addr *ha; |
| 845 | 854 | ||
| 846 | netdev_for_each_mc_addr(ha, dev) { | 855 | netdev_for_each_mc_addr(ha, dev) |
| 847 | addr[naddr++] = ha->addr; | 856 | if (index++ >= offset) { |
| 848 | if (naddr >= maxaddrs) | 857 | addr[naddr++] = ha->addr; |
| 849 | break; | 858 | if (naddr >= maxaddrs) |
| 850 | } | 859 | break; |
| 860 | } | ||
| 851 | return naddr; | 861 | return naddr; |
| 852 | } | 862 | } |
| 853 | 863 | ||
| @@ -860,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
| 860 | u64 mhash = 0; | 870 | u64 mhash = 0; |
| 861 | u64 uhash = 0; | 871 | u64 uhash = 0; |
| 862 | bool free = true; | 872 | bool free = true; |
| 863 | u16 filt_idx[7]; | 873 | unsigned int offset, naddr; |
| 864 | const u8 *addr[7]; | 874 | const u8 *addr[7]; |
| 865 | int ret, naddr = 0; | 875 | int ret; |
| 866 | const struct port_info *pi = netdev_priv(dev); | 876 | const struct port_info *pi = netdev_priv(dev); |
| 867 | 877 | ||
| 868 | /* first do the secondary unicast addresses */ | 878 | /* first do the secondary unicast addresses */ |
| 869 | naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr)); | 879 | for (offset = 0; ; offset += naddr) { |
| 870 | if (naddr > 0) { | 880 | naddr = collect_netdev_uc_list_addrs(dev, addr, offset, |
| 881 | ARRAY_SIZE(addr)); | ||
| 882 | if (naddr == 0) | ||
| 883 | break; | ||
| 884 | |||
| 871 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, | 885 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, |
| 872 | naddr, addr, filt_idx, &uhash, sleep); | 886 | naddr, addr, NULL, &uhash, sleep); |
| 873 | if (ret < 0) | 887 | if (ret < 0) |
| 874 | return ret; | 888 | return ret; |
| 875 | 889 | ||
| @@ -877,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
| 877 | } | 891 | } |
| 878 | 892 | ||
| 879 | /* next set up the multicast addresses */ | 893 | /* next set up the multicast addresses */ |
| 880 | naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr)); | 894 | for (offset = 0; ; offset += naddr) { |
| 881 | if (naddr > 0) { | 895 | naddr = collect_netdev_mc_list_addrs(dev, addr, offset, |
| 896 | ARRAY_SIZE(addr)); | ||
| 897 | if (naddr == 0) | ||
| 898 | break; | ||
| 899 | |||
| 882 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, | 900 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, |
| 883 | naddr, addr, filt_idx, &mhash, sleep); | 901 | naddr, addr, NULL, &mhash, sleep); |
| 884 | if (ret < 0) | 902 | if (ret < 0) |
| 885 | return ret; | 903 | return ret; |
| 904 | free = false; | ||
| 886 | } | 905 | } |
| 887 | 906 | ||
| 888 | return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0, | 907 | return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0, |
| @@ -1103,18 +1122,6 @@ static int cxgb4vf_set_mac_addr(struct net_device *dev, void *_addr) | |||
| 1103 | return 0; | 1122 | return 0; |
| 1104 | } | 1123 | } |
| 1105 | 1124 | ||
| 1106 | /* | ||
| 1107 | * Return a TX Queue on which to send the specified skb. | ||
| 1108 | */ | ||
| 1109 | static u16 cxgb4vf_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
| 1110 | { | ||
| 1111 | /* | ||
| 1112 | * XXX For now just use the default hash but we probably want to | ||
| 1113 | * XXX look at other possibilities ... | ||
| 1114 | */ | ||
| 1115 | return skb_tx_hash(dev, skb); | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1125 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 1119 | /* | 1126 | /* |
| 1120 | * Poll all of our receive queues. This is called outside of normal interrupt | 1127 | * Poll all of our receive queues. This is called outside of normal interrupt |
| @@ -2075,6 +2082,22 @@ static int adap_init0(struct adapter *adapter) | |||
| 2075 | } | 2082 | } |
| 2076 | 2083 | ||
| 2077 | /* | 2084 | /* |
| 2085 | * Some environments do not properly handle PCIE FLRs -- e.g. in Linux | ||
| 2086 | * 2.6.31 and later we can't call pci_reset_function() in order to | ||
| 2087 | * issue an FLR because of a self- deadlock on the device semaphore. | ||
| 2088 | * Meanwhile, the OS infrastructure doesn't issue FLRs in all the | ||
| 2089 | * cases where they're needed -- for instance, some versions of KVM | ||
| 2090 | * fail to reset "Assigned Devices" when the VM reboots. Therefore we | ||
| 2091 | * use the firmware based reset in order to reset any per function | ||
| 2092 | * state. | ||
| 2093 | */ | ||
| 2094 | err = t4vf_fw_reset(adapter); | ||
| 2095 | if (err < 0) { | ||
| 2096 | dev_err(adapter->pdev_dev, "FW reset failed: err=%d\n", err); | ||
| 2097 | return err; | ||
| 2098 | } | ||
| 2099 | |||
| 2100 | /* | ||
| 2078 | * Grab basic operational parameters. These will predominantly have | 2101 | * Grab basic operational parameters. These will predominantly have |
| 2079 | * been set up by the Physical Function Driver or will be hard coded | 2102 | * been set up by the Physical Function Driver or will be hard coded |
| 2080 | * into the adapter. We just have to live with them ... Note that | 2103 | * into the adapter. We just have to live with them ... Note that |
| @@ -2417,7 +2440,6 @@ static const struct net_device_ops cxgb4vf_netdev_ops = { | |||
| 2417 | .ndo_get_stats = cxgb4vf_get_stats, | 2440 | .ndo_get_stats = cxgb4vf_get_stats, |
| 2418 | .ndo_set_rx_mode = cxgb4vf_set_rxmode, | 2441 | .ndo_set_rx_mode = cxgb4vf_set_rxmode, |
| 2419 | .ndo_set_mac_address = cxgb4vf_set_mac_addr, | 2442 | .ndo_set_mac_address = cxgb4vf_set_mac_addr, |
| 2420 | .ndo_select_queue = cxgb4vf_select_queue, | ||
| 2421 | .ndo_validate_addr = eth_validate_addr, | 2443 | .ndo_validate_addr = eth_validate_addr, |
| 2422 | .ndo_do_ioctl = cxgb4vf_do_ioctl, | 2444 | .ndo_do_ioctl = cxgb4vf_do_ioctl, |
| 2423 | .ndo_change_mtu = cxgb4vf_change_mtu, | 2445 | .ndo_change_mtu = cxgb4vf_change_mtu, |
| @@ -2600,7 +2622,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2600 | pi->xact_addr_filt = -1; | 2622 | pi->xact_addr_filt = -1; |
| 2601 | pi->rx_offload = RX_CSO; | 2623 | pi->rx_offload = RX_CSO; |
| 2602 | netif_carrier_off(netdev); | 2624 | netif_carrier_off(netdev); |
| 2603 | netif_tx_stop_all_queues(netdev); | ||
| 2604 | netdev->irq = pdev->irq; | 2625 | netdev->irq = pdev->irq; |
| 2605 | 2626 | ||
| 2606 | netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | | 2627 | netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | |
| @@ -2625,7 +2646,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2625 | netdev->do_ioctl = cxgb4vf_do_ioctl; | 2646 | netdev->do_ioctl = cxgb4vf_do_ioctl; |
| 2626 | netdev->change_mtu = cxgb4vf_change_mtu; | 2647 | netdev->change_mtu = cxgb4vf_change_mtu; |
| 2627 | netdev->set_mac_address = cxgb4vf_set_mac_addr; | 2648 | netdev->set_mac_address = cxgb4vf_set_mac_addr; |
| 2628 | netdev->select_queue = cxgb4vf_select_queue; | ||
| 2629 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2649 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 2630 | netdev->poll_controller = cxgb4vf_poll_controller; | 2650 | netdev->poll_controller = cxgb4vf_poll_controller; |
| 2631 | #endif | 2651 | #endif |
| @@ -2844,6 +2864,14 @@ static struct pci_device_id cxgb4vf_pci_tbl[] = { | |||
| 2844 | CH_DEVICE(0x4800, 0), /* T440-dbg */ | 2864 | CH_DEVICE(0x4800, 0), /* T440-dbg */ |
| 2845 | CH_DEVICE(0x4801, 0), /* T420-cr */ | 2865 | CH_DEVICE(0x4801, 0), /* T420-cr */ |
| 2846 | CH_DEVICE(0x4802, 0), /* T422-cr */ | 2866 | CH_DEVICE(0x4802, 0), /* T422-cr */ |
| 2867 | CH_DEVICE(0x4803, 0), /* T440-cr */ | ||
| 2868 | CH_DEVICE(0x4804, 0), /* T420-bch */ | ||
| 2869 | CH_DEVICE(0x4805, 0), /* T440-bch */ | ||
| 2870 | CH_DEVICE(0x4806, 0), /* T460-ch */ | ||
| 2871 | CH_DEVICE(0x4807, 0), /* T420-so */ | ||
| 2872 | CH_DEVICE(0x4808, 0), /* T420-cx */ | ||
| 2873 | CH_DEVICE(0x4809, 0), /* T420-bt */ | ||
| 2874 | CH_DEVICE(0x480a, 0), /* T404-bt */ | ||
| 2847 | { 0, } | 2875 | { 0, } |
| 2848 | }; | 2876 | }; |
| 2849 | 2877 | ||
