aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 23:53:45 -0400
commitcd6362befe4cc7bf589a5236d2a780af2d47bcc9 (patch)
tree3bd4e13ec3f92a00dc4f6c3d65e820b54dbfe46e /drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
parent0f1b1e6d73cb989ce2c071edc57deade3b084dfe (diff)
parentb1586f099ba897542ece36e8a23c1a62907261ef (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Here is my initial pull request for the networking subsystem during this merge window: 1) Support for ESN in AH (RFC 4302) from Fan Du. 2) Add full kernel doc for ethtool command structures, from Ben Hutchings. 3) Add BCM7xxx PHY driver, from Florian Fainelli. 4) Export computed TCP rate information in netlink socket dumps, from Eric Dumazet. 5) Allow IPSEC SA to be dumped partially using a filter, from Nicolas Dichtel. 6) Convert many drivers to pci_enable_msix_range(), from Alexander Gordeev. 7) Record SKB timestamps more efficiently, from Eric Dumazet. 8) Switch to microsecond resolution for TCP round trip times, also from Eric Dumazet. 9) Clean up and fix 6lowpan fragmentation handling by making use of the existing inet_frag api for it's implementation. 10) Add TX grant mapping to xen-netback driver, from Zoltan Kiss. 11) Auto size SKB lengths when composing netlink messages based upon past message sizes used, from Eric Dumazet. 12) qdisc dumps can take a long time, add a cond_resched(), From Eric Dumazet. 13) Sanitize netpoll core and drivers wrt. SKB handling semantics. Get rid of never-used-in-tree netpoll RX handling. From Eric W Biederman. 14) Support inter-address-family and namespace changing in VTI tunnel driver(s). From Steffen Klassert. 15) Add Altera TSE driver, from Vince Bridgers. 16) Optimizing csum_replace2() so that it doesn't adjust the checksum by checksumming the entire header, from Eric Dumazet. 17) Expand BPF internal implementation for faster interpreting, more direct translations into JIT'd code, and much cleaner uses of BPF filtering in non-socket ocntexts. From Daniel Borkmann and Alexei Starovoitov" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1976 commits) netpoll: Use skb_irq_freeable to make zap_completion_queue safe. net: Add a test to see if a skb is freeable in irq context qlcnic: Fix build failure due to undefined reference to `vxlan_get_rx_port' net: ptp: move PTP classifier in its own file net: sxgbe: make "core_ops" static net: sxgbe: fix logical vs bitwise operation net: sxgbe: sxgbe_mdio_register() frees the bus Call efx_set_channels() before efx->type->dimension_resources() xen-netback: disable rogue vif in kthread context net/mlx4: Set proper build dependancy with vxlan be2net: fix build dependency on VxLAN mac802154: make csma/cca parameters per-wpan mac802154: allow only one WPAN to be up at any given time net: filter: minor: fix kdoc in __sk_run_filter netlink: don't compare the nul-termination in nla_strcmp can: c_can: Avoid led toggling for every packet. can: c_can: Simplify TX interrupt cleanup can: c_can: Store dlc private can: c_can: Reduce register access can: c_can: Make the code readable ...
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c135
1 files changed, 104 insertions, 31 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index b9d1c1c8ca5a..02c11a7f7d29 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -69,7 +69,7 @@ static inline bool i40e_vc_isvalid_vector_id(struct i40e_vf *vf, u8 vector_id)
69{ 69{
70 struct i40e_pf *pf = vf->pf; 70 struct i40e_pf *pf = vf->pf;
71 71
72 return vector_id <= pf->hw.func_caps.num_msix_vectors_vf; 72 return vector_id < pf->hw.func_caps.num_msix_vectors_vf;
73} 73}
74 74
75/***********************vf resource mgmt routines*****************/ 75/***********************vf resource mgmt routines*****************/
@@ -126,8 +126,8 @@ static void i40e_config_irq_link_list(struct i40e_vf *vf, u16 vsi_idx,
126 reg_idx = I40E_VPINT_LNKLST0(vf->vf_id); 126 reg_idx = I40E_VPINT_LNKLST0(vf->vf_id);
127 else 127 else
128 reg_idx = I40E_VPINT_LNKLSTN( 128 reg_idx = I40E_VPINT_LNKLSTN(
129 (pf->hw.func_caps.num_msix_vectors_vf 129 ((pf->hw.func_caps.num_msix_vectors_vf - 1) * vf->vf_id) +
130 * vf->vf_id) + (vector_id - 1)); 130 (vector_id - 1));
131 131
132 if (vecmap->rxq_map == 0 && vecmap->txq_map == 0) { 132 if (vecmap->rxq_map == 0 && vecmap->txq_map == 0) {
133 /* Special case - No queues mapped on this vector */ 133 /* Special case - No queues mapped on this vector */
@@ -230,6 +230,9 @@ static int i40e_config_vsi_tx_queue(struct i40e_vf *vf, u16 vsi_idx,
230 tx_ctx.qlen = info->ring_len; 230 tx_ctx.qlen = info->ring_len;
231 tx_ctx.rdylist = le16_to_cpu(pf->vsi[vsi_idx]->info.qs_handle[0]); 231 tx_ctx.rdylist = le16_to_cpu(pf->vsi[vsi_idx]->info.qs_handle[0]);
232 tx_ctx.rdylist_act = 0; 232 tx_ctx.rdylist_act = 0;
233 tx_ctx.head_wb_ena = 1;
234 tx_ctx.head_wb_addr = info->dma_ring_addr +
235 (info->ring_len * sizeof(struct i40e_tx_desc));
233 236
234 /* clear the context in the HMC */ 237 /* clear the context in the HMC */
235 ret = i40e_clear_lan_tx_queue_context(hw, pf_queue_id); 238 ret = i40e_clear_lan_tx_queue_context(hw, pf_queue_id);
@@ -408,18 +411,10 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
408 "Could not allocate VF broadcast filter\n"); 411 "Could not allocate VF broadcast filter\n");
409 } 412 }
410 413
411 if (!f) {
412 dev_err(&pf->pdev->dev, "Unable to add ucast filter\n");
413 ret = -ENOMEM;
414 goto error_alloc_vsi_res;
415 }
416
417 /* program mac filter */ 414 /* program mac filter */
418 ret = i40e_sync_vsi_filters(vsi); 415 ret = i40e_sync_vsi_filters(vsi);
419 if (ret) { 416 if (ret)
420 dev_err(&pf->pdev->dev, "Unable to program ucast filters\n"); 417 dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
421 goto error_alloc_vsi_res;
422 }
423 418
424error_alloc_vsi_res: 419error_alloc_vsi_res:
425 return ret; 420 return ret;
@@ -514,7 +509,8 @@ static void i40e_free_vf_res(struct i40e_vf *vf)
514 vf->lan_vsi_index = 0; 509 vf->lan_vsi_index = 0;
515 vf->lan_vsi_id = 0; 510 vf->lan_vsi_id = 0;
516 } 511 }
517 msix_vf = pf->hw.func_caps.num_msix_vectors_vf + 1; 512 msix_vf = pf->hw.func_caps.num_msix_vectors_vf;
513
518 /* disable interrupts so the VF starts in a known state */ 514 /* disable interrupts so the VF starts in a known state */
519 for (i = 0; i < msix_vf; i++) { 515 for (i = 0; i < msix_vf; i++) {
520 /* format is same for both registers */ 516 /* format is same for both registers */
@@ -679,9 +675,9 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
679complete_reset: 675complete_reset:
680 /* reallocate vf resources to reset the VSI state */ 676 /* reallocate vf resources to reset the VSI state */
681 i40e_free_vf_res(vf); 677 i40e_free_vf_res(vf);
682 mdelay(10);
683 i40e_alloc_vf_res(vf); 678 i40e_alloc_vf_res(vf);
684 i40e_enable_vf_mappings(vf); 679 i40e_enable_vf_mappings(vf);
680 set_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states);
685 681
686 /* tell the VF the reset is done */ 682 /* tell the VF the reset is done */
687 wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE); 683 wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE);
@@ -847,7 +843,7 @@ void i40e_free_vfs(struct i40e_pf *pf)
847 * 843 *
848 * allocate vf resources 844 * allocate vf resources
849 **/ 845 **/
850static int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs) 846int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
851{ 847{
852 struct i40e_vf *vfs; 848 struct i40e_vf *vfs;
853 int i, ret = 0; 849 int i, ret = 0;
@@ -855,16 +851,18 @@ static int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
855 /* Disable interrupt 0 so we don't try to handle the VFLR. */ 851 /* Disable interrupt 0 so we don't try to handle the VFLR. */
856 i40e_irq_dynamic_disable_icr0(pf); 852 i40e_irq_dynamic_disable_icr0(pf);
857 853
858 ret = pci_enable_sriov(pf->pdev, num_alloc_vfs); 854 /* Check to see if we're just allocating resources for extant VFs */
859 if (ret) { 855 if (pci_num_vf(pf->pdev) != num_alloc_vfs) {
860 dev_err(&pf->pdev->dev, 856 ret = pci_enable_sriov(pf->pdev, num_alloc_vfs);
861 "pci_enable_sriov failed with error %d!\n", ret); 857 if (ret) {
862 pf->num_alloc_vfs = 0; 858 dev_err(&pf->pdev->dev,
863 goto err_iov; 859 "Failed to enable SR-IOV, error %d.\n", ret);
860 pf->num_alloc_vfs = 0;
861 goto err_iov;
862 }
864 } 863 }
865
866 /* allocate memory */ 864 /* allocate memory */
867 vfs = kzalloc(num_alloc_vfs * sizeof(struct i40e_vf), GFP_KERNEL); 865 vfs = kcalloc(num_alloc_vfs, sizeof(struct i40e_vf), GFP_KERNEL);
868 if (!vfs) { 866 if (!vfs) {
869 ret = -ENOMEM; 867 ret = -ENOMEM;
870 goto err_alloc; 868 goto err_alloc;
@@ -1776,7 +1774,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
1776 u32 v_retval, u8 *msg, u16 msglen) 1774 u32 v_retval, u8 *msg, u16 msglen)
1777{ 1775{
1778 struct i40e_hw *hw = &pf->hw; 1776 struct i40e_hw *hw = &pf->hw;
1779 int local_vf_id = vf_id - hw->func_caps.vf_base_id; 1777 unsigned int local_vf_id = vf_id - hw->func_caps.vf_base_id;
1780 struct i40e_vf *vf; 1778 struct i40e_vf *vf;
1781 int ret; 1779 int ret;
1782 1780
@@ -1873,7 +1871,8 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf)
1873 /* clear the bit in GLGEN_VFLRSTAT */ 1871 /* clear the bit in GLGEN_VFLRSTAT */
1874 wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx)); 1872 wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx));
1875 1873
1876 i40e_reset_vf(vf, true); 1874 if (!test_bit(__I40E_DOWN, &pf->state))
1875 i40e_reset_vf(vf, true);
1877 } 1876 }
1878 } 1877 }
1879 1878
@@ -1924,15 +1923,28 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
1924void i40e_vc_notify_link_state(struct i40e_pf *pf) 1923void i40e_vc_notify_link_state(struct i40e_pf *pf)
1925{ 1924{
1926 struct i40e_virtchnl_pf_event pfe; 1925 struct i40e_virtchnl_pf_event pfe;
1926 struct i40e_hw *hw = &pf->hw;
1927 struct i40e_vf *vf = pf->vf;
1928 struct i40e_link_status *ls = &pf->hw.phy.link_info;
1929 int i;
1927 1930
1928 pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE; 1931 pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
1929 pfe.severity = I40E_PF_EVENT_SEVERITY_INFO; 1932 pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
1930 pfe.event_data.link_event.link_status = 1933 for (i = 0; i < pf->num_alloc_vfs; i++) {
1931 pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP; 1934 if (vf->link_forced) {
1932 pfe.event_data.link_event.link_speed = pf->hw.phy.link_info.link_speed; 1935 pfe.event_data.link_event.link_status = vf->link_up;
1933 1936 pfe.event_data.link_event.link_speed =
1934 i40e_vc_vf_broadcast(pf, I40E_VIRTCHNL_OP_EVENT, I40E_SUCCESS, 1937 (vf->link_up ? I40E_LINK_SPEED_40GB : 0);
1935 (u8 *)&pfe, sizeof(struct i40e_virtchnl_pf_event)); 1938 } else {
1939 pfe.event_data.link_event.link_status =
1940 ls->link_info & I40E_AQ_LINK_UP;
1941 pfe.event_data.link_event.link_speed = ls->link_speed;
1942 }
1943 i40e_aq_send_msg_to_vf(hw, vf->vf_id, I40E_VIRTCHNL_OP_EVENT,
1944 0, (u8 *)&pfe, sizeof(pfe),
1945 NULL);
1946 vf++;
1947 }
1936} 1948}
1937 1949
1938/** 1950/**
@@ -2197,3 +2209,64 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
2197error_param: 2209error_param:
2198 return ret; 2210 return ret;
2199} 2211}
2212
2213/**
2214 * i40e_ndo_set_vf_link_state
2215 * @netdev: network interface device structure
2216 * @vf_id: vf identifier
2217 * @link: required link state
2218 *
2219 * Set the link state of a specified VF, regardless of physical link state
2220 **/
2221int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
2222{
2223 struct i40e_netdev_priv *np = netdev_priv(netdev);
2224 struct i40e_pf *pf = np->vsi->back;
2225 struct i40e_virtchnl_pf_event pfe;
2226 struct i40e_hw *hw = &pf->hw;
2227 struct i40e_vf *vf;
2228 int ret = 0;
2229
2230 /* validate the request */
2231 if (vf_id >= pf->num_alloc_vfs) {
2232 dev_err(&pf->pdev->dev, "Invalid VF Identifier %d\n", vf_id);
2233 ret = -EINVAL;
2234 goto error_out;
2235 }
2236
2237 vf = &pf->vf[vf_id];
2238
2239 pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
2240 pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
2241
2242 switch (link) {
2243 case IFLA_VF_LINK_STATE_AUTO:
2244 vf->link_forced = false;
2245 pfe.event_data.link_event.link_status =
2246 pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP;
2247 pfe.event_data.link_event.link_speed =
2248 pf->hw.phy.link_info.link_speed;
2249 break;
2250 case IFLA_VF_LINK_STATE_ENABLE:
2251 vf->link_forced = true;
2252 vf->link_up = true;
2253 pfe.event_data.link_event.link_status = true;
2254 pfe.event_data.link_event.link_speed = I40E_LINK_SPEED_40GB;
2255 break;
2256 case IFLA_VF_LINK_STATE_DISABLE:
2257 vf->link_forced = true;
2258 vf->link_up = false;
2259 pfe.event_data.link_event.link_status = false;
2260 pfe.event_data.link_event.link_speed = 0;
2261 break;
2262 default:
2263 ret = -EINVAL;
2264 goto error_out;
2265 }
2266 /* Notify the VF of its new link state */
2267 i40e_aq_send_msg_to_vf(hw, vf->vf_id, I40E_VIRTCHNL_OP_EVENT,
2268 0, (u8 *)&pfe, sizeof(pfe), NULL);
2269
2270error_out:
2271 return ret;
2272}