From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:48
This series contains updates to fm10k only.
Jake provides all the changes in this series starting with fixes an issue
where VF devices may fail during an unbind/bind and we will never zero
the reference counter for the pci_dev structure. Updated the hot path
to use SW counters instead of checking for hardware Tx pending for
possible transmit hangs, which will improve performance. Fixed the NAPI
budget accounting so that fm10k_poll will return actual work done,
capped at (budget - 1) instead of returning 0. Added a check to ensure
that the device is in the normal IO state before continuing to probe,
which allows us to give a more descriptive message of what is wrong
in the case of uncorrectable AER error. In preparation for adding Geneve
Rx offload support, refactored the current VXLAN offload flow to be a bit
more generic. Added support for receive offloads on one Geneve tunnel.
Ensure that other bits in the RXQCTL register do not get cleared, to
make sure that bits related to queue ownership are maintained. Fixed
an issue in queue ownership assignment which casued a race condition
between the PF and the VF such that potentially a VF could cause FUM
fault errors due to normal PF/VF driver behavior.
The following are changes since commit 0b498a52778368ff501557d68c7b50878ab1701e:
net_sched: fix use of uninitialized ethertype variable in cls_flower
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue 100GbE
Jacob Keller (14):
fm10k: fix PCI device enable_cnt leak in .io_slot_reset
fm10k: use software values when checking for Tx hangs in hot path
fm10k: use variadic form of alloc_workqueue
fm10k: remove fm10k_get_reta_size from namespace
fm10k: prefer READ_ONCE instead of ACCESS_ONCE
fm10k: NAPI polling routine must return actual work done
fm10k: print error code when pci_enable_device_mem fails during probe
fm10k: don't continue probe if PCI device not in normal IO state
fm10k: don't try to stop queues if we've lost hw_addr
fm10k: rework vxlan_port offload before adding geneve support
fm10k: add support for Rx offloads on one Geneve tunnel
fm10k: remove unnecessary extra parenthesis around ((~value))
fm10k: don't clear the RXQCTL register when enabling or disabling
queues
fm10k: don't re-map queues when a mailbox message suffices
drivers/net/ethernet/intel/fm10k/fm10k.h | 10 +-
drivers/net/ethernet/intel/fm10k/fm10k_common.c | 3 +
drivers/net/ethernet/intel/fm10k/fm10k_common.h | 4 +-
drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 2 +-
drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 4 +-
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 29 ++--
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 193 ++++++++++++++---------
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 30 ++--
drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 46 ++++--
drivers/net/ethernet/intel/fm10k/fm10k_type.h | 1 +
10 files changed, 200 insertions(+), 122 deletions(-)
--
2.7.4
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:49
From: Jacob Keller <jacob.e.keller@intel.com>
A previous patch added support to check for hardware Tx pending in the
fm10k_down routine. This support was intended to ensure that we
accurately check what the hardware state is. However, checking for Tx
hangs in this manor during the hotpath results in a large performance
hit. Avoid this by making the hotpath check use the SW counters instead.
Fixes: a0f53cf49cb0 ("fm10k: use actual hardware registers when checking for pending Tx", 2016-06-08)
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k.h | 2 +-
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 19 +++++++++++++++----
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 2 +-
3 files changed, 17 insertions(+), 6 deletions(-)
@@ -1699,7 +1699,7 @@ void fm10k_down(struct fm10k_intfc *interface)/* start checking at the last ring to have pending Tx */for(;i<interface->num_tx_queues;i++)-if(fm10k_get_tx_pending(interface->tx_ring[i]))+if(fm10k_get_tx_pending(interface->tx_ring[i],false))break;/* if all the queues are drained, we can break now */
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:49
From: Jacob Keller <jacob.e.keller@intel.com>
A previous patch removed the pci_disable_device() call in
.io_error_detected. This call corresponded to a pci_enable_device_mem()
call within .io_slot_reset handler. Change the call here to
a pci_reenable_device() so that it does not increment and leak the
enable_cnt reference count for the device. Without this change, VF
devices may fail during an unbind/bind, and we'll never zero the
reference counter for the pci_dev structure.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:50
From: Jacob Keller <jacob.e.keller@intel.com>
When fm10k_poll fully cleans rings it returns 0. This is incorrect as it
messes up the budget accounting in the core NAPI code. Fix this by
returning actual work done, capped at budget - 1 since the core doesn't
expect a return of the full budget when the driver modifies the NAPI
status.
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Venkatesh Srinivas <redacted>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Acked-by: Paolo Abeni <pabeni@redhat.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -1484,7 +1484,7 @@ static int fm10k_poll(struct napi_struct *napi, int budget)/* re-enable the q_vector */fm10k_qv_enable(q_vector);-return0;+returnmin(work_done,budget-1);}/**
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:50
From: Jacob Keller <jacob.e.keller@intel.com>
While technically not needed, as all our uses of ACCESS_ONCE are scalar
types, we already use READ_ONCE in a few places, and for code
readability we can swap all the uses of the older ACCESS_ONCE into
READ_ONCE.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k_common.h | 4 ++--
drivers/net/ethernet/intel/fm10k/fm10k_iov.c | 4 ++--
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 2 +-
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 6 +++---
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
@@ -51,7 +51,7 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface)inti;/* if there is no iov_data then there is no mailbox to process */-if(!ACCESS_ONCE(interface->iov_data))+if(!READ_ONCE(interface->iov_data))return0;rcu_read_lock();
@@ -99,7 +99,7 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface)inti;/* if there is no iov_data then there is no mailbox to process */-if(!ACCESS_ONCE(interface->iov_data))+if(!READ_ONCE(interface->iov_data))return0;rcu_read_lock();
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:50
From: Jacob Keller <jacob.e.keller@intel.com>
The function is only used in fm10k_ethtool.c, so make it static.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k.h | 1 -
drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
@@ -133,7 +133,7 @@ static void fm10k_detach_subtask(struct fm10k_intfc *interface)/* check the real address space to see if we've recovered */hw_addr=READ_ONCE(interface->uc_addr);value=readl(hw_addr);-if((~value)){+if(~value){interface->hw.hw_addr=interface->uc_addr;netif_device_attach(netdev);interface->flags|=FM10K_FLAG_RESET_REQUESTED;
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:51
From: Jacob Keller <jacob.e.keller@intel.com>
In preparation for adding Geneve Rx offload support, refactor the
current VXLAN offload flow to be a bit more generic so that it will be
easier to add the new Geneve code. The fm10k hardware supports one VXLAN
and one Geneve tunnel, so we will eventually treat the VXLAN and Geneve
tunnels identically. To this end, factor out the code that handles the
current list so that we can use the generic flow for both tunnels in the
next patch.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k.h | 6 +-
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 4 +-
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 161 +++++++++++++-----------
3 files changed, 93 insertions(+), 78 deletions(-)
@@ -335,7 +333,7 @@ struct fm10k_intfc {u32reta[FM10K_RETA_SIZE];u32rssrk[FM10K_RSSRK_SIZE];-/* VXLAN port tracking information */+/* UDP encapsulation port tracking information */structlist_headvxlan_port;#ifdef CONFIG_DEBUG_FS
@@ -651,11 +651,11 @@ static int fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,staticstructethhdr*fm10k_port_is_vxlan(structsk_buff*skb){structfm10k_intfc*interface=netdev_priv(skb->dev);-structfm10k_vxlan_port*vxlan_port;+structfm10k_udp_port*vxlan_port;/* we can only offload a vxlan if we recognize it as such */vxlan_port=list_first_entry_or_null(&interface->vxlan_port,-structfm10k_vxlan_port,list);+structfm10k_udp_port,list);if(!vxlan_port)returnNULL;
@@ -384,129 +384,147 @@ static void fm10k_request_glort_range(struct fm10k_intfc *interface)}/**-*fm10k_del_vxlan_port_all+*fm10k_free_udp_port_info*@interface:boardprivatestructure**Thisfunctionfreestheentirevxlan_portlist**/-staticvoidfm10k_del_vxlan_port_all(structfm10k_intfc*interface)+staticvoidfm10k_free_udp_port_info(structfm10k_intfc*interface){-structfm10k_vxlan_port*vxlan_port;--/* flush all entries from list */-vxlan_port=list_first_entry_or_null(&interface->vxlan_port,-structfm10k_vxlan_port,list);-while(vxlan_port){-list_del(&vxlan_port->list);-kfree(vxlan_port);-vxlan_port=list_first_entry_or_null(&interface->vxlan_port,-structfm10k_vxlan_port,-list);+structfm10k_udp_port*port;++/* flush all entries from vxlan list */+port=list_first_entry_or_null(&interface->vxlan_port,+structfm10k_udp_port,list);+while(port){+list_del(&port->list);+kfree(port);+port=list_first_entry_or_null(&interface->vxlan_port,+structfm10k_udp_port,+list);}}/**-*fm10k_restore_vxlan_port+*fm10k_restore_udp_port_info*@interface:boardprivatestructure*-*Thisfunctionrestoresthevalueinthetunnel_cfgregisterafterreset+*Thisfunctionrestoresthevalueinthetunnel_cfgregister(s)afterreset**/-staticvoidfm10k_restore_vxlan_port(structfm10k_intfc*interface)+staticvoidfm10k_restore_udp_port_info(structfm10k_intfc*interface){structfm10k_hw*hw=&interface->hw;-structfm10k_vxlan_port*vxlan_port;+structfm10k_udp_port*port;/* only the PF supports configuring tunnels */if(hw->mac.type!=fm10k_mac_pf)return;-vxlan_port=list_first_entry_or_null(&interface->vxlan_port,-structfm10k_vxlan_port,list);+port=list_first_entry_or_null(&interface->vxlan_port,+structfm10k_udp_port,list);/* restore tunnel configuration register */fm10k_write_reg(hw,FM10K_TUNNEL_CFG,-(vxlan_port?ntohs(vxlan_port->port):0)|+(port?ntohs(port->port):0)|(ETH_P_TEB<<FM10K_TUNNEL_CFG_NVGRE_SHIFT));}+staticstructfm10k_udp_port*+fm10k_remove_tunnel_port(structlist_head*ports,+structudp_tunnel_info*ti)+{+structfm10k_udp_port*port;++list_for_each_entry(port,ports,list){+if((port->port==ti->port)&&+(port->sa_family==ti->sa_family)){+list_del(&port->list);+returnport;+}+}++returnNULL;+}++staticvoidfm10k_insert_tunnel_port(structlist_head*ports,+structudp_tunnel_info*ti)+{+structfm10k_udp_port*port;++/* remove existing port entry from the list so that the newest items+*arealwaysatthetailofthelist.+*/+port=fm10k_remove_tunnel_port(ports,ti);+if(!port){+port=kmalloc(sizeof(*port),GFP_ATOMIC);+if(!port)+return;+port->port=ti->port;+port->sa_family=ti->sa_family;+}++list_add_tail(&port->list,ports);+}+/**-*fm10k_add_vxlan_port+*fm10k_udp_tunnel_add*@netdev:networkinterfacedevicestructure*@ti:Tunnelendpointinformation*-*ThisfunctioniscalledwhenanewVXLANinterfacehasaddedanewport-*numbertotherangethatiscurrentlyinuseforVXLAN.Thenewport-*numberisalwaysaddedtothetailsothattheportnumberlistshould-*matchtheorderinwhichtheportswereallocated.Theheadofthelist-*isalwaysusedastheVXLANportnumberforoffloads.+*ThisfunctioniscalledwhenanewUDPtunnelporthasbeenadded.+*CurrentlyweonlysupportVXLANandonlyoneportwillactuallybe+*offloadedduetohardwarerestrictions.**/-staticvoidfm10k_add_vxlan_port(structnet_device*dev,+staticvoidfm10k_udp_tunnel_add(structnet_device*dev,structudp_tunnel_info*ti){structfm10k_intfc*interface=netdev_priv(dev);-structfm10k_vxlan_port*vxlan_port;-if(ti->type!=UDP_TUNNEL_TYPE_VXLAN)-return;/* only the PF supports configuring tunnels */if(interface->hw.mac.type!=fm10k_mac_pf)return;-/* existing ports are pulled out so our new entry is always last */-fm10k_vxlan_port_for_each(vxlan_port,interface){-if((vxlan_port->port==ti->port)&&-(vxlan_port->sa_family==ti->sa_family)){-list_del(&vxlan_port->list);-gotoinsert_tail;-}-}--/* allocate memory to track ports */-vxlan_port=kmalloc(sizeof(*vxlan_port),GFP_ATOMIC);-if(!vxlan_port)+switch(ti->type){+caseUDP_TUNNEL_TYPE_VXLAN:+fm10k_insert_tunnel_port(&interface->vxlan_port,ti);+break;+default:return;-vxlan_port->port=ti->port;-vxlan_port->sa_family=ti->sa_family;--insert_tail:-/* add new port value to list */-list_add_tail(&vxlan_port->list,&interface->vxlan_port);+}-fm10k_restore_vxlan_port(interface);+fm10k_restore_udp_port_info(interface);}/**-*fm10k_del_vxlan_port+*fm10k_udp_tunnel_del*@netdev:networkinterfacedevicestructure*@ti:Tunnelendpointinformation*-*ThisfunctioniscalledwhenanewVXLANinterfacehasfreedaport-*numberfromtherangethatiscurrentlyinuseforVXLAN.Thefreed-*portisremovedfromthelistandthenewheadisusedtodetermine-*theportnumberforoffloads.+*ThisfunctioniscalledwhenanewUDPtunnelportisdeleted.Thefreed+*portwillberemovedfromthelist,thenwereprogramtheoffloadedport+*basedontheheadofthelist.**/-staticvoidfm10k_del_vxlan_port(structnet_device*dev,+staticvoidfm10k_udp_tunnel_del(structnet_device*dev,structudp_tunnel_info*ti){structfm10k_intfc*interface=netdev_priv(dev);-structfm10k_vxlan_port*vxlan_port;+structfm10k_udp_port*port=NULL;-if(ti->type!=UDP_TUNNEL_TYPE_VXLAN)-return;if(interface->hw.mac.type!=fm10k_mac_pf)return;-/* find the port in the list and free it */-fm10k_vxlan_port_for_each(vxlan_port,interface){-if((vxlan_port->port==ti->port)&&-(vxlan_port->sa_family==ti->sa_family)){-list_del(&vxlan_port->list);-kfree(vxlan_port);-break;-}+switch(ti->type){+caseUDP_TUNNEL_TYPE_VXLAN:+port=fm10k_remove_tunnel_port(&interface->vxlan_port,ti);+break;+default:+return;}-fm10k_restore_vxlan_port(interface);+/* if we did remove a port we need to free its memory */+kfree(port);++fm10k_restore_udp_port_info(interface);}/**
@@ -555,7 +573,6 @@ int fm10k_open(struct net_device *netdev)if(err)gotoerr_set_queues;-/* update VXLAN port configuration */udp_tunnel_get_rx_info(netdev);fm10k_up(interface);
@@ -591,7 +608,7 @@ int fm10k_close(struct net_device *netdev)fm10k_qv_free_irq(interface);-fm10k_del_vxlan_port_all(interface);+fm10k_free_udp_port_info(interface);fm10k_free_all_tx_resources(interface);fm10k_free_all_rx_resources(interface);
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:51
From: Jacob Keller <jacob.e.keller@intel.com>
In the event of a surprise remove, we expect the driver to go down,
which includes calling .stop_hw(). However, this function will return an
error because the queues won't appear to cleanly disable. Prevent this
and avoid the unnecessary checks by just returning when
FM10K_REMOVED(hw->hw_addr) is true.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k_common.c | 3 +++
1 file changed, 3 insertions(+)
@@ -207,6 +207,9 @@ s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt)/* clear tx_ready to prevent any false hits for reset */hw->mac.tx_ready=false;+if(FM10K_REMOVED(hw->hw_addr))+return0;+/* clear the enable bit for all rings */for(i=0;i<q_cnt;i++){reg=fm10k_read_reg(hw,FM10K_TXDCTL(i));
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:51
From: Jacob Keller <jacob.e.keller@intel.com>
Similar to how we handle VXLAN offload, enable support for a single
Geneve tunnel.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k.h | 1 +
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 30 ++++++++++++++++++++++---
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 3 ++-
drivers/net/ethernet/intel/fm10k/fm10k_type.h | 1 +
4 files changed, 31 insertions(+), 4 deletions(-)
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:51
From: Jacob Keller <jacob.e.keller@intel.com>
In the event of an uncorrectable AER error occurring when the driver has
not loaded, the recovery routines are not done. This is done because
future loads of the driver may not be aware of the IO state and may not
be able to recover at all. In this case, when we next load the driver it
fails due to what appears to be a surprise remove event. Instead, add
a check to ensure that the device is in the normal IO state before
continuing to probe. This allows us to give a more descriptive message
of what is wrong.
Without this change, the driver will attempt to probe up to our first
call of .reset_hw() which will be unable to read registers and act as if
a surprise remove event occurred.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 6 ++++++
1 file changed, 6 insertions(+)
@@ -1950,6 +1950,12 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent)structfm10k_intfc*interface;interr;+if(pdev->error_state!=pci_channel_io_normal){+dev_err(&pdev->dev,+"PCI device still in an error state. Unable to load...\n");+return-EIO;+}+err=pci_enable_device_mem(pdev);if(err){dev_err(&pdev->dev,
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:52
From: Jacob Keller <jacob.e.keller@intel.com>
When the PF assigns a new MAC address to a VF it uses the base address
registers to store the MAC address. This allows a VF which loads after
this setup the ability to get the initial address without having to wait
for a mailbox message. Unfortunately to do this, the PF must take queue
ownership away from the VF, which can cause fault errors when there is
already an active VF driver.
This queue ownership assignment causes race condition between the PF and
the VF such that potentially a VF can cause FUM fault errors due to
normal PF/VF driver behavior.
It is not safe to simply allow the PF to write the base address
registers without taking queue ownership back as the PF must also
disable the queues, and this would impact active VF use. The current
code is safe because the queue ownership will prevent the VF from
actually writing but does trigger the FUM fault.
We can do better by simply avoiding the register write process when
a mailbox message suffices. If the message can be sent over the mailbox,
then we will not perform the queue ownership assignment and we won't
update the base address to be the same as the MAC address.
We do still have to write the TXQCTL registers in order to update the
VID of the queue. This is necessary because the TXQCTL register is
read-only from the VF, and thus the VF cannot do this for itself. This
register does not need to wait for the Tx queue to be disabled and is
safe for the PF to write during normal VF operation, so we move this
write to the top of the function above the mailbox message. Without
this, the TXQCTL register would be misconfigured and cause the VF to Tx
hang.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k_pf.c | 46 ++++++++++++++++++-----------
1 file changed, 29 insertions(+), 17 deletions(-)
@@ -867,10 +867,6 @@ static s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,vf_q_idx=fm10k_vf_queue_index(hw,vf_idx);qmap_idx=qmap_stride*vf_idx;-/* MAP Tx queue back to 0 temporarily, and disable it */-fm10k_write_reg(hw,FM10K_TQMAP(qmap_idx),0);-fm10k_write_reg(hw,FM10K_TXDCTL(vf_q_idx),0);-/* Determine correct default VLAN ID. The FM10K_VLAN_OVERRIDE bit is*usedheretoindicatetotheVFthatitwillnothaveprivilegeto*writeVLAN_TABLE.AllpolicyisenforcedonthePFbutthisallows
@@ -886,9 +882,35 @@ static s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,fm10k_tlv_attr_put_mac_vlan(msg,FM10K_MAC_VLAN_MSG_DEFAULT_MAC,vf_info->mac,vf_vid);-/* load onto outgoing mailbox, ignore any errors on enqueue */-if(vf_info->mbx.ops.enqueue_tx)-vf_info->mbx.ops.enqueue_tx(hw,&vf_info->mbx,msg);+/* Configure Queue control register with new VLAN ID. The TXQCTL+*registerisROfromtheVF,sothePFmustdothiseveninthe+*caseofnotifyingtheVFofanewVIDviathemailbox.+*/+txqctl=((u32)vf_vid<<FM10K_TXQCTL_VID_SHIFT)&+FM10K_TXQCTL_VID_MASK;+txqctl|=(vf_idx<<FM10K_TXQCTL_TC_SHIFT)|+FM10K_TXQCTL_VF|vf_idx;++for(i=0;i<queues_per_pool;i++)+fm10k_write_reg(hw,FM10K_TXQCTL(vf_q_idx+i),txqctl);++/* try loading a message onto outgoing mailbox first */+if(vf_info->mbx.ops.enqueue_tx){+err=vf_info->mbx.ops.enqueue_tx(hw,&vf_info->mbx,msg);+if(err!=FM10K_MBX_ERR_NO_MBX)+returnerr;+err=0;+}++/* If we aren't connected to a mailbox, this is most likely because+*theVFdriverisnotrunning.Itshouldthusbesafetore-map+*queuesandusetheregisterstopasstheMACaddresssothattheVF+*drivergetscorrectinformationduringitsinitialization.+*/++/* MAP Tx queue back to 0 temporarily, and disable it */+fm10k_write_reg(hw,FM10K_TQMAP(qmap_idx),0);+fm10k_write_reg(hw,FM10K_TXDCTL(vf_q_idx),0);/* verify ring has disabled before modifying base address registers */txdctl=fm10k_read_reg(hw,FM10K_TXDCTL(vf_q_idx));
@@ -927,16 +949,6 @@ static s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,FM10K_TDLEN_ITR_SCALE_SHIFT);err_out:-/* configure Queue control register */-txqctl=((u32)vf_vid<<FM10K_TXQCTL_VID_SHIFT)&-FM10K_TXQCTL_VID_MASK;-txqctl|=(vf_idx<<FM10K_TXQCTL_TC_SHIFT)|-FM10K_TXQCTL_VF|vf_idx;--/* assign VLAN ID */-for(i=0;i<queues_per_pool;i++)-fm10k_write_reg(hw,FM10K_TXQCTL(vf_q_idx+i),txqctl);-/* restore the queue back to VF ownership */fm10k_write_reg(hw,FM10K_TQMAP(qmap_idx),vf_q_idx);returnerr;
From: Jeff Kirsher <hidden> Date: 2016-08-29 09:13:52
From: Jacob Keller <jacob.e.keller@intel.com>
Ensure that other bits in the RXQCTL register do not get cleared. This
ensures that bits related to queue ownership are maintained.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <redacted>
Signed-off-by: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/fm10k/fm10k_pci.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
@@ -734,15 +734,15 @@ static void fm10k_configure_rx_ring(struct fm10k_intfc *interface,u64rdba=ring->dma;structfm10k_hw*hw=&interface->hw;u32size=ring->count*sizeof(unionfm10k_rx_desc);-u32rxqctl=FM10K_RXQCTL_ENABLE|FM10K_RXQCTL_PF;-u32rxdctl=FM10K_RXDCTL_WRITE_BACK_MIN_DELAY;+u32rxqctl,rxdctl=FM10K_RXDCTL_WRITE_BACK_MIN_DELAY;u32srrctl=FM10K_SRRCTL_BUFFER_CHAINING_EN;u32rxint=FM10K_INT_MAP_DISABLE;u8rx_pause=interface->rx_pause;u8reg_idx=ring->reg_idx;/* disable queue to avoid issues while updating state */-fm10k_write_reg(hw,FM10K_RXQCTL(reg_idx),0);+rxqctl=fm10k_read_reg(hw,FM10K_RXQCTL(reg_idx));+rxqctl&=~FM10K_RXQCTL_ENABLE;fm10k_write_flush(hw);/* possible poll here to verify ring resources have been cleaned */
@@ -797,6 +797,8 @@ static void fm10k_configure_rx_ring(struct fm10k_intfc *interface,fm10k_write_reg(hw,FM10K_RXINT(reg_idx),rxint);/* enable queue */+rxqctl=fm10k_read_reg(hw,FM10K_RXQCTL(reg_idx));+rxqctl|=FM10K_RXQCTL_ENABLE;fm10k_write_reg(hw,FM10K_RXQCTL(reg_idx),rxqctl);/* place buffers on ring for receive data */