diff options
Diffstat (limited to 'drivers/net/wan')
-rw-r--r-- | drivers/net/wan/c101.c | 1 | ||||
-rw-r--r-- | drivers/net/wan/fsl_ucc_hdlc.c | 77 | ||||
-rw-r--r-- | drivers/net/wan/fsl_ucc_hdlc.h | 1 | ||||
-rw-r--r-- | drivers/net/wan/pci200syn.c | 1 | ||||
-rw-r--r-- | drivers/net/wan/x25_asy.c | 19 |
5 files changed, 69 insertions, 30 deletions
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 2371e078afbb..91dbbde3c35b 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -24,7 +24,6 @@ #include <linux/string.h> #include <linux/errno.h> #include <linux/init.h> -#include <linux/moduleparam.h> #include <linux/netdevice.h> #include <linux/hdlc.h> #include <linux/delay.h> diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 5f0366a125e2..4d6409605207 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -36,6 +36,7 @@ #define DRV_NAME "ucc_hdlc" #define TDM_PPPOHT_SLIC_MAXIN +#define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S) static struct ucc_tdm_info utdm_primary_info = { .uf_info = { @@ -97,6 +98,12 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) if (priv->tsa) { uf_info->tsa = 1; uf_info->ctsp = 1; + uf_info->cds = 1; + uf_info->ctss = 1; + } else { + uf_info->cds = 0; + uf_info->ctsp = 0; + uf_info->ctss = 0; } /* This sets HPM register in CMXUCR register which configures a @@ -265,7 +272,7 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) iowrite16be(MAX_FRAME_LENGTH, &priv->ucc_pram->mflr); iowrite16be(DEFAULT_RFTHR, &priv->ucc_pram->rfthr); iowrite16be(DEFAULT_RFTHR, &priv->ucc_pram->rfcnt); - iowrite16be(DEFAULT_ADDR_MASK, &priv->ucc_pram->hmask); + iowrite16be(priv->hmask, &priv->ucc_pram->hmask); iowrite16be(DEFAULT_HDLC_ADDR, &priv->ucc_pram->haddr1); iowrite16be(DEFAULT_HDLC_ADDR, &priv->ucc_pram->haddr2); iowrite16be(DEFAULT_HDLC_ADDR, &priv->ucc_pram->haddr3); @@ -375,6 +382,10 @@ static netdev_tx_t ucc_hdlc_tx(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_bytes += skb->len; break; + case ARPHRD_ETHER: + dev->stats.tx_bytes += skb->len; + break; + default: dev->stats.tx_dropped++; dev_kfree_skb(skb); @@ -420,12 +431,25 @@ static netdev_tx_t ucc_hdlc_tx(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +static int hdlc_tx_restart(struct ucc_hdlc_private *priv) +{ + u32 cecr_subblock; + + cecr_subblock = + ucc_fast_get_qe_cr_subblock(priv->ut_info->uf_info.ucc_num); + + qe_issue_cmd(QE_RESTART_TX, cecr_subblock, + QE_CR_PROTOCOL_UNSPECIFIED, 0); + return 0; +} + static int hdlc_tx_done(struct ucc_hdlc_private *priv) { /* Start from the next BD that should be filled */ struct net_device *dev = priv->ndev; struct qe_bd *bd; /* BD pointer */ u16 bd_status; + int tx_restart = 0; bd = priv->dirty_tx; bd_status = ioread16be(&bd->status); @@ -434,6 +458,15 @@ static int hdlc_tx_done(struct ucc_hdlc_private *priv) while ((bd_status & T_R_S) == 0) { struct sk_buff *skb; + if (bd_status & T_UN_S) { /* Underrun */ + dev->stats.tx_fifo_errors++; + tx_restart = 1; + } + if (bd_status & T_CT_S) { /* Carrier lost */ + dev->stats.tx_carrier_errors++; + tx_restart = 1; + } + /* BD contains already transmitted buffer. */ /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ @@ -465,6 +498,9 @@ static int hdlc_tx_done(struct ucc_hdlc_private *priv) } priv->dirty_tx = bd; + if (tx_restart) + hdlc_tx_restart(priv); + return 0; } @@ -483,11 +519,22 @@ static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit) /* while there are received buffers and BD is full (~R_E) */ while (!((bd_status & (R_E_S)) || (--rx_work_limit < 0))) { - if (bd_status & R_OV_S) - dev->stats.rx_over_errors++; - if (bd_status & R_CR_S) { - dev->stats.rx_crc_errors++; - dev->stats.rx_dropped++; + if (bd_status & (RX_BD_ERRORS)) { + dev->stats.rx_errors++; + + if (bd_status & R_CD_S) + dev->stats.collisions++; + if (bd_status & R_OV_S) + dev->stats.rx_fifo_errors++; + if (bd_status & R_CR_S) + dev->stats.rx_crc_errors++; + if (bd_status & R_AB_S) + dev->stats.rx_over_errors++; + if (bd_status & R_NO_S) + dev->stats.rx_frame_errors++; + if (bd_status & R_LG_S) + dev->stats.rx_length_errors++; + goto recycle; } bdbuffer = priv->rx_buffer + @@ -512,6 +559,7 @@ static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit) break; case ARPHRD_PPP: + case ARPHRD_ETHER: length -= HDLC_CRC_SIZE; skb = dev_alloc_skb(length); @@ -535,7 +583,7 @@ static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit) netif_receive_skb(skb); recycle: - iowrite16be(bd_status | R_E_S | R_I_S, &bd->status); + iowrite16be((bd_status & R_W_S) | R_E_S | R_I_S, &bd->status); /* update to point at the next bd */ if (bd_status & R_W_S) { @@ -611,7 +659,7 @@ static irqreturn_t ucc_hdlc_irq_handler(int irq, void *dev_id) /* Errors and other events */ if (ucce >> 16 & UCC_HDLC_UCCE_BSY) - dev->stats.rx_errors++; + dev->stats.rx_missed_errors++; if (ucce >> 16 & UCC_HDLC_UCCE_TXE) dev->stats.tx_errors++; @@ -780,6 +828,7 @@ static int ucc_hdlc_attach(struct net_device *dev, unsigned short encoding, if (parity != PARITY_NONE && parity != PARITY_CRC32_PR1_CCITT && + parity != PARITY_CRC16_PR0_CCITT && parity != PARITY_CRC16_PR1_CCITT) return -EINVAL; @@ -987,11 +1036,17 @@ static const struct dev_pm_ops uhdlc_pm_ops = { #define HDLC_PM_OPS NULL #endif +static void uhdlc_tx_timeout(struct net_device *ndev) +{ + netdev_err(ndev, "%s\n", __func__); +} + static const struct net_device_ops uhdlc_ops = { .ndo_open = uhdlc_open, .ndo_stop = uhdlc_close, .ndo_start_xmit = hdlc_start_xmit, .ndo_do_ioctl = uhdlc_ioctl, + .ndo_tx_timeout = uhdlc_tx_timeout, }; static int ucc_hdlc_probe(struct platform_device *pdev) @@ -1015,7 +1070,7 @@ static int ucc_hdlc_probe(struct platform_device *pdev) } ucc_num = val - 1; - if ((ucc_num > 3) || (ucc_num < 0)) { + if (ucc_num > (UCC_MAX_NUM - 1) || ucc_num < 0) { dev_err(&pdev->dev, ": Invalid UCC num\n"); return -EINVAL; } @@ -1090,6 +1145,9 @@ static int ucc_hdlc_probe(struct platform_device *pdev) goto free_utdm; } + if (of_property_read_u16(np, "fsl,hmask", &uhdlc_priv->hmask)) + uhdlc_priv->hmask = DEFAULT_ADDR_MASK; + ret = uhdlc_init(uhdlc_priv); if (ret) { dev_err(&pdev->dev, "Failed to init uhdlc\n"); @@ -1107,6 +1165,7 @@ static int ucc_hdlc_probe(struct platform_device *pdev) hdlc = dev_to_hdlc(dev); dev->tx_queue_len = 16; dev->netdev_ops = &uhdlc_ops; + dev->watchdog_timeo = 2 * HZ; hdlc->attach = ucc_hdlc_attach; hdlc->xmit = ucc_hdlc_tx; netif_napi_add(dev, &uhdlc_priv->napi, ucc_hdlc_poll, 32); diff --git a/drivers/net/wan/fsl_ucc_hdlc.h b/drivers/net/wan/fsl_ucc_hdlc.h index c21134c1f180..b99fa2f1cd99 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.h +++ b/drivers/net/wan/fsl_ucc_hdlc.h @@ -106,6 +106,7 @@ struct ucc_hdlc_private { unsigned short encoding; unsigned short parity; + unsigned short hmask; u32 clocking; spinlock_t lock; /* lock for Tx BD and Tx buffer */ #ifdef CONFIG_PM diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 4e437c599e9a..1f8a3f77a7b9 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -27,7 +27,6 @@ #include <linux/errno.h> #include <linux/init.h> #include <linux/ioport.h> -#include <linux/moduleparam.h> #include <linux/netdevice.h> #include <linux/hdlc.h> #include <linux/pci.h> diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 74c06a5f586f..1098263ab862 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -33,7 +33,6 @@ #include <linux/lapb.h> #include <linux/init.h> #include <linux/rtnetlink.h> -#include <linux/compat.h> #include <linux/slab.h> #include <net/x25device.h> #include "x25_asy.h" @@ -703,21 +702,6 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file, } } -#ifdef CONFIG_COMPAT -static long x25_asy_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCGIFNAME: - case SIOCSIFHWADDR: - return x25_asy_ioctl(tty, file, cmd, - (unsigned long)compat_ptr(arg)); - } - - return -ENOIOCTLCMD; -} -#endif - static int x25_asy_open_dev(struct net_device *dev) { struct x25_asy *sl = netdev_priv(dev); @@ -769,9 +753,6 @@ static struct tty_ldisc_ops x25_ldisc = { .open = x25_asy_open_tty, .close = x25_asy_close_tty, .ioctl = x25_asy_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = x25_asy_compat_ioctl, -#endif .receive_buf = x25_asy_receive_buf, .write_wakeup = x25_asy_write_wakeup, }; |