Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Count ttl-dropped frames properly in mac80211, from Bob Copeland. 2) Integer overflow in ktime handling of bcm can code, from Oliver Hartkopp. 3) Fix RX desc handling wrt. hw checksumming in ravb, from Simon Horman. 4) Various hash key fixes in hv_netvsc, from Haiyang Zhang. 5) Use after free in ax25, from Eric Dumazet. 6) Several fixes to the SSN support in SCTP, from Xin Long. 7) Do not process frames after a NAPI reschedule in ibmveth, from Thomas Falcon. 8) Fix NLA_POLICY_NESTED arguments, from Johannes Berg. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (42 commits) qed: Revert error handling changes. cfg80211: extend range deviation for DMG cfg80211: reg: remove warn_on for a normal case mac80211: Add attribute aligned(2) to struct 'action' mac80211: don't initiate TDLS connection if station is not associated to AP nl80211: fix NLA_POLICY_NESTED() arguments ibmveth: Do not process frames after calling napi_reschedule net: dev_is_mac_header_xmit() true for ARPHRD_RAWIP net: usb: asix: ax88772_bind return error when hw_reset fail MAINTAINERS: Update cavium networking drivers net/mlx4_core: Fix error handling when initializing CQ bufs in the driver net/mlx4_core: Add masking for a few queries on HCA caps sctp: set flow sport from saddr only when it's 0 sctp: set chunk transport correctly when it's a new asoc sctp: improve the events for sctp stream adding sctp: improve the events for sctp stream reset ip_tunnel: Make none-tunnel-dst tunnel port work with lwtunnel ax25: fix possible use-after-free sfc: suppress duplicate nvmem partition types in efx_ef10_mtd_probe hv_netvsc: fix typos in code comments ...
This commit is contained in:
commit
037222ad3f
42
MAINTAINERS
42
MAINTAINERS
|
@ -3052,8 +3052,8 @@ F: include/linux/bcm963xx_nvram.h
|
||||||
F: include/linux/bcm963xx_tag.h
|
F: include/linux/bcm963xx_tag.h
|
||||||
|
|
||||||
BROADCOM BNX2 GIGABIT ETHERNET DRIVER
|
BROADCOM BNX2 GIGABIT ETHERNET DRIVER
|
||||||
M: Rasesh Mody <rasesh.mody@cavium.com>
|
M: Rasesh Mody <rmody@marvell.com>
|
||||||
M: Dept-GELinuxNICDev@cavium.com
|
M: GR-Linux-NIC-Dev@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/broadcom/bnx2.*
|
F: drivers/net/ethernet/broadcom/bnx2.*
|
||||||
|
@ -3072,9 +3072,9 @@ S: Supported
|
||||||
F: drivers/scsi/bnx2i/
|
F: drivers/scsi/bnx2i/
|
||||||
|
|
||||||
BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
|
BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
|
||||||
M: Ariel Elior <ariel.elior@cavium.com>
|
M: Ariel Elior <aelior@marvell.com>
|
||||||
M: Sudarsana Kalluru <sudarsana.kalluru@cavium.com>
|
M: Sudarsana Kalluru <skalluru@marvell.com>
|
||||||
M: everest-linux-l2@cavium.com
|
M: GR-everest-linux-l2@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/broadcom/bnx2x/
|
F: drivers/net/ethernet/broadcom/bnx2x/
|
||||||
|
@ -3249,9 +3249,9 @@ S: Supported
|
||||||
F: drivers/scsi/bfa/
|
F: drivers/scsi/bfa/
|
||||||
|
|
||||||
BROCADE BNA 10 GIGABIT ETHERNET DRIVER
|
BROCADE BNA 10 GIGABIT ETHERNET DRIVER
|
||||||
M: Rasesh Mody <rasesh.mody@cavium.com>
|
M: Rasesh Mody <rmody@marvell.com>
|
||||||
M: Sudarsana Kalluru <sudarsana.kalluru@cavium.com>
|
M: Sudarsana Kalluru <skalluru@marvell.com>
|
||||||
M: Dept-GELinuxNICDev@cavium.com
|
M: GR-Linux-NIC-Dev@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/brocade/bna/
|
F: drivers/net/ethernet/brocade/bna/
|
||||||
|
@ -10690,9 +10690,9 @@ S: Maintained
|
||||||
F: drivers/net/netdevsim/*
|
F: drivers/net/netdevsim/*
|
||||||
|
|
||||||
NETXEN (1/10) GbE SUPPORT
|
NETXEN (1/10) GbE SUPPORT
|
||||||
M: Manish Chopra <manish.chopra@cavium.com>
|
M: Manish Chopra <manishc@marvell.com>
|
||||||
M: Rahul Verma <rahul.verma@cavium.com>
|
M: Rahul Verma <rahulv@marvell.com>
|
||||||
M: Dept-GELinuxNICDev@cavium.com
|
M: GR-Linux-NIC-Dev@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/qlogic/netxen/
|
F: drivers/net/ethernet/qlogic/netxen/
|
||||||
|
@ -12476,8 +12476,8 @@ S: Supported
|
||||||
F: drivers/scsi/qedi/
|
F: drivers/scsi/qedi/
|
||||||
|
|
||||||
QLOGIC QL4xxx ETHERNET DRIVER
|
QLOGIC QL4xxx ETHERNET DRIVER
|
||||||
M: Ariel Elior <Ariel.Elior@cavium.com>
|
M: Ariel Elior <aelior@marvell.com>
|
||||||
M: everest-linux-l2@cavium.com
|
M: GR-everest-linux-l2@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/qlogic/qed/
|
F: drivers/net/ethernet/qlogic/qed/
|
||||||
|
@ -12485,8 +12485,8 @@ F: include/linux/qed/
|
||||||
F: drivers/net/ethernet/qlogic/qede/
|
F: drivers/net/ethernet/qlogic/qede/
|
||||||
|
|
||||||
QLOGIC QL4xxx RDMA DRIVER
|
QLOGIC QL4xxx RDMA DRIVER
|
||||||
M: Michal Kalderon <Michal.Kalderon@cavium.com>
|
M: Michal Kalderon <mkalderon@marvell.com>
|
||||||
M: Ariel Elior <Ariel.Elior@cavium.com>
|
M: Ariel Elior <aelior@marvell.com>
|
||||||
L: linux-rdma@vger.kernel.org
|
L: linux-rdma@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/infiniband/hw/qedr/
|
F: drivers/infiniband/hw/qedr/
|
||||||
|
@ -12506,7 +12506,7 @@ F: Documentation/scsi/LICENSE.qla2xxx
|
||||||
F: drivers/scsi/qla2xxx/
|
F: drivers/scsi/qla2xxx/
|
||||||
|
|
||||||
QLOGIC QLA3XXX NETWORK DRIVER
|
QLOGIC QLA3XXX NETWORK DRIVER
|
||||||
M: Dept-GELinuxNICDev@cavium.com
|
M: GR-Linux-NIC-Dev@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/networking/device_drivers/qlogic/LICENSE.qla3xxx
|
F: Documentation/networking/device_drivers/qlogic/LICENSE.qla3xxx
|
||||||
|
@ -12520,16 +12520,16 @@ F: Documentation/scsi/LICENSE.qla4xxx
|
||||||
F: drivers/scsi/qla4xxx/
|
F: drivers/scsi/qla4xxx/
|
||||||
|
|
||||||
QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
|
QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
|
||||||
M: Shahed Shaikh <Shahed.Shaikh@cavium.com>
|
M: Shahed Shaikh <shshaikh@marvell.com>
|
||||||
M: Manish Chopra <manish.chopra@cavium.com>
|
M: Manish Chopra <manishc@marvell.com>
|
||||||
M: Dept-GELinuxNICDev@cavium.com
|
M: GR-Linux-NIC-Dev@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/qlogic/qlcnic/
|
F: drivers/net/ethernet/qlogic/qlcnic/
|
||||||
|
|
||||||
QLOGIC QLGE 10Gb ETHERNET DRIVER
|
QLOGIC QLGE 10Gb ETHERNET DRIVER
|
||||||
M: Manish Chopra <manish.chopra@cavium.com>
|
M: Manish Chopra <manishc@marvell.com>
|
||||||
M: Dept-GELinuxNICDev@cavium.com
|
M: GR-Linux-NIC-Dev@marvell.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/qlogic/qlge/
|
F: drivers/net/ethernet/qlogic/qlge/
|
||||||
|
|
|
@ -480,8 +480,6 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
|
||||||
struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
|
struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
|
||||||
{
|
{
|
||||||
struct can_priv *priv = netdev_priv(dev);
|
struct can_priv *priv = netdev_priv(dev);
|
||||||
struct sk_buff *skb = priv->echo_skb[idx];
|
|
||||||
struct canfd_frame *cf;
|
|
||||||
|
|
||||||
if (idx >= priv->echo_skb_max) {
|
if (idx >= priv->echo_skb_max) {
|
||||||
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
|
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
|
||||||
|
@ -489,20 +487,21 @@ struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skb) {
|
if (priv->echo_skb[idx]) {
|
||||||
netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n",
|
/* Using "struct canfd_frame::len" for the frame
|
||||||
__func__, idx);
|
* length is supported on both CAN and CANFD frames.
|
||||||
return NULL;
|
*/
|
||||||
|
struct sk_buff *skb = priv->echo_skb[idx];
|
||||||
|
struct canfd_frame *cf = (struct canfd_frame *)skb->data;
|
||||||
|
u8 len = cf->len;
|
||||||
|
|
||||||
|
*len_ptr = len;
|
||||||
|
priv->echo_skb[idx] = NULL;
|
||||||
|
|
||||||
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Using "struct canfd_frame::len" for the frame
|
return NULL;
|
||||||
* length is supported on both CAN and CANFD frames.
|
|
||||||
*/
|
|
||||||
cf = (struct canfd_frame *)skb->data;
|
|
||||||
*len_ptr = cf->len;
|
|
||||||
priv->echo_skb[idx] = NULL;
|
|
||||||
|
|
||||||
return skb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1106,7 +1106,7 @@ static int flexcan_chip_start(struct net_device *dev)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* clear and invalidate unused mailboxes first */
|
/* clear and invalidate unused mailboxes first */
|
||||||
for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= priv->mb_count; i++) {
|
for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i < priv->mb_count; i++) {
|
||||||
mb = flexcan_get_mb(priv, i);
|
mb = flexcan_get_mb(priv, i);
|
||||||
priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
||||||
&mb->can_ctrl);
|
&mb->can_ctrl);
|
||||||
|
@ -1432,7 +1432,7 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev)
|
||||||
gpr_np = of_find_node_by_phandle(phandle);
|
gpr_np = of_find_node_by_phandle(phandle);
|
||||||
if (!gpr_np) {
|
if (!gpr_np) {
|
||||||
dev_dbg(&pdev->dev, "could not find gpr node by phandle\n");
|
dev_dbg(&pdev->dev, "could not find gpr node by phandle\n");
|
||||||
return PTR_ERR(gpr_np);
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = netdev_priv(dev);
|
priv = netdev_priv(dev);
|
||||||
|
|
|
@ -714,8 +714,10 @@ static struct phy_device *connect_local_phy(struct net_device *dev)
|
||||||
|
|
||||||
phydev = phy_connect(dev, phy_id_fmt, &altera_tse_adjust_link,
|
phydev = phy_connect(dev, phy_id_fmt, &altera_tse_adjust_link,
|
||||||
priv->phy_iface);
|
priv->phy_iface);
|
||||||
if (IS_ERR(phydev))
|
if (IS_ERR(phydev)) {
|
||||||
netdev_err(dev, "Could not attach to PHY\n");
|
netdev_err(dev, "Could not attach to PHY\n");
|
||||||
|
phydev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -9,8 +9,9 @@ config FSL_DPAA2_ETH
|
||||||
|
|
||||||
config FSL_DPAA2_PTP_CLOCK
|
config FSL_DPAA2_PTP_CLOCK
|
||||||
tristate "Freescale DPAA2 PTP Clock"
|
tristate "Freescale DPAA2 PTP Clock"
|
||||||
depends on FSL_DPAA2_ETH && POSIX_TIMERS
|
depends on FSL_DPAA2_ETH
|
||||||
select PTP_1588_CLOCK
|
imply PTP_1588_CLOCK
|
||||||
|
default y
|
||||||
help
|
help
|
||||||
This driver adds support for using the DPAA2 1588 timer module
|
This driver adds support for using the DPAA2 1588 timer module
|
||||||
as a PTP clock.
|
as a PTP clock.
|
||||||
|
|
|
@ -3467,7 +3467,7 @@ fec_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed_clk_ipg;
|
goto failed_clk_ipg;
|
||||||
|
|
||||||
fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
|
fep->reg_phy = devm_regulator_get_optional(&pdev->dev, "phy");
|
||||||
if (!IS_ERR(fep->reg_phy)) {
|
if (!IS_ERR(fep->reg_phy)) {
|
||||||
ret = regulator_enable(fep->reg_phy);
|
ret = regulator_enable(fep->reg_phy);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
|
@ -1313,7 +1313,6 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
|
||||||
unsigned long lpar_rc;
|
unsigned long lpar_rc;
|
||||||
u16 mss = 0;
|
u16 mss = 0;
|
||||||
|
|
||||||
restart_poll:
|
|
||||||
while (frames_processed < budget) {
|
while (frames_processed < budget) {
|
||||||
if (!ibmveth_rxq_pending_buffer(adapter))
|
if (!ibmveth_rxq_pending_buffer(adapter))
|
||||||
break;
|
break;
|
||||||
|
@ -1401,7 +1400,6 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
|
||||||
napi_reschedule(napi)) {
|
napi_reschedule(napi)) {
|
||||||
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
|
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
|
||||||
VIO_IRQ_DISABLE);
|
VIO_IRQ_DISABLE);
|
||||||
goto restart_poll;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -306,14 +306,16 @@ static int mlx4_init_user_cqes(void *buf, int entries, int cqe_size)
|
||||||
|
|
||||||
if (entries_per_copy < entries) {
|
if (entries_per_copy < entries) {
|
||||||
for (i = 0; i < entries / entries_per_copy; i++) {
|
for (i = 0; i < entries / entries_per_copy; i++) {
|
||||||
err = copy_to_user(buf, init_ents, PAGE_SIZE);
|
err = copy_to_user((void __user *)buf, init_ents, PAGE_SIZE) ?
|
||||||
|
-EFAULT : 0;
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
buf += PAGE_SIZE;
|
buf += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = copy_to_user(buf, init_ents, entries * cqe_size);
|
err = copy_to_user((void __user *)buf, init_ents, entries * cqe_size) ?
|
||||||
|
-EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -2067,9 +2067,11 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
|
||||||
{
|
{
|
||||||
struct mlx4_cmd_mailbox *mailbox;
|
struct mlx4_cmd_mailbox *mailbox;
|
||||||
__be32 *outbox;
|
__be32 *outbox;
|
||||||
|
u64 qword_field;
|
||||||
u32 dword_field;
|
u32 dword_field;
|
||||||
int err;
|
u16 word_field;
|
||||||
u8 byte_field;
|
u8 byte_field;
|
||||||
|
int err;
|
||||||
static const u8 a0_dmfs_query_hw_steering[] = {
|
static const u8 a0_dmfs_query_hw_steering[] = {
|
||||||
[0] = MLX4_STEERING_DMFS_A0_DEFAULT,
|
[0] = MLX4_STEERING_DMFS_A0_DEFAULT,
|
||||||
[1] = MLX4_STEERING_DMFS_A0_DYNAMIC,
|
[1] = MLX4_STEERING_DMFS_A0_DYNAMIC,
|
||||||
|
@ -2097,19 +2099,32 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
|
||||||
|
|
||||||
/* QPC/EEC/CQC/EQC/RDMARC attributes */
|
/* QPC/EEC/CQC/EQC/RDMARC attributes */
|
||||||
|
|
||||||
MLX4_GET(param->qpc_base, outbox, INIT_HCA_QPC_BASE_OFFSET);
|
MLX4_GET(qword_field, outbox, INIT_HCA_QPC_BASE_OFFSET);
|
||||||
MLX4_GET(param->log_num_qps, outbox, INIT_HCA_LOG_QP_OFFSET);
|
param->qpc_base = qword_field & ~((u64)0x1f);
|
||||||
MLX4_GET(param->srqc_base, outbox, INIT_HCA_SRQC_BASE_OFFSET);
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_QP_OFFSET);
|
||||||
MLX4_GET(param->log_num_srqs, outbox, INIT_HCA_LOG_SRQ_OFFSET);
|
param->log_num_qps = byte_field & 0x1f;
|
||||||
MLX4_GET(param->cqc_base, outbox, INIT_HCA_CQC_BASE_OFFSET);
|
MLX4_GET(qword_field, outbox, INIT_HCA_SRQC_BASE_OFFSET);
|
||||||
MLX4_GET(param->log_num_cqs, outbox, INIT_HCA_LOG_CQ_OFFSET);
|
param->srqc_base = qword_field & ~((u64)0x1f);
|
||||||
MLX4_GET(param->altc_base, outbox, INIT_HCA_ALTC_BASE_OFFSET);
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_SRQ_OFFSET);
|
||||||
MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET);
|
param->log_num_srqs = byte_field & 0x1f;
|
||||||
MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET);
|
MLX4_GET(qword_field, outbox, INIT_HCA_CQC_BASE_OFFSET);
|
||||||
MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET);
|
param->cqc_base = qword_field & ~((u64)0x1f);
|
||||||
MLX4_GET(param->num_sys_eqs, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET);
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_CQ_OFFSET);
|
||||||
MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET);
|
param->log_num_cqs = byte_field & 0x1f;
|
||||||
MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET);
|
MLX4_GET(qword_field, outbox, INIT_HCA_ALTC_BASE_OFFSET);
|
||||||
|
param->altc_base = qword_field;
|
||||||
|
MLX4_GET(qword_field, outbox, INIT_HCA_AUXC_BASE_OFFSET);
|
||||||
|
param->auxc_base = qword_field;
|
||||||
|
MLX4_GET(qword_field, outbox, INIT_HCA_EQC_BASE_OFFSET);
|
||||||
|
param->eqc_base = qword_field & ~((u64)0x1f);
|
||||||
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_EQ_OFFSET);
|
||||||
|
param->log_num_eqs = byte_field & 0x1f;
|
||||||
|
MLX4_GET(word_field, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET);
|
||||||
|
param->num_sys_eqs = word_field & 0xfff;
|
||||||
|
MLX4_GET(qword_field, outbox, INIT_HCA_RDMARC_BASE_OFFSET);
|
||||||
|
param->rdmarc_base = qword_field & ~((u64)0x1f);
|
||||||
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_RD_OFFSET);
|
||||||
|
param->log_rd_per_qp = byte_field & 0x7;
|
||||||
|
|
||||||
MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET);
|
MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET);
|
||||||
if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) {
|
if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) {
|
||||||
|
@ -2128,22 +2143,21 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
|
||||||
/* steering attributes */
|
/* steering attributes */
|
||||||
if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) {
|
if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) {
|
||||||
MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET);
|
MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET);
|
||||||
MLX4_GET(param->log_mc_entry_sz, outbox,
|
MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET);
|
||||||
INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET);
|
param->log_mc_entry_sz = byte_field & 0x1f;
|
||||||
MLX4_GET(param->log_mc_table_sz, outbox,
|
MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_TABLE_SZ_OFFSET);
|
||||||
INIT_HCA_FS_LOG_TABLE_SZ_OFFSET);
|
param->log_mc_table_sz = byte_field & 0x1f;
|
||||||
MLX4_GET(byte_field, outbox,
|
MLX4_GET(byte_field, outbox, INIT_HCA_FS_A0_OFFSET);
|
||||||
INIT_HCA_FS_A0_OFFSET);
|
|
||||||
param->dmfs_high_steer_mode =
|
param->dmfs_high_steer_mode =
|
||||||
a0_dmfs_query_hw_steering[(byte_field >> 6) & 3];
|
a0_dmfs_query_hw_steering[(byte_field >> 6) & 3];
|
||||||
} else {
|
} else {
|
||||||
MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET);
|
MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET);
|
||||||
MLX4_GET(param->log_mc_entry_sz, outbox,
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET);
|
||||||
INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET);
|
param->log_mc_entry_sz = byte_field & 0x1f;
|
||||||
MLX4_GET(param->log_mc_hash_sz, outbox,
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_HASH_SZ_OFFSET);
|
||||||
INIT_HCA_LOG_MC_HASH_SZ_OFFSET);
|
param->log_mc_hash_sz = byte_field & 0x1f;
|
||||||
MLX4_GET(param->log_mc_table_sz, outbox,
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET);
|
||||||
INIT_HCA_LOG_MC_TABLE_SZ_OFFSET);
|
param->log_mc_table_sz = byte_field & 0x1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */
|
/* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */
|
||||||
|
@ -2167,15 +2181,18 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev,
|
||||||
/* TPT attributes */
|
/* TPT attributes */
|
||||||
|
|
||||||
MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET);
|
MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET);
|
||||||
MLX4_GET(param->mw_enabled, outbox, INIT_HCA_TPT_MW_OFFSET);
|
MLX4_GET(byte_field, outbox, INIT_HCA_TPT_MW_OFFSET);
|
||||||
MLX4_GET(param->log_mpt_sz, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET);
|
param->mw_enabled = byte_field >> 7;
|
||||||
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET);
|
||||||
|
param->log_mpt_sz = byte_field & 0x3f;
|
||||||
MLX4_GET(param->mtt_base, outbox, INIT_HCA_MTT_BASE_OFFSET);
|
MLX4_GET(param->mtt_base, outbox, INIT_HCA_MTT_BASE_OFFSET);
|
||||||
MLX4_GET(param->cmpt_base, outbox, INIT_HCA_CMPT_BASE_OFFSET);
|
MLX4_GET(param->cmpt_base, outbox, INIT_HCA_CMPT_BASE_OFFSET);
|
||||||
|
|
||||||
/* UAR attributes */
|
/* UAR attributes */
|
||||||
|
|
||||||
MLX4_GET(param->uar_page_sz, outbox, INIT_HCA_UAR_PAGE_SZ_OFFSET);
|
MLX4_GET(param->uar_page_sz, outbox, INIT_HCA_UAR_PAGE_SZ_OFFSET);
|
||||||
MLX4_GET(param->log_uar_sz, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET);
|
MLX4_GET(byte_field, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET);
|
||||||
|
param->log_uar_sz = byte_field & 0xf;
|
||||||
|
|
||||||
/* phv_check enable */
|
/* phv_check enable */
|
||||||
MLX4_GET(byte_field, outbox, INIT_HCA_CACHELINE_SZ_OFFSET);
|
MLX4_GET(byte_field, outbox, INIT_HCA_CACHELINE_SZ_OFFSET);
|
||||||
|
|
|
@ -343,7 +343,7 @@ static int ravb_ring_init(struct net_device *ndev, int q)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
priv->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ : ndev->mtu) +
|
priv->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ : ndev->mtu) +
|
||||||
ETH_HLEN + VLAN_HLEN;
|
ETH_HLEN + VLAN_HLEN + sizeof(__sum16);
|
||||||
|
|
||||||
/* Allocate RX and TX skb rings */
|
/* Allocate RX and TX skb rings */
|
||||||
priv->rx_skb[q] = kcalloc(priv->num_rx_ring[q],
|
priv->rx_skb[q] = kcalloc(priv->num_rx_ring[q],
|
||||||
|
@ -524,13 +524,15 @@ static void ravb_rx_csum(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
u8 *hw_csum;
|
u8 *hw_csum;
|
||||||
|
|
||||||
/* The hardware checksum is 2 bytes appended to packet data */
|
/* The hardware checksum is contained in sizeof(__sum16) (2) bytes
|
||||||
if (unlikely(skb->len < 2))
|
* appended to packet data
|
||||||
|
*/
|
||||||
|
if (unlikely(skb->len < sizeof(__sum16)))
|
||||||
return;
|
return;
|
||||||
hw_csum = skb_tail_pointer(skb) - 2;
|
hw_csum = skb_tail_pointer(skb) - sizeof(__sum16);
|
||||||
skb->csum = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum));
|
skb->csum = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum));
|
||||||
skb->ip_summed = CHECKSUM_COMPLETE;
|
skb->ip_summed = CHECKSUM_COMPLETE;
|
||||||
skb_trim(skb, skb->len - 2);
|
skb_trim(skb, skb->len - sizeof(__sum16));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Packet receive function for Ethernet AVB */
|
/* Packet receive function for Ethernet AVB */
|
||||||
|
|
|
@ -6046,22 +6046,25 @@ static const struct efx_ef10_nvram_type_info efx_ef10_nvram_types[] = {
|
||||||
{ NVRAM_PARTITION_TYPE_EXPANSION_UEFI, 0, 0, "sfc_uefi" },
|
{ NVRAM_PARTITION_TYPE_EXPANSION_UEFI, 0, 0, "sfc_uefi" },
|
||||||
{ NVRAM_PARTITION_TYPE_STATUS, 0, 0, "sfc_status" }
|
{ NVRAM_PARTITION_TYPE_STATUS, 0, 0, "sfc_status" }
|
||||||
};
|
};
|
||||||
|
#define EF10_NVRAM_PARTITION_COUNT ARRAY_SIZE(efx_ef10_nvram_types)
|
||||||
|
|
||||||
static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
|
static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
|
||||||
struct efx_mcdi_mtd_partition *part,
|
struct efx_mcdi_mtd_partition *part,
|
||||||
unsigned int type)
|
unsigned int type,
|
||||||
|
unsigned long *found)
|
||||||
{
|
{
|
||||||
MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN);
|
MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN);
|
||||||
MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_METADATA_OUT_LENMAX);
|
MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_METADATA_OUT_LENMAX);
|
||||||
const struct efx_ef10_nvram_type_info *info;
|
const struct efx_ef10_nvram_type_info *info;
|
||||||
size_t size, erase_size, outlen;
|
size_t size, erase_size, outlen;
|
||||||
|
int type_idx = 0;
|
||||||
bool protected;
|
bool protected;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
for (info = efx_ef10_nvram_types; ; info++) {
|
for (type_idx = 0; ; type_idx++) {
|
||||||
if (info ==
|
if (type_idx == EF10_NVRAM_PARTITION_COUNT)
|
||||||
efx_ef10_nvram_types + ARRAY_SIZE(efx_ef10_nvram_types))
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
info = efx_ef10_nvram_types + type_idx;
|
||||||
if ((type & ~info->type_mask) == info->type)
|
if ((type & ~info->type_mask) == info->type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6074,6 +6077,13 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
|
||||||
if (protected)
|
if (protected)
|
||||||
return -ENODEV; /* hide it */
|
return -ENODEV; /* hide it */
|
||||||
|
|
||||||
|
/* If we've already exposed a partition of this type, hide this
|
||||||
|
* duplicate. All operations on MTDs are keyed by the type anyway,
|
||||||
|
* so we can't act on the duplicate.
|
||||||
|
*/
|
||||||
|
if (__test_and_set_bit(type_idx, found))
|
||||||
|
return -EEXIST;
|
||||||
|
|
||||||
part->nvram_type = type;
|
part->nvram_type = type;
|
||||||
|
|
||||||
MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_TYPE, type);
|
MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_TYPE, type);
|
||||||
|
@ -6105,6 +6115,7 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx,
|
||||||
static int efx_ef10_mtd_probe(struct efx_nic *efx)
|
static int efx_ef10_mtd_probe(struct efx_nic *efx)
|
||||||
{
|
{
|
||||||
MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
|
MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
|
||||||
|
DECLARE_BITMAP(found, EF10_NVRAM_PARTITION_COUNT);
|
||||||
struct efx_mcdi_mtd_partition *parts;
|
struct efx_mcdi_mtd_partition *parts;
|
||||||
size_t outlen, n_parts_total, i, n_parts;
|
size_t outlen, n_parts_total, i, n_parts;
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
@ -6133,11 +6144,13 @@ static int efx_ef10_mtd_probe(struct efx_nic *efx)
|
||||||
for (i = 0; i < n_parts_total; i++) {
|
for (i = 0; i < n_parts_total; i++) {
|
||||||
type = MCDI_ARRAY_DWORD(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID,
|
type = MCDI_ARRAY_DWORD(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID,
|
||||||
i);
|
i);
|
||||||
rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type);
|
rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type,
|
||||||
if (rc == 0)
|
found);
|
||||||
n_parts++;
|
if (rc == -EEXIST || rc == -ENODEV)
|
||||||
else if (rc != -ENODEV)
|
continue;
|
||||||
|
if (rc)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
n_parts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
|
rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
|
||||||
|
|
|
@ -1,22 +1,9 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/* cassini.c: Sun Microsystems Cassini(+) ethernet driver.
|
/* cassini.c: Sun Microsystems Cassini(+) ethernet driver.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004 Sun Microsystems Inc.
|
* Copyright (C) 2004 Sun Microsystems Inc.
|
||||||
* Copyright (C) 2003 Adrian Sun (asun@darksunrising.com)
|
* Copyright (C) 2003 Adrian Sun (asun@darksunrising.com)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* This driver uses the sungem driver (c) David Miller
|
* This driver uses the sungem driver (c) David Miller
|
||||||
* (davem@redhat.com) as its basis.
|
* (davem@redhat.com) as its basis.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,23 +1,10 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
/* $Id: cassini.h,v 1.16 2004/08/17 21:15:16 zaumen Exp $
|
/* $Id: cassini.h,v 1.16 2004/08/17 21:15:16 zaumen Exp $
|
||||||
* cassini.h: Definitions for Sun Microsystems Cassini(+) ethernet driver.
|
* cassini.h: Definitions for Sun Microsystems Cassini(+) ethernet driver.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004 Sun Microsystems Inc.
|
* Copyright (C) 2004 Sun Microsystems Inc.
|
||||||
* Copyright (c) 2003 Adrian Sun (asun@darksunrising.com)
|
* Copyright (c) 2003 Adrian Sun (asun@darksunrising.com)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* vendor id: 0x108E (Sun Microsystems, Inc.)
|
* vendor id: 0x108E (Sun Microsystems, Inc.)
|
||||||
* device id: 0xabba (Cassini)
|
* device id: 0xabba (Cassini)
|
||||||
* revision ids: 0x01 = Cassini
|
* revision ids: 0x01 = Cassini
|
||||||
|
|
|
@ -144,6 +144,8 @@ struct hv_netvsc_packet {
|
||||||
u32 total_data_buflen;
|
u32 total_data_buflen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define NETVSC_HASH_KEYLEN 40
|
||||||
|
|
||||||
struct netvsc_device_info {
|
struct netvsc_device_info {
|
||||||
unsigned char mac_adr[ETH_ALEN];
|
unsigned char mac_adr[ETH_ALEN];
|
||||||
u32 num_chn;
|
u32 num_chn;
|
||||||
|
@ -151,6 +153,8 @@ struct netvsc_device_info {
|
||||||
u32 recv_sections;
|
u32 recv_sections;
|
||||||
u32 send_section_size;
|
u32 send_section_size;
|
||||||
u32 recv_section_size;
|
u32 recv_section_size;
|
||||||
|
|
||||||
|
u8 rss_key[NETVSC_HASH_KEYLEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum rndis_device_state {
|
enum rndis_device_state {
|
||||||
|
@ -160,8 +164,6 @@ enum rndis_device_state {
|
||||||
RNDIS_DEV_DATAINITIALIZED,
|
RNDIS_DEV_DATAINITIALIZED,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NETVSC_HASH_KEYLEN 40
|
|
||||||
|
|
||||||
struct rndis_device {
|
struct rndis_device {
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
|
|
||||||
|
@ -209,7 +211,9 @@ int netvsc_recv_callback(struct net_device *net,
|
||||||
void netvsc_channel_cb(void *context);
|
void netvsc_channel_cb(void *context);
|
||||||
int netvsc_poll(struct napi_struct *napi, int budget);
|
int netvsc_poll(struct napi_struct *napi, int budget);
|
||||||
|
|
||||||
int rndis_set_subchannel(struct net_device *ndev, struct netvsc_device *nvdev);
|
int rndis_set_subchannel(struct net_device *ndev,
|
||||||
|
struct netvsc_device *nvdev,
|
||||||
|
struct netvsc_device_info *dev_info);
|
||||||
int rndis_filter_open(struct netvsc_device *nvdev);
|
int rndis_filter_open(struct netvsc_device *nvdev);
|
||||||
int rndis_filter_close(struct netvsc_device *nvdev);
|
int rndis_filter_close(struct netvsc_device *nvdev);
|
||||||
struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
|
struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
|
||||||
|
@ -1177,7 +1181,7 @@ enum ndis_per_pkt_info_type {
|
||||||
|
|
||||||
enum rndis_per_pkt_info_interal_type {
|
enum rndis_per_pkt_info_interal_type {
|
||||||
RNDIS_PKTINFO_ID = 1,
|
RNDIS_PKTINFO_ID = 1,
|
||||||
/* Add more memebers here */
|
/* Add more members here */
|
||||||
|
|
||||||
RNDIS_PKTINFO_MAX
|
RNDIS_PKTINFO_MAX
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,7 +84,7 @@ static void netvsc_subchan_work(struct work_struct *w)
|
||||||
|
|
||||||
rdev = nvdev->extension;
|
rdev = nvdev->extension;
|
||||||
if (rdev) {
|
if (rdev) {
|
||||||
ret = rndis_set_subchannel(rdev->ndev, nvdev);
|
ret = rndis_set_subchannel(rdev->ndev, nvdev, NULL);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
netif_device_attach(rdev->ndev);
|
netif_device_attach(rdev->ndev);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1331,7 +1331,7 @@ void netvsc_channel_cb(void *context)
|
||||||
prefetch(hv_get_ring_buffer(rbi) + rbi->priv_read_index);
|
prefetch(hv_get_ring_buffer(rbi) + rbi->priv_read_index);
|
||||||
|
|
||||||
if (napi_schedule_prep(&nvchan->napi)) {
|
if (napi_schedule_prep(&nvchan->napi)) {
|
||||||
/* disable interupts from host */
|
/* disable interrupts from host */
|
||||||
hv_begin_read(rbi);
|
hv_begin_read(rbi);
|
||||||
|
|
||||||
__napi_schedule_irqoff(&nvchan->napi);
|
__napi_schedule_irqoff(&nvchan->napi);
|
||||||
|
|
|
@ -370,7 +370,7 @@ static u32 fill_pg_buf(struct page *page, u32 offset, u32 len,
|
||||||
{
|
{
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
/* Deal with compund pages by ignoring unused part
|
/* Deal with compound pages by ignoring unused part
|
||||||
* of the page.
|
* of the page.
|
||||||
*/
|
*/
|
||||||
page += (offset >> PAGE_SHIFT);
|
page += (offset >> PAGE_SHIFT);
|
||||||
|
@ -858,6 +858,39 @@ static void netvsc_get_channels(struct net_device *net,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Alloc struct netvsc_device_info, and initialize it from either existing
|
||||||
|
* struct netvsc_device, or from default values.
|
||||||
|
*/
|
||||||
|
static struct netvsc_device_info *netvsc_devinfo_get
|
||||||
|
(struct netvsc_device *nvdev)
|
||||||
|
{
|
||||||
|
struct netvsc_device_info *dev_info;
|
||||||
|
|
||||||
|
dev_info = kzalloc(sizeof(*dev_info), GFP_ATOMIC);
|
||||||
|
|
||||||
|
if (!dev_info)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (nvdev) {
|
||||||
|
dev_info->num_chn = nvdev->num_chn;
|
||||||
|
dev_info->send_sections = nvdev->send_section_cnt;
|
||||||
|
dev_info->send_section_size = nvdev->send_section_size;
|
||||||
|
dev_info->recv_sections = nvdev->recv_section_cnt;
|
||||||
|
dev_info->recv_section_size = nvdev->recv_section_size;
|
||||||
|
|
||||||
|
memcpy(dev_info->rss_key, nvdev->extension->rss_key,
|
||||||
|
NETVSC_HASH_KEYLEN);
|
||||||
|
} else {
|
||||||
|
dev_info->num_chn = VRSS_CHANNEL_DEFAULT;
|
||||||
|
dev_info->send_sections = NETVSC_DEFAULT_TX;
|
||||||
|
dev_info->send_section_size = NETVSC_SEND_SECTION_SIZE;
|
||||||
|
dev_info->recv_sections = NETVSC_DEFAULT_RX;
|
||||||
|
dev_info->recv_section_size = NETVSC_RECV_SECTION_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev_info;
|
||||||
|
}
|
||||||
|
|
||||||
static int netvsc_detach(struct net_device *ndev,
|
static int netvsc_detach(struct net_device *ndev,
|
||||||
struct netvsc_device *nvdev)
|
struct netvsc_device *nvdev)
|
||||||
{
|
{
|
||||||
|
@ -909,7 +942,7 @@ static int netvsc_attach(struct net_device *ndev,
|
||||||
return PTR_ERR(nvdev);
|
return PTR_ERR(nvdev);
|
||||||
|
|
||||||
if (nvdev->num_chn > 1) {
|
if (nvdev->num_chn > 1) {
|
||||||
ret = rndis_set_subchannel(ndev, nvdev);
|
ret = rndis_set_subchannel(ndev, nvdev, dev_info);
|
||||||
|
|
||||||
/* if unavailable, just proceed with one queue */
|
/* if unavailable, just proceed with one queue */
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -943,7 +976,7 @@ static int netvsc_set_channels(struct net_device *net,
|
||||||
struct net_device_context *net_device_ctx = netdev_priv(net);
|
struct net_device_context *net_device_ctx = netdev_priv(net);
|
||||||
struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
|
struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
|
||||||
unsigned int orig, count = channels->combined_count;
|
unsigned int orig, count = channels->combined_count;
|
||||||
struct netvsc_device_info device_info;
|
struct netvsc_device_info *device_info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* We do not support separate count for rx, tx, or other */
|
/* We do not support separate count for rx, tx, or other */
|
||||||
|
@ -962,24 +995,26 @@ static int netvsc_set_channels(struct net_device *net,
|
||||||
|
|
||||||
orig = nvdev->num_chn;
|
orig = nvdev->num_chn;
|
||||||
|
|
||||||
memset(&device_info, 0, sizeof(device_info));
|
device_info = netvsc_devinfo_get(nvdev);
|
||||||
device_info.num_chn = count;
|
|
||||||
device_info.send_sections = nvdev->send_section_cnt;
|
if (!device_info)
|
||||||
device_info.send_section_size = nvdev->send_section_size;
|
return -ENOMEM;
|
||||||
device_info.recv_sections = nvdev->recv_section_cnt;
|
|
||||||
device_info.recv_section_size = nvdev->recv_section_size;
|
device_info->num_chn = count;
|
||||||
|
|
||||||
ret = netvsc_detach(net, nvdev);
|
ret = netvsc_detach(net, nvdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
|
|
||||||
ret = netvsc_attach(net, &device_info);
|
ret = netvsc_attach(net, device_info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
device_info.num_chn = orig;
|
device_info->num_chn = orig;
|
||||||
if (netvsc_attach(net, &device_info))
|
if (netvsc_attach(net, device_info))
|
||||||
netdev_err(net, "restoring channel setting failed\n");
|
netdev_err(net, "restoring channel setting failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(device_info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1048,48 +1083,45 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
|
||||||
struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev);
|
struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev);
|
||||||
struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
|
struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
|
||||||
int orig_mtu = ndev->mtu;
|
int orig_mtu = ndev->mtu;
|
||||||
struct netvsc_device_info device_info;
|
struct netvsc_device_info *device_info;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!nvdev || nvdev->destroy)
|
if (!nvdev || nvdev->destroy)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
device_info = netvsc_devinfo_get(nvdev);
|
||||||
|
|
||||||
|
if (!device_info)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Change MTU of underlying VF netdev first. */
|
/* Change MTU of underlying VF netdev first. */
|
||||||
if (vf_netdev) {
|
if (vf_netdev) {
|
||||||
ret = dev_set_mtu(vf_netdev, mtu);
|
ret = dev_set_mtu(vf_netdev, mtu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&device_info, 0, sizeof(device_info));
|
|
||||||
device_info.num_chn = nvdev->num_chn;
|
|
||||||
device_info.send_sections = nvdev->send_section_cnt;
|
|
||||||
device_info.send_section_size = nvdev->send_section_size;
|
|
||||||
device_info.recv_sections = nvdev->recv_section_cnt;
|
|
||||||
device_info.recv_section_size = nvdev->recv_section_size;
|
|
||||||
|
|
||||||
ret = netvsc_detach(ndev, nvdev);
|
ret = netvsc_detach(ndev, nvdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto rollback_vf;
|
goto rollback_vf;
|
||||||
|
|
||||||
ndev->mtu = mtu;
|
ndev->mtu = mtu;
|
||||||
|
|
||||||
ret = netvsc_attach(ndev, &device_info);
|
ret = netvsc_attach(ndev, device_info);
|
||||||
if (ret)
|
if (!ret)
|
||||||
goto rollback;
|
goto out;
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rollback:
|
|
||||||
/* Attempt rollback to original MTU */
|
/* Attempt rollback to original MTU */
|
||||||
ndev->mtu = orig_mtu;
|
ndev->mtu = orig_mtu;
|
||||||
|
|
||||||
if (netvsc_attach(ndev, &device_info))
|
if (netvsc_attach(ndev, device_info))
|
||||||
netdev_err(ndev, "restoring mtu failed\n");
|
netdev_err(ndev, "restoring mtu failed\n");
|
||||||
rollback_vf:
|
rollback_vf:
|
||||||
if (vf_netdev)
|
if (vf_netdev)
|
||||||
dev_set_mtu(vf_netdev, orig_mtu);
|
dev_set_mtu(vf_netdev, orig_mtu);
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(device_info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1674,7 +1706,7 @@ static int netvsc_set_ringparam(struct net_device *ndev,
|
||||||
{
|
{
|
||||||
struct net_device_context *ndevctx = netdev_priv(ndev);
|
struct net_device_context *ndevctx = netdev_priv(ndev);
|
||||||
struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
|
struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
|
||||||
struct netvsc_device_info device_info;
|
struct netvsc_device_info *device_info;
|
||||||
struct ethtool_ringparam orig;
|
struct ethtool_ringparam orig;
|
||||||
u32 new_tx, new_rx;
|
u32 new_tx, new_rx;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -1694,26 +1726,29 @@ static int netvsc_set_ringparam(struct net_device *ndev,
|
||||||
new_rx == orig.rx_pending)
|
new_rx == orig.rx_pending)
|
||||||
return 0; /* no change */
|
return 0; /* no change */
|
||||||
|
|
||||||
memset(&device_info, 0, sizeof(device_info));
|
device_info = netvsc_devinfo_get(nvdev);
|
||||||
device_info.num_chn = nvdev->num_chn;
|
|
||||||
device_info.send_sections = new_tx;
|
if (!device_info)
|
||||||
device_info.send_section_size = nvdev->send_section_size;
|
return -ENOMEM;
|
||||||
device_info.recv_sections = new_rx;
|
|
||||||
device_info.recv_section_size = nvdev->recv_section_size;
|
device_info->send_sections = new_tx;
|
||||||
|
device_info->recv_sections = new_rx;
|
||||||
|
|
||||||
ret = netvsc_detach(ndev, nvdev);
|
ret = netvsc_detach(ndev, nvdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
|
|
||||||
ret = netvsc_attach(ndev, &device_info);
|
ret = netvsc_attach(ndev, device_info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
device_info.send_sections = orig.tx_pending;
|
device_info->send_sections = orig.tx_pending;
|
||||||
device_info.recv_sections = orig.rx_pending;
|
device_info->recv_sections = orig.rx_pending;
|
||||||
|
|
||||||
if (netvsc_attach(ndev, &device_info))
|
if (netvsc_attach(ndev, device_info))
|
||||||
netdev_err(ndev, "restoring ringparam failed");
|
netdev_err(ndev, "restoring ringparam failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(device_info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2088,7 +2123,7 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
|
||||||
if (!netvsc_dev || rtnl_dereference(net_device_ctx->vf_netdev))
|
if (!netvsc_dev || rtnl_dereference(net_device_ctx->vf_netdev))
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
/* if syntihetic interface is a different namespace,
|
/* if synthetic interface is a different namespace,
|
||||||
* then move the VF to that namespace; join will be
|
* then move the VF to that namespace; join will be
|
||||||
* done again in that context.
|
* done again in that context.
|
||||||
*/
|
*/
|
||||||
|
@ -2167,7 +2202,7 @@ static int netvsc_probe(struct hv_device *dev,
|
||||||
{
|
{
|
||||||
struct net_device *net = NULL;
|
struct net_device *net = NULL;
|
||||||
struct net_device_context *net_device_ctx;
|
struct net_device_context *net_device_ctx;
|
||||||
struct netvsc_device_info device_info;
|
struct netvsc_device_info *device_info = NULL;
|
||||||
struct netvsc_device *nvdev;
|
struct netvsc_device *nvdev;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
|
@ -2214,21 +2249,21 @@ static int netvsc_probe(struct hv_device *dev,
|
||||||
netif_set_real_num_rx_queues(net, 1);
|
netif_set_real_num_rx_queues(net, 1);
|
||||||
|
|
||||||
/* Notify the netvsc driver of the new device */
|
/* Notify the netvsc driver of the new device */
|
||||||
memset(&device_info, 0, sizeof(device_info));
|
device_info = netvsc_devinfo_get(NULL);
|
||||||
device_info.num_chn = VRSS_CHANNEL_DEFAULT;
|
|
||||||
device_info.send_sections = NETVSC_DEFAULT_TX;
|
|
||||||
device_info.send_section_size = NETVSC_SEND_SECTION_SIZE;
|
|
||||||
device_info.recv_sections = NETVSC_DEFAULT_RX;
|
|
||||||
device_info.recv_section_size = NETVSC_RECV_SECTION_SIZE;
|
|
||||||
|
|
||||||
nvdev = rndis_filter_device_add(dev, &device_info);
|
if (!device_info) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto devinfo_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvdev = rndis_filter_device_add(dev, device_info);
|
||||||
if (IS_ERR(nvdev)) {
|
if (IS_ERR(nvdev)) {
|
||||||
ret = PTR_ERR(nvdev);
|
ret = PTR_ERR(nvdev);
|
||||||
netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
|
netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
|
||||||
goto rndis_failed;
|
goto rndis_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
|
memcpy(net->dev_addr, device_info->mac_adr, ETH_ALEN);
|
||||||
|
|
||||||
/* We must get rtnl lock before scheduling nvdev->subchan_work,
|
/* We must get rtnl lock before scheduling nvdev->subchan_work,
|
||||||
* otherwise netvsc_subchan_work() can get rtnl lock first and wait
|
* otherwise netvsc_subchan_work() can get rtnl lock first and wait
|
||||||
|
@ -2236,7 +2271,7 @@ static int netvsc_probe(struct hv_device *dev,
|
||||||
* netvsc_probe() can't get rtnl lock and as a result vmbus_onoffer()
|
* netvsc_probe() can't get rtnl lock and as a result vmbus_onoffer()
|
||||||
* -> ... -> device_add() -> ... -> __device_attach() can't get
|
* -> ... -> device_add() -> ... -> __device_attach() can't get
|
||||||
* the device lock, so all the subchannels can't be processed --
|
* the device lock, so all the subchannels can't be processed --
|
||||||
* finally netvsc_subchan_work() hangs for ever.
|
* finally netvsc_subchan_work() hangs forever.
|
||||||
*/
|
*/
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
|
|
||||||
|
@ -2266,12 +2301,16 @@ static int netvsc_probe(struct hv_device *dev,
|
||||||
|
|
||||||
list_add(&net_device_ctx->list, &netvsc_dev_list);
|
list_add(&net_device_ctx->list, &netvsc_dev_list);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
|
kfree(device_info);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
register_failed:
|
register_failed:
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
rndis_filter_device_remove(dev, nvdev);
|
rndis_filter_device_remove(dev, nvdev);
|
||||||
rndis_failed:
|
rndis_failed:
|
||||||
|
kfree(device_info);
|
||||||
|
devinfo_failed:
|
||||||
free_percpu(net_device_ctx->vf_stats);
|
free_percpu(net_device_ctx->vf_stats);
|
||||||
no_stats:
|
no_stats:
|
||||||
hv_set_drvdata(dev, NULL);
|
hv_set_drvdata(dev, NULL);
|
||||||
|
|
|
@ -774,8 +774,8 @@ rndis_filter_set_offload_params(struct net_device *ndev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rndis_filter_set_rss_param(struct rndis_device *rdev,
|
static int rndis_set_rss_param_msg(struct rndis_device *rdev,
|
||||||
const u8 *rss_key)
|
const u8 *rss_key, u16 flag)
|
||||||
{
|
{
|
||||||
struct net_device *ndev = rdev->ndev;
|
struct net_device *ndev = rdev->ndev;
|
||||||
struct rndis_request *request;
|
struct rndis_request *request;
|
||||||
|
@ -804,7 +804,7 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev,
|
||||||
rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
|
rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
|
||||||
rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
|
rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
|
||||||
rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
|
rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
|
||||||
rssp->flag = 0;
|
rssp->flag = flag;
|
||||||
rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
|
rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
|
||||||
NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
|
NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
|
||||||
NDIS_HASH_TCP_IPV6;
|
NDIS_HASH_TCP_IPV6;
|
||||||
|
@ -829,9 +829,12 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev,
|
||||||
|
|
||||||
wait_for_completion(&request->wait_event);
|
wait_for_completion(&request->wait_event);
|
||||||
set_complete = &request->response_msg.msg.set_complete;
|
set_complete = &request->response_msg.msg.set_complete;
|
||||||
if (set_complete->status == RNDIS_STATUS_SUCCESS)
|
if (set_complete->status == RNDIS_STATUS_SUCCESS) {
|
||||||
memcpy(rdev->rss_key, rss_key, NETVSC_HASH_KEYLEN);
|
if (!(flag & NDIS_RSS_PARAM_FLAG_DISABLE_RSS) &&
|
||||||
else {
|
!(flag & NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED))
|
||||||
|
memcpy(rdev->rss_key, rss_key, NETVSC_HASH_KEYLEN);
|
||||||
|
|
||||||
|
} else {
|
||||||
netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
|
netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
|
||||||
set_complete->status);
|
set_complete->status);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -842,6 +845,16 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rndis_filter_set_rss_param(struct rndis_device *rdev,
|
||||||
|
const u8 *rss_key)
|
||||||
|
{
|
||||||
|
/* Disable RSS before change */
|
||||||
|
rndis_set_rss_param_msg(rdev, rss_key,
|
||||||
|
NDIS_RSS_PARAM_FLAG_DISABLE_RSS);
|
||||||
|
|
||||||
|
return rndis_set_rss_param_msg(rdev, rss_key, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int rndis_filter_query_device_link_status(struct rndis_device *dev,
|
static int rndis_filter_query_device_link_status(struct rndis_device *dev,
|
||||||
struct netvsc_device *net_device)
|
struct netvsc_device *net_device)
|
||||||
{
|
{
|
||||||
|
@ -1121,7 +1134,9 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
|
||||||
* This breaks overlap of processing the host message for the
|
* This breaks overlap of processing the host message for the
|
||||||
* new primary channel with the initialization of sub-channels.
|
* new primary channel with the initialization of sub-channels.
|
||||||
*/
|
*/
|
||||||
int rndis_set_subchannel(struct net_device *ndev, struct netvsc_device *nvdev)
|
int rndis_set_subchannel(struct net_device *ndev,
|
||||||
|
struct netvsc_device *nvdev,
|
||||||
|
struct netvsc_device_info *dev_info)
|
||||||
{
|
{
|
||||||
struct nvsp_message *init_packet = &nvdev->channel_init_pkt;
|
struct nvsp_message *init_packet = &nvdev->channel_init_pkt;
|
||||||
struct net_device_context *ndev_ctx = netdev_priv(ndev);
|
struct net_device_context *ndev_ctx = netdev_priv(ndev);
|
||||||
|
@ -1161,8 +1176,11 @@ int rndis_set_subchannel(struct net_device *ndev, struct netvsc_device *nvdev)
|
||||||
wait_event(nvdev->subchan_open,
|
wait_event(nvdev->subchan_open,
|
||||||
atomic_read(&nvdev->open_chn) == nvdev->num_chn);
|
atomic_read(&nvdev->open_chn) == nvdev->num_chn);
|
||||||
|
|
||||||
/* ignore failues from setting rss parameters, still have channels */
|
/* ignore failures from setting rss parameters, still have channels */
|
||||||
rndis_filter_set_rss_param(rdev, netvsc_hash_key);
|
if (dev_info)
|
||||||
|
rndis_filter_set_rss_param(rdev, dev_info->rss_key);
|
||||||
|
else
|
||||||
|
rndis_filter_set_rss_param(rdev, netvsc_hash_key);
|
||||||
|
|
||||||
netif_set_real_num_tx_queues(ndev, nvdev->num_chn);
|
netif_set_real_num_tx_queues(ndev, nvdev->num_chn);
|
||||||
netif_set_real_num_rx_queues(ndev, nvdev->num_chn);
|
netif_set_real_num_rx_queues(ndev, nvdev->num_chn);
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/* Driver for Asix PHYs
|
/* Driver for Asix PHYs
|
||||||
*
|
*
|
||||||
* Author: Michael Schmitz <schmitzmic@gmail.com>
|
* Author: Michael Schmitz <schmitzmic@gmail.com>
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
* option) any later version.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
|
|
@ -1,20 +1,8 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Hisilicon Fast Ethernet MDIO Bus Driver
|
* Hisilicon Fast Ethernet MDIO Bus Driver
|
||||||
*
|
*
|
||||||
* Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
|
* Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
|
@ -163,4 +151,4 @@ module_platform_driver(hisi_femac_mdio_driver);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC MDIO interface driver");
|
MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC MDIO interface driver");
|
||||||
MODULE_AUTHOR("Dongpo Li <lidongpo@hisilicon.com>");
|
MODULE_AUTHOR("Dongpo Li <lidongpo@hisilicon.com>");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/**
|
/**
|
||||||
* drivers/net/phy/rockchip.c
|
* drivers/net/phy/rockchip.c
|
||||||
*
|
*
|
||||||
|
@ -6,12 +7,6 @@
|
||||||
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
|
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
|
||||||
*
|
*
|
||||||
* David Wu <david.wu@rock-chips.com>
|
* David Wu <david.wu@rock-chips.com>
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
|
@ -229,4 +224,4 @@ MODULE_DEVICE_TABLE(mdio, rockchip_phy_tbl);
|
||||||
|
|
||||||
MODULE_AUTHOR("David Wu <david.wu@rock-chips.com>");
|
MODULE_AUTHOR("David Wu <david.wu@rock-chips.com>");
|
||||||
MODULE_DESCRIPTION("Rockchip Ethernet PHY driver");
|
MODULE_DESCRIPTION("Rockchip Ethernet PHY driver");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -739,8 +739,13 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||||
asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &chipcode, 0);
|
asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, 0, 0, 1, &chipcode, 0);
|
||||||
chipcode &= AX_CHIPCODE_MASK;
|
chipcode &= AX_CHIPCODE_MASK;
|
||||||
|
|
||||||
(chipcode == AX_AX88772_CHIPCODE) ? ax88772_hw_reset(dev, 0) :
|
ret = (chipcode == AX_AX88772_CHIPCODE) ? ax88772_hw_reset(dev, 0) :
|
||||||
ax88772a_hw_reset(dev, 0);
|
ax88772a_hw_reset(dev, 0);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
netdev_dbg(dev->net, "Failed to reset AX88772: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read PHYID register *AFTER* the PHY was reset properly */
|
/* Read PHYID register *AFTER* the PHY was reset properly */
|
||||||
phyid = asix_get_phyid(dev);
|
phyid = asix_get_phyid(dev);
|
||||||
|
|
|
@ -2761,6 +2761,11 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
|
||||||
BIT(NL80211_CHAN_WIDTH_160);
|
BIT(NL80211_CHAN_WIDTH_160);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!n_limits) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto failed_hw;
|
||||||
|
}
|
||||||
|
|
||||||
data->if_combination.n_limits = n_limits;
|
data->if_combination.n_limits = n_limits;
|
||||||
data->if_combination.max_interfaces = 2048;
|
data->if_combination.max_interfaces = 2048;
|
||||||
data->if_combination.limits = data->if_limits;
|
data->if_combination.limits = data->if_limits;
|
||||||
|
|
|
@ -530,8 +530,10 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
|
||||||
SET_NETDEV_DEV(dev, &priv->lowerdev->dev);
|
SET_NETDEV_DEV(dev, &priv->lowerdev->dev);
|
||||||
dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL);
|
dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL);
|
||||||
|
|
||||||
if (!dev->ieee80211_ptr)
|
if (!dev->ieee80211_ptr) {
|
||||||
|
err = -ENOMEM;
|
||||||
goto remove_handler;
|
goto remove_handler;
|
||||||
|
}
|
||||||
|
|
||||||
dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
|
dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
|
||||||
dev->ieee80211_ptr->wiphy = common_wiphy;
|
dev->ieee80211_ptr->wiphy = common_wiphy;
|
||||||
|
|
|
@ -54,6 +54,7 @@ static inline bool dev_is_mac_header_xmit(const struct net_device *dev)
|
||||||
case ARPHRD_IPGRE:
|
case ARPHRD_IPGRE:
|
||||||
case ARPHRD_VOID:
|
case ARPHRD_VOID:
|
||||||
case ARPHRD_NONE:
|
case ARPHRD_NONE:
|
||||||
|
case ARPHRD_RAWIP:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -201,6 +201,18 @@ static inline void ax25_hold_route(ax25_route *ax25_rt)
|
||||||
|
|
||||||
void __ax25_put_route(ax25_route *ax25_rt);
|
void __ax25_put_route(ax25_route *ax25_rt);
|
||||||
|
|
||||||
|
extern rwlock_t ax25_route_lock;
|
||||||
|
|
||||||
|
static inline void ax25_route_lock_use(void)
|
||||||
|
{
|
||||||
|
read_lock(&ax25_route_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ax25_route_lock_unuse(void)
|
||||||
|
{
|
||||||
|
read_unlock(&ax25_route_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ax25_put_route(ax25_route *ax25_rt)
|
static inline void ax25_put_route(ax25_route *ax25_rt)
|
||||||
{
|
{
|
||||||
if (refcount_dec_and_test(&ax25_rt->refcount))
|
if (refcount_dec_and_test(&ax25_rt->refcount))
|
||||||
|
|
|
@ -114,6 +114,7 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
|
||||||
dst = (ax25_address *)(bp + 1);
|
dst = (ax25_address *)(bp + 1);
|
||||||
src = (ax25_address *)(bp + 8);
|
src = (ax25_address *)(bp + 8);
|
||||||
|
|
||||||
|
ax25_route_lock_use();
|
||||||
route = ax25_get_route(dst, NULL);
|
route = ax25_get_route(dst, NULL);
|
||||||
if (route) {
|
if (route) {
|
||||||
digipeat = route->digipeat;
|
digipeat = route->digipeat;
|
||||||
|
@ -206,9 +207,8 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
|
||||||
ax25_queue_xmit(skb, dev);
|
ax25_queue_xmit(skb, dev);
|
||||||
|
|
||||||
put:
|
put:
|
||||||
if (route)
|
|
||||||
ax25_put_route(route);
|
|
||||||
|
|
||||||
|
ax25_route_lock_unuse();
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
|
||||||
static ax25_route *ax25_route_list;
|
static ax25_route *ax25_route_list;
|
||||||
static DEFINE_RWLOCK(ax25_route_lock);
|
DEFINE_RWLOCK(ax25_route_lock);
|
||||||
|
|
||||||
void ax25_rt_device_down(struct net_device *dev)
|
void ax25_rt_device_down(struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -335,6 +335,7 @@ const struct seq_operations ax25_rt_seqops = {
|
||||||
* Find AX.25 route
|
* Find AX.25 route
|
||||||
*
|
*
|
||||||
* Only routes with a reference count of zero can be destroyed.
|
* Only routes with a reference count of zero can be destroyed.
|
||||||
|
* Must be called with ax25_route_lock read locked.
|
||||||
*/
|
*/
|
||||||
ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
|
ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -342,7 +343,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
|
||||||
ax25_route *ax25_def_rt = NULL;
|
ax25_route *ax25_def_rt = NULL;
|
||||||
ax25_route *ax25_rt;
|
ax25_route *ax25_rt;
|
||||||
|
|
||||||
read_lock(&ax25_route_lock);
|
|
||||||
/*
|
/*
|
||||||
* Bind to the physical interface we heard them on, or the default
|
* Bind to the physical interface we heard them on, or the default
|
||||||
* route if none is found;
|
* route if none is found;
|
||||||
|
@ -365,11 +365,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
|
||||||
if (ax25_spe_rt != NULL)
|
if (ax25_spe_rt != NULL)
|
||||||
ax25_rt = ax25_spe_rt;
|
ax25_rt = ax25_spe_rt;
|
||||||
|
|
||||||
if (ax25_rt != NULL)
|
|
||||||
ax25_hold_route(ax25_rt);
|
|
||||||
|
|
||||||
read_unlock(&ax25_route_lock);
|
|
||||||
|
|
||||||
return ax25_rt;
|
return ax25_rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,9 +395,12 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
|
||||||
ax25_route *ax25_rt;
|
ax25_route *ax25_rt;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL)
|
ax25_route_lock_use();
|
||||||
|
ax25_rt = ax25_get_route(addr, NULL);
|
||||||
|
if (!ax25_rt) {
|
||||||
|
ax25_route_lock_unuse();
|
||||||
return -EHOSTUNREACH;
|
return -EHOSTUNREACH;
|
||||||
|
}
|
||||||
if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
|
if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
|
||||||
err = -EHOSTUNREACH;
|
err = -EHOSTUNREACH;
|
||||||
goto put;
|
goto put;
|
||||||
|
@ -437,8 +435,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
put:
|
put:
|
||||||
ax25_put_route(ax25_rt);
|
ax25_route_lock_unuse();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,9 @@
|
||||||
*/
|
*/
|
||||||
#define MAX_NFRAMES 256
|
#define MAX_NFRAMES 256
|
||||||
|
|
||||||
|
/* limit timers to 400 days for sending/timeouts */
|
||||||
|
#define BCM_TIMER_SEC_MAX (400 * 24 * 60 * 60)
|
||||||
|
|
||||||
/* use of last_frames[index].flags */
|
/* use of last_frames[index].flags */
|
||||||
#define RX_RECV 0x40 /* received data for this element */
|
#define RX_RECV 0x40 /* received data for this element */
|
||||||
#define RX_THR 0x80 /* element not been sent due to throttle feature */
|
#define RX_THR 0x80 /* element not been sent due to throttle feature */
|
||||||
|
@ -140,6 +143,22 @@ static inline ktime_t bcm_timeval_to_ktime(struct bcm_timeval tv)
|
||||||
return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
|
return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check limitations for timeval provided by user */
|
||||||
|
static bool bcm_is_invalid_tv(struct bcm_msg_head *msg_head)
|
||||||
|
{
|
||||||
|
if ((msg_head->ival1.tv_sec < 0) ||
|
||||||
|
(msg_head->ival1.tv_sec > BCM_TIMER_SEC_MAX) ||
|
||||||
|
(msg_head->ival1.tv_usec < 0) ||
|
||||||
|
(msg_head->ival1.tv_usec >= USEC_PER_SEC) ||
|
||||||
|
(msg_head->ival2.tv_sec < 0) ||
|
||||||
|
(msg_head->ival2.tv_sec > BCM_TIMER_SEC_MAX) ||
|
||||||
|
(msg_head->ival2.tv_usec < 0) ||
|
||||||
|
(msg_head->ival2.tv_usec >= USEC_PER_SEC))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#define CFSIZ(flags) ((flags & CAN_FD_FRAME) ? CANFD_MTU : CAN_MTU)
|
#define CFSIZ(flags) ((flags & CAN_FD_FRAME) ? CANFD_MTU : CAN_MTU)
|
||||||
#define OPSIZ sizeof(struct bcm_op)
|
#define OPSIZ sizeof(struct bcm_op)
|
||||||
#define MHSIZ sizeof(struct bcm_msg_head)
|
#define MHSIZ sizeof(struct bcm_msg_head)
|
||||||
|
@ -873,6 +892,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||||
if (msg_head->nframes < 1 || msg_head->nframes > MAX_NFRAMES)
|
if (msg_head->nframes < 1 || msg_head->nframes > MAX_NFRAMES)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* check timeval limitations */
|
||||||
|
if ((msg_head->flags & SETTIMER) && bcm_is_invalid_tv(msg_head))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* check the given can_id */
|
/* check the given can_id */
|
||||||
op = bcm_find_op(&bo->tx_ops, msg_head, ifindex);
|
op = bcm_find_op(&bo->tx_ops, msg_head, ifindex);
|
||||||
if (op) {
|
if (op) {
|
||||||
|
@ -1053,6 +1076,10 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||||
(!(msg_head->can_id & CAN_RTR_FLAG))))
|
(!(msg_head->can_id & CAN_RTR_FLAG))))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* check timeval limitations */
|
||||||
|
if ((msg_head->flags & SETTIMER) && bcm_is_invalid_tv(msg_head))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* check the given can_id */
|
/* check the given can_id */
|
||||||
op = bcm_find_op(&bo->rx_ops, msg_head, ifindex);
|
op = bcm_find_op(&bo->rx_ops, msg_head, ifindex);
|
||||||
if (op) {
|
if (op) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <net/protocol.h>
|
#include <net/protocol.h>
|
||||||
#include <net/gre.h>
|
#include <net/gre.h>
|
||||||
|
#include <net/erspan.h>
|
||||||
|
|
||||||
#include <net/icmp.h>
|
#include <net/icmp.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
|
@ -119,6 +120,22 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
||||||
hdr_len += 4;
|
hdr_len += 4;
|
||||||
}
|
}
|
||||||
tpi->hdr_len = hdr_len;
|
tpi->hdr_len = hdr_len;
|
||||||
|
|
||||||
|
/* ERSPAN ver 1 and 2 protocol sets GRE key field
|
||||||
|
* to 0 and sets the configured key in the
|
||||||
|
* inner erspan header field
|
||||||
|
*/
|
||||||
|
if (greh->protocol == htons(ETH_P_ERSPAN) ||
|
||||||
|
greh->protocol == htons(ETH_P_ERSPAN2)) {
|
||||||
|
struct erspan_base_hdr *ershdr;
|
||||||
|
|
||||||
|
if (!pskb_may_pull(skb, nhs + hdr_len + sizeof(*ershdr)))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ershdr = (struct erspan_base_hdr *)options;
|
||||||
|
tpi->key = cpu_to_be32(get_session_id(ershdr));
|
||||||
|
}
|
||||||
|
|
||||||
return hdr_len;
|
return hdr_len;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(gre_parse_header);
|
EXPORT_SYMBOL(gre_parse_header);
|
||||||
|
|
|
@ -268,20 +268,11 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
itn = net_generic(net, erspan_net_id);
|
itn = net_generic(net, erspan_net_id);
|
||||||
len = gre_hdr_len + sizeof(*ershdr);
|
|
||||||
|
|
||||||
/* Check based hdr len */
|
|
||||||
if (unlikely(!pskb_may_pull(skb, len)))
|
|
||||||
return PACKET_REJECT;
|
|
||||||
|
|
||||||
iph = ip_hdr(skb);
|
iph = ip_hdr(skb);
|
||||||
ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
|
ershdr = (struct erspan_base_hdr *)(skb->data + gre_hdr_len);
|
||||||
ver = ershdr->ver;
|
ver = ershdr->ver;
|
||||||
|
|
||||||
/* The original GRE header does not have key field,
|
|
||||||
* Use ERSPAN 10-bit session ID as key.
|
|
||||||
*/
|
|
||||||
tpi->key = cpu_to_be32(get_session_id(ershdr));
|
|
||||||
tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
|
tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
|
||||||
tpi->flags | TUNNEL_KEY,
|
tpi->flags | TUNNEL_KEY,
|
||||||
iph->saddr, iph->daddr, tpi->key);
|
iph->saddr, iph->daddr, tpi->key);
|
||||||
|
|
|
@ -644,13 +644,19 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||||
dst = tnl_params->daddr;
|
dst = tnl_params->daddr;
|
||||||
if (dst == 0) {
|
if (dst == 0) {
|
||||||
/* NBMA tunnel */
|
/* NBMA tunnel */
|
||||||
|
struct ip_tunnel_info *tun_info;
|
||||||
|
|
||||||
if (!skb_dst(skb)) {
|
if (!skb_dst(skb)) {
|
||||||
dev->stats.tx_fifo_errors++;
|
dev->stats.tx_fifo_errors++;
|
||||||
goto tx_error;
|
goto tx_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skb->protocol == htons(ETH_P_IP)) {
|
tun_info = skb_tunnel_info(skb);
|
||||||
|
if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) &&
|
||||||
|
ip_tunnel_info_af(tun_info) == AF_INET &&
|
||||||
|
tun_info->key.u.ipv4.dst)
|
||||||
|
dst = tun_info->key.u.ipv4.dst;
|
||||||
|
else if (skb->protocol == htons(ETH_P_IP)) {
|
||||||
rt = skb_rtable(skb);
|
rt = skb_rtable(skb);
|
||||||
dst = rt_nexthop(rt, inner_iph->daddr);
|
dst = rt_nexthop(rt, inner_iph->daddr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3495,8 +3495,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||||
|
|
||||||
if (!addrconf_link_ready(dev)) {
|
if (!addrconf_link_ready(dev)) {
|
||||||
/* device is not ready yet. */
|
/* device is not ready yet. */
|
||||||
pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
|
pr_debug("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5120,6 +5120,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
|
||||||
if (idev) {
|
if (idev) {
|
||||||
err = in6_dump_addrs(idev, skb, cb, s_ip_idx,
|
err = in6_dump_addrs(idev, skb, cb, s_ip_idx,
|
||||||
&fillargs);
|
&fillargs);
|
||||||
|
if (err > 0)
|
||||||
|
err = 0;
|
||||||
}
|
}
|
||||||
goto put_tgt_net;
|
goto put_tgt_net;
|
||||||
}
|
}
|
||||||
|
|
|
@ -534,13 +534,9 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
|
||||||
struct ip6_tnl *tunnel;
|
struct ip6_tnl *tunnel;
|
||||||
u8 ver;
|
u8 ver;
|
||||||
|
|
||||||
if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr))))
|
|
||||||
return PACKET_REJECT;
|
|
||||||
|
|
||||||
ipv6h = ipv6_hdr(skb);
|
ipv6h = ipv6_hdr(skb);
|
||||||
ershdr = (struct erspan_base_hdr *)skb->data;
|
ershdr = (struct erspan_base_hdr *)skb->data;
|
||||||
ver = ershdr->ver;
|
ver = ershdr->ver;
|
||||||
tpi->key = cpu_to_be32(get_session_id(ershdr));
|
|
||||||
|
|
||||||
tunnel = ip6gre_tunnel_lookup(skb->dev,
|
tunnel = ip6gre_tunnel_lookup(skb->dev,
|
||||||
&ipv6h->saddr, &ipv6h->daddr, tpi->key,
|
&ipv6h->saddr, &ipv6h->daddr, tpi->key,
|
||||||
|
|
|
@ -1490,6 +1490,10 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
|
||||||
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
|
||||||
sta->sta.tdls = true;
|
sta->sta.tdls = true;
|
||||||
|
|
||||||
|
if (sta->sta.tdls && sdata->vif.type == NL80211_IFTYPE_STATION &&
|
||||||
|
!sdata->u.mgd.associated)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
err = sta_apply_parameters(local, sta, params);
|
err = sta_apply_parameters(local, sta, params);
|
||||||
if (err) {
|
if (err) {
|
||||||
sta_info_free(local, sta);
|
sta_info_free(local, sta);
|
||||||
|
|
|
@ -231,7 +231,7 @@ static void ieee80211_handle_mu_mimo_mon(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_hdr_3addr hdr;
|
struct ieee80211_hdr_3addr hdr;
|
||||||
u8 category;
|
u8 category;
|
||||||
u8 action_code;
|
u8 action_code;
|
||||||
} __packed action;
|
} __packed __aligned(2) action;
|
||||||
|
|
||||||
if (!sdata)
|
if (!sdata)
|
||||||
return;
|
return;
|
||||||
|
@ -2723,7 +2723,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
||||||
skb_set_queue_mapping(skb, q);
|
skb_set_queue_mapping(skb, q);
|
||||||
|
|
||||||
if (!--mesh_hdr->ttl) {
|
if (!--mesh_hdr->ttl) {
|
||||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
|
if (!is_multicast_ether_addr(hdr->addr1))
|
||||||
|
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh,
|
||||||
|
dropped_frames_ttl);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
|
||||||
|
|
||||||
if (saddr) {
|
if (saddr) {
|
||||||
fl6->saddr = saddr->v6.sin6_addr;
|
fl6->saddr = saddr->v6.sin6_addr;
|
||||||
fl6->fl6_sport = saddr->v6.sin6_port;
|
if (!fl6->fl6_sport)
|
||||||
|
fl6->fl6_sport = saddr->v6.sin6_port;
|
||||||
|
|
||||||
pr_debug("src=%pI6 - ", &fl6->saddr);
|
pr_debug("src=%pI6 - ", &fl6->saddr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,7 +440,8 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
|
||||||
}
|
}
|
||||||
if (saddr) {
|
if (saddr) {
|
||||||
fl4->saddr = saddr->v4.sin_addr.s_addr;
|
fl4->saddr = saddr->v4.sin_addr.s_addr;
|
||||||
fl4->fl4_sport = saddr->v4.sin_port;
|
if (!fl4->fl4_sport)
|
||||||
|
fl4->fl4_sport = saddr->v4.sin_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("%s: dst:%pI4, src:%pI4 - ", __func__, &fl4->daddr,
|
pr_debug("%s: dst:%pI4, src:%pI4 - ", __func__, &fl4->daddr,
|
||||||
|
|
|
@ -495,7 +495,10 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
|
||||||
*
|
*
|
||||||
* [INIT ACK back to where the INIT came from.]
|
* [INIT ACK back to where the INIT came from.]
|
||||||
*/
|
*/
|
||||||
retval->transport = chunk->transport;
|
if (chunk->transport)
|
||||||
|
retval->transport =
|
||||||
|
sctp_assoc_lookup_paddr(asoc,
|
||||||
|
&chunk->transport->ipaddr);
|
||||||
|
|
||||||
retval->subh.init_hdr =
|
retval->subh.init_hdr =
|
||||||
sctp_addto_chunk(retval, sizeof(initack), &initack);
|
sctp_addto_chunk(retval, sizeof(initack), &initack);
|
||||||
|
@ -642,8 +645,10 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
|
||||||
*
|
*
|
||||||
* [COOKIE ACK back to where the COOKIE ECHO came from.]
|
* [COOKIE ACK back to where the COOKIE ECHO came from.]
|
||||||
*/
|
*/
|
||||||
if (retval && chunk)
|
if (retval && chunk && chunk->transport)
|
||||||
retval->transport = chunk->transport;
|
retval->transport =
|
||||||
|
sctp_assoc_lookup_paddr(asoc,
|
||||||
|
&chunk->transport->ipaddr);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -585,9 +585,9 @@ struct sctp_chunk *sctp_process_strreset_outreq(
|
||||||
struct sctp_strreset_outreq *outreq = param.v;
|
struct sctp_strreset_outreq *outreq = param.v;
|
||||||
struct sctp_stream *stream = &asoc->stream;
|
struct sctp_stream *stream = &asoc->stream;
|
||||||
__u32 result = SCTP_STRRESET_DENIED;
|
__u32 result = SCTP_STRRESET_DENIED;
|
||||||
__u16 i, nums, flags = 0;
|
|
||||||
__be16 *str_p = NULL;
|
__be16 *str_p = NULL;
|
||||||
__u32 request_seq;
|
__u32 request_seq;
|
||||||
|
__u16 i, nums;
|
||||||
|
|
||||||
request_seq = ntohl(outreq->request_seq);
|
request_seq = ntohl(outreq->request_seq);
|
||||||
|
|
||||||
|
@ -615,6 +615,15 @@ struct sctp_chunk *sctp_process_strreset_outreq(
|
||||||
if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
|
if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16);
|
||||||
|
str_p = outreq->list_of_streams;
|
||||||
|
for (i = 0; i < nums; i++) {
|
||||||
|
if (ntohs(str_p[i]) >= stream->incnt) {
|
||||||
|
result = SCTP_STRRESET_ERR_WRONG_SSN;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (asoc->strreset_chunk) {
|
if (asoc->strreset_chunk) {
|
||||||
if (!sctp_chunk_lookup_strreset_param(
|
if (!sctp_chunk_lookup_strreset_param(
|
||||||
asoc, outreq->response_seq,
|
asoc, outreq->response_seq,
|
||||||
|
@ -637,32 +646,19 @@ struct sctp_chunk *sctp_process_strreset_outreq(
|
||||||
sctp_chunk_put(asoc->strreset_chunk);
|
sctp_chunk_put(asoc->strreset_chunk);
|
||||||
asoc->strreset_chunk = NULL;
|
asoc->strreset_chunk = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = SCTP_STREAM_RESET_INCOMING_SSN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16);
|
if (nums)
|
||||||
if (nums) {
|
|
||||||
str_p = outreq->list_of_streams;
|
|
||||||
for (i = 0; i < nums; i++) {
|
|
||||||
if (ntohs(str_p[i]) >= stream->incnt) {
|
|
||||||
result = SCTP_STRRESET_ERR_WRONG_SSN;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nums; i++)
|
for (i = 0; i < nums; i++)
|
||||||
SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
|
SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
|
||||||
} else {
|
else
|
||||||
for (i = 0; i < stream->incnt; i++)
|
for (i = 0; i < stream->incnt; i++)
|
||||||
SCTP_SI(stream, i)->mid = 0;
|
SCTP_SI(stream, i)->mid = 0;
|
||||||
}
|
|
||||||
|
|
||||||
result = SCTP_STRRESET_PERFORMED;
|
result = SCTP_STRRESET_PERFORMED;
|
||||||
|
|
||||||
*evp = sctp_ulpevent_make_stream_reset_event(asoc,
|
*evp = sctp_ulpevent_make_stream_reset_event(asoc,
|
||||||
flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p,
|
SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
|
||||||
GFP_ATOMIC);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sctp_update_strreset_result(asoc, result);
|
sctp_update_strreset_result(asoc, result);
|
||||||
|
@ -738,9 +734,6 @@ struct sctp_chunk *sctp_process_strreset_inreq(
|
||||||
|
|
||||||
result = SCTP_STRRESET_PERFORMED;
|
result = SCTP_STRRESET_PERFORMED;
|
||||||
|
|
||||||
*evp = sctp_ulpevent_make_stream_reset_event(asoc,
|
|
||||||
SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sctp_update_strreset_result(asoc, result);
|
sctp_update_strreset_result(asoc, result);
|
||||||
err:
|
err:
|
||||||
|
@ -873,6 +866,14 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
|
||||||
if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ))
|
if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
in = ntohs(addstrm->number_of_streams);
|
||||||
|
incnt = stream->incnt + in;
|
||||||
|
if (!in || incnt > SCTP_MAX_STREAM)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (asoc->strreset_chunk) {
|
if (asoc->strreset_chunk) {
|
||||||
if (!sctp_chunk_lookup_strreset_param(
|
if (!sctp_chunk_lookup_strreset_param(
|
||||||
asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) {
|
asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) {
|
||||||
|
@ -896,14 +897,6 @@ struct sctp_chunk *sctp_process_strreset_addstrm_out(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in = ntohs(addstrm->number_of_streams);
|
|
||||||
incnt = stream->incnt + in;
|
|
||||||
if (!in || incnt > SCTP_MAX_STREAM)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
stream->incnt = incnt;
|
stream->incnt = incnt;
|
||||||
|
|
||||||
result = SCTP_STRRESET_PERFORMED;
|
result = SCTP_STRRESET_PERFORMED;
|
||||||
|
@ -973,9 +966,6 @@ struct sctp_chunk *sctp_process_strreset_addstrm_in(
|
||||||
|
|
||||||
result = SCTP_STRRESET_PERFORMED;
|
result = SCTP_STRRESET_PERFORMED;
|
||||||
|
|
||||||
*evp = sctp_ulpevent_make_stream_change_event(asoc,
|
|
||||||
0, 0, ntohs(addstrm->number_of_streams), GFP_ATOMIC);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sctp_update_strreset_result(asoc, result);
|
sctp_update_strreset_result(asoc, result);
|
||||||
err:
|
err:
|
||||||
|
@ -1036,10 +1026,10 @@ struct sctp_chunk *sctp_process_strreset_resp(
|
||||||
sout->mid_uo = 0;
|
sout->mid_uo = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = SCTP_STREAM_RESET_OUTGOING_SSN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flags |= SCTP_STREAM_RESET_OUTGOING_SSN;
|
||||||
|
|
||||||
for (i = 0; i < stream->outcnt; i++)
|
for (i = 0; i < stream->outcnt; i++)
|
||||||
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
|
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
|
||||||
|
|
||||||
|
@ -1058,6 +1048,8 @@ struct sctp_chunk *sctp_process_strreset_resp(
|
||||||
nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) /
|
nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) /
|
||||||
sizeof(__u16);
|
sizeof(__u16);
|
||||||
|
|
||||||
|
flags |= SCTP_STREAM_RESET_INCOMING_SSN;
|
||||||
|
|
||||||
*evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
|
*evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
|
||||||
nums, str_p, GFP_ATOMIC);
|
nums, str_p, GFP_ATOMIC);
|
||||||
} else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) {
|
} else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) {
|
||||||
|
|
|
@ -555,7 +555,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||||
},
|
},
|
||||||
[NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
|
[NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||||
[NL80211_ATTR_PEER_MEASUREMENTS] =
|
[NL80211_ATTR_PEER_MEASUREMENTS] =
|
||||||
NLA_POLICY_NESTED(NL80211_PMSR_FTM_REQ_ATTR_MAX,
|
NLA_POLICY_NESTED(NL80211_PMSR_ATTR_MAX,
|
||||||
nl80211_pmsr_attr_policy),
|
nl80211_pmsr_attr_policy),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1024,8 +1024,13 @@ static void regdb_fw_cb(const struct firmware *fw, void *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
if (WARN_ON(regdb && !IS_ERR(regdb))) {
|
if (regdb && !IS_ERR(regdb)) {
|
||||||
/* just restore and free new db */
|
/* negative case - a bug
|
||||||
|
* positive case - can happen due to race in case of multiple cb's in
|
||||||
|
* queue, due to usage of asynchronous callback
|
||||||
|
*
|
||||||
|
* Either case, just restore and free new db.
|
||||||
|
*/
|
||||||
} else if (set_error) {
|
} else if (set_error) {
|
||||||
regdb = ERR_PTR(set_error);
|
regdb = ERR_PTR(set_error);
|
||||||
} else if (fw) {
|
} else if (fw) {
|
||||||
|
@ -1255,7 +1260,7 @@ static bool is_valid_rd(const struct ieee80211_regdomain *rd)
|
||||||
* definitions (the "2.4 GHz band", the "5 GHz band" and the "60GHz band"),
|
* definitions (the "2.4 GHz band", the "5 GHz band" and the "60GHz band"),
|
||||||
* however it is safe for now to assume that a frequency rule should not be
|
* however it is safe for now to assume that a frequency rule should not be
|
||||||
* part of a frequency's band if the start freq or end freq are off by more
|
* part of a frequency's band if the start freq or end freq are off by more
|
||||||
* than 2 GHz for the 2.4 and 5 GHz bands, and by more than 10 GHz for the
|
* than 2 GHz for the 2.4 and 5 GHz bands, and by more than 20 GHz for the
|
||||||
* 60 GHz band.
|
* 60 GHz band.
|
||||||
* This resolution can be lowered and should be considered as we add
|
* This resolution can be lowered and should be considered as we add
|
||||||
* regulatory rule support for other "bands".
|
* regulatory rule support for other "bands".
|
||||||
|
@ -1270,7 +1275,7 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
|
||||||
* with the Channel starting frequency above 45 GHz.
|
* with the Channel starting frequency above 45 GHz.
|
||||||
*/
|
*/
|
||||||
u32 limit = freq_khz > 45 * ONE_GHZ_IN_KHZ ?
|
u32 limit = freq_khz > 45 * ONE_GHZ_IN_KHZ ?
|
||||||
10 * ONE_GHZ_IN_KHZ : 2 * ONE_GHZ_IN_KHZ;
|
20 * ONE_GHZ_IN_KHZ : 2 * ONE_GHZ_IN_KHZ;
|
||||||
if (abs(freq_khz - freq_range->start_freq_khz) <= limit)
|
if (abs(freq_khz - freq_range->start_freq_khz) <= limit)
|
||||||
return true;
|
return true;
|
||||||
if (abs(freq_khz - freq_range->end_freq_khz) <= limit)
|
if (abs(freq_khz - freq_range->end_freq_khz) <= limit)
|
||||||
|
|
Loading…
Reference in New Issue