diff options
Diffstat (limited to 'drivers/net/ethernet/samsung')
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h | 42 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 81 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h | 5 |
9 files changed, 108 insertions, 84 deletions
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h index 6203c7d8550f..45019649bbbd 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h @@ -358,6 +358,8 @@ struct sxgbe_core_ops { /* Enable disable checksum offload operations */ void (*enable_rx_csum)(void __iomem *ioaddr); void (*disable_rx_csum)(void __iomem *ioaddr); + void (*enable_rxqueue)(void __iomem *ioaddr, int queue_num); + void (*disable_rxqueue)(void __iomem *ioaddr, int queue_num); }; const struct sxgbe_core_ops *sxgbe_get_core_ops(void); diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c index c4da7a2b002a..58c35692560e 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c @@ -165,6 +165,26 @@ static void sxgbe_core_set_speed(void __iomem *ioaddr, unsigned char speed) writel(tx_cfg, ioaddr + SXGBE_CORE_TX_CONFIG_REG); } +static void sxgbe_core_enable_rxqueue(void __iomem *ioaddr, int queue_num) +{ + u32 reg_val; + + reg_val = readl(ioaddr + SXGBE_CORE_RX_CTL0_REG); + reg_val &= ~(SXGBE_CORE_RXQ_ENABLE_MASK << queue_num); + reg_val |= SXGBE_CORE_RXQ_ENABLE; + writel(reg_val, ioaddr + SXGBE_CORE_RX_CTL0_REG); +} + +static void sxgbe_core_disable_rxqueue(void __iomem *ioaddr, int queue_num) +{ + u32 reg_val; + + reg_val = readl(ioaddr + SXGBE_CORE_RX_CTL0_REG); + reg_val &= ~(SXGBE_CORE_RXQ_ENABLE_MASK << queue_num); + reg_val |= SXGBE_CORE_RXQ_DISABLE; + writel(reg_val, ioaddr + SXGBE_CORE_RX_CTL0_REG); +} + static void sxgbe_set_eee_mode(void __iomem *ioaddr) { u32 ctrl; @@ -254,6 +274,8 @@ static const struct sxgbe_core_ops core_ops = { .set_eee_pls = sxgbe_set_eee_pls, .enable_rx_csum = sxgbe_enable_rx_csum, .disable_rx_csum = sxgbe_disable_rx_csum, + .enable_rxqueue = sxgbe_core_enable_rxqueue, + .disable_rxqueue = sxgbe_core_disable_rxqueue, }; const struct sxgbe_core_ops *sxgbe_get_core_ops(void) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c index e896dbbd2e15..2686bb5b6765 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c @@ -45,10 +45,10 @@ static void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd, p->tdes23.tx_rd_des23.first_desc = is_fd; p->tdes23.tx_rd_des23.buf1_size = buf1_len; - p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.total_pkt_len = pkt_len; + p->tdes23.tx_rd_des23.tx_pkt_len.pkt_len.total_pkt_len = pkt_len; if (cksum) - p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.cksum_ctl = cic_full; + p->tdes23.tx_rd_des23.cksum_ctl = cic_full; } /* Set VLAN control information */ @@ -233,6 +233,12 @@ static void sxgbe_set_rx_owner(struct sxgbe_rx_norm_desc *p) p->rdes23.rx_rd_des23.own_bit = 1; } +/* Set Interrupt on completion bit */ +static void sxgbe_set_rx_int_on_com(struct sxgbe_rx_norm_desc *p) +{ + p->rdes23.rx_rd_des23.int_on_com = 1; +} + /* Get the receive frame size */ static int sxgbe_get_rx_frame_len(struct sxgbe_rx_norm_desc *p) { @@ -498,6 +504,7 @@ static const struct sxgbe_desc_ops desc_ops = { .init_rx_desc = sxgbe_init_rx_desc, .get_rx_owner = sxgbe_get_rx_owner, .set_rx_owner = sxgbe_set_rx_owner, + .set_rx_int_on_com = sxgbe_set_rx_int_on_com, .get_rx_frame_len = sxgbe_get_rx_frame_len, .get_rx_fd_status = sxgbe_get_rx_fd_status, .get_rx_ld_status = sxgbe_get_rx_ld_status, diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h index 838cb9fb0ea9..18609324db72 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h @@ -39,22 +39,22 @@ struct sxgbe_tx_norm_desc { u32 int_on_com:1; /* TDES3 */ union { - u32 tcp_payload_len:18; + u16 tcp_payload_len; struct { u32 total_pkt_len:15; u32 reserved1:1; - u32 cksum_ctl:2; - } cksum_pktlen; + } pkt_len; } tx_pkt_len; - u32 tse_bit:1; - u32 tcp_hdr_len:4; - u32 sa_insert_ctl:3; - u32 crc_pad_ctl:2; - u32 last_desc:1; - u32 first_desc:1; - u32 ctxt_bit:1; - u32 own_bit:1; + u16 cksum_ctl:2; + u16 tse_bit:1; + u16 tcp_hdr_len:4; + u16 sa_insert_ctl:3; + u16 crc_pad_ctl:2; + u16 last_desc:1; + u16 first_desc:1; + u16 ctxt_bit:1; + u16 own_bit:1; } tx_rd_des23; /* tx write back Desc 2,3 */ @@ -70,25 +70,20 @@ struct sxgbe_tx_norm_desc { struct sxgbe_rx_norm_desc { union { - u32 rdes0; /* buf1 address */ - struct { + u64 rdes01; /* buf1 address */ + union { u32 out_vlan_tag:16; u32 in_vlan_tag:16; - } wb_rx_des0; - } rd_wb_des0; - - union { - u32 rdes1; /* buf2 address or buf1[63:32] */ - u32 rss_hash; /* Write-back RX */ - } rd_wb_des1; + u32 rss_hash; + } rx_wb_des01; + } rdes01; union { /* RX Read format Desc 2,3 */ struct{ /* RDES2 */ - u32 buf2_addr; + u64 buf2_addr:62; /* RDES3 */ - u32 buf2_hi_addr:30; u32 int_on_com:1; u32 own_bit:1; } rx_rd_des23; @@ -263,6 +258,9 @@ struct sxgbe_desc_ops { /* Set own bit */ void (*set_rx_owner)(struct sxgbe_rx_norm_desc *p); + /* Set Interrupt on completion bit */ + void (*set_rx_int_on_com)(struct sxgbe_rx_norm_desc *p); + /* Get the receive frame size */ int (*get_rx_frame_len)(struct sxgbe_rx_norm_desc *p); diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c index 4d989ff6c978..bb9b5b8afc5f 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c @@ -23,21 +23,8 @@ /* DMA core initialization */ static int sxgbe_dma_init(void __iomem *ioaddr, int fix_burst, int burst_map) { - int retry_count = 10; u32 reg_val; - /* reset the DMA */ - writel(SXGBE_DMA_SOFT_RESET, ioaddr + SXGBE_DMA_MODE_REG); - while (retry_count--) { - if (!(readl(ioaddr + SXGBE_DMA_MODE_REG) & - SXGBE_DMA_SOFT_RESET)) - break; - mdelay(10); - } - - if (retry_count < 0) - return -EBUSY; - reg_val = readl(ioaddr + SXGBE_DMA_SYSBUS_MODE_REG); /* if fix_burst = 0, Set UNDEF = 1 of DMA_Sys_Mode Register. diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c index 0415fa50eeb7..c0981ae45874 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c @@ -520,5 +520,5 @@ static const struct ethtool_ops sxgbe_ethtool_ops = { void sxgbe_set_ethtool_ops(struct net_device *netdev) { - SET_ETHTOOL_OPS(netdev, &sxgbe_ethtool_ops); + netdev->ethtool_ops = &sxgbe_ethtool_ops; } diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 27e8c824b204..698494481d18 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -425,8 +425,8 @@ dmamem_err: * @rx_rsize: ring size * Description: this function initializes the DMA RX descriptor */ -void free_rx_ring(struct device *dev, struct sxgbe_rx_queue *rx_ring, - int rx_rsize) +static void free_rx_ring(struct device *dev, struct sxgbe_rx_queue *rx_ring, + int rx_rsize) { dma_free_coherent(dev, rx_rsize * sizeof(struct sxgbe_rx_norm_desc), rx_ring->dma_rx, rx_ring->dma_rx_phy); @@ -519,8 +519,8 @@ error: * @tx_rsize: ring size * Description: this function initializes the DMA TX descriptor */ -void free_tx_ring(struct device *dev, struct sxgbe_tx_queue *tx_ring, - int tx_rsize) +static void free_tx_ring(struct device *dev, struct sxgbe_tx_queue *tx_ring, + int tx_rsize) { dma_free_coherent(dev, tx_rsize * sizeof(struct sxgbe_tx_norm_desc), tx_ring->dma_tx, tx_ring->dma_tx_phy); @@ -1076,6 +1076,9 @@ static int sxgbe_open(struct net_device *dev) /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->ioaddr); + SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) { + priv->hw->mac->enable_rxqueue(priv->ioaddr, queue_num); + } /* Request the IRQ lines */ ret = devm_request_irq(priv->device, priv->irq, sxgbe_common_interrupt, @@ -1218,11 +1221,10 @@ static int sxgbe_release(struct net_device *dev) return 0; } - /* Prepare first Tx descriptor for doing TSO operation */ -void sxgbe_tso_prepare(struct sxgbe_priv_data *priv, - struct sxgbe_tx_norm_desc *first_desc, - struct sk_buff *skb) +static void sxgbe_tso_prepare(struct sxgbe_priv_data *priv, + struct sxgbe_tx_norm_desc *first_desc, + struct sk_buff *skb) { unsigned int total_hdr_len, tcp_hdr_len; @@ -1453,6 +1455,7 @@ static void sxgbe_rx_refill(struct sxgbe_priv_data *priv) /* Added memory barrier for RX descriptor modification */ wmb(); priv->hw->desc->set_rx_owner(p); + priv->hw->desc->set_rx_int_on_com(p); /* Added memory barrier for RX descriptor modification */ wmb(); } @@ -1910,40 +1913,6 @@ static void sxgbe_set_rx_mode(struct net_device *dev) readl(ioaddr + SXGBE_HASH_LOW)); } -/** - * sxgbe_config - entry point for changing configuration mode passed on by - * ifconfig - * @dev : pointer to the device structure - * @map : pointer to the device mapping structure - * Description: - * This function is a driver entry point which gets called by the kernel - * whenever some device configuration is changed. - * Return value: - * This function returns 0 if success and appropriate error otherwise. - */ -static int sxgbe_config(struct net_device *dev, struct ifmap *map) -{ - struct sxgbe_priv_data *priv = netdev_priv(dev); - - /* Can't act on a running interface */ - if (dev->flags & IFF_UP) - return -EBUSY; - - /* Don't allow changing the I/O address */ - if (map->base_addr != (unsigned long)priv->ioaddr) { - netdev_warn(dev, "can't change I/O address\n"); - return -EOPNOTSUPP; - } - - /* Don't allow changing the IRQ */ - if (map->irq != priv->irq) { - netdev_warn(dev, "not change IRQ number %d\n", priv->irq); - return -EOPNOTSUPP; - } - - return 0; -} - #ifdef CONFIG_NET_POLL_CONTROLLER /** * sxgbe_poll_controller - entry point for polling receive by device @@ -2005,7 +1974,6 @@ static const struct net_device_ops sxgbe_netdev_ops = { .ndo_set_rx_mode = sxgbe_set_rx_mode, .ndo_tx_timeout = sxgbe_tx_timeout, .ndo_do_ioctl = sxgbe_ioctl, - .ndo_set_config = sxgbe_config, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = sxgbe_poll_controller, #endif @@ -2070,6 +2038,24 @@ static int sxgbe_hw_init(struct sxgbe_priv_data * const priv) return 0; } +static int sxgbe_sw_reset(void __iomem *addr) +{ + int retry_count = 10; + + writel(SXGBE_DMA_SOFT_RESET, addr + SXGBE_DMA_MODE_REG); + while (retry_count--) { + if (!(readl(addr + SXGBE_DMA_MODE_REG) & + SXGBE_DMA_SOFT_RESET)) + break; + mdelay(10); + } + + if (retry_count < 0) + return -EBUSY; + + return 0; +} + /** * sxgbe_drv_probe * @device: device pointer @@ -2102,6 +2088,10 @@ struct sxgbe_priv_data *sxgbe_drv_probe(struct device *device, priv->plat = plat_dat; priv->ioaddr = addr; + ret = sxgbe_sw_reset(priv->ioaddr); + if (ret) + goto error_free_netdev; + /* Verify driver arguments */ sxgbe_verify_args(); @@ -2218,9 +2208,14 @@ error_free_netdev: int sxgbe_drv_remove(struct net_device *ndev) { struct sxgbe_priv_data *priv = netdev_priv(ndev); + u8 queue_num; netdev_info(ndev, "%s: removing driver\n", __func__); + SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) { + priv->hw->mac->disable_rxqueue(priv->ioaddr, queue_num); + } + priv->hw->dma->stop_rx(priv->ioaddr, SXGBE_RX_QUEUES); priv->hw->dma->stop_tx(priv->ioaddr, SXGBE_TX_QUEUES); diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c index 01af2cbb479d..43ccb4a6de15 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c @@ -27,7 +27,7 @@ #define SXGBE_SMA_PREAD_CMD 0x02 /* post read increament address */ #define SXGBE_SMA_READ_CMD 0x03 /* read command */ #define SXGBE_SMA_SKIP_ADDRFRM 0x00040000 /* skip the address frame */ -#define SXGBE_MII_BUSY 0x00800000 /* mii busy */ +#define SXGBE_MII_BUSY 0x00400000 /* mii busy */ static int sxgbe_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_data) { @@ -147,6 +147,7 @@ int sxgbe_mdio_register(struct net_device *ndev) struct sxgbe_mdio_bus_data *mdio_data = priv->plat->mdio_bus_data; int err, phy_addr; int *irqlist; + bool phy_found = false; bool act; /* allocate the new mdio bus */ @@ -162,7 +163,7 @@ int sxgbe_mdio_register(struct net_device *ndev) irqlist = priv->mii_irq; /* assign mii bus fields */ - mdio_bus->name = "samsxgbe"; + mdio_bus->name = "sxgbe"; mdio_bus->read = &sxgbe_mdio_read; mdio_bus->write = &sxgbe_mdio_write; snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%x", @@ -216,13 +217,22 @@ int sxgbe_mdio_register(struct net_device *ndev) netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n", phy->phy_id, phy_addr, irq_str, dev_name(&phy->dev), act ? " active" : ""); + phy_found = true; } } + if (!phy_found) { + netdev_err(ndev, "PHY not found\n"); + goto phyfound_err; + } + priv->mii = mdio_bus; return 0; +phyfound_err: + err = -ENODEV; + mdiobus_unregister(mdio_bus); mdiobus_err: mdiobus_free(mdio_bus); return err; diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h index 5a89acb4c505..81437d91df99 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h @@ -52,6 +52,10 @@ #define SXGBE_CORE_RX_CTL2_REG 0x00A8 #define SXGBE_CORE_RX_CTL3_REG 0x00AC +#define SXGBE_CORE_RXQ_ENABLE_MASK 0x0003 +#define SXGBE_CORE_RXQ_ENABLE 0x0002 +#define SXGBE_CORE_RXQ_DISABLE 0x0000 + /* Interrupt Registers */ #define SXGBE_CORE_INT_STATUS_REG 0x00B0 #define SXGBE_CORE_INT_ENABLE_REG 0x00B4 @@ -184,7 +188,6 @@ /* L3/L4 function registers */ #define SXGBE_CORE_L34_ADDCTL_REG 0x0C00 -#define SXGBE_CORE_L34_ADDCTL_REG 0x0C00 #define SXGBE_CORE_L34_DATA_REG 0x0C04 /* ARP registers */ |