diff options
Diffstat (limited to 'drivers/net')
27 files changed, 254 insertions, 109 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b4351caf8e01..9e0f8a7ef8b1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1749,6 +1749,7 @@ err_undo_flags: slave_dev->dev_addr)) eth_hw_addr_random(bond_dev); if (bond_dev->type != ARPHRD_ETHER) { + dev_close(bond_dev); ether_setup(bond_dev); bond_dev->flags |= IFF_MASTER; bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING; diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index de3962014af7..4721948a92f6 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -730,11 +730,14 @@ int cfspi_spi_probe(struct platform_device *pdev) int res; dev = (struct cfspi_dev *)pdev->dev.platform_data; - ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d", - NET_NAME_UNKNOWN, cfspi_setup); if (!dev) return -ENODEV; + ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d", + NET_NAME_UNKNOWN, cfspi_setup); + if (!ndev) + return -ENOMEM; + cfspi = netdev_priv(ndev); netif_stop_queue(ndev); cfspi->ndev = ndev; diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 54aa00012dd0..6e18213b9c04 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -103,6 +103,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = { #endif .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, + .port_join_bridge = mv88e6xxx_port_bridge_join, + .port_leave_bridge = mv88e6xxx_port_bridge_leave, .port_stp_update = mv88e6xxx_port_stp_update, .port_pvid_get = mv88e6xxx_port_pvid_get, .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index ff846d0cfceb..cc6c54553418 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -323,6 +323,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = { .set_eeprom = mv88e6352_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, + .port_join_bridge = mv88e6xxx_port_bridge_join, + .port_leave_bridge = mv88e6xxx_port_bridge_leave, .port_stp_update = mv88e6xxx_port_stp_update, .port_pvid_get = mv88e6xxx_port_pvid_get, .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 04cff58d771b..b06dba05594a 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1462,6 +1462,10 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan, struct switchdev_trans *trans) { + /* We reserve a few VLANs to isolate unbridged ports */ + if (vlan->vid_end >= 4000) + return -EOPNOTSUPP; + /* We don't need any dynamic resource from the kernel (yet), * so skip the prepare phase. */ @@ -1870,6 +1874,36 @@ unlock: return err; } +int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port; + int err; + + /* The port joined a bridge, so leave its reserved VLAN */ + mutex_lock(&ps->smi_mutex); + err = _mv88e6xxx_port_vlan_del(ds, port, pvid); + if (!err) + err = _mv88e6xxx_port_pvid_set(ds, port, 0); + mutex_unlock(&ps->smi_mutex); + return err; +} + +int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port; + int err; + + /* The port left the bridge, so join its reserved VLAN */ + mutex_lock(&ps->smi_mutex); + err = _mv88e6xxx_port_vlan_add(ds, port, pvid, true); + if (!err) + err = _mv88e6xxx_port_pvid_set(ds, port, pvid); + mutex_unlock(&ps->smi_mutex); + return err; +} + static void mv88e6xxx_bridge_work(struct work_struct *work) { struct mv88e6xxx_priv_state *ps; @@ -2140,6 +2174,14 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) ret = mv88e6xxx_setup_port(ds, i); if (ret < 0) return ret; + + if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)) + continue; + + /* setup the unbridged state */ + ret = mv88e6xxx_port_bridge_leave(ds, i, 0); + if (ret < 0) + return ret; } return 0; } diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index fb9a8739712f..21c8daa03f78 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -468,6 +468,8 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, struct phy_device *phydev, struct ethtool_eee *e); +int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members); +int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members); int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state); int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan, diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index 33850a0f7e82..c31e691d11fc 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c @@ -459,6 +459,45 @@ static void xgene_gmac_reset(struct xgene_enet_pdata *pdata) xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0); } +static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata) +{ + struct device *dev = &pdata->pdev->dev; + + if (dev->of_node) { + struct clk *parent = clk_get_parent(pdata->clk); + + switch (pdata->phy_speed) { + case SPEED_10: + clk_set_rate(parent, 2500000); + break; + case SPEED_100: + clk_set_rate(parent, 25000000); + break; + default: + clk_set_rate(parent, 125000000); + break; + } + } +#ifdef CONFIG_ACPI + else { + switch (pdata->phy_speed) { + case SPEED_10: + acpi_evaluate_object(ACPI_HANDLE(dev), + "S10", NULL, NULL); + break; + case SPEED_100: + acpi_evaluate_object(ACPI_HANDLE(dev), + "S100", NULL, NULL); + break; + default: + acpi_evaluate_object(ACPI_HANDLE(dev), + "S1G", NULL, NULL); + break; + } + } +#endif +} + static void xgene_gmac_init(struct xgene_enet_pdata *pdata) { struct device *dev = &pdata->pdev->dev; @@ -477,12 +516,14 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) switch (pdata->phy_speed) { case SPEED_10: ENET_INTERFACE_MODE2_SET(&mc2, 1); + intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE); CFG_MACMODE_SET(&icm0, 0); CFG_WAITASYNCRD_SET(&icm2, 500); rgmii &= ~CFG_SPEED_1250; break; case SPEED_100: ENET_INTERFACE_MODE2_SET(&mc2, 1); + intf_ctl &= ~ENET_GHD_MODE; intf_ctl |= ENET_LHD_MODE; CFG_MACMODE_SET(&icm0, 1); CFG_WAITASYNCRD_SET(&icm2, 80); @@ -490,12 +531,15 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) break; default: ENET_INTERFACE_MODE2_SET(&mc2, 2); + intf_ctl &= ~ENET_LHD_MODE; intf_ctl |= ENET_GHD_MODE; - + CFG_MACMODE_SET(&icm0, 2); + CFG_WAITASYNCRD_SET(&icm2, 0); if (dev->of_node) { CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay); CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay); } + rgmii |= CFG_SPEED_1250; xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value); value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX; @@ -503,7 +547,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) break; } - mc2 |= FULL_DUPLEX2; + mc2 |= FULL_DUPLEX2 | PAD_CRC; xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2); xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl); @@ -522,6 +566,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) /* Rtype should be copied from FP */ xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0); xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii); + xgene_enet_configure_clock(pdata); /* Rx-Tx traffic resume */ xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h index 6dee73c3c1e1..c153a1dc5ff7 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h @@ -181,6 +181,7 @@ enum xgene_enet_rm { #define ENET_LHD_MODE BIT(25) #define ENET_GHD_MODE BIT(26) #define FULL_DUPLEX2 BIT(0) +#define PAD_CRC BIT(2) #define SCAN_AUTO_INCR BIT(5) #define TBYT_ADDR 0x38 #define TPKT_ADDR 0x39 diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index ce1068771b32..991412ce6f48 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -698,7 +698,6 @@ static int xgene_enet_open(struct net_device *ndev) else schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF); - netif_carrier_off(ndev); netif_start_queue(ndev); return ret; diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 67a7d520d9f5..8550df189ceb 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -173,6 +173,7 @@ config SYSTEMPORT config BNXT tristate "Broadcom NetXtreme-C/E support" depends on PCI + depends on VXLAN || VXLAN=n select FW_LOADER select LIBCRC32C ---help--- diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 6c2e0c622831..db15c5ee09c5 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1292,8 +1292,6 @@ static inline int bnxt_has_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr) return TX_CMP_VALID(txcmp, raw_cons); } -#define CAG_LEGACY_INT_STATUS 0x2014 - static irqreturn_t bnxt_inta(int irq, void *dev_instance) { struct bnxt_napi *bnapi = dev_instance; @@ -1305,7 +1303,7 @@ static irqreturn_t bnxt_inta(int irq, void *dev_instance) prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]); if (!bnxt_has_work(bp, cpr)) { - int_status = readl(bp->bar0 + CAG_LEGACY_INT_STATUS); + int_status = readl(bp->bar0 + BNXT_CAG_REG_LEGACY_INT_STATUS); /* return if erroneous interrupt */ if (!(int_status & (0x10000 << cpr->cp_ring_struct.fw_ring_id))) return IRQ_NONE; @@ -4527,10 +4525,25 @@ static int bnxt_update_phy_setting(struct bnxt *bp) return rc; } +/* Common routine to pre-map certain register block to different GRC window. + * A PF has 16 4K windows and a VF has 4 4K windows. However, only 15 windows + * in PF and 3 windows in VF that can be customized to map in different + * register blocks. + */ +static void bnxt_preset_reg_win(struct bnxt *bp) +{ + if (BNXT_PF(bp)) { + /* CAG registers map to GRC window #4 */ + writel(BNXT_CAG_REG_BASE, + bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 12); + } +} + static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) { int rc = 0; + bnxt_preset_reg_win(bp); netif_carrier_off(bp->dev); if (irq_re_init) { rc = bnxt_setup_int_mode(bp); @@ -5294,7 +5307,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, struct bnxt_ntuple_filter *fltr, *new_fltr; struct flow_keys *fkeys; struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb); - int rc = 0, idx; + int rc = 0, idx, bit_id; struct hlist_head *head; if (skb->encapsulation) @@ -5332,14 +5345,15 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, rcu_read_unlock(); spin_lock_bh(&bp->ntp_fltr_lock); - new_fltr->sw_id = bitmap_find_free_region(bp->ntp_fltr_bmap, - BNXT_NTP_FLTR_MAX_FLTR, 0); - if (new_fltr->sw_id < 0) { + bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, + BNXT_NTP_FLTR_MAX_FLTR, 0); + if (bit_id < 0) { spin_unlock_bh(&bp->ntp_fltr_lock); rc = -ENOMEM; goto err_free; } + new_fltr->sw_id = (u16)bit_id; new_fltr->flow_id = flow_id; new_fltr->rxq = rxq_index; hlist_add_head_rcu(&new_fltr->hash, head); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 4f2267ca482d..674bc5159b91 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -166,9 +166,11 @@ struct rx_cmp { #define RX_CMP_HASH_VALID(rxcmp) \ ((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID)) +#define RSS_PROFILE_ID_MASK 0x1f + #define RX_CMP_HASH_TYPE(rxcmp) \ - ((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\ - RX_CMP_RSS_HASH_TYPE_SHIFT) + (((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\ + RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK) struct rx_cmp_ext { __le32 rx_cmp_flags2; @@ -282,9 +284,9 @@ struct rx_tpa_start_cmp { cpu_to_le32(RX_TPA_START_CMP_FLAGS_RSS_VALID)) #define TPA_START_HASH_TYPE(rx_tpa_start) \ - ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ - RX_TPA_START_CMP_RSS_HASH_TYPE) >> \ - RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) + (((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ + RX_TPA_START_CMP_RSS_HASH_TYPE) >> \ + RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK) #define TPA_START_AGG_ID(rx_tpa_start) \ ((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \ @@ -839,6 +841,10 @@ struct bnxt_queue_info { u8 queue_profile; }; +#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400 +#define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014 +#define BNXT_CAG_REG_BASE 0x300000 + struct bnxt { void __iomem *bar0; void __iomem *bar1; @@ -959,11 +965,11 @@ struct bnxt { #define BNXT_RX_MASK_SP_EVENT 0 #define BNXT_RX_NTP_FLTR_SP_EVENT 1 #define BNXT_LINK_CHNG_SP_EVENT 2 -#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 4 -#define BNXT_VXLAN_ADD_PORT_SP_EVENT 8 -#define BNXT_VXLAN_DEL_PORT_SP_EVENT 16 -#define BNXT_RESET_TASK_SP_EVENT 32 -#define BNXT_RST_RING_SP_EVENT 64 +#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 3 +#define BNXT_VXLAN_ADD_PORT_SP_EVENT 4 +#define BNXT_VXLAN_DEL_PORT_SP_EVENT 5 +#define BNXT_RESET_TASK_SP_EVENT 6 +#define BNXT_RST_RING_SP_EVENT 7 struct bnxt_pf_info pf; #ifdef CONFIG_BNXT_SRIOV diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 60989e7e266a..f4cf68861069 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -258,7 +258,7 @@ static int bnxt_set_vf_attr(struct bnxt *bp, int num_vfs) return 0; } -static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp) +static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp, int num_vfs) { int i, rc = 0; struct bnxt_pf_info *pf = &bp->pf; @@ -267,7 +267,7 @@ static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp) bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1); mutex_lock(&bp->hwrm_cmd_lock); - for (i = pf->first_vf_id; i < pf->first_vf_id + pf->active_vfs; i++) { + for (i = pf->first_vf_id; i < pf->first_vf_id + num_vfs; i++) { req.vf_id = cpu_to_le16(i); rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); @@ -509,7 +509,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs) err_out2: /* Free the resources reserved for various VF's */ - bnxt_hwrm_func_vf_resource_free(bp); + bnxt_hwrm_func_vf_resource_free(bp, *num_vfs); err_out1: bnxt_free_vf_resources(bp); @@ -519,13 +519,19 @@ err_out1: void bnxt_sriov_disable(struct bnxt *bp) { - if (!bp->pf.active_vfs) - return; + u16 num_vfs = pci_num_vf(bp->pdev); - pci_disable_sriov(bp->pdev); + if (!num_vfs) + return; - /* Free the resources reserved for various VF's */ - bnxt_hwrm_func_vf_resource_free(bp); + if (pci_vfs_assigned(bp->pdev)) { + netdev_warn(bp->dev, "Unable to free %d VFs because some are assigned to VMs.\n", + num_vfs); + } else { + pci_disable_sriov(bp->pdev); + /* Free the HW resources reserved for various VF's */ + bnxt_hwrm_func_vf_resource_free(bp, num_vfs); + } bnxt_free_vf_resources(bp); @@ -552,17 +558,25 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs) } bp->sriov_cfg = true; rtnl_unlock(); - if (!num_vfs) { - bnxt_sriov_disable(bp); - return 0; + + if (pci_vfs_assigned(bp->pdev)) { + netdev_warn(dev, "Unable to configure SRIOV since some VFs are assigned to VMs.\n"); + num_vfs = 0; + goto sriov_cfg_exit; } /* Check if enabled VFs is same as requested */ - if (num_vfs == bp->pf.active_vfs) - return 0; + if (num_vfs && num_vfs == bp->pf.active_vfs) + goto sriov_cfg_exit; + + /* if there are previous existing VFs, clean them up */ + bnxt_sriov_disable(bp); + if (!num_vfs) + goto sriov_cfg_exit; bnxt_sriov_enable(bp, &num_vfs); +sriov_cfg_exit: bp->sriov_cfg = false; wake_up(&bp->sriov_cfg_wait); diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig index f250dec488fd..74beb1867230 100644 --- a/drivers/net/ethernet/hisilicon/Kconfig +++ b/drivers/net/ethernet/hisilicon/Kconfig @@ -5,7 +5,8 @@ config NET_VENDOR_HISILICON bool "Hisilicon devices" default y - depends on OF && (ARM || ARM64 || COMPILE_TEST) + depends on OF && HAS_DMA + depends on ARM || ARM64 || COMPILE_TEST ---help--- If you have a network (Ethernet) card belonging to this class, say Y. diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index 80af9ffce5ea..a1c862b4664d 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig @@ -44,6 +44,7 @@ config MVNETA tristate "Marvell Armada 370/38x/XP network interface support" depends on PLAT_ORION select MVMDIO + select FIXED_PHY ---help--- This driver supports the network interface units in the Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family. diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index a47496a020d9..e84c7f2634d3 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1493,9 +1493,9 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp, struct mvneta_rx_desc *rx_desc = rxq->descs + i; void *data = (void *)rx_desc->buf_cookie; - mvneta_frag_free(pp, data); dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); + mvneta_frag_free(pp, data); } if (rx_done) diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig index 30a6f246dfc9..ddcfcab034c2 100644 --- a/drivers/net/ethernet/qlogic/Kconfig +++ b/drivers/net/ethernet/qlogic/Kconfig @@ -94,6 +94,7 @@ config NETXEN_NIC config QED tristate "QLogic QED 25/40/100Gb core driver" depends on PCI + select ZLIB_INFLATE ---help--- This enables the support for ... diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index b9b7b7e6fa53..803b190ccada 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -223,6 +223,7 @@ int qed_resc_alloc(struct qed_dev *cdev) if (!p_hwfn->p_tx_cids) { DP_NOTICE(p_hwfn, "Failed to allocate memory for Tx Cids\n"); + rc = -ENOMEM; goto alloc_err; } @@ -230,6 +231,7 @@ int qed_resc_alloc(struct qed_dev *cdev) if (!p_hwfn->p_rx_cids) { DP_NOTICE(p_hwfn, "Failed to allocate memory for Rx Cids\n"); + rc = -ENOMEM; goto alloc_err; } } @@ -281,14 +283,17 @@ int qed_resc_alloc(struct qed_dev *cdev) /* EQ */ p_eq = qed_eq_alloc(p_hwfn, 256); - - if (!p_eq) + if (!p_eq) { + rc = -ENOMEM; goto alloc_err; + } p_hwfn->p_eq = p_eq; p_consq = qed_consq_alloc(p_hwfn); - if (!p_consq) + if (!p_consq) { + rc = -ENOMEM; goto alloc_err; + } p_hwfn->p_consq = p_consq; /* DMA info initialization */ @@ -303,6 +308,7 @@ int qed_resc_alloc(struct qed_dev *cdev) cdev->reset_stats = kzalloc(sizeof(*cdev->reset_stats), GFP_KERNEL); if (!cdev->reset_stats) { DP_NOTICE(cdev, "Failed to allocate reset statistics\n"); + rc = -ENOMEM; goto alloc_err; } @@ -562,7 +568,7 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn, } /* Enable classification by MAC if needed */ - if (hw_mode & MODE_MF_SI) { + if (hw_mode & (1 << MODE_MF_SI)) { DP_VERBOSE(p_hwfn, NETIF_MSG_HW, "Configuring TAGMAC_CLS_TYPE\n"); STORE_RT_REG(p_hwfn, diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index 2e399b6137a2..de50e84902af 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c @@ -251,11 +251,6 @@ void qed_int_sp_dpc(unsigned long hwfn_cookie) int arr_size; u16 rc = 0; - if (!p_hwfn) { - DP_ERR(p_hwfn->cdev, "DPC called - no hwfn!\n"); - return; - } - if (!p_hwfn->p_sp_sb) { DP_ERR(p_hwfn->cdev, "DPC called - no p_sp_sb\n"); return; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index d4481454b5f8..1205f6f9c941 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -353,7 +353,8 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; - if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data)) + if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data) && + ether_addr_equal_unaligned(netdev->dev_addr, addr->sa_data)) return 0; if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 6150a235b72c..e7bab7909ed9 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1098,7 +1098,7 @@ static struct mdiobb_ops bb_ops = { static void sh_eth_ring_free(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - int i; + int ringsize, i; /* Free Rx skb ringbuffer */ if (mdp->rx_skbuff) { @@ -1115,6 +1115,20 @@ static void sh_eth_ring_free(struct net_device *ndev) } kfree(mdp->tx_skbuff); mdp->tx_skbuff = NULL; + + if (mdp->rx_ring) { + ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; + dma_free_coherent(NULL, ringsize, mdp->rx_ring, + mdp->rx_desc_dma); + mdp->rx_ring = NULL; + } + + if (mdp->tx_ring) { + ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; + dma_free_coherent(NULL, ringsize, mdp->tx_ring, + mdp->tx_desc_dma); + mdp->tx_ring = NULL; + } } /* format skb and descriptor buffer */ @@ -1199,7 +1213,7 @@ static void sh_eth_ring_format(struct net_device *ndev) static int sh_eth_ring_init(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - int rx_ringsize, tx_ringsize, ret = 0; + int rx_ringsize, tx_ringsize; /* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the * card needs room to do 8 byte alignment, +2 so we can reserve @@ -1214,26 +1228,20 @@ static int sh_eth_ring_init(struct net_device *ndev) /* Allocate RX and TX skb rings */ mdp->rx_skbuff = kcalloc(mdp->num_rx_ring, sizeof(*mdp->rx_skbuff), GFP_KERNEL); - if (!mdp->rx_skbuff) { - ret = -ENOMEM; - return ret; - } + if (!mdp->rx_skbuff) + return -ENOMEM; mdp->tx_skbuff = kcalloc(mdp->num_tx_ring, sizeof(*mdp->tx_skbuff), GFP_KERNEL); - if (!mdp->tx_skbuff) { - ret = -ENOMEM; - goto skb_ring_free; - } + if (!mdp->tx_skbuff) + goto ring_free; /* Allocate all Rx descriptors. */ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, GFP_KERNEL); - if (!mdp->rx_ring) { - ret = -ENOMEM; - goto skb_ring_free; - } + if (!mdp->rx_ring) + goto ring_free; mdp->dirty_rx = 0; @@ -1241,42 +1249,15 @@ static int sh_eth_ring_init(struct net_device *ndev) tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, GFP_KERNEL); - if (!mdp->tx_ring) { - ret = -ENOMEM; - goto desc_ring_free; - } - return ret; - -desc_ring_free: - /* free DMA buffer */ - dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma); + if (!mdp->tx_ring) + goto ring_free; + return 0; -skb_ring_free: - /* Free Rx and Tx skb ring buffer */ +ring_free: + /* Free Rx and Tx skb ring buffer and DMA buffer */ sh_eth_ring_free(ndev); - mdp->tx_ring = NULL; - mdp->rx_ring = NULL; - - return ret; -} - -static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp) -{ - int ringsize; - - if (mdp->rx_ring) { - ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; - dma_free_coherent(NULL, ringsize, mdp->rx_ring, - mdp->rx_desc_dma); - mdp->rx_ring = NULL; - } - if (mdp->tx_ring) { - ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; - dma_free_coherent(NULL, ringsize, mdp->tx_ring, - mdp->tx_desc_dma); - mdp->tx_ring = NULL; - } + return -ENOMEM; } static int sh_eth_dev_init(struct net_device *ndev, bool start) @@ -2239,10 +2220,8 @@ static int sh_eth_set_ringparam(struct net_device *ndev, sh_eth_dev_exit(ndev); - /* Free all the skbuffs in the Rx queue. */ + /* Free all the skbuffs in the Rx queue and the DMA buffers. */ sh_eth_ring_free(ndev); - /* Free DMA buffer */ - sh_eth_free_dma_buffer(mdp); } /* Set new parameters */ @@ -2487,12 +2466,9 @@ static int sh_eth_close(struct net_device *ndev) free_irq(ndev->irq, ndev); - /* Free all the skbuffs in the Rx queue. */ + /* Free all the skbuffs in the Rx queue and the DMA buffer. */ sh_eth_ring_free(ndev); - /* free DMA buffer */ - sh_eth_free_dma_buffer(mdp); - pm_runtime_put_sync(&mdp->pdev->dev); mdp->is_opened = 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 11baa4b19779..0cd3ecff768b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -354,7 +354,7 @@ static int gmac_clk_init(struct rk_priv_data *bsp_priv) static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) { - int phy_iface = phy_iface = bsp_priv->phy_iface; + int phy_iface = bsp_priv->phy_iface; if (enable) { if (!bsp_priv->clk_enabled) { diff --git a/drivers/net/ethernet/synopsys/dwc_eth_qos.c b/drivers/net/ethernet/synopsys/dwc_eth_qos.c index 85b3326775b8..9066d7a8483c 100644 --- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c +++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c @@ -2970,8 +2970,7 @@ err_out_unregister_netdev: err_out_clk_dis_aper: clk_disable_unprepare(lp->apb_pclk); err_out_free_netdev: - if (lp->phy_node) - of_node_put(lp->phy_node); + of_node_put(lp->phy_node); free_netdev(ndev); platform_set_drvdata(pdev, NULL); return ret; diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 040fbc1e5508..48b92c9de12a 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -2037,6 +2037,19 @@ static int cpsw_probe_dt(struct cpsw_priv *priv, continue; priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0); + if (of_phy_is_fixed_link(slave_node)) { + struct phy_device *pd; + + ret = of_phy_register_fixed_link(slave_node); + if (ret) + return ret; + pd = of_phy_find_device(slave_node); + if (!pd) + return -ENODEV; + snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), + PHY_ID_FMT, pd->bus->id, pd->phy_id); + goto no_phy_slave; + } parp = of_get_property(slave_node, "phy_id", &lenp); if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i); diff --git a/drivers/net/fjes/fjes_hw.c b/drivers/net/fjes/fjes_hw.c index 2d3848c9dc35..bb8b5304d851 100644 --- a/drivers/net/fjes/fjes_hw.c +++ b/drivers/net/fjes/fjes_hw.c @@ -143,9 +143,7 @@ static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh) static void fjes_hw_free_epbuf(struct epbuf_handler *epbh) { - if (epbh->buffer) - vfree(epbh->buffer); - + vfree(epbh->buffer); epbh->buffer = NULL; epbh->size = 0; diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 197c93937c2d..54036ae0a388 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -935,6 +935,9 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, /* Nothing to read, let's sleep */ schedule(); } + if (!noblock) + finish_wait(sk_sleep(&q->sk), &wait); + if (skb) { ret = macvtap_put_user(q, skb, to); if (unlikely(ret < 0)) @@ -942,8 +945,6 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, else consume_skb(skb); } - if (!noblock) - finish_wait(sk_sleep(&q->sk), &wait); return ret; } diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c54719984c4b..34799eaace41 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -771,6 +771,7 @@ static const struct usb_device_id products[] = { {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ {QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ + {QMI_FIXED_INTF(0x05c6, 0x9215, 4)}, /* Quectel EC20 Mini PCIe */ {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ @@ -802,10 +803,24 @@ static const struct usb_device_id products[] = { }; MODULE_DEVICE_TABLE(usb, products); +static bool quectel_ec20_detected(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + + if (dev->actconfig && + le16_to_cpu(dev->descriptor.idVendor) == 0x05c6 && + le16_to_cpu(dev->descriptor.idProduct) == 0x9215 && + dev->actconfig->desc.bNumInterfaces == 5) + return true; + + return false; +} + static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id *prod) { struct usb_device_id *id = (struct usb_device_id *)prod; + struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; /* Workaround to enable dynamic IDs. This disables usbnet * blacklisting functionality. Which, if required, can be @@ -817,6 +832,12 @@ static int qmi_wwan_probe(struct usb_interface *intf, id->driver_info = (unsigned long)&qmi_wwan_info; } + /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ + if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { + dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); + return -ENODEV; + } + return usbnet_probe(intf, id); } |