diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Kconfig | 8 | ||||
-rw-r--r-- | drivers/net/bfin_mac.c | 145 | ||||
-rw-r--r-- | drivers/net/bfin_mac.h | 2 | ||||
-rw-r--r-- | drivers/net/mlx4/en_main.c | 15 | ||||
-rw-r--r-- | drivers/net/mlx4/en_netdev.c | 10 | ||||
-rw-r--r-- | drivers/net/mlx4/en_port.c | 4 | ||||
-rw-r--r-- | drivers/net/mlx4/en_port.h | 3 | ||||
-rw-r--r-- | drivers/net/mlx4/fw.c | 3 | ||||
-rw-r--r-- | drivers/net/mlx4/intf.c | 21 | ||||
-rw-r--r-- | drivers/net/mlx4/main.c | 4 | ||||
-rw-r--r-- | drivers/net/mlx4/mlx4_en.h | 1 | ||||
-rw-r--r-- | drivers/net/mlx4/port.c | 19 | ||||
-rw-r--r-- | drivers/net/xilinx_emaclite.c | 8 |
13 files changed, 171 insertions, 72 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 702f598..86fe67f 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -883,14 +883,6 @@ config BFIN_RX_DESC_NUM help Set the number of buffer packets used in driver. -config BFIN_MAC_RMII - bool "RMII PHY Interface" - depends on BFIN_MAC - default y if BFIN527_EZKIT - default n if BFIN537_STAMP - help - Use Reduced PHY MII Interface - config BFIN_MAC_USE_HWSTAMP bool "Use IEEE 1588 hwstamp" depends on BFIN_MAC && BF518 diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index f723319..ce1e5e9 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -1,7 +1,7 @@ /* * Blackfin On-Chip MAC Driver * - * Copyright 2004-2007 Analog Devices Inc. + * Copyright 2004-2010 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ * @@ -23,7 +23,6 @@ #include <linux/device.h> #include <linux/spinlock.h> #include <linux/mii.h> -#include <linux/phy.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -76,12 +75,6 @@ static struct net_dma_desc_tx *current_tx_ptr; static struct net_dma_desc_tx *tx_desc; static struct net_dma_desc_rx *rx_desc; -#if defined(CONFIG_BFIN_MAC_RMII) -static u16 pin_req[] = P_RMII0; -#else -static u16 pin_req[] = P_MII0; -#endif - static void desc_list_free(void) { struct net_dma_desc_rx *r; @@ -347,23 +340,23 @@ static void bfin_mac_adjust_link(struct net_device *dev) } if (phydev->speed != lp->old_speed) { -#if defined(CONFIG_BFIN_MAC_RMII) - u32 opmode = bfin_read_EMAC_OPMODE(); - switch (phydev->speed) { - case 10: - opmode |= RMII_10; - break; - case 100: - opmode &= ~(RMII_10); - break; - default: - printk(KERN_WARNING - "%s: Ack! Speed (%d) is not 10/100!\n", - DRV_NAME, phydev->speed); - break; + if (phydev->interface == PHY_INTERFACE_MODE_RMII) { + u32 opmode = bfin_read_EMAC_OPMODE(); + switch (phydev->speed) { + case 10: + opmode |= RMII_10; + break; + case 100: + opmode &= ~RMII_10; + break; + default: + printk(KERN_WARNING + "%s: Ack! Speed (%d) is not 10/100!\n", + DRV_NAME, phydev->speed); + break; + } + bfin_write_EMAC_OPMODE(opmode); } - bfin_write_EMAC_OPMODE(opmode); -#endif new_state = 1; lp->old_speed = phydev->speed; @@ -392,7 +385,7 @@ static void bfin_mac_adjust_link(struct net_device *dev) /* MDC = 2.5 MHz */ #define MDC_CLK 2500000 -static int mii_probe(struct net_device *dev) +static int mii_probe(struct net_device *dev, int phy_mode) { struct bfin_mac_local *lp = netdev_priv(dev); struct phy_device *phydev = NULL; @@ -411,8 +404,8 @@ static int mii_probe(struct net_device *dev) sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div); bfin_write_EMAC_SYSCTL(sysctl); - /* search for connect PHY device */ - for (i = 0; i < PHY_MAX_ADDR; i++) { + /* search for connected PHY device */ + for (i = 0; i < PHY_MAX_ADDR; ++i) { struct phy_device *const tmp_phydev = lp->mii_bus->phy_map[i]; if (!tmp_phydev) @@ -429,13 +422,14 @@ static int mii_probe(struct net_device *dev) return -ENODEV; } -#if defined(CONFIG_BFIN_MAC_RMII) - phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link, - 0, PHY_INTERFACE_MODE_RMII); -#else + if (phy_mode != PHY_INTERFACE_MODE_RMII && + phy_mode != PHY_INTERFACE_MODE_MII) { + printk(KERN_INFO "%s: Invalid phy interface mode\n", dev->name); + return -EINVAL; + } + phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link, - 0, PHY_INTERFACE_MODE_MII); -#endif + 0, phy_mode); if (IS_ERR(phydev)) { printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); @@ -570,6 +564,8 @@ static const struct ethtool_ops bfin_mac_ethtool_ops = { /**************************************************************************/ void setup_system_regs(struct net_device *dev) { + struct bfin_mac_local *lp = netdev_priv(dev); + int i; unsigned short sysctl; /* @@ -577,6 +573,15 @@ void setup_system_regs(struct net_device *dev) * Configure checksum support and rcve frame word alignment */ sysctl = bfin_read_EMAC_SYSCTL(); + /* + * check if interrupt is requested for any PHY, + * enable PHY interrupt only if needed + */ + for (i = 0; i < PHY_MAX_ADDR; ++i) + if (lp->mii_bus->irq[i] != PHY_POLL) + break; + if (i < PHY_MAX_ADDR) + sysctl |= PHYIE; sysctl |= RXDWA; #if defined(BFIN_MAC_CSUM_OFFLOAD) sysctl |= RXCKS; @@ -1203,7 +1208,7 @@ static void bfin_mac_disable(void) /* * Enable Interrupts, Receive, and Transmit */ -static int bfin_mac_enable(void) +static int bfin_mac_enable(struct phy_device *phydev) { int ret; u32 opmode; @@ -1233,12 +1238,13 @@ static int bfin_mac_enable(void) opmode |= DRO | DC | PSF; opmode |= RE; -#if defined(CONFIG_BFIN_MAC_RMII) - opmode |= RMII; /* For Now only 100MBit are supported */ + if (phydev->interface == PHY_INTERFACE_MODE_RMII) { + opmode |= RMII; /* For Now only 100MBit are supported */ #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2 - opmode |= TE; -#endif + opmode |= TE; #endif + } + /* Turn on the EMAC rx */ bfin_write_EMAC_OPMODE(opmode); @@ -1270,7 +1276,7 @@ static void bfin_mac_timeout(struct net_device *dev) if (netif_queue_stopped(lp->ndev)) netif_wake_queue(lp->ndev); - bfin_mac_enable(); + bfin_mac_enable(lp->phydev); /* We can accept TX packets again */ dev->trans_start = jiffies; /* prevent tx timeout */ @@ -1342,11 +1348,19 @@ static void bfin_mac_set_multicast_list(struct net_device *dev) static int bfin_mac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { + struct bfin_mac_local *lp = netdev_priv(netdev); + + if (!netif_running(netdev)) + return -EINVAL; + switch (cmd) { case SIOCSHWTSTAMP: return bfin_mac_hwtstamp_ioctl(netdev, ifr, cmd); default: - return -EOPNOTSUPP; + if (lp->phydev) + return phy_mii_ioctl(lp->phydev, ifr, cmd); + else + return -EOPNOTSUPP; } } @@ -1394,7 +1408,7 @@ static int bfin_mac_open(struct net_device *dev) setup_mac_addr(dev->dev_addr); bfin_mac_disable(); - ret = bfin_mac_enable(); + ret = bfin_mac_enable(lp->phydev); if (ret) return ret; pr_debug("hardware init finished\n"); @@ -1450,6 +1464,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) struct net_device *ndev; struct bfin_mac_local *lp; struct platform_device *pd; + struct bfin_mii_bus_platform_data *mii_bus_data; int rc; ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); @@ -1501,11 +1516,12 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) if (!lp->mii_bus) { dev_err(&pdev->dev, "Cannot get mii_bus!\n"); rc = -ENODEV; - goto out_err_mii_bus_probe; + goto out_err_probe_mac; } lp->mii_bus->priv = ndev; + mii_bus_data = pd->dev.platform_data; - rc = mii_probe(ndev); + rc = mii_probe(ndev, mii_bus_data->phy_mode); if (rc) { dev_err(&pdev->dev, "MII Probe failed!\n"); goto out_err_mii_probe; @@ -1552,8 +1568,6 @@ out_err_request_irq: out_err_mii_probe: mdiobus_unregister(lp->mii_bus); mdiobus_free(lp->mii_bus); -out_err_mii_bus_probe: - peripheral_free_list(pin_req); out_err_probe_mac: platform_set_drvdata(pdev, NULL); free_netdev(ndev); @@ -1576,8 +1590,6 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev) free_netdev(ndev); - peripheral_free_list(pin_req); - return 0; } @@ -1623,12 +1635,21 @@ static int bfin_mac_resume(struct platform_device *pdev) static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) { struct mii_bus *miibus; + struct bfin_mii_bus_platform_data *mii_bus_pd; + const unsigned short *pin_req; int rc, i; + mii_bus_pd = dev_get_platdata(&pdev->dev); + if (!mii_bus_pd) { + dev_err(&pdev->dev, "No peripherals in platform data!\n"); + return -EINVAL; + } + /* * We are setting up a network card, * so set the GPIO pins to Ethernet mode */ + pin_req = mii_bus_pd->mac_peripherals; rc = peripheral_request_list(pin_req, DRV_NAME); if (rc) { dev_err(&pdev->dev, "Requesting peripherals failed!\n"); @@ -1645,13 +1666,30 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) miibus->parent = &pdev->dev; miibus->name = "bfin_mii_bus"; + miibus->phy_mask = mii_bus_pd->phy_mask; + snprintf(miibus->id, MII_BUS_ID_SIZE, "0"); miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); - if (miibus->irq == NULL) - goto out_err_alloc; - for (i = 0; i < PHY_MAX_ADDR; ++i) + if (!miibus->irq) + goto out_err_irq_alloc; + + for (i = rc; i < PHY_MAX_ADDR; ++i) miibus->irq[i] = PHY_POLL; + rc = clamp(mii_bus_pd->phydev_number, 0, PHY_MAX_ADDR); + if (rc != mii_bus_pd->phydev_number) + dev_err(&pdev->dev, "Invalid number (%i) of phydevs\n", + mii_bus_pd->phydev_number); + for (i = 0; i < rc; ++i) { + unsigned short phyaddr = mii_bus_pd->phydev_data[i].addr; + if (phyaddr < PHY_MAX_ADDR) + miibus->irq[phyaddr] = mii_bus_pd->phydev_data[i].irq; + else + dev_err(&pdev->dev, + "Invalid PHY address %i for phydev %i\n", + phyaddr, i); + } + rc = mdiobus_register(miibus); if (rc) { dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); @@ -1663,6 +1701,7 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) out_err_mdiobus_register: kfree(miibus->irq); +out_err_irq_alloc: mdiobus_free(miibus); out_err_alloc: peripheral_free_list(pin_req); @@ -1673,11 +1712,15 @@ out_err_alloc: static int __devexit bfin_mii_bus_remove(struct platform_device *pdev) { struct mii_bus *miibus = platform_get_drvdata(pdev); + struct bfin_mii_bus_platform_data *mii_bus_pd = + dev_get_platdata(&pdev->dev); + platform_set_drvdata(pdev, NULL); mdiobus_unregister(miibus); kfree(miibus->irq); mdiobus_free(miibus); - peripheral_free_list(pin_req); + peripheral_free_list(mii_bus_pd->mac_peripherals); + return 0; } diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h index 04e4050..aed68be 100644 --- a/drivers/net/bfin_mac.h +++ b/drivers/net/bfin_mac.h @@ -14,6 +14,8 @@ #include <linux/clocksource.h> #include <linux/timecompare.h> #include <linux/timer.h> +#include <linux/etherdevice.h> +#include <linux/bfin_mac.h> #define BFIN_MAC_CSUM_OFFLOAD diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index 1439064..f6e0d40 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c @@ -124,6 +124,13 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) return 0; } +static void *mlx4_en_get_netdev(struct mlx4_dev *dev, void *ctx, u8 port) +{ + struct mlx4_en_dev *endev = ctx; + + return endev->pndev[port]; +} + static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr, enum mlx4_dev_event event, int port) { @@ -282,9 +289,11 @@ err_free_res: } static struct mlx4_interface mlx4_en_interface = { - .add = mlx4_en_add, - .remove = mlx4_en_remove, - .event = mlx4_en_event, + .add = mlx4_en_add, + .remove = mlx4_en_remove, + .event = mlx4_en_event, + .get_dev = mlx4_en_get_netdev, + .protocol = MLX4_PROTOCOL_EN, }; static int __init mlx4_en_init(void) diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 79478bd..6d6806b 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -69,6 +69,7 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; int err; + int idx; if (!priv->vlgrp) return; @@ -83,7 +84,10 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) if (err) en_err(priv, "Failed configuring VLAN filter\n"); } + if (mlx4_register_vlan(mdev->dev, priv->port, vid, &idx)) + en_err(priv, "failed adding vlan %d\n", vid); mutex_unlock(&mdev->state_lock); + } static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) @@ -91,6 +95,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; int err; + int idx; if (!priv->vlgrp) return; @@ -101,6 +106,11 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) /* Remove VID from port VLAN filter */ mutex_lock(&mdev->state_lock); + if (!mlx4_find_cached_vlan(mdev->dev, priv->port, vid, &idx)) + mlx4_unregister_vlan(mdev->dev, priv->port, idx); + else + en_err(priv, "could not find vid %d in cache\n", vid); + if (mdev->device_up && priv->port_up) { err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); if (err) diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index aa3ef2a..7f5a322 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c @@ -127,8 +127,8 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, memset(context, 0, sizeof *context); context->base_qpn = cpu_to_be32(base_qpn); - context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT | base_qpn); - context->mcast = cpu_to_be32(1 << SET_PORT_PROMISC_SHIFT | base_qpn); + context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_EN_SHIFT | base_qpn); + context->mcast = cpu_to_be32(1 << SET_PORT_PROMISC_MODE_SHIFT | base_qpn); context->intra_no_vlan = 0; context->no_vlan = MLX4_NO_VLAN_IDX; context->intra_vlan_miss = 0; diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h index f6511aa..092e814 100644 --- a/drivers/net/mlx4/en_port.h +++ b/drivers/net/mlx4/en_port.h @@ -36,7 +36,8 @@ #define SET_PORT_GEN_ALL_VALID 0x7 -#define SET_PORT_PROMISC_SHIFT 31 +#define SET_PORT_PROMISC_EN_SHIFT 31 +#define SET_PORT_PROMISC_MODE_SHIFT 30 enum { MLX4_CMD_SET_VLAN_FLTR = 0x47, diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index b716e1a..b68eee2 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -98,7 +98,8 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags) [20] = "Address vector port checking support", [21] = "UD multicast support", [24] = "Demand paging support", - [25] = "Router support" + [25] = "Router support", + [30] = "IBoE support" }; int i; diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c index 5550678..73c94fc 100644 --- a/drivers/net/mlx4/intf.c +++ b/drivers/net/mlx4/intf.c @@ -161,3 +161,24 @@ void mlx4_unregister_device(struct mlx4_dev *dev) mutex_unlock(&intf_mutex); } + +void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + struct mlx4_device_context *dev_ctx; + unsigned long flags; + void *result = NULL; + + spin_lock_irqsave(&priv->ctx_lock, flags); + + list_for_each_entry(dev_ctx, &priv->ctx_list, list) + if (dev_ctx->intf->protocol == proto && dev_ctx->intf->get_dev) { + result = dev_ctx->intf->get_dev(dev, dev_ctx->context, port); + break; + } + + spin_unlock_irqrestore(&priv->ctx_lock, flags); + + return result; +} +EXPORT_SYMBOL_GPL(mlx4_get_protocol_dev); diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 569fa3d..782f11d 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -103,7 +103,7 @@ MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports " static int log_mtts_per_seg = ilog2(MLX4_MTT_ENTRY_PER_SEG); module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444); -MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-5)"); +MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-7)"); int mlx4_check_port_params(struct mlx4_dev *dev, enum mlx4_port_type *port_type) @@ -1310,7 +1310,7 @@ static int __init mlx4_verify_params(void) return -1; } - if ((log_mtts_per_seg < 1) || (log_mtts_per_seg > 5)) { + if ((log_mtts_per_seg < 1) || (log_mtts_per_seg > 7)) { pr_warning("mlx4_core: bad log_mtts_per_seg: %d\n", log_mtts_per_seg); return -1; } diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 1fc16ab..dfed6a0 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -475,6 +475,7 @@ struct mlx4_en_priv { char *mc_addrs; int mc_addrs_cnt; struct mlx4_en_stat_out_mbox hw_stats; + int vids[128]; }; diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c index 606aa58..56371ef 100644 --- a/drivers/net/mlx4/port.c +++ b/drivers/net/mlx4/port.c @@ -182,6 +182,25 @@ static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port, return err; } +int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx) +{ + struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; + int i; + + for (i = 0; i < MLX4_MAX_VLAN_NUM; ++i) { + if (table->refs[i] && + (vid == (MLX4_VLAN_MASK & + be32_to_cpu(table->entries[i])))) { + /* VLAN already registered, increase reference count */ + *idx = i; + return 0; + } + } + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan); + int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index) { struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index f3f8be5..14f0955 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -430,8 +430,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) } /* Get the protocol type of the ethernet frame that arrived */ - proto_type = ((in_be32(addr + XEL_HEADER_OFFSET + - XEL_RXBUFF_OFFSET) >> XEL_HEADER_SHIFT) & + proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET + + XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & XEL_RPLR_LENGTH_MASK); /* Check if received ethernet frame is a raw ethernet frame @@ -439,9 +439,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) { if (proto_type == ETH_P_IP) { - length = ((in_be32(addr + + length = ((ntohl(in_be32(addr + XEL_HEADER_IP_LENGTH_OFFSET + - XEL_RXBUFF_OFFSET) >> + XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & XEL_RPLR_LENGTH_MASK); length += ETH_HLEN + ETH_FCS_LEN; |