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

Pull networking changes from David Miller:
 "The most important bit in here is the fix for input route caching from
  Eric Dumazet, it's a shame we couldn't fully analyze this in time for
  3.6 as it's a 3.6 regression introduced by the routing cache removal.

  Anyways, will send quickly to -stable after you pull this in.

  Other changes of note:

   1) Fix lockdep splats in team and bonding, from Eric Dumazet.

   2) IPV6 adds link local route even when there is no link local
      address, from Nicolas Dichtel.

   3) Fix ixgbe PTP implementation, from Jacob Keller.

   4) Fix excessive stack usage in cxgb4 driver, from Vipul Pandya.

   5) MAC length computed improperly in VLAN demux, from Antonio
      Quartulli."

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (26 commits)
  ipv6: release reference of ip6_null_entry's dst entry in __ip6_del_rt
  Remove noisy printks from llcp_sock_connect
  tipc: prevent dropped connections due to rcvbuf overflow
  silence some noisy printks in irda
  team: set qdisc_tx_busylock to avoid LOCKDEP splat
  bonding: set qdisc_tx_busylock to avoid LOCKDEP splat
  sctp: check src addr when processing SACK to update transport state
  sctp: fix a typo in prototype of __sctp_rcv_lookup()
  ipv4: add a fib_type to fib_info
  can: mpc5xxx_can: fix section type conflict
  can: peak_pcmcia: fix error return code
  can: peak_pci: fix error return code
  cxgb4: Fix build error due to missing linux/vmalloc.h include.
  bnx2x: fix ring size for 10G functions
  cxgb4: Dynamically allocate memory in t4_memory_rw() and get_vpd_params()
  ixgbe: add support for X540-AT1
  ixgbe: fix poll loop for FDIRCTRL.INIT_DONE bit
  ixgbe: fix PTP ethtool timestamping function
  ixgbe: (PTP) Fix PPS interrupt code
  ixgbe: Fix PTP X540 SDP alignment code for PPS signal
  ...
This commit is contained in:
Linus Torvalds 2012-10-06 03:11:59 +09:00
commit 283dbd8205
32 changed files with 209 additions and 185 deletions

View File

@ -4826,6 +4826,7 @@ static int bond_check_params(struct bond_params *params)
static struct lock_class_key bonding_netdev_xmit_lock_key; static struct lock_class_key bonding_netdev_xmit_lock_key;
static struct lock_class_key bonding_netdev_addr_lock_key; static struct lock_class_key bonding_netdev_addr_lock_key;
static struct lock_class_key bonding_tx_busylock_key;
static void bond_set_lockdep_class_one(struct net_device *dev, static void bond_set_lockdep_class_one(struct net_device *dev,
struct netdev_queue *txq, struct netdev_queue *txq,
@ -4840,6 +4841,7 @@ static void bond_set_lockdep_class(struct net_device *dev)
lockdep_set_class(&dev->addr_list_lock, lockdep_set_class(&dev->addr_list_lock,
&bonding_netdev_addr_lock_key); &bonding_netdev_addr_lock_key);
netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL); netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
dev->qdisc_tx_busylock = &bonding_tx_busylock_key;
} }
/* /*

View File

@ -247,7 +247,7 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
} }
#endif /* CONFIG_PPC_MPC512x */ #endif /* CONFIG_PPC_MPC512x */
static struct of_device_id mpc5xxx_can_table[]; static const struct of_device_id mpc5xxx_can_table[];
static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev)
{ {
const struct of_device_id *match; const struct of_device_id *match;
@ -380,17 +380,17 @@ static int mpc5xxx_can_resume(struct platform_device *ofdev)
} }
#endif #endif
static const struct mpc5xxx_can_data __devinitdata mpc5200_can_data = { static const struct mpc5xxx_can_data __devinitconst mpc5200_can_data = {
.type = MSCAN_TYPE_MPC5200, .type = MSCAN_TYPE_MPC5200,
.get_clock = mpc52xx_can_get_clock, .get_clock = mpc52xx_can_get_clock,
}; };
static const struct mpc5xxx_can_data __devinitdata mpc5121_can_data = { static const struct mpc5xxx_can_data __devinitconst mpc5121_can_data = {
.type = MSCAN_TYPE_MPC5121, .type = MSCAN_TYPE_MPC5121,
.get_clock = mpc512x_can_get_clock, .get_clock = mpc512x_can_get_clock,
}; };
static struct of_device_id __devinitdata mpc5xxx_can_table[] = { static const struct of_device_id __devinitconst mpc5xxx_can_table[] = {
{ .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, }, { .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, },
/* Note that only MPC5121 Rev. 2 (and later) is supported */ /* Note that only MPC5121 Rev. 2 (and later) is supported */
{ .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, }, { .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, },

View File

@ -583,12 +583,14 @@ static int __devinit peak_pci_probe(struct pci_dev *pdev,
cfg_base = pci_iomap(pdev, 0, PEAK_PCI_CFG_SIZE); cfg_base = pci_iomap(pdev, 0, PEAK_PCI_CFG_SIZE);
if (!cfg_base) { if (!cfg_base) {
dev_err(&pdev->dev, "failed to map PCI resource #0\n"); dev_err(&pdev->dev, "failed to map PCI resource #0\n");
err = -ENOMEM;
goto failure_release_regions; goto failure_release_regions;
} }
reg_base = pci_iomap(pdev, 1, PEAK_PCI_CHAN_SIZE * channels); reg_base = pci_iomap(pdev, 1, PEAK_PCI_CHAN_SIZE * channels);
if (!reg_base) { if (!reg_base) {
dev_err(&pdev->dev, "failed to map PCI resource #1\n"); dev_err(&pdev->dev, "failed to map PCI resource #1\n");
err = -ENOMEM;
goto failure_unmap_cfg_base; goto failure_unmap_cfg_base;
} }

View File

@ -686,8 +686,10 @@ static int __devinit pcan_probe(struct pcmcia_device *pdev)
/* detect available channels */ /* detect available channels */
pcan_add_channels(card); pcan_add_channels(card);
if (!card->chan_count) if (!card->chan_count) {
err = -ENOMEM;
goto probe_err_4; goto probe_err_4;
}
/* init the timer which controls the leds */ /* init the timer which controls the leds */
init_timer(&card->led_timer); init_timer(&card->led_timer);

View File

@ -3523,15 +3523,18 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
} else } else
#endif #endif
if (!bp->rx_ring_size) { if (!bp->rx_ring_size) {
u32 cfg = SHMEM_RD(bp,
dev_info.port_hw_config[BP_PORT(bp)].default_cfg);
rx_ring_size = MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp); rx_ring_size = MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp);
/* Dercease ring size for 1G functions */ if (CHIP_IS_E3(bp)) {
if ((cfg & PORT_HW_CFG_NET_SERDES_IF_MASK) == u32 cfg = SHMEM_RD(bp,
PORT_HW_CFG_NET_SERDES_IF_SGMII) dev_info.port_hw_config[BP_PORT(bp)].
rx_ring_size /= 10; default_cfg);
/* Decrease ring size for 1G functions */
if ((cfg & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
PORT_HW_CFG_NET_SERDES_IF_SGMII)
rx_ring_size /= 10;
}
/* allocate at least number of buffers required by FW */ /* allocate at least number of buffers required by FW */
rx_ring_size = max_t(int, bp->disable_tpa ? MIN_RX_SIZE_NONTPA : rx_ring_size = max_t(int, bp->disable_tpa ? MIN_RX_SIZE_NONTPA :

View File

@ -3052,9 +3052,8 @@ static void bnx2x_drv_info_ether_stat(struct bnx2x *bp)
struct eth_stats_info *ether_stat = struct eth_stats_info *ether_stat =
&bp->slowpath->drv_info_to_mcp.ether_stat; &bp->slowpath->drv_info_to_mcp.ether_stat;
/* leave last char as NULL */ strlcpy(ether_stat->version, DRV_MODULE_VERSION,
memcpy(ether_stat->version, DRV_MODULE_VERSION, ETH_STAT_INFO_VERSION_LEN);
ETH_STAT_INFO_VERSION_LEN - 1);
bp->sp_objs[0].mac_obj.get_n_elements(bp, &bp->sp_objs[0].mac_obj, bp->sp_objs[0].mac_obj.get_n_elements(bp, &bp->sp_objs[0].mac_obj,
DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED, DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED,

View File

@ -782,7 +782,8 @@ static int tg3_ape_wait_for_event(struct tg3 *tp, u32 timeout_us)
return i == timeout_us / 10; return i == timeout_us / 10;
} }
int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off, u32 len) static int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off,
u32 len)
{ {
int err; int err;
u32 i, bufoff, msgoff, maxlen, apedata; u32 i, bufoff, msgoff, maxlen, apedata;
@ -7763,7 +7764,7 @@ static int tg3_alloc_consistent(struct tg3 *tp)
sblk = tnapi->hw_status; sblk = tnapi->hw_status;
if (tg3_flag(tp, ENABLE_RSS)) { if (tg3_flag(tp, ENABLE_RSS)) {
u16 *prodptr = 0; u16 *prodptr = NULL;
/* /*
* When RSS is enabled, the status block format changes * When RSS is enabled, the status block format changes
@ -8103,11 +8104,11 @@ static int tg3_chip_reset(struct tg3 *tp)
u16 val16; u16 val16;
if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) { if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
int i; int j;
u32 cfg_val; u32 cfg_val;
/* Wait for link training to complete. */ /* Wait for link training to complete. */
for (i = 0; i < 5000; i++) for (j = 0; j < 5000; j++)
udelay(100); udelay(100);
pci_read_config_dword(tp->pdev, 0xc4, &cfg_val); pci_read_config_dword(tp->pdev, 0xc4, &cfg_val);
@ -10206,7 +10207,7 @@ static u32 tg3_irq_count(struct tg3 *tp)
static bool tg3_enable_msix(struct tg3 *tp) static bool tg3_enable_msix(struct tg3 *tp)
{ {
int i, rc; int i, rc;
struct msix_entry msix_ent[tp->irq_max]; struct msix_entry msix_ent[TG3_IRQ_MAX_VECS];
tp->txq_cnt = tp->txq_req; tp->txq_cnt = tp->txq_req;
tp->rxq_cnt = tp->rxq_req; tp->rxq_cnt = tp->rxq_req;

View File

@ -43,6 +43,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/vmalloc.h>
#include <asm/io.h> #include <asm/io.h>
#include "cxgb4_uld.h" #include "cxgb4_uld.h"
#include "t4_hw.h" #include "t4_hw.h"

View File

@ -408,7 +408,8 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
__be32 *buf, int dir) __be32 *buf, int dir)
{ {
u32 pos, start, end, offset, memoffset; u32 pos, start, end, offset, memoffset;
int ret; int ret = 0;
__be32 *data;
/* /*
* Argument sanity checks ... * Argument sanity checks ...
@ -416,6 +417,10 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
if ((addr & 0x3) || (len & 0x3)) if ((addr & 0x3) || (len & 0x3))
return -EINVAL; return -EINVAL;
data = vmalloc(MEMWIN0_APERTURE/sizeof(__be32));
if (!data)
return -ENOMEM;
/* /*
* Offset into the region of memory which is being accessed * Offset into the region of memory which is being accessed
* MEM_EDC0 = 0 * MEM_EDC0 = 0
@ -438,7 +443,6 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
offset = (addr - start)/sizeof(__be32); offset = (addr - start)/sizeof(__be32);
for (pos = start; pos < end; pos += MEMWIN0_APERTURE, offset = 0) { for (pos = start; pos < end; pos += MEMWIN0_APERTURE, offset = 0) {
__be32 data[MEMWIN0_APERTURE/sizeof(__be32)];
/* /*
* If we're writing, copy the data from the caller's memory * If we're writing, copy the data from the caller's memory
@ -452,7 +456,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
if (offset || len < MEMWIN0_APERTURE) { if (offset || len < MEMWIN0_APERTURE) {
ret = t4_mem_win_rw(adap, pos, data, 1); ret = t4_mem_win_rw(adap, pos, data, 1);
if (ret) if (ret)
return ret; break;
} }
while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) && while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) &&
len > 0) { len > 0) {
@ -466,7 +470,7 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
*/ */
ret = t4_mem_win_rw(adap, pos, data, dir); ret = t4_mem_win_rw(adap, pos, data, dir);
if (ret) if (ret)
return ret; break;
/* /*
* If we're reading, copy the data into the caller's memory * If we're reading, copy the data into the caller's memory
@ -480,7 +484,8 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
} }
} }
return 0; vfree(data);
return ret;
} }
int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len,
@ -519,16 +524,21 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
u32 cclk_param, cclk_val; u32 cclk_param, cclk_val;
int i, ret; int i, ret;
int ec, sn; int ec, sn;
u8 vpd[VPD_LEN], csum; u8 *vpd, csum;
unsigned int vpdr_len, kw_offset, id_len; unsigned int vpdr_len, kw_offset, id_len;
ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), vpd); vpd = vmalloc(VPD_LEN);
if (!vpd)
return -ENOMEM;
ret = pci_read_vpd(adapter->pdev, VPD_BASE, VPD_LEN, vpd);
if (ret < 0) if (ret < 0)
return ret; goto out;
if (vpd[0] != PCI_VPD_LRDT_ID_STRING) { if (vpd[0] != PCI_VPD_LRDT_ID_STRING) {
dev_err(adapter->pdev_dev, "missing VPD ID string\n"); dev_err(adapter->pdev_dev, "missing VPD ID string\n");
return -EINVAL; ret = -EINVAL;
goto out;
} }
id_len = pci_vpd_lrdt_size(vpd); id_len = pci_vpd_lrdt_size(vpd);
@ -538,21 +548,24 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA); i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA);
if (i < 0) { if (i < 0) {
dev_err(adapter->pdev_dev, "missing VPD-R section\n"); dev_err(adapter->pdev_dev, "missing VPD-R section\n");
return -EINVAL; ret = -EINVAL;
goto out;
} }
vpdr_len = pci_vpd_lrdt_size(&vpd[i]); vpdr_len = pci_vpd_lrdt_size(&vpd[i]);
kw_offset = i + PCI_VPD_LRDT_TAG_SIZE; kw_offset = i + PCI_VPD_LRDT_TAG_SIZE;
if (vpdr_len + kw_offset > VPD_LEN) { if (vpdr_len + kw_offset > VPD_LEN) {
dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len); dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len);
return -EINVAL; ret = -EINVAL;
goto out;
} }
#define FIND_VPD_KW(var, name) do { \ #define FIND_VPD_KW(var, name) do { \
var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \ var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \
if (var < 0) { \ if (var < 0) { \
dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \ dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \
return -EINVAL; \ ret = -EINVAL; \
goto out; \
} \ } \
var += PCI_VPD_INFO_FLD_HDR_SIZE; \ var += PCI_VPD_INFO_FLD_HDR_SIZE; \
} while (0) } while (0)
@ -564,7 +577,8 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
if (csum) { if (csum) {
dev_err(adapter->pdev_dev, dev_err(adapter->pdev_dev,
"corrupted VPD EEPROM, actual csum %u\n", csum); "corrupted VPD EEPROM, actual csum %u\n", csum);
return -EINVAL; ret = -EINVAL;
goto out;
} }
FIND_VPD_KW(ec, "EC"); FIND_VPD_KW(ec, "EC");
@ -587,6 +601,9 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK)); FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK));
ret = t4_query_params(adapter, adapter->mbox, 0, 0, ret = t4_query_params(adapter, adapter->mbox, 0, 0,
1, &cclk_param, &cclk_val); 1, &cclk_param, &cclk_val);
out:
vfree(vpd);
if (ret) if (ret)
return ret; return ret;
p->cclk = cclk_val; p->cclk = cclk_val;

View File

@ -1099,7 +1099,7 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
IXGBE_FDIRCTRL_INIT_DONE) IXGBE_FDIRCTRL_INIT_DONE)
break; break;
udelay(10); usleep_range(1000, 2000);
} }
if (i >= IXGBE_FDIR_INIT_DONE_POLL) { if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");

View File

@ -70,6 +70,7 @@ static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
switch (hw->device_id) { switch (hw->device_id) {
case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T:
case IXGBE_DEV_ID_X540T1:
return 0; return 0;
case IXGBE_DEV_ID_82599_T3_LOM: case IXGBE_DEV_ID_82599_T3_LOM:
return 0; return 0;

View File

@ -2690,10 +2690,7 @@ static int ixgbe_get_ts_info(struct net_device *dev,
(1 << HWTSTAMP_FILTER_NONE) | (1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
(1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
(1 << HWTSTAMP_FILTER_SOME);
break; break;
#endif /* CONFIG_IXGBE_PTP */ #endif /* CONFIG_IXGBE_PTP */
default: default:

View File

@ -114,6 +114,7 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS), board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP), board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF_QP), board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF_QP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T1), board_X540 },
/* required last entry */ /* required last entry */
{0, } {0, }
}; };
@ -2322,6 +2323,12 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
default: default:
break; break;
} }
#ifdef CONFIG_IXGBE_PTP
if (adapter->hw.mac.type == ixgbe_mac_X540)
mask |= IXGBE_EIMS_TIMESYNC;
#endif
if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) &&
!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) !(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT))
mask |= IXGBE_EIMS_FLOW_DIR; mask |= IXGBE_EIMS_FLOW_DIR;
@ -2385,8 +2392,10 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data)
} }
ixgbe_check_fan_failure(adapter, eicr); ixgbe_check_fan_failure(adapter, eicr);
#ifdef CONFIG_IXGBE_PTP #ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_check_pps_event(adapter, eicr); if (unlikely(eicr & IXGBE_EICR_TIMESYNC))
ixgbe_ptp_check_pps_event(adapter, eicr);
#endif #endif
/* re-enable the original interrupt state, no lsc, no queues */ /* re-enable the original interrupt state, no lsc, no queues */
@ -2580,7 +2589,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr); ixgbe_check_fan_failure(adapter, eicr);
#ifdef CONFIG_IXGBE_PTP #ifdef CONFIG_IXGBE_PTP
ixgbe_ptp_check_pps_event(adapter, eicr); if (unlikely(eicr & IXGBE_EICR_TIMESYNC))
ixgbe_ptp_check_pps_event(adapter, eicr);
#endif #endif
/* would disable interrupts here but EIAM disabled it */ /* would disable interrupts here but EIAM disabled it */
@ -7045,6 +7055,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
is_wol_supported = 1; is_wol_supported = 1;
break; break;
case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T:
case IXGBE_DEV_ID_X540T1:
/* check eeprom to see if enabled wol */ /* check eeprom to see if enabled wol */
if ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0_1) || if ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0_1) ||
((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0) && ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0) &&

View File

@ -105,6 +105,83 @@ static struct sock_filter ptp_filter[] = {
PTP_FILTER PTP_FILTER
}; };
/**
* ixgbe_ptp_setup_sdp
* @hw: the hardware private structure
*
* this function enables or disables the clock out feature on SDP0 for
* the X540 device. It will create a 1second periodic output that can
* be used as the PPS (via an interrupt).
*
* It calculates when the systime will be on an exact second, and then
* aligns the start of the PPS signal to that value. The shift is
* necessary because it can change based on the link speed.
*/
static void ixgbe_ptp_setup_sdp(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
int shift = adapter->cc.shift;
u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem;
u64 ns = 0, clock_edge = 0;
if ((adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED) &&
(hw->mac.type == ixgbe_mac_X540)) {
/* disable the pin first */
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
IXGBE_WRITE_FLUSH(hw);
esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
/*
* enable the SDP0 pin as output, and connected to the
* native function for Timesync (ClockOut)
*/
esdp |= (IXGBE_ESDP_SDP0_DIR |
IXGBE_ESDP_SDP0_NATIVE);
/*
* enable the Clock Out feature on SDP0, and allow
* interrupts to occur when the pin changes
*/
tsauxc = (IXGBE_TSAUXC_EN_CLK |
IXGBE_TSAUXC_SYNCLK |
IXGBE_TSAUXC_SDP0_INT);
/* clock period (or pulse length) */
clktiml = (u32)(NSECS_PER_SEC << shift);
clktimh = (u32)((NSECS_PER_SEC << shift) >> 32);
/*
* Account for the cyclecounter wrap-around value by
* using the converted ns value of the current time to
* check for when the next aligned second would occur.
*/
clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
ns = timecounter_cyc2time(&adapter->tc, clock_edge);
div_u64_rem(ns, NSECS_PER_SEC, &rem);
clock_edge += ((NSECS_PER_SEC - (u64)rem) << shift);
/* specify the initial clock start time */
trgttiml = (u32)clock_edge;
trgttimh = (u32)(clock_edge >> 32);
IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml);
IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh);
IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml);
IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh);
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
} else {
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
}
IXGBE_WRITE_FLUSH(hw);
}
/** /**
* ixgbe_ptp_read - read raw cycle counter (to be used by time counter) * ixgbe_ptp_read - read raw cycle counter (to be used by time counter)
* @cc: the cyclecounter structure * @cc: the cyclecounter structure
@ -198,6 +275,9 @@ static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
now); now);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags); spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
ixgbe_ptp_setup_sdp(adapter);
return 0; return 0;
} }
@ -251,6 +331,7 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,
timecounter_init(&adapter->tc, &adapter->cc, ns); timecounter_init(&adapter->tc, &adapter->cc, ns);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags); spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
ixgbe_ptp_setup_sdp(adapter);
return 0; return 0;
} }
@ -281,8 +362,9 @@ static int ixgbe_ptp_enable(struct ptp_clock_info *ptp,
if (on) if (on)
adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED;
else else
adapter->flags2 &= adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
~IXGBE_FLAG2_PTP_PPS_ENABLED;
ixgbe_ptp_setup_sdp(adapter);
return 0; return 0;
default: default:
break; break;
@ -305,109 +387,15 @@ void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr)
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct ptp_clock_event event; struct ptp_clock_event event;
event.type = PTP_CLOCK_PPS;
/* Make sure ptp clock is valid, and PPS event enabled */
if (!adapter->ptp_clock ||
!(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED))
return;
if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) {
switch (hw->mac.type) {
case ixgbe_mac_X540:
ptp_clock_event(adapter->ptp_clock, &event);
break;
default:
break;
}
}
}
/**
* ixgbe_ptp_enable_sdp
* @hw: the hardware private structure
* @shift: the clock shift for calculating nanoseconds
*
* this function enables the clock out feature on the sdp0 for the
* X540 device. It will create a 1second periodic output that can be
* used as the PPS (via an interrupt).
*
* It calculates when the systime will be on an exact second, and then
* aligns the start of the PPS signal to that value. The shift is
* necessary because it can change based on the link speed.
*/
static void ixgbe_ptp_enable_sdp(struct ixgbe_hw *hw, int shift)
{
u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh;
u64 clock_edge = 0;
u32 rem;
switch (hw->mac.type) { switch (hw->mac.type) {
case ixgbe_mac_X540: case ixgbe_mac_X540:
esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); ptp_clock_event(adapter->ptp_clock, &event);
/*
* enable the SDP0 pin as output, and connected to the native
* function for Timesync (ClockOut)
*/
esdp |= (IXGBE_ESDP_SDP0_DIR |
IXGBE_ESDP_SDP0_NATIVE);
/*
* enable the Clock Out feature on SDP0, and allow interrupts
* to occur when the pin changes
*/
tsauxc = (IXGBE_TSAUXC_EN_CLK |
IXGBE_TSAUXC_SYNCLK |
IXGBE_TSAUXC_SDP0_INT);
/* clock period (or pulse length) */
clktiml = (u32)(NSECS_PER_SEC << shift);
clktimh = (u32)((NSECS_PER_SEC << shift) >> 32);
clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
/*
* account for the fact that we can't do u64 division
* with remainder, by converting the clock values into
* nanoseconds first
*/
clock_edge >>= shift;
div_u64_rem(clock_edge, NSECS_PER_SEC, &rem);
clock_edge += (NSECS_PER_SEC - rem);
clock_edge <<= shift;
/* specify the initial clock start time */
trgttiml = (u32)clock_edge;
trgttimh = (u32)(clock_edge >> 32);
IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml);
IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh);
IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml);
IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh);
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_TIMESYNC);
break; break;
default: default:
break; break;
} }
} }
/**
* ixgbe_ptp_disable_sdp
* @hw: the private hardware structure
*
* this function disables the auxiliary SDP clock out feature
*/
static void ixgbe_ptp_disable_sdp(struct ixgbe_hw *hw)
{
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_TIMESYNC);
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0);
}
/** /**
* ixgbe_ptp_overflow_check - delayed work to detect SYSTIME overflow * ixgbe_ptp_overflow_check - delayed work to detect SYSTIME overflow
@ -822,9 +810,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
if (adapter->cycle_speed == cycle_speed && timinca) if (adapter->cycle_speed == cycle_speed && timinca)
return; return;
/* disable the SDP clock out */
ixgbe_ptp_disable_sdp(hw);
/** /**
* Scale the NIC cycle counter by a large factor so that * Scale the NIC cycle counter by a large factor so that
* relatively small corrections to the frequency can be added * relatively small corrections to the frequency can be added
@ -877,10 +862,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
/* now that the shift has been calculated and the systime
* registers reset, (re-)enable the Clock out feature*/
ixgbe_ptp_enable_sdp(hw, shift);
/* store the new cycle speed */ /* store the new cycle speed */
adapter->cycle_speed = cycle_speed; adapter->cycle_speed = cycle_speed;
@ -901,6 +882,12 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
ktime_to_ns(ktime_get_real())); ktime_to_ns(ktime_get_real()));
spin_unlock_irqrestore(&adapter->tmreg_lock, flags); spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
/*
* Now that the shift has been calculated and the systime
* registers reset, (re-)enable the Clock out feature
*/
ixgbe_ptp_setup_sdp(adapter);
} }
/** /**
@ -979,10 +966,11 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
*/ */
void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
{ {
ixgbe_ptp_disable_sdp(&adapter->hw);
/* stop the overflow check task */ /* stop the overflow check task */
adapter->flags2 &= ~IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; adapter->flags2 &= ~(IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED |
IXGBE_FLAG2_PTP_PPS_ENABLED);
ixgbe_ptp_setup_sdp(adapter);
if (adapter->ptp_clock) { if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock); ptp_clock_unregister(adapter->ptp_clock);

View File

@ -65,6 +65,7 @@
#define IXGBE_DEV_ID_82599_LS 0x154F #define IXGBE_DEV_ID_82599_LS 0x154F
#define IXGBE_DEV_ID_X540T 0x1528 #define IXGBE_DEV_ID_X540T 0x1528
#define IXGBE_DEV_ID_82599_SFP_SF_QP 0x154A #define IXGBE_DEV_ID_82599_SFP_SF_QP 0x154A
#define IXGBE_DEV_ID_X540T1 0x1560
/* VF Device IDs */ /* VF Device IDs */
#define IXGBE_DEV_ID_82599_VF 0x10ED #define IXGBE_DEV_ID_82599_VF 0x10ED

View File

@ -26,7 +26,7 @@ if PCH_GBE
config PCH_PTP config PCH_PTP
bool "PCH PTP clock support" bool "PCH PTP clock support"
default n default n
depends on PTP_1588_CLOCK_PCH select PTP_1588_CLOCK_PCH
---help--- ---help---
Say Y here if you want to use Precision Time Protocol (PTP) in the Say Y here if you want to use Precision Time Protocol (PTP) in the
driver. PTP is a method to precisely synchronize distributed clocks driver. PTP is a method to precisely synchronize distributed clocks

View File

@ -863,6 +863,7 @@ int cpdma_chan_stop(struct cpdma_chan *chan)
next_dma = desc_read(desc, hw_next); next_dma = desc_read(desc, hw_next);
chan->head = desc_from_phys(pool, next_dma); chan->head = desc_from_phys(pool, next_dma);
chan->count--;
chan->stats.teardown_dequeue++; chan->stats.teardown_dequeue++;
/* issue callback without locks held */ /* issue callback without locks held */

View File

@ -1315,6 +1315,7 @@ static const struct team_option team_options[] = {
static struct lock_class_key team_netdev_xmit_lock_key; static struct lock_class_key team_netdev_xmit_lock_key;
static struct lock_class_key team_netdev_addr_lock_key; static struct lock_class_key team_netdev_addr_lock_key;
static struct lock_class_key team_tx_busylock_key;
static void team_set_lockdep_class_one(struct net_device *dev, static void team_set_lockdep_class_one(struct net_device *dev,
struct netdev_queue *txq, struct netdev_queue *txq,
@ -1327,6 +1328,7 @@ static void team_set_lockdep_class(struct net_device *dev)
{ {
lockdep_set_class(&dev->addr_list_lock, &team_netdev_addr_lock_key); lockdep_set_class(&dev->addr_list_lock, &team_netdev_addr_lock_key);
netdev_for_each_tx_queue(dev, team_set_lockdep_class_one, NULL); netdev_for_each_tx_queue(dev, team_set_lockdep_class_one, NULL);
dev->qdisc_tx_busylock = &team_tx_busylock_key;
} }
static int team_init(struct net_device *dev) static int team_init(struct net_device *dev)

View File

@ -102,6 +102,7 @@ struct fib_info {
unsigned char fib_dead; unsigned char fib_dead;
unsigned char fib_protocol; unsigned char fib_protocol;
unsigned char fib_scope; unsigned char fib_scope;
unsigned char fib_type;
__be32 fib_prefsrc; __be32 fib_prefsrc;
u32 fib_priority; u32 fib_priority;
u32 *fib_metrics; u32 *fib_metrics;

View File

@ -1068,7 +1068,7 @@ void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
void sctp_outq_teardown(struct sctp_outq *); void sctp_outq_teardown(struct sctp_outq *);
void sctp_outq_free(struct sctp_outq*); void sctp_outq_free(struct sctp_outq*);
int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk);
int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); int sctp_outq_sack(struct sctp_outq *, struct sctp_chunk *);
int sctp_outq_is_empty(const struct sctp_outq *); int sctp_outq_is_empty(const struct sctp_outq *);
void sctp_outq_restart(struct sctp_outq *); void sctp_outq_restart(struct sctp_outq *);

View File

@ -105,7 +105,6 @@ static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)
return NULL; return NULL;
memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN); memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
skb->mac_header += VLAN_HLEN; skb->mac_header += VLAN_HLEN;
skb_reset_mac_len(skb);
return skb; return skb;
} }
@ -139,6 +138,8 @@ struct sk_buff *vlan_untag(struct sk_buff *skb)
skb_reset_network_header(skb); skb_reset_network_header(skb);
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
skb_reset_mac_len(skb);
return skb; return skb;
err_free: err_free:

View File

@ -314,6 +314,7 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
nfi->fib_scope == fi->fib_scope && nfi->fib_scope == fi->fib_scope &&
nfi->fib_prefsrc == fi->fib_prefsrc && nfi->fib_prefsrc == fi->fib_prefsrc &&
nfi->fib_priority == fi->fib_priority && nfi->fib_priority == fi->fib_priority &&
nfi->fib_type == fi->fib_type &&
memcmp(nfi->fib_metrics, fi->fib_metrics, memcmp(nfi->fib_metrics, fi->fib_metrics,
sizeof(u32) * RTAX_MAX) == 0 && sizeof(u32) * RTAX_MAX) == 0 &&
((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 && ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
@ -833,6 +834,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
fi->fib_flags = cfg->fc_flags; fi->fib_flags = cfg->fc_flags;
fi->fib_priority = cfg->fc_priority; fi->fib_priority = cfg->fc_priority;
fi->fib_prefsrc = cfg->fc_prefsrc; fi->fib_prefsrc = cfg->fc_prefsrc;
fi->fib_type = cfg->fc_type;
fi->fib_nhs = nhs; fi->fib_nhs = nhs;
change_nexthops(fi) { change_nexthops(fi) {

View File

@ -1769,14 +1769,6 @@ static void sit_route_add(struct net_device *dev)
} }
#endif #endif
static void addrconf_add_lroute(struct net_device *dev)
{
struct in6_addr addr;
ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
addrconf_prefix_route(&addr, 64, dev, 0, 0);
}
static struct inet6_dev *addrconf_add_dev(struct net_device *dev) static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
{ {
struct inet6_dev *idev; struct inet6_dev *idev;
@ -1794,8 +1786,6 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
if (!(dev->flags & IFF_LOOPBACK)) if (!(dev->flags & IFF_LOOPBACK))
addrconf_add_mroute(dev); addrconf_add_mroute(dev);
/* Add link local route */
addrconf_add_lroute(dev);
return idev; return idev;
} }
@ -2474,10 +2464,9 @@ static void addrconf_sit_config(struct net_device *dev)
sit_add_v4_addrs(idev); sit_add_v4_addrs(idev);
if (dev->flags&IFF_POINTOPOINT) { if (dev->flags&IFF_POINTOPOINT)
addrconf_add_mroute(dev); addrconf_add_mroute(dev);
addrconf_add_lroute(dev); else
} else
sit_route_add(dev); sit_route_add(dev);
} }
#endif #endif

View File

@ -1593,17 +1593,18 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
struct fib6_table *table; struct fib6_table *table;
struct net *net = dev_net(rt->dst.dev); struct net *net = dev_net(rt->dst.dev);
if (rt == net->ipv6.ip6_null_entry) if (rt == net->ipv6.ip6_null_entry) {
return -ENOENT; err = -ENOENT;
goto out;
}
table = rt->rt6i_table; table = rt->rt6i_table;
write_lock_bh(&table->tb6_lock); write_lock_bh(&table->tb6_lock);
err = fib6_del(rt, info); err = fib6_del(rt, info);
dst_release(&rt->dst);
write_unlock_bh(&table->tb6_lock); write_unlock_bh(&table->tb6_lock);
out:
dst_release(&rt->dst);
return err; return err;
} }

View File

@ -468,7 +468,7 @@ static int irda_open_tsap(struct irda_sock *self, __u8 tsap_sel, char *name)
notify_t notify; notify_t notify;
if (self->tsap) { if (self->tsap) {
IRDA_WARNING("%s: busy!\n", __func__); IRDA_DEBUG(0, "%s: busy!\n", __func__);
return -EBUSY; return -EBUSY;
} }

View File

@ -440,7 +440,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
*/ */
lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0); lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0);
if (lsap == NULL) { if (lsap == NULL) {
IRDA_WARNING("%s: unable to allocate LSAP!!\n", __func__); IRDA_DEBUG(0, "%s: unable to allocate LSAP!!\n", __func__);
return NULL; return NULL;
} }

View File

@ -497,15 +497,11 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags); pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags);
if (!addr || len < sizeof(struct sockaddr_nfc) || if (!addr || len < sizeof(struct sockaddr_nfc) ||
addr->sa_family != AF_NFC) { addr->sa_family != AF_NFC)
pr_err("Invalid socket\n");
return -EINVAL; return -EINVAL;
}
if (addr->service_name_len == 0 && addr->dsap == 0) { if (addr->service_name_len == 0 && addr->dsap == 0)
pr_err("Missing service name or dsap\n");
return -EINVAL; return -EINVAL;
}
pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx, pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx,
addr->target_idx, addr->nfc_protocol); addr->target_idx, addr->nfc_protocol);

View File

@ -68,8 +68,8 @@
static int sctp_rcv_ootb(struct sk_buff *); static int sctp_rcv_ootb(struct sk_buff *);
static struct sctp_association *__sctp_rcv_lookup(struct net *net, static struct sctp_association *__sctp_rcv_lookup(struct net *net,
struct sk_buff *skb, struct sk_buff *skb,
const union sctp_addr *laddr,
const union sctp_addr *paddr, const union sctp_addr *paddr,
const union sctp_addr *laddr,
struct sctp_transport **transportp); struct sctp_transport **transportp);
static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
const union sctp_addr *laddr); const union sctp_addr *laddr);

View File

@ -63,6 +63,7 @@ static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn);
static void sctp_check_transmitted(struct sctp_outq *q, static void sctp_check_transmitted(struct sctp_outq *q,
struct list_head *transmitted_queue, struct list_head *transmitted_queue,
struct sctp_transport *transport, struct sctp_transport *transport,
union sctp_addr *saddr,
struct sctp_sackhdr *sack, struct sctp_sackhdr *sack,
__u32 *highest_new_tsn); __u32 *highest_new_tsn);
@ -1139,9 +1140,10 @@ static void sctp_sack_update_unack_data(struct sctp_association *assoc,
* Process the SACK against the outqueue. Mostly, this just frees * Process the SACK against the outqueue. Mostly, this just frees
* things off the transmitted queue. * things off the transmitted queue.
*/ */
int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
{ {
struct sctp_association *asoc = q->asoc; struct sctp_association *asoc = q->asoc;
struct sctp_sackhdr *sack = chunk->subh.sack_hdr;
struct sctp_transport *transport; struct sctp_transport *transport;
struct sctp_chunk *tchunk = NULL; struct sctp_chunk *tchunk = NULL;
struct list_head *lchunk, *transport_list, *temp; struct list_head *lchunk, *transport_list, *temp;
@ -1210,7 +1212,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
/* Run through the retransmit queue. Credit bytes received /* Run through the retransmit queue. Credit bytes received
* and free those chunks that we can. * and free those chunks that we can.
*/ */
sctp_check_transmitted(q, &q->retransmit, NULL, sack, &highest_new_tsn); sctp_check_transmitted(q, &q->retransmit, NULL, NULL, sack, &highest_new_tsn);
/* Run through the transmitted queue. /* Run through the transmitted queue.
* Credit bytes received and free those chunks which we can. * Credit bytes received and free those chunks which we can.
@ -1219,7 +1221,8 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
*/ */
list_for_each_entry(transport, transport_list, transports) { list_for_each_entry(transport, transport_list, transports) {
sctp_check_transmitted(q, &transport->transmitted, sctp_check_transmitted(q, &transport->transmitted,
transport, sack, &highest_new_tsn); transport, &chunk->source, sack,
&highest_new_tsn);
/* /*
* SFR-CACC algorithm: * SFR-CACC algorithm:
* C) Let count_of_newacks be the number of * C) Let count_of_newacks be the number of
@ -1326,6 +1329,7 @@ int sctp_outq_is_empty(const struct sctp_outq *q)
static void sctp_check_transmitted(struct sctp_outq *q, static void sctp_check_transmitted(struct sctp_outq *q,
struct list_head *transmitted_queue, struct list_head *transmitted_queue,
struct sctp_transport *transport, struct sctp_transport *transport,
union sctp_addr *saddr,
struct sctp_sackhdr *sack, struct sctp_sackhdr *sack,
__u32 *highest_new_tsn_in_sack) __u32 *highest_new_tsn_in_sack)
{ {
@ -1633,8 +1637,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
/* Mark the destination transport address as /* Mark the destination transport address as
* active if it is not so marked. * active if it is not so marked.
*/ */
if ((transport->state == SCTP_INACTIVE) || if ((transport->state == SCTP_INACTIVE ||
(transport->state == SCTP_UNCONFIRMED)) { transport->state == SCTP_UNCONFIRMED) &&
sctp_cmp_addr_exact(&transport->ipaddr, saddr)) {
sctp_assoc_control_transport( sctp_assoc_control_transport(
transport->asoc, transport->asoc,
transport, transport,

View File

@ -752,11 +752,11 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
/* Helper function to process the process SACK command. */ /* Helper function to process the process SACK command. */
static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
struct sctp_association *asoc, struct sctp_association *asoc,
struct sctp_sackhdr *sackh) struct sctp_chunk *chunk)
{ {
int err = 0; int err = 0;
if (sctp_outq_sack(&asoc->outqueue, sackh)) { if (sctp_outq_sack(&asoc->outqueue, chunk)) {
struct net *net = sock_net(asoc->base.sk); struct net *net = sock_net(asoc->base.sk);
/* There are no more TSNs awaiting SACK. */ /* There are no more TSNs awaiting SACK. */

View File

@ -3179,7 +3179,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(struct net *net,
return sctp_sf_violation_ctsn(net, ep, asoc, type, arg, commands); return sctp_sf_violation_ctsn(net, ep, asoc, type, arg, commands);
/* Return this SACK for further processing. */ /* Return this SACK for further processing. */
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh)); sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_CHUNK(chunk));
/* Note: We do the rest of the work on the PROCESS_SACK /* Note: We do the rest of the work on the PROCESS_SACK
* sideeffect. * sideeffect.

View File

@ -220,6 +220,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol,
sock_init_data(sock, sk); sock_init_data(sock, sk);
sk->sk_backlog_rcv = backlog_rcv; sk->sk_backlog_rcv = backlog_rcv;
sk->sk_rcvbuf = TIPC_FLOW_CONTROL_WIN * 2 * TIPC_MAX_USER_MSG_SIZE * 2;
tipc_sk(sk)->p = tp_ptr; tipc_sk(sk)->p = tp_ptr;
tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT; tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT;