Commit 63c64de7 authored by David S. Miller's avatar David S. Miller

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2017-01-08

This series contains updates to fm10k only.

Ngai-Mint changes the driver to use the MAC pointer in the fm10k_mac_info
structure for fm10k_get_host_state_generic().  Fixed a race condition
where the mailbox interrupt request bits can be cleared before being
handled causing certain mailbox messages from the PF to be untreated
and the PF will enter in some inactive state.

Jake removes the typecast of u8 to char, and the extra variable that was
created for the typecast.  Bumps the driver version.  Added back the
receive descriptor timestamp value so that applications built on top
of the IES API can function properly.  Cleaned up the debug statistics
flag, since debug statistics were removed and the flag was missed in
the removal.

Scott limits the DMA sync for CPU to the actual length of the packet,
instead of the entire buffer, since the DMA sync occurs every time a
packet is received.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dc33da59 0035ddf4
...@@ -260,9 +260,7 @@ struct fm10k_intfc { ...@@ -260,9 +260,7 @@ struct fm10k_intfc {
#define FM10K_FLAG_RESET_REQUESTED (u32)(BIT(0)) #define FM10K_FLAG_RESET_REQUESTED (u32)(BIT(0))
#define FM10K_FLAG_RSS_FIELD_IPV4_UDP (u32)(BIT(1)) #define FM10K_FLAG_RSS_FIELD_IPV4_UDP (u32)(BIT(1))
#define FM10K_FLAG_RSS_FIELD_IPV6_UDP (u32)(BIT(2)) #define FM10K_FLAG_RSS_FIELD_IPV6_UDP (u32)(BIT(2))
#define FM10K_FLAG_RX_TS_ENABLED (u32)(BIT(3)) #define FM10K_FLAG_SWPRI_CONFIG (u32)(BIT(3))
#define FM10K_FLAG_SWPRI_CONFIG (u32)(BIT(4))
#define FM10K_FLAG_DEBUG_STATS (u32)(BIT(5))
int xcast_mode; int xcast_mode;
/* Tx fast path data */ /* Tx fast path data */
......
...@@ -506,7 +506,7 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready) ...@@ -506,7 +506,7 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
goto out; goto out;
/* if we somehow dropped the Tx enable we should reset */ /* if we somehow dropped the Tx enable we should reset */
if (hw->mac.tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) { if (mac->tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) {
ret_val = FM10K_ERR_RESET_REQUESTED; ret_val = FM10K_ERR_RESET_REQUESTED;
goto out; goto out;
} }
...@@ -523,8 +523,8 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready) ...@@ -523,8 +523,8 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
/* interface cannot receive traffic without logical ports */ /* interface cannot receive traffic without logical ports */
if (mac->dglort_map == FM10K_DGLORTMAP_NONE) { if (mac->dglort_map == FM10K_DGLORTMAP_NONE) {
if (hw->mac.ops.request_lport_map) if (mac->ops.request_lport_map)
ret_val = hw->mac.ops.request_lport_map(hw); ret_val = mac->ops.request_lport_map(hw);
goto out; goto out;
} }
......
...@@ -148,7 +148,7 @@ enum { ...@@ -148,7 +148,7 @@ enum {
static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = { static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = {
}; };
static void fm10k_add_stat_strings(char **p, const char *prefix, static void fm10k_add_stat_strings(u8 **p, const char *prefix,
const struct fm10k_stats stats[], const struct fm10k_stats stats[],
const unsigned int size) const unsigned int size)
{ {
...@@ -164,32 +164,31 @@ static void fm10k_add_stat_strings(char **p, const char *prefix, ...@@ -164,32 +164,31 @@ static void fm10k_add_stat_strings(char **p, const char *prefix,
static void fm10k_get_stat_strings(struct net_device *dev, u8 *data) static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
{ {
struct fm10k_intfc *interface = netdev_priv(dev); struct fm10k_intfc *interface = netdev_priv(dev);
char *p = (char *)data;
unsigned int i; unsigned int i;
fm10k_add_stat_strings(&p, "", fm10k_gstrings_net_stats, fm10k_add_stat_strings(&data, "", fm10k_gstrings_net_stats,
FM10K_NETDEV_STATS_LEN); FM10K_NETDEV_STATS_LEN);
fm10k_add_stat_strings(&p, "", fm10k_gstrings_global_stats, fm10k_add_stat_strings(&data, "", fm10k_gstrings_global_stats,
FM10K_GLOBAL_STATS_LEN); FM10K_GLOBAL_STATS_LEN);
fm10k_add_stat_strings(&p, "", fm10k_gstrings_mbx_stats, fm10k_add_stat_strings(&data, "", fm10k_gstrings_mbx_stats,
FM10K_MBX_STATS_LEN); FM10K_MBX_STATS_LEN);
if (interface->hw.mac.type != fm10k_mac_vf) if (interface->hw.mac.type != fm10k_mac_vf)
fm10k_add_stat_strings(&p, "", fm10k_gstrings_pf_stats, fm10k_add_stat_strings(&data, "", fm10k_gstrings_pf_stats,
FM10K_PF_STATS_LEN); FM10K_PF_STATS_LEN);
for (i = 0; i < interface->hw.mac.max_queues; i++) { for (i = 0; i < interface->hw.mac.max_queues; i++) {
char prefix[ETH_GSTRING_LEN]; char prefix[ETH_GSTRING_LEN];
snprintf(prefix, ETH_GSTRING_LEN, "tx_queue_%u_", i); snprintf(prefix, ETH_GSTRING_LEN, "tx_queue_%u_", i);
fm10k_add_stat_strings(&p, prefix, fm10k_add_stat_strings(&data, prefix,
fm10k_gstrings_queue_stats, fm10k_gstrings_queue_stats,
FM10K_QUEUE_STATS_LEN); FM10K_QUEUE_STATS_LEN);
snprintf(prefix, ETH_GSTRING_LEN, "rx_queue_%u_", i); snprintf(prefix, ETH_GSTRING_LEN, "rx_queue_%u_", i);
fm10k_add_stat_strings(&p, prefix, fm10k_add_stat_strings(&data, prefix,
fm10k_gstrings_queue_stats, fm10k_gstrings_queue_stats,
FM10K_QUEUE_STATS_LEN); FM10K_QUEUE_STATS_LEN);
} }
...@@ -198,18 +197,16 @@ static void fm10k_get_stat_strings(struct net_device *dev, u8 *data) ...@@ -198,18 +197,16 @@ static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
static void fm10k_get_strings(struct net_device *dev, static void fm10k_get_strings(struct net_device *dev,
u32 stringset, u8 *data) u32 stringset, u8 *data)
{ {
char *p = (char *)data;
switch (stringset) { switch (stringset) {
case ETH_SS_TEST: case ETH_SS_TEST:
memcpy(data, *fm10k_gstrings_test, memcpy(data, fm10k_gstrings_test,
FM10K_TEST_LEN * ETH_GSTRING_LEN); FM10K_TEST_LEN * ETH_GSTRING_LEN);
break; break;
case ETH_SS_STATS: case ETH_SS_STATS:
fm10k_get_stat_strings(dev, data); fm10k_get_stat_strings(dev, data);
break; break;
case ETH_SS_PRIV_FLAGS: case ETH_SS_PRIV_FLAGS:
memcpy(p, fm10k_prv_flags, memcpy(data, fm10k_prv_flags,
FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN); FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN);
break; break;
} }
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "fm10k.h" #include "fm10k.h"
#define DRV_VERSION "0.21.2-k" #define DRV_VERSION "0.21.7-k"
#define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver" #define DRV_SUMMARY "Intel(R) Ethernet Switch Host Interface Driver"
const char fm10k_driver_version[] = DRV_VERSION; const char fm10k_driver_version[] = DRV_VERSION;
char fm10k_driver_name[] = "fm10k"; char fm10k_driver_name[] = "fm10k";
...@@ -251,6 +251,7 @@ static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer, ...@@ -251,6 +251,7 @@ static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer,
/** /**
* fm10k_add_rx_frag - Add contents of Rx buffer to sk_buff * fm10k_add_rx_frag - Add contents of Rx buffer to sk_buff
* @rx_buffer: buffer containing page to add * @rx_buffer: buffer containing page to add
* @size: packet size from rx_desc
* @rx_desc: descriptor containing length of buffer written by hardware * @rx_desc: descriptor containing length of buffer written by hardware
* @skb: sk_buff to place the data into * @skb: sk_buff to place the data into
* *
...@@ -263,12 +264,12 @@ static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer, ...@@ -263,12 +264,12 @@ static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer,
* true if the buffer can be reused by the interface. * true if the buffer can be reused by the interface.
**/ **/
static bool fm10k_add_rx_frag(struct fm10k_rx_buffer *rx_buffer, static bool fm10k_add_rx_frag(struct fm10k_rx_buffer *rx_buffer,
unsigned int size,
union fm10k_rx_desc *rx_desc, union fm10k_rx_desc *rx_desc,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct page *page = rx_buffer->page; struct page *page = rx_buffer->page;
unsigned char *va = page_address(page) + rx_buffer->page_offset; unsigned char *va = page_address(page) + rx_buffer->page_offset;
unsigned int size = le16_to_cpu(rx_desc->w.length);
#if (PAGE_SIZE < 8192) #if (PAGE_SIZE < 8192)
unsigned int truesize = FM10K_RX_BUFSZ; unsigned int truesize = FM10K_RX_BUFSZ;
#else #else
...@@ -314,6 +315,7 @@ static struct sk_buff *fm10k_fetch_rx_buffer(struct fm10k_ring *rx_ring, ...@@ -314,6 +315,7 @@ static struct sk_buff *fm10k_fetch_rx_buffer(struct fm10k_ring *rx_ring,
union fm10k_rx_desc *rx_desc, union fm10k_rx_desc *rx_desc,
struct sk_buff *skb) struct sk_buff *skb)
{ {
unsigned int size = le16_to_cpu(rx_desc->w.length);
struct fm10k_rx_buffer *rx_buffer; struct fm10k_rx_buffer *rx_buffer;
struct page *page; struct page *page;
...@@ -350,11 +352,11 @@ static struct sk_buff *fm10k_fetch_rx_buffer(struct fm10k_ring *rx_ring, ...@@ -350,11 +352,11 @@ static struct sk_buff *fm10k_fetch_rx_buffer(struct fm10k_ring *rx_ring,
dma_sync_single_range_for_cpu(rx_ring->dev, dma_sync_single_range_for_cpu(rx_ring->dev,
rx_buffer->dma, rx_buffer->dma,
rx_buffer->page_offset, rx_buffer->page_offset,
FM10K_RX_BUFSZ, size,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
/* pull page into skb */ /* pull page into skb */
if (fm10k_add_rx_frag(rx_buffer, rx_desc, skb)) { if (fm10k_add_rx_frag(rx_buffer, size, rx_desc, skb)) {
/* hand second half of page back to the ring */ /* hand second half of page back to the ring */
fm10k_reuse_rx_page(rx_ring, rx_buffer); fm10k_reuse_rx_page(rx_ring, rx_buffer);
} else { } else {
...@@ -473,6 +475,8 @@ static unsigned int fm10k_process_skb_fields(struct fm10k_ring *rx_ring, ...@@ -473,6 +475,8 @@ static unsigned int fm10k_process_skb_fields(struct fm10k_ring *rx_ring,
fm10k_rx_checksum(rx_ring, rx_desc, skb); fm10k_rx_checksum(rx_ring, rx_desc, skb);
FM10K_CB(skb)->tstamp = rx_desc->q.timestamp;
FM10K_CB(skb)->fi.w.vlan = rx_desc->w.vlan; FM10K_CB(skb)->fi.w.vlan = rx_desc->w.vlan;
skb_record_rx_queue(skb, rx_ring->queue_index); skb_record_rx_queue(skb, rx_ring->queue_index);
......
...@@ -2011,9 +2011,10 @@ static void fm10k_sm_mbx_create_reply(struct fm10k_hw *hw, ...@@ -2011,9 +2011,10 @@ static void fm10k_sm_mbx_create_reply(struct fm10k_hw *hw,
* function can also be used to respond to an error as the connection * function can also be used to respond to an error as the connection
* resetting would also be a means of dealing with errors. * resetting would also be a means of dealing with errors.
**/ **/
static void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw, static s32 fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,
struct fm10k_mbx_info *mbx) struct fm10k_mbx_info *mbx)
{ {
s32 err = 0;
const enum fm10k_mbx_state state = mbx->state; const enum fm10k_mbx_state state = mbx->state;
switch (state) { switch (state) {
...@@ -2026,6 +2027,7 @@ static void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw, ...@@ -2026,6 +2027,7 @@ static void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,
case FM10K_STATE_OPEN: case FM10K_STATE_OPEN:
/* flush any incomplete work */ /* flush any incomplete work */
fm10k_sm_mbx_connect_reset(mbx); fm10k_sm_mbx_connect_reset(mbx);
err = FM10K_ERR_RESET_REQUESTED;
break; break;
case FM10K_STATE_CONNECT: case FM10K_STATE_CONNECT:
/* Update remote value to match local value */ /* Update remote value to match local value */
...@@ -2035,6 +2037,8 @@ static void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw, ...@@ -2035,6 +2037,8 @@ static void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw,
} }
fm10k_sm_mbx_create_reply(hw, mbx, mbx->tail); fm10k_sm_mbx_create_reply(hw, mbx, mbx->tail);
return err;
} }
/** /**
...@@ -2115,7 +2119,7 @@ static s32 fm10k_sm_mbx_process(struct fm10k_hw *hw, ...@@ -2115,7 +2119,7 @@ static s32 fm10k_sm_mbx_process(struct fm10k_hw *hw,
switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_VER)) { switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_VER)) {
case 0: case 0:
fm10k_sm_mbx_process_reset(hw, mbx); err = fm10k_sm_mbx_process_reset(hw, mbx);
break; break;
case FM10K_SM_MBX_VERSION: case FM10K_SM_MBX_VERSION:
err = fm10k_sm_mbx_process_version_1(hw, mbx); err = fm10k_sm_mbx_process_version_1(hw, mbx);
......
...@@ -1144,6 +1144,7 @@ static irqreturn_t fm10k_msix_mbx_pf(int __always_unused irq, void *data) ...@@ -1144,6 +1144,7 @@ static irqreturn_t fm10k_msix_mbx_pf(int __always_unused irq, void *data)
struct fm10k_hw *hw = &interface->hw; struct fm10k_hw *hw = &interface->hw;
struct fm10k_mbx_info *mbx = &hw->mbx; struct fm10k_mbx_info *mbx = &hw->mbx;
u32 eicr; u32 eicr;
s32 err = 0;
/* unmask any set bits related to this interrupt */ /* unmask any set bits related to this interrupt */
eicr = fm10k_read_reg(hw, FM10K_EICR); eicr = fm10k_read_reg(hw, FM10K_EICR);
...@@ -1159,12 +1160,15 @@ static irqreturn_t fm10k_msix_mbx_pf(int __always_unused irq, void *data) ...@@ -1159,12 +1160,15 @@ static irqreturn_t fm10k_msix_mbx_pf(int __always_unused irq, void *data)
/* service mailboxes */ /* service mailboxes */
if (fm10k_mbx_trylock(interface)) { if (fm10k_mbx_trylock(interface)) {
mbx->ops.process(hw, mbx); err = mbx->ops.process(hw, mbx);
/* handle VFLRE events */ /* handle VFLRE events */
fm10k_iov_event(interface); fm10k_iov_event(interface);
fm10k_mbx_unlock(interface); fm10k_mbx_unlock(interface);
} }
if (err == FM10K_ERR_RESET_REQUESTED)
interface->flags |= FM10K_FLAG_RESET_REQUESTED;
/* if switch toggled state we should reset GLORTs */ /* if switch toggled state we should reset GLORTs */
if (eicr & FM10K_EICR_SWITCHNOTREADY) { if (eicr & FM10K_EICR_SWITCHNOTREADY) {
/* force link down for at least 4 seconds */ /* force link down for at least 4 seconds */
......
...@@ -72,10 +72,6 @@ static s32 fm10k_reset_hw_pf(struct fm10k_hw *hw) ...@@ -72,10 +72,6 @@ static s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
fm10k_write_flush(hw); fm10k_write_flush(hw);
udelay(FM10K_RESET_TIMEOUT); udelay(FM10K_RESET_TIMEOUT);
/* Reset mailbox global interrupts */
reg = FM10K_MBX_GLOBAL_REQ_INTERRUPT | FM10K_MBX_GLOBAL_ACK_INTERRUPT;
fm10k_write_reg(hw, FM10K_GMBX, reg);
/* Verify we made it out of reset */ /* Verify we made it out of reset */
reg = fm10k_read_reg(hw, FM10K_IP); reg = fm10k_read_reg(hw, FM10K_IP);
if (!(reg & FM10K_IP_NOTINRESET)) if (!(reg & FM10K_IP_NOTINRESET))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment