Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Browse files Browse the repository at this point in the history
Pull networking fixes from David Miller:
 "Famouse last words: "final pull request" :-)

  I'm sending this because Jason Wang's fixes are pretty important

   1) Add missing per-cpu stats initialization to ip6_vti.  Otherwise
      lockdep spits out a call trace.  From Li RongQing.

   2) Fix NULL oops in wireless hwsim, from Javier Lopez

   3) TIPC deferred packet queue unlink must NULL out skb->next to avoid
      crashes.  From Erik Hugne

   4) Fix access to uninitialized buffer in nf_nat netfilter code, from
      Daniel Borkmann

   5) Fix lifetime of ipv6 loopback and SIT tunnel addresses, otherwise
      they basically timeout immediately.  From Hannes Frederic Sowa

   6) Fix DMA unmapping of TSO packets in bnx2x driver, from Michal
      Schmidt

   7) Do not allow L2 forwarding offload via macvtap device, the way
      things are now it will not end up being forwaded at all.  From
      Jason Wang

   8) Fix transmit queue selection via ndo_dfwd_start_xmit(), fixing
      things like applying NETIF_F_LLTX to the wrong device (!!) and
      eliding the proper transmit watchdog handling

   9) qlcnic driver was not updating tx statistics at all, from Manish
      Chopra"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  qlcnic: Fix ethtool statistics length calculation
  qlcnic: Fix bug in TX statistics
  net: core: explicitly select a txq before doing l2 forwarding
  macvlan: forbid L2 fowarding offload for macvtap
  bnx2x: fix DMA unmapping of TSO split BDs
  ipv6: add link-local, sit and loopback address with INFINITY_LIFE_TIME
  bnx2x: prevent WARN during driver unload
  tipc: correctly unlink packets from deferred packet queue
  ipv6: pcpu_tstats.syncp should be initialised in ip6_vti.c
  netfilter: only warn once on wrong seqadj usage
  netfilter: nf_nat: fix access to uninitialized buffer in IRC NAT helper
  NFC: Fix target mode p2p link establishment
  iwlwifi: add new devices for 7265 series
  mac80211: move "bufferable MMPDU" check to fix AP mode scan
  mac80211_hwsim: Fix NULL pointer dereference
  • Loading branch information
Linus Torvalds committed Jan 10, 2014
2 parents e2bc447 + d6e9c89 commit 228fdc0
Show file tree
Hide file tree
Showing 34 changed files with 219 additions and 126 deletions.
3 changes: 2 additions & 1 deletion drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3732,7 +3732,8 @@ static inline int bond_slave_override(struct bonding *bond,
}


static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv)
{
/*
* This helper function exists to help dev_pick_tx get the correct
Expand Down
44 changes: 34 additions & 10 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,12 @@ struct bnx2x_fastpath {
#define BNX2X_FP_STATE_IDLE 0
#define BNX2X_FP_STATE_NAPI (1 << 0) /* NAPI owns this FP */
#define BNX2X_FP_STATE_POLL (1 << 1) /* poll owns this FP */
#define BNX2X_FP_STATE_NAPI_YIELD (1 << 2) /* NAPI yielded this FP */
#define BNX2X_FP_STATE_POLL_YIELD (1 << 3) /* poll yielded this FP */
#define BNX2X_FP_STATE_DISABLED (1 << 2)
#define BNX2X_FP_STATE_NAPI_YIELD (1 << 3) /* NAPI yielded this FP */
#define BNX2X_FP_STATE_POLL_YIELD (1 << 4) /* poll yielded this FP */
#define BNX2X_FP_OWNED (BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
#define BNX2X_FP_YIELD (BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)
#define BNX2X_FP_LOCKED (BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
#define BNX2X_FP_LOCKED (BNX2X_FP_OWNED | BNX2X_FP_STATE_DISABLED)
#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
/* protect state */
spinlock_t lock;
Expand Down Expand Up @@ -613,7 +615,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
{
bool rc = true;

spin_lock(&fp->lock);
spin_lock_bh(&fp->lock);
if (fp->state & BNX2X_FP_LOCKED) {
WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
fp->state |= BNX2X_FP_STATE_NAPI_YIELD;
Expand All @@ -622,7 +624,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
/* we don't care if someone yielded */
fp->state = BNX2X_FP_STATE_NAPI;
}
spin_unlock(&fp->lock);
spin_unlock_bh(&fp->lock);
return rc;
}

Expand All @@ -631,14 +633,16 @@ static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
{
bool rc = false;

spin_lock(&fp->lock);
spin_lock_bh(&fp->lock);
WARN_ON(fp->state &
(BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));

if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
rc = true;
fp->state = BNX2X_FP_STATE_IDLE;
spin_unlock(&fp->lock);

/* state ==> idle, unless currently disabled */
fp->state &= BNX2X_FP_STATE_DISABLED;
spin_unlock_bh(&fp->lock);
return rc;
}

Expand Down Expand Up @@ -669,17 +673,33 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)

if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
rc = true;
fp->state = BNX2X_FP_STATE_IDLE;

/* state ==> idle, unless currently disabled */
fp->state &= BNX2X_FP_STATE_DISABLED;
spin_unlock_bh(&fp->lock);
return rc;
}

/* true if a socket is polling, even if it did not get the lock */
static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
{
WARN_ON(!(fp->state & BNX2X_FP_LOCKED));
WARN_ON(!(fp->state & BNX2X_FP_OWNED));
return fp->state & BNX2X_FP_USER_PEND;
}

/* false if fp is currently owned */
static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
{
int rc = true;

spin_lock_bh(&fp->lock);
if (fp->state & BNX2X_FP_OWNED)
rc = false;
fp->state |= BNX2X_FP_STATE_DISABLED;
spin_unlock_bh(&fp->lock);

return rc;
}
#else
static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
{
Expand Down Expand Up @@ -709,6 +729,10 @@ static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
{
return false;
}
static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
{
return true;
}
#endif /* CONFIG_NET_RX_BUSY_POLL */

/* Use 2500 as a mini-jumbo MTU for FCoE */
Expand Down
28 changes: 15 additions & 13 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,15 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
struct sk_buff *skb = tx_buf->skb;
u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
int nbd;
u16 split_bd_len = 0;

/* prefetch skb end pointer to speedup dev_kfree_skb() */
prefetch(&skb->end);

DP(NETIF_MSG_TX_DONE, "fp[%d]: pkt_idx %d buff @(%p)->skb %p\n",
txdata->txq_index, idx, tx_buf, skb);

/* unmap first bd */
tx_start_bd = &txdata->tx_desc_ring[bd_idx].start_bd;
dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE);

nbd = le16_to_cpu(tx_start_bd->nbd) - 1;
#ifdef BNX2X_STOP_ON_ERROR
Expand All @@ -188,12 +186,19 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
--nbd;
bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));

/* ...and the TSO split header bd since they have no mapping */
/* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
split_bd_len = BD_UNMAP_LEN(tx_data_bd);
--nbd;
bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
}

/* unmap first bd */
dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
BD_UNMAP_LEN(tx_start_bd) + split_bd_len,
DMA_TO_DEVICE);

/* now free frags */
while (nbd > 0) {

Expand Down Expand Up @@ -1790,26 +1795,22 @@ static void bnx2x_napi_disable_cnic(struct bnx2x *bp)
{
int i;

local_bh_disable();
for_each_rx_queue_cnic(bp, i) {
napi_disable(&bnx2x_fp(bp, i, napi));
while (!bnx2x_fp_lock_napi(&bp->fp[i]))
mdelay(1);
while (!bnx2x_fp_ll_disable(&bp->fp[i]))
usleep_range(1000, 2000);
}
local_bh_enable();
}

static void bnx2x_napi_disable(struct bnx2x *bp)
{
int i;

local_bh_disable();
for_each_eth_queue(bp, i) {
napi_disable(&bnx2x_fp(bp, i, napi));
while (!bnx2x_fp_lock_napi(&bp->fp[i]))
mdelay(1);
while (!bnx2x_fp_ll_disable(&bp->fp[i]))
usleep_range(1000, 2000);
}
local_bh_enable();
}

void bnx2x_netif_start(struct bnx2x *bp)
Expand All @@ -1832,7 +1833,8 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
bnx2x_napi_disable_cnic(bp);
}

u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb)
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv)
{
struct bnx2x *bp = netdev_priv(dev);

Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,8 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos);

/* select_queue callback */
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb);
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv);

static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
struct bnx2x_fastpath *fp,
Expand Down
33 changes: 13 additions & 20 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6827,12 +6827,20 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
return __ixgbe_maybe_stop_tx(tx_ring, size);
}

#ifdef IXGBE_FCOE
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv)
{
struct ixgbe_fwd_adapter *fwd_adapter = accel_priv;
#ifdef IXGBE_FCOE
struct ixgbe_adapter *adapter;
struct ixgbe_ring_feature *f;
int txq;
#endif

if (fwd_adapter)
return skb->queue_mapping + fwd_adapter->tx_base_queue;

#ifdef IXGBE_FCOE

/*
* only execute the code below if protocol is FCoE
Expand All @@ -6858,9 +6866,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
txq -= f->indices;

return txq + f->offset;
#else
return __netdev_pick_tx(dev, skb);
#endif
}

#endif
netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring)
Expand Down Expand Up @@ -7629,27 +7639,11 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv)
kfree(fwd_adapter);
}

static netdev_tx_t ixgbe_fwd_xmit(struct sk_buff *skb,
struct net_device *dev,
void *priv)
{
struct ixgbe_fwd_adapter *fwd_adapter = priv;
unsigned int queue;
struct ixgbe_ring *tx_ring;

queue = skb->queue_mapping + fwd_adapter->tx_base_queue;
tx_ring = fwd_adapter->real_adapter->tx_ring[queue];

return __ixgbe_xmit_frame(skb, dev, tx_ring);
}

static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
.ndo_start_xmit = ixgbe_xmit_frame,
#ifdef IXGBE_FCOE
.ndo_select_queue = ixgbe_select_queue,
#endif
.ndo_set_rx_mode = ixgbe_set_rx_mode,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = ixgbe_set_mac,
Expand Down Expand Up @@ -7689,7 +7683,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
.ndo_dfwd_add_station = ixgbe_fwd_add,
.ndo_dfwd_del_station = ixgbe_fwd_del,
.ndo_dfwd_start_xmit = ixgbe_fwd_xmit,
};

/**
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/lantiq_etop.c
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,8 @@ ltq_etop_set_multicast_list(struct net_device *dev)
}

static u16
ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb)
ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv)
{
/* we are currently only using the first queue */
return 0;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlx4/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,8 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
}
}

u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
u16 rings_p_up = priv->num_tx_rings_p_up;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,8 @@ int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);

void mlx4_en_tx_irq(struct mlx4_cq *mcq);
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb);
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv);
netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);

int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,7 @@ int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *);
void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *);
void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx);
void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx);
void qlcnic_update_stats(struct qlcnic_adapter *);

/* Adapter hardware abstraction */
struct qlcnic_hardware_ops {
Expand Down
41 changes: 22 additions & 19 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,27 +167,35 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {

#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)

static inline int qlcnic_82xx_statistics(void)
static inline int qlcnic_82xx_statistics(struct qlcnic_adapter *adapter)
{
return ARRAY_SIZE(qlcnic_device_gstrings_stats) +
ARRAY_SIZE(qlcnic_83xx_mac_stats_strings);
return ARRAY_SIZE(qlcnic_gstrings_stats) +
ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
}

static inline int qlcnic_83xx_statistics(void)
static inline int qlcnic_83xx_statistics(struct qlcnic_adapter *adapter)
{
return ARRAY_SIZE(qlcnic_83xx_tx_stats_strings) +
return ARRAY_SIZE(qlcnic_gstrings_stats) +
ARRAY_SIZE(qlcnic_83xx_tx_stats_strings) +
ARRAY_SIZE(qlcnic_83xx_mac_stats_strings) +
ARRAY_SIZE(qlcnic_83xx_rx_stats_strings);
ARRAY_SIZE(qlcnic_83xx_rx_stats_strings) +
QLCNIC_TX_STATS_LEN * adapter->drv_tx_rings;
}

static int qlcnic_dev_statistics_len(struct qlcnic_adapter *adapter)
{
if (qlcnic_82xx_check(adapter))
return qlcnic_82xx_statistics();
else if (qlcnic_83xx_check(adapter))
return qlcnic_83xx_statistics();
else
return -1;
int len = -1;

if (qlcnic_82xx_check(adapter)) {
len = qlcnic_82xx_statistics(adapter);
if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
len += ARRAY_SIZE(qlcnic_device_gstrings_stats);
} else if (qlcnic_83xx_check(adapter)) {
len = qlcnic_83xx_statistics(adapter);
}

return len;
}

#define QLCNIC_TX_INTR_NOT_CONFIGURED 0X78563412
Expand Down Expand Up @@ -920,18 +928,13 @@ static int qlcnic_eeprom_test(struct net_device *dev)

static int qlcnic_get_sset_count(struct net_device *dev, int sset)
{
int len;

struct qlcnic_adapter *adapter = netdev_priv(dev);
switch (sset) {
case ETH_SS_TEST:
return QLCNIC_TEST_LEN;
case ETH_SS_STATS:
len = qlcnic_dev_statistics_len(adapter) + QLCNIC_STATS_LEN;
if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
qlcnic_83xx_check(adapter))
return len;
return qlcnic_82xx_statistics();
return qlcnic_dev_statistics_len(adapter);
default:
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -1267,7 +1270,7 @@ static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
return data;
}

static void qlcnic_update_stats(struct qlcnic_adapter *adapter)
void qlcnic_update_stats(struct qlcnic_adapter *adapter)
{
struct qlcnic_host_tx_ring *tx_ring;
int ring;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2780,6 +2780,9 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct net_device_stats *stats = &netdev->stats;

if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
qlcnic_update_stats(adapter);

stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
stats->tx_packets = adapter->stats.xmitfinished;
stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes;
Expand Down
Loading

0 comments on commit 228fdc0

Please sign in to comment.