Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:

 1) Fix verifier memory corruption and other bugs in BPF layer, from
    Alexei Starovoitov.

 2) Add a conservative fix for doing BPF properly in the BPF classifier
    of the packet scheduler on ingress.  Also from Alexei.

 3) The SKB scrubber should not clear out the packet MARK and security
    label, from Herbert Xu.

 4) Fix oops on rmmod in stmmac driver, from Bryan O'Donoghue.

 5) Pause handling is not correct in the stmmac driver because it
    doesn't take into consideration the RX and TX fifo sizes.  From
    Vince Bridgers.

 6) Failure path missing unlock in FOU driver, from Wang Cong.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (44 commits)
  net: dsa: use DEVICE_ATTR_RW to declare temp1_max
  netns: remove BUG_ONs from net_generic()
  IB/ipoib: Fix ndo_get_iflink
  sfc: Fix memcpy() with const destination compiler warning.
  altera tse: Fix network-delays and -retransmissions after high throughput.
  net: remove unused 'dev' argument from netif_needs_gso()
  act_mirred: Fix bogus header when redirecting from VLAN
  inet_diag: fix access to tcp cc information
  tcp: tcp_get_info() should fetch socket fields once
  net: dsa: mv88e6xxx: Add missing initialization in mv88e6xxx_set_port_state()
  skbuff: Do not scrub skb mark within the same name space
  Revert "net: Reset secmark when scrubbing packet"
  bpf: fix two bugs in verification logic when accessing 'ctx' pointer
  bpf: fix bpf helpers to use skb->mac_header relative offsets
  stmmac: Configure Flow Control to work correctly based on rxfifo size
  stmmac: Enable unicast pause frame detect in GMAC Register 6
  stmmac: Read tx-fifo-depth and rx-fifo-depth from the devicetree
  stmmac: Add defines and documentation for enabling flow control
  stmmac: Add properties for transmit and receive fifo sizes
  stmmac: fix oops on rmmod after assigning ip addr
  ...
This commit is contained in:
Linus Torvalds
2015-04-17 16:31:08 -04:00
62 changed files with 655 additions and 351 deletions
@@ -19,6 +19,12 @@ The following properties are common to the Ethernet controllers:
- phy: the same as "phy-handle" property, not recommended for new bindings.
- phy-device: the same as "phy-handle" property, not recommended for new
bindings.
- rx-fifo-depth: the size of the controller's receive fifo in bytes. This
is used for components that can have configurable receive fifo sizes,
and is useful for determining certain configuration settings such as
flow control thresholds.
- tx-fifo-depth: the size of the controller's transmit fifo in bytes. This
is used for components that can have configurable fifo sizes.
Child nodes of the Ethernet controller are typically the individual PHY devices
connected via the MDIO bus (sometimes the MDIO bus controller is separate).
@@ -45,6 +45,8 @@ Optional properties:
If not passed then the system clock will be used and this is fine on some
platforms.
- snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register.
- tx-fifo-depth: See ethernet.txt file in the same directory
- rx-fifo-depth: See ethernet.txt file in the same directory
Examples:
@@ -59,6 +61,8 @@ Examples:
phy-mode = "gmii";
snps,multicast-filter-bins = <256>;
snps,perfect-filter-entries = <128>;
rx-fifo-depth = <16384>;
tx-fifo-depth = <16384>;
clocks = <&clock>;
clock-names = "stmmaceth";
};
+1 -1
View File
@@ -73,7 +73,7 @@ static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr,
c4iw_init_wr_wait(&wr_wait);
wr_len = roundup(sizeof(*req) + sizeof(*sgl), 16);
skb = alloc_skb(wr_len, GFP_KERNEL | __GFP_NOFAIL);
skb = alloc_skb(wr_len, GFP_KERNEL);
if (!skb)
return -ENOMEM;
set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
@@ -846,6 +846,11 @@ static int ipoib_get_iflink(const struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
/* parent interface */
if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
return dev->ifindex;
/* child/vlan interface */
return priv->parent->ifindex;
}
+1 -2
View File
@@ -58,6 +58,7 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
/* MTU will be reset when mcast join happens */
priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu);
priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu;
priv->parent = ppriv->dev;
set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
result = ipoib_set_dev_features(priv, ppriv->ca);
@@ -84,8 +85,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
goto register_failed;
}
priv->parent = ppriv->dev;
ipoib_create_debug_files(priv->dev);
/* RTNL childs don't need proprietary sysfs entries */
+4 -4
View File
@@ -602,8 +602,6 @@ static void _mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
u32 high = 0;
if (s->reg >= 0x100) {
int ret;
ret = mv88e6xxx_reg_read(ds, REG_PORT(port),
s->reg - 0x100);
if (ret < 0)
@@ -902,14 +900,16 @@ static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
static int mv88e6xxx_set_port_state(struct dsa_switch *ds, int port, u8 state)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int reg, ret;
int reg, ret = 0;
u8 oldstate;
mutex_lock(&ps->smi_mutex);
reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_CONTROL);
if (reg < 0)
if (reg < 0) {
ret = reg;
goto abort;
}
oldstate = reg & PORT_CONTROL_STATE_MASK;
if (oldstate != state) {
@@ -376,8 +376,13 @@ static int tse_rx(struct altera_tse_private *priv, int limit)
u16 pktlength;
u16 pktstatus;
while (((rxstatus = priv->dmaops->get_rx_status(priv)) != 0) &&
(count < limit)) {
/* Check for count < limit first as get_rx_status is changing
* the response-fifo so we must process the next packet
* after calling get_rx_status if a response is pending.
* (reading the last byte of the response pops the value from the fifo.)
*/
while ((count < limit) &&
((rxstatus = priv->dmaops->get_rx_status(priv)) != 0)) {
pktstatus = rxstatus >> 16;
pktlength = rxstatus & 0xffff;
+50 -85
View File
@@ -531,20 +531,8 @@ struct bnx2x_fastpath {
struct napi_struct napi;
#ifdef CONFIG_NET_RX_BUSY_POLL
unsigned int state;
#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_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_OWNED | BNX2X_FP_STATE_DISABLED)
#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
/* protect state */
spinlock_t lock;
#endif /* CONFIG_NET_RX_BUSY_POLL */
unsigned long busy_poll_state;
#endif
union host_hc_status_block status_blk;
/* chip independent shortcuts into sb structure */
@@ -619,104 +607,83 @@ struct bnx2x_fastpath {
#define bnx2x_fp_qstats(bp, fp) (&((bp)->fp_stats[(fp)->index].eth_q_stats))
#ifdef CONFIG_NET_RX_BUSY_POLL
static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
enum bnx2x_fp_state {
BNX2X_STATE_FP_NAPI = BIT(0), /* NAPI handler owns the queue */
BNX2X_STATE_FP_NAPI_REQ_BIT = 1, /* NAPI would like to own the queue */
BNX2X_STATE_FP_NAPI_REQ = BIT(1),
BNX2X_STATE_FP_POLL_BIT = 2,
BNX2X_STATE_FP_POLL = BIT(2), /* busy_poll owns the queue */
BNX2X_STATE_FP_DISABLE_BIT = 3, /* queue is dismantled */
};
static inline void bnx2x_fp_busy_poll_init(struct bnx2x_fastpath *fp)
{
spin_lock_init(&fp->lock);
fp->state = BNX2X_FP_STATE_IDLE;
WRITE_ONCE(fp->busy_poll_state, 0);
}
/* called from the device poll routine to get ownership of a FP */
static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
{
bool rc = true;
unsigned long prev, old = READ_ONCE(fp->busy_poll_state);
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;
rc = false;
} else {
/* we don't care if someone yielded */
fp->state = BNX2X_FP_STATE_NAPI;
while (1) {
switch (old) {
case BNX2X_STATE_FP_POLL:
/* make sure bnx2x_fp_lock_poll() wont starve us */
set_bit(BNX2X_STATE_FP_NAPI_REQ_BIT,
&fp->busy_poll_state);
/* fallthrough */
case BNX2X_STATE_FP_POLL | BNX2X_STATE_FP_NAPI_REQ:
return false;
default:
break;
}
prev = cmpxchg(&fp->busy_poll_state, old, BNX2X_STATE_FP_NAPI);
if (unlikely(prev != old)) {
old = prev;
continue;
}
return true;
}
spin_unlock_bh(&fp->lock);
return rc;
}
/* returns true is someone tried to get the FP while napi had it */
static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
static inline void bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
{
bool rc = false;
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;
/* state ==> idle, unless currently disabled */
fp->state &= BNX2X_FP_STATE_DISABLED;
spin_unlock_bh(&fp->lock);
return rc;
smp_wmb();
fp->busy_poll_state = 0;
}
/* called from bnx2x_low_latency_poll() */
static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
{
bool rc = true;
spin_lock_bh(&fp->lock);
if ((fp->state & BNX2X_FP_LOCKED)) {
fp->state |= BNX2X_FP_STATE_POLL_YIELD;
rc = false;
} else {
/* preserve yield marks */
fp->state |= BNX2X_FP_STATE_POLL;
}
spin_unlock_bh(&fp->lock);
return rc;
return cmpxchg(&fp->busy_poll_state, 0, BNX2X_STATE_FP_POLL) == 0;
}
/* returns true if someone tried to get the FP while it was locked */
static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
static inline void bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
{
bool rc = false;
spin_lock_bh(&fp->lock);
WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
rc = true;
/* state ==> idle, unless currently disabled */
fp->state &= BNX2X_FP_STATE_DISABLED;
spin_unlock_bh(&fp->lock);
return rc;
smp_mb__before_atomic();
clear_bit(BNX2X_STATE_FP_POLL_BIT, &fp->busy_poll_state);
}
/* true if a socket is polling, even if it did not get the lock */
/* true if a socket is polling */
static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
{
WARN_ON(!(fp->state & BNX2X_FP_OWNED));
return fp->state & BNX2X_FP_USER_PEND;
return READ_ONCE(fp->busy_poll_state) & BNX2X_STATE_FP_POLL;
}
/* false if fp is currently owned */
static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
{
int rc = true;
set_bit(BNX2X_STATE_FP_DISABLE_BIT, &fp->busy_poll_state);
return !bnx2x_fp_ll_polling(fp);
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)
static inline void bnx2x_fp_busy_poll_init(struct bnx2x_fastpath *fp)
{
}
@@ -725,9 +692,8 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
return true;
}
static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
static inline void bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
{
return false;
}
static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
@@ -735,9 +701,8 @@ static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
return false;
}
static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
static inline void bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
{
return false;
}
static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
@@ -1849,7 +1849,7 @@ static void bnx2x_napi_enable_cnic(struct bnx2x *bp)
int i;
for_each_rx_queue_cnic(bp, i) {
bnx2x_fp_init_lock(&bp->fp[i]);
bnx2x_fp_busy_poll_init(&bp->fp[i]);
napi_enable(&bnx2x_fp(bp, i, napi));
}
}
@@ -1859,7 +1859,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp)
int i;
for_each_eth_queue(bp, i) {
bnx2x_fp_init_lock(&bp->fp[i]);
bnx2x_fp_busy_poll_init(&bp->fp[i]);
napi_enable(&bnx2x_fp(bp, i, napi));
}
}
@@ -3191,9 +3191,10 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
}
}
bnx2x_fp_unlock_napi(fp);
/* Fall out from the NAPI loop if needed */
if (!bnx2x_fp_unlock_napi(fp) &&
!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
/* No need to update SB for FCoE L2 ring as long as
* it's connected to the default SB and the SB
@@ -1140,6 +1140,10 @@ static int set_filter_wr(struct adapter *adapter, int fidx)
struct fw_filter_wr *fwr;
unsigned int ftid;
skb = alloc_skb(sizeof(*fwr), GFP_KERNEL);
if (!skb)
return -ENOMEM;
/* If the new filter requires loopback Destination MAC and/or VLAN
* rewriting then we need to allocate a Layer 2 Table (L2T) entry for
* the filter.
@@ -1147,19 +1151,21 @@ static int set_filter_wr(struct adapter *adapter, int fidx)
if (f->fs.newdmac || f->fs.newvlan) {
/* allocate L2T entry for new filter */
f->l2t = t4_l2t_alloc_switching(adapter->l2t);
if (f->l2t == NULL)
if (f->l2t == NULL) {
kfree_skb(skb);
return -EAGAIN;
}
if (t4_l2t_set_switching(adapter, f->l2t, f->fs.vlan,
f->fs.eport, f->fs.dmac)) {
cxgb4_l2t_release(f->l2t);
f->l2t = NULL;
kfree_skb(skb);
return -ENOMEM;
}
}
ftid = adapter->tids.ftid_base + fidx;
skb = alloc_skb(sizeof(*fwr), GFP_KERNEL | __GFP_NOFAIL);
fwr = (struct fw_filter_wr *)__skb_put(skb, sizeof(*fwr));
memset(fwr, 0, sizeof(*fwr));
@@ -1257,7 +1263,10 @@ static int del_filter_wr(struct adapter *adapter, int fidx)
len = sizeof(*fwr);
ftid = adapter->tids.ftid_base + fidx;
skb = alloc_skb(len, GFP_KERNEL | __GFP_NOFAIL);
skb = alloc_skb(len, GFP_KERNEL);
if (!skb)
return -ENOMEM;
fwr = (struct fw_filter_wr *)__skb_put(skb, len);
t4_mk_filtdelwr(ftid, fwr, adapter->sge.fw_evtq.abs_id);
+11 -7
View File
@@ -413,6 +413,15 @@ out:
return count;
}
static void hip04_start_tx_timer(struct hip04_priv *priv)
{
unsigned long ns = priv->tx_coalesce_usecs * NSEC_PER_USEC / 2;
/* allow timer to fire after half the time at the earliest */
hrtimer_start_range_ns(&priv->tx_coalesce_timer, ns_to_ktime(ns),
ns, HRTIMER_MODE_REL);
}
static int hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct hip04_priv *priv = netdev_priv(ndev);
@@ -466,8 +475,7 @@ static int hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
} else if (!hrtimer_is_queued(&priv->tx_coalesce_timer)) {
/* cleanup not pending yet, start a new timer */
hrtimer_start_expires(&priv->tx_coalesce_timer,
HRTIMER_MODE_REL);
hip04_start_tx_timer(priv);
}
return NETDEV_TX_OK;
@@ -549,7 +557,7 @@ done:
/* clean up tx descriptors and start a new timer if necessary */
tx_remaining = hip04_tx_reclaim(ndev, false);
if (rx < budget && tx_remaining)
hrtimer_start_expires(&priv->tx_coalesce_timer, HRTIMER_MODE_REL);
hip04_start_tx_timer(priv);
return rx;
}
@@ -809,7 +817,6 @@ static int hip04_mac_probe(struct platform_device *pdev)
struct hip04_priv *priv;
struct resource *res;
unsigned int irq;
ktime_t txtime;
int ret;
ndev = alloc_etherdev(sizeof(struct hip04_priv));
@@ -846,9 +853,6 @@ static int hip04_mac_probe(struct platform_device *pdev)
*/
priv->tx_coalesce_frames = TX_DESC_NUM * 3 / 4;
priv->tx_coalesce_usecs = 200;
/* allow timer to fire after half the time at the earliest */
txtime = ktime_set(0, priv->tx_coalesce_usecs * NSEC_PER_USEC / 2);
hrtimer_set_expires_range(&priv->tx_coalesce_timer, txtime, txtime);
priv->tx_coalesce_timer.function = tx_done;
priv->map = syscon_node_to_regmap(arg.np);
@@ -2397,6 +2397,7 @@ i40e_aq_erase_nvm_exit:
#define I40E_DEV_FUNC_CAP_LED 0x61
#define I40E_DEV_FUNC_CAP_SDP 0x62
#define I40E_DEV_FUNC_CAP_MDIO 0x63
#define I40E_DEV_FUNC_CAP_WR_CSR_PROT 0x64
/**
* i40e_parse_discover_capabilities
@@ -2541,11 +2542,18 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
p->fd_filters_guaranteed = number;
p->fd_filters_best_effort = logical_id;
break;
case I40E_DEV_FUNC_CAP_WR_CSR_PROT:
p->wr_csr_prot = (u64)number;
p->wr_csr_prot |= (u64)logical_id << 32;
break;
default:
break;
}
}
if (p->fcoe)
i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
/* Software override ensuring FCoE is disabled if npar or mfp
* mode because it is not supported in these modes.
*/
@@ -3502,6 +3510,63 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
}
}
/**
* i40e_aq_debug_dump
* @hw: pointer to the hardware structure
* @cluster_id: specific cluster to dump
* @table_id: table id within cluster
* @start_index: index of line in the block to read
* @buff_size: dump buffer size
* @buff: dump buffer
* @ret_buff_size: actual buffer size returned
* @ret_next_table: next block to read
* @ret_next_index: next index to read
*
* Dump internal FW/HW data for debug purposes.
*
**/
i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
u8 table_id, u32 start_index, u16 buff_size,
void *buff, u16 *ret_buff_size,
u8 *ret_next_table, u32 *ret_next_index,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_debug_dump_internals *cmd =
(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
struct i40e_aqc_debug_dump_internals *resp =
(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
i40e_status status;
if (buff_size == 0 || !buff)
return I40E_ERR_PARAM;
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_debug_dump_internals);
/* Indirect Command */
desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
if (buff_size > I40E_AQ_LARGE_BUF)
desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
cmd->cluster_id = cluster_id;
cmd->table_id = table_id;
cmd->idx = cpu_to_le32(start_index);
desc.datalen = cpu_to_le16(buff_size);
status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
if (!status) {
if (ret_buff_size)
*ret_buff_size = le16_to_cpu(desc.datalen);
if (ret_next_table)
*ret_next_table = resp->table_id;
if (ret_next_index)
*ret_next_index = le32_to_cpu(resp->idx);
}
return status;
}
/**
* i40e_read_bw_from_alt_ram
* @hw: pointer to the hardware structure
+2 -4
View File
@@ -419,7 +419,7 @@ static void i40e_cee_to_dcb_v1_config(
{
u16 status, tlv_status = le16_to_cpu(cee_cfg->tlv_status);
u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
u8 i, tc, err, sync, oper;
u8 i, tc, err;
/* CEE PG data to ETS config */
dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
@@ -456,9 +456,7 @@ static void i40e_cee_to_dcb_v1_config(
status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
I40E_AQC_CEE_APP_STATUS_SHIFT;
err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
/* Add APPs if Error is False and Oper/Sync is True */
/* Add APPs if Error is False */
if (!err) {
/* CEE operating configuration supports FCoE/iSCSI/FIP only */
dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
@@ -1388,6 +1388,50 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
r_cfg->app[i].selector,
r_cfg->app[i].protocolid);
}
} else if (strncmp(&cmd_buf[5], "debug fwdata", 12) == 0) {
int cluster_id, table_id;
int index, ret;
u16 buff_len = 4096;
u32 next_index;
u8 next_table;
u8 *buff;
u16 rlen;
cnt = sscanf(&cmd_buf[18], "%i %i %i",
&cluster_id, &table_id, &index);
if (cnt != 3) {
dev_info(&pf->pdev->dev,
"dump debug fwdata <cluster_id> <table_id> <index>\n");
goto command_write_done;
}
dev_info(&pf->pdev->dev,
"AQ debug dump fwdata params %x %x %x %x\n",
cluster_id, table_id, index, buff_len);
buff = kzalloc(buff_len, GFP_KERNEL);
if (!buff)
goto command_write_done;
ret = i40e_aq_debug_dump(&pf->hw, cluster_id, table_id,
index, buff_len, buff, &rlen,
&next_table, &next_index,
NULL);
if (ret) {
dev_info(&pf->pdev->dev,
"debug dump fwdata AQ Failed %d 0x%x\n",
ret, pf->hw.aq.asq_last_status);
kfree(buff);
buff = NULL;
goto command_write_done;
}
dev_info(&pf->pdev->dev,
"AQ debug dump fwdata rlen=0x%x next_table=0x%x next_index=0x%x\n",
rlen, next_table, next_index);
print_hex_dump(KERN_INFO, "AQ buffer WB: ",
DUMP_PREFIX_OFFSET, 16, 1,
buff, rlen, true);
kfree(buff);
buff = NULL;
} else {
dev_info(&pf->pdev->dev,
"dump desc tx <vsi_seid> <ring_id> [<desc_n>], dump desc rx <vsi_seid> <ring_id> [<desc_n>],\n");
@@ -1903,6 +1947,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
dev_info(&pf->pdev->dev, " dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n");
dev_info(&pf->pdev->dev, " dump desc aq\n");
dev_info(&pf->pdev->dev, " dump reset stats\n");
dev_info(&pf->pdev->dev, " dump debug fwdata <cluster_id> <table_id> <index>\n");
dev_info(&pf->pdev->dev, " msg_enable [level]\n");
dev_info(&pf->pdev->dev, " read <reg>\n");
dev_info(&pf->pdev->dev, " write <reg> <value>\n");
+27 -2
View File
@@ -356,8 +356,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
/* Set speed and duplex */
switch (link_speed) {
case I40E_LINK_SPEED_40GB:
/* need a SPEED_40000 in ethtool.h */
ethtool_cmd_speed_set(ecmd, 40000);
ethtool_cmd_speed_set(ecmd, SPEED_40000);
break;
case I40E_LINK_SPEED_20GB:
ethtool_cmd_speed_set(ecmd, SPEED_20000);
@@ -1914,6 +1913,16 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
else
fsp->ring_cookie = rule->q_index;
if (rule->dest_vsi != pf->vsi[pf->lan_vsi]->id) {
struct i40e_vsi *vsi;
vsi = i40e_find_vsi_from_id(pf, rule->dest_vsi);
if (vsi && vsi->type == I40E_VSI_SRIOV) {
fsp->h_ext.data[1] = htonl(vsi->vf_id);
fsp->m_ext.data[1] = htonl(0x1);
}
}
return 0;
}
@@ -2207,6 +2216,7 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
struct i40e_fdir_filter *input;
struct i40e_pf *pf;
int ret = -EINVAL;
u16 vf_id;
if (!vsi)
return -EINVAL;
@@ -2267,7 +2277,22 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src;
input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst;
if (ntohl(fsp->m_ext.data[1])) {
if (ntohl(fsp->h_ext.data[1]) >= pf->num_alloc_vfs) {
netif_info(pf, drv, vsi->netdev, "Invalid VF id\n");
goto free_input;
}
vf_id = ntohl(fsp->h_ext.data[1]);
/* Find vsi id from vf id and override dest vsi */
input->dest_vsi = pf->vf[vf_id].lan_vsi_id;
if (input->q_index >= pf->vf[vf_id].num_queue_pairs) {
netif_info(pf, drv, vsi->netdev, "Invalid queue id\n");
goto free_input;
}
}
ret = i40e_add_del_fdir(vsi, input, true);
free_input:
if (ret)
kfree(input);
else
+12 -4
View File
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 3
#define DRV_VERSION_BUILD 1
#define DRV_VERSION_BUILD 2
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
@@ -7301,7 +7301,7 @@ err_out:
* i40e_init_interrupt_scheme - Determine proper interrupt scheme
* @pf: board private structure to initialize
**/
static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
static int i40e_init_interrupt_scheme(struct i40e_pf *pf)
{
int vectors = 0;
ssize_t size;
@@ -7343,11 +7343,17 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
/* set up vector assignment tracking */
size = sizeof(struct i40e_lump_tracking) + (sizeof(u16) * vectors);
pf->irq_pile = kzalloc(size, GFP_KERNEL);
if (!pf->irq_pile) {
dev_err(&pf->pdev->dev, "error allocating irq_pile memory\n");
return -ENOMEM;
}
pf->irq_pile->num_entries = vectors;
pf->irq_pile->search_hint = 0;
/* track first vector for misc interrupts */
/* track first vector for misc interrupts, ignore return */
(void)i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT - 1);
return 0;
}
/**
@@ -9827,7 +9833,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* set up the main switch operations */
i40e_determine_queue_usage(pf);
i40e_init_interrupt_scheme(pf);
err = i40e_init_interrupt_scheme(pf);
if (err)
goto err_switch_setup;
/* The number of VSIs reported by the FW is the minimum guaranteed
* to us; HW supports far more and we share the remaining pool with
+1 -2
View File
@@ -821,13 +821,12 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
int *errno)
{
enum i40e_nvmupd_cmd upd_cmd;
u8 transaction, module;
u8 transaction;
/* anything that doesn't match a recognized case is an error */
upd_cmd = I40E_NVMUPD_INVALID;
transaction = i40e_nvmupd_get_transaction(cmd->config);
module = i40e_nvmupd_get_module(cmd->config);
/* limits on data size */
if ((cmd->data_size < 1) ||
@@ -303,4 +303,9 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
u16 vsi_seid, u16 queue, bool is_add,
struct i40e_control_filter_stats *stats,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
u8 table_id, u32 start_index, u16 buff_size,
void *buff, u16 *ret_buff_size,
u8 *ret_next_table, u32 *ret_next_index,
struct i40e_asq_cmd_details *cmd_details);
#endif /* _I40E_PROTOTYPE_H_ */
@@ -242,6 +242,7 @@ struct i40e_hw_capabilities {
u8 rx_buf_chain_len;
u32 enabled_tcmap;
u32 maxtc;
u64 wr_csr_prot;
};
struct i40e_mac_info {
+132 -112
View File
@@ -26,6 +26,129 @@
#include "i40e.h"
/*********************notification routines***********************/
/**
* i40e_vc_vf_broadcast
* @pf: pointer to the PF structure
* @opcode: operation code
* @retval: return value
* @msg: pointer to the msg buffer
* @msglen: msg length
*
* send a message to all VFs on a given PF
**/
static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
enum i40e_virtchnl_ops v_opcode,
i40e_status v_retval, u8 *msg,
u16 msglen)
{
struct i40e_hw *hw = &pf->hw;
struct i40e_vf *vf = pf->vf;
int i;
for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
/* Not all vfs are enabled so skip the ones that are not */
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
continue;
/* Ignore return value on purpose - a given VF may fail, but
* we need to keep going and send to all of them
*/
i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval,
msg, msglen, NULL);
}
}
/**
* i40e_vc_notify_link_state
* @vf: pointer to the VF structure
*
* send a link status message to a single VF
**/
static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf)
{
struct i40e_virtchnl_pf_event pfe;
struct i40e_pf *pf = vf->pf;
struct i40e_hw *hw = &pf->hw;
struct i40e_link_status *ls = &pf->hw.phy.link_info;
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
if (vf->link_forced) {
pfe.event_data.link_event.link_status = vf->link_up;
pfe.event_data.link_event.link_speed =
(vf->link_up ? I40E_LINK_SPEED_40GB : 0);
} else {
pfe.event_data.link_event.link_status =
ls->link_info & I40E_AQ_LINK_UP;
pfe.event_data.link_event.link_speed = ls->link_speed;
}
i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
0, (u8 *)&pfe, sizeof(pfe), NULL);
}
/**
* i40e_vc_notify_link_state
* @pf: pointer to the PF structure
*
* send a link status message to all VFs on a given PF
**/
void i40e_vc_notify_link_state(struct i40e_pf *pf)
{
int i;
for (i = 0; i < pf->num_alloc_vfs; i++)
i40e_vc_notify_vf_link_state(&pf->vf[i]);
}
/**
* i40e_vc_notify_reset
* @pf: pointer to the PF structure
*
* indicate a pending reset to all VFs on a given PF
**/
void i40e_vc_notify_reset(struct i40e_pf *pf)
{
struct i40e_virtchnl_pf_event pfe;
pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
i40e_vc_vf_broadcast(pf, I40E_VIRTCHNL_OP_EVENT, 0,
(u8 *)&pfe, sizeof(struct i40e_virtchnl_pf_event));
}
/**
* i40e_vc_notify_vf_reset
* @vf: pointer to the VF structure
*
* indicate a pending reset to the given VF
**/
void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
{
struct i40e_virtchnl_pf_event pfe;
int abs_vf_id;
/* validate the request */
if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs)
return;
/* verify if the VF is in either init or active before proceeding */
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
return;
abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
i40e_aq_send_msg_to_vf(&vf->pf->hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
0, (u8 *)&pfe,
sizeof(struct i40e_virtchnl_pf_event), NULL);
}
/***********************misc routines*****************************/
/**
@@ -689,6 +812,9 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
}
}
if (flr)
usleep_range(10000, 20000);
if (!rsd)
dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
vf->vf_id);
@@ -733,6 +859,11 @@ void i40e_free_vfs(struct i40e_pf *pf)
while (test_and_set_bit(__I40E_VF_DISABLE, &pf->state))
usleep_range(1000, 2000);
for (i = 0; i < pf->num_alloc_vfs; i++)
if (test_bit(I40E_VF_STAT_INIT, &pf->vf[i].vf_states))
i40e_vsi_control_rings(pf->vsi[pf->vf[i].lan_vsi_idx],
false);
/* Disable IOV before freeing resources. This lets any VF drivers
* running in the host get themselves cleaned up before we yank
* the carpet out from underneath their feet.
@@ -1762,6 +1893,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
break;
case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
ret = i40e_vc_enable_queues_msg(vf, msg, msglen);
i40e_vc_notify_vf_link_state(vf);
break;
case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
ret = i40e_vc_disable_queues_msg(vf, msg, msglen);
@@ -1834,118 +1966,6 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf)
return 0;
}
/**
* i40e_vc_vf_broadcast
* @pf: pointer to the PF structure
* @opcode: operation code
* @retval: return value
* @msg: pointer to the msg buffer
* @msglen: msg length
*
* send a message to all VFs on a given PF
**/
static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
enum i40e_virtchnl_ops v_opcode,
i40e_status v_retval, u8 *msg,
u16 msglen)
{
struct i40e_hw *hw = &pf->hw;
struct i40e_vf *vf = pf->vf;
int i;
for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
/* Not all VFs are enabled so skip the ones that are not */
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
continue;
/* Ignore return value on purpose - a given VF may fail, but
* we need to keep going and send to all of them
*/
i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval,
msg, msglen, NULL);
}
}
/**
* i40e_vc_notify_link_state
* @pf: pointer to the PF structure
*
* send a link status message to all VFs on a given PF
**/
void i40e_vc_notify_link_state(struct i40e_pf *pf)
{
struct i40e_virtchnl_pf_event pfe;
struct i40e_hw *hw = &pf->hw;
struct i40e_vf *vf = pf->vf;
struct i40e_link_status *ls = &pf->hw.phy.link_info;
int i;
pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
for (i = 0; i < pf->num_alloc_vfs; i++, vf++) {
int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
if (vf->link_forced) {
pfe.event_data.link_event.link_status = vf->link_up;
pfe.event_data.link_event.link_speed =
(vf->link_up ? I40E_LINK_SPEED_40GB : 0);
} else {
pfe.event_data.link_event.link_status =
ls->link_info & I40E_AQ_LINK_UP;
pfe.event_data.link_event.link_speed = ls->link_speed;
}
i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
0, (u8 *)&pfe, sizeof(pfe),
NULL);
}
}
/**
* i40e_vc_notify_reset
* @pf: pointer to the PF structure
*
* indicate a pending reset to all VFs on a given PF
**/
void i40e_vc_notify_reset(struct i40e_pf *pf)
{
struct i40e_virtchnl_pf_event pfe;
pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
i40e_vc_vf_broadcast(pf, I40E_VIRTCHNL_OP_EVENT, I40E_SUCCESS,
(u8 *)&pfe, sizeof(struct i40e_virtchnl_pf_event));
}
/**
* i40e_vc_notify_vf_reset
* @vf: pointer to the VF structure
*
* indicate a pending reset to the given VF
**/
void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
{
struct i40e_virtchnl_pf_event pfe;
int abs_vf_id;
/* validate the request */
if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs)
return;
/* verify if the VF is in either init or active before proceeding */
if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states) &&
!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states))
return;
abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
i40e_aq_send_msg_to_vf(&vf->pf->hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
I40E_SUCCESS, (u8 *)&pfe,
sizeof(struct i40e_virtchnl_pf_event), NULL);
}
/**
* i40e_ndo_set_vf_mac
* @netdev: network interface device structure

Some files were not shown because too many files have changed in this diff Show More