* [net-next 3/8] stmmac: update the driver version and doc (V4)
From: Giuseppe CAVALLARO @ 2011-10-18 10:01 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, Giuseppe Cavallaro
In-Reply-To: <1318932085-14927-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 11 ++++++++++-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index 40ec92c..8d67980 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -76,7 +76,16 @@ core.
4.5) DMA descriptors
Driver handles both normal and enhanced descriptors. The latter has been only
-tested on DWC Ether MAC 10/100/1000 Universal version 3.41a.
+tested on DWC Ether MAC 10/100/1000 Universal version 3.41a and later.
+
+STMMAC supports DMA descriptor to operate both in dual buffer (RING)
+and linked-list(CHAINED) mode. In RING each descriptor points to two
+data buffer pointers whereas in CHAINED mode they point to only one data
+buffer pointer. RING mode is the default.
+
+In CHAINED mode each descriptor will have pointer to next descriptor in
+the list, hence creating the explicit chaining in the descriptor itself,
+whereas such explicit chaining is not possible in RING mode.
4.6) Ethtool support
Ethtool is supported. Driver statistics and internal errors can be taken using:
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 50e95d8..49a4af3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -20,7 +20,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
-#define DRV_MODULE_VERSION "Aug_2011"
+#define DRV_MODULE_VERSION "Oct_2011"
#include <linux/stmmac.h>
#include "common.h"
--
1.7.4.4
^ permalink raw reply related
* [net-next 2/8] stmmac: protect tx process with lock (V4)
From: Giuseppe CAVALLARO @ 2011-10-18 10:01 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, Giuseppe Cavallaro
In-Reply-To: <1318932085-14927-1-git-send-email-peppe.cavallaro@st.com>
This patch fixes a problem raised on Orly ARM SMP platform
where, in case of fragmented frames, the descriptors
in the TX ring resulted broken. This was due to a missing lock
protection in the tx process.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Tested-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++++
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1434bdb..50e95d8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -70,6 +70,7 @@ struct stmmac_priv {
u32 msg_enable;
spinlock_t lock;
+ spinlock_t tx_lock;
int wolopts;
int wolenabled;
int wol_irq;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 229fe44..d0af002 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -588,6 +588,8 @@ static void stmmac_tx(struct stmmac_priv *priv)
{
unsigned int txsize = priv->dma_tx_size;
+ spin_lock(&priv->tx_lock);
+
while (priv->dirty_tx != priv->cur_tx) {
int last;
unsigned int entry = priv->dirty_tx % txsize;
@@ -651,6 +653,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
}
netif_tx_unlock(priv->dev);
}
+ spin_unlock(&priv->tx_lock);
}
static inline void stmmac_enable_irq(struct stmmac_priv *priv)
@@ -1078,6 +1081,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
+ spin_lock(&priv->tx_lock);
+
entry = priv->cur_tx % txsize;
#ifdef STMMAC_XMIT_DEBUG
@@ -1166,6 +1171,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
priv->hw->dma->enable_dma_transmission(priv->ioaddr);
+ spin_unlock(&priv->tx_lock);
+
return NETDEV_TX_OK;
}
@@ -1731,6 +1738,7 @@ static int stmmac_probe(struct net_device *dev)
"please, use ifconfig or nwhwconfig!\n");
spin_lock_init(&priv->lock);
+ spin_lock_init(&priv->tx_lock);
ret = register_netdev(dev);
if (ret) {
--
1.7.4.4
^ permalink raw reply related
* [net-next 1/8] stmmac: Stop advertising 1000Base capabilties for non GMII iface (V4).
From: Giuseppe CAVALLARO @ 2011-10-18 10:01 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, Srinivas Kandagatla, Giuseppe Cavallaro
In-Reply-To: <1318932085-14927-1-git-send-email-peppe.cavallaro@st.com>
From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
This patch stops advertising 1000Base capablities if GMAC is either
configured for MII or RMII mode and on board there is a GPHY plugged on.
Without this patch if an GBit switch is connected on MII interface,
Ethernet stops working at all.
Discovered as part of
https://bugzilla.stlinux.com/show_bug.cgi?id=14148 triage
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c0ee6b6..229fe44 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -304,7 +304,7 @@ static int stmmac_init_phy(struct net_device *dev)
struct phy_device *phydev;
char phy_id[MII_BUS_ID_SIZE + 3];
char bus_id[MII_BUS_ID_SIZE];
-
+ int interface = priv->plat->interface;
priv->oldlink = 0;
priv->speed = 0;
priv->oldduplex = -1;
@@ -314,14 +314,21 @@ static int stmmac_init_phy(struct net_device *dev)
priv->plat->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
- phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
- priv->plat->interface);
+ phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface);
if (IS_ERR(phydev)) {
pr_err("%s: Could not attach to PHY\n", dev->name);
return PTR_ERR(phydev);
}
+ /* Stop Advertising 1000BASE Capability if interface is not GMII */
+ if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) ||
+ (interface == PHY_INTERFACE_MODE_RMII))) {
+ phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ priv->phydev->advertising = priv->phydev->supported;
+ }
+
/*
* Broken HW is sometimes missing the pull-up resistor on the
* MDIO line, which results in reads to non-existent devices returning
--
1.7.4.4
^ permalink raw reply related
* [net-next 0/8] stmmac: update to Oct 2011 version (v4)
From: Giuseppe CAVALLARO @ 2011-10-18 10:01 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, Giuseppe Cavallaro
This patches update the driver adding the chained
descriptor mode and some new useful fixes.
I've reviewed some patches after the V1/2/3 and added new ones:
stmmac: allow mtu bigger than 1500 in case of normal desc (V4)
|-> removed the useless max_mtu init: Thx Eric's feedback
stmmac: add CHAINED descriptor mode support (V4)
|-> removed ifdef in the C and added small routines
specialised for chained/ring modes. See comment
within the patch itself. Thx David's feedback.
stmmac: allow mmc usage only if feature actually available (V4)
|-> added a check if interface is NULL
stmmac: limit max_mtu in case of 4KiB and use __netdev_alloc_skb.
|-> another enhancements proposed by Eric (built on top of the
V3 patches sent today).
stmmac: use predefined macros for HW cap register fields (V4)
stmmac: allow mmc usage only if feature actually available (V4)
Let me know if all is ok.
Regards
Peppe
Giuseppe Cavallaro (6):
stmmac: protect tx process with lock (V4)
stmmac: update the driver version and doc (V4)
stmmac: allow mtu bigger than 1500 in case of normal desc (V4)
stmmac: allow mmc usage only if feature actually available (V4)
stmmac: add CHAINED descriptor mode support (V4)
stmmac: limit max_mtu in case of 4KiB and use __netdev_alloc_skb.
Rayagond Kokatanur (1):
stmmac: use predefined macros for HW cap register fields (V4)
Srinivas Kandagatla (1):
stmmac: Stop advertising 1000Base capabilties for non GMII iface
(V4).
Documentation/networking/stmmac.txt | 11 +-
drivers/net/ethernet/stmicro/stmmac/Kconfig | 18 ++
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 137 ++++++++++++
drivers/net/ethernet/stmicro/stmmac/common.h | 43 ++++
drivers/net/ethernet/stmicro/stmmac/descs_com.h | 126 +++++++++++
drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 22 +--
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 14 +-
drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 126 +++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 5 +-
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 24 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 223 ++++++++++----------
12 files changed, 610 insertions(+), 141 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/chain_mode.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/descs_com.h
create mode 100644 drivers/net/ethernet/stmicro/stmmac/ring_mode.c
--
1.7.4.4
^ permalink raw reply
* Re: PROBLEM: System call 'sendmsg' of process ospfd (quagga) causes kernel oops
From: Eric Dumazet @ 2011-10-18 10:01 UTC (permalink / raw)
To: Herbert Xu; +Cc: Elmar Vonlanthen, linux-kernel, netdev, Timo Teräs
In-Reply-To: <20111018093411.GA15165@gondor.apana.org.au>
Le mardi 18 octobre 2011 à 11:34 +0200, Herbert Xu a écrit :
> On Tue, Oct 18, 2011 at 04:30:32AM +0200, Eric Dumazet wrote:
> >
> > If David/Herbert/Timo agree, then patch should find its way into current
> > kernel, then to stable trees as well.
>
> Actually, I think we should instead fix the users of needed_headroom
> to not read it twice which is causing problems here.
>
> GRE tunnels by their nature do not have a fixed value for
> needed_headroom. As the underlying routes change the necessary
> headroom may need to be adjusted due to further encapsulation such
> as IPsec.
>
> Keeping it constant from tunnel creation may result in suboptimal
> performance due to unnecessary header reallocations.
>
> However, until we audit the stack to see if there are further
> instances of double-readings such as the one causing the crash
> here, I'm fine with your patch making it constant.
>
> Once we're sure that all of the double-readings are gone we
> can revert to a dynamic needed_headroom.
>
Sure, we can work on this path for future kernels.
Adding an RCU protected structure to hold hard_header_len /
needed_headroom / needed_tailroom should be possible, but this adds yet
another pointer dereference...
Thanks !
^ permalink raw reply
* Re: [net-next 7/7] stmmac: add CHAINED descriptor mode support (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 9:51 UTC (permalink / raw)
To: netdev; +Cc: davem, Rayagond Kokatanur, Eric Dumazet
In-Reply-To: <1318927331-20855-8-git-send-email-peppe.cavallaro@st.com>
Please discard these. I'm sending the V4 (with the Eric patch for mtu
and dma_init).
Peppe
On 10/18/2011 10:42 AM, Giuseppe CAVALLARO wrote:
> This patch enhances the STMMAC driver to support CHAINED mode of
> descriptor.
>
> STMMAC supports DMA descriptor to operate both in dual buffer(RING)
> and linked-list(CHAINED) mode. In RING mode (default) each descriptor
> points to two data buffer pointers whereas in CHAINED mode they point
> to only one data buffer pointer.
>
> In CHAINED mode each descriptor will have pointer to next descriptor in
> the list, hence creating the explicit chaining in the descriptor itself,
> whereas such explicit chaining is not possible in RING mode.
>
> First version of this work has been done by Rayagond.
> Then the patch has been reworked avoiding ifdef inside the C code.
> A new header file has been added to define all the functions needed for
> managing enhanced and normal descriptors.
> In fact, these have to be specialized according to the ring/chain usage.
> Two new C files have been also added to implement the helper routines
> needed to manage: jumbo frames, chain and ring setup (i.e. desc3).
>
> Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/Kconfig | 18 +++
> drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +
> drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 137 +++++++++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/common.h | 13 ++
> drivers/net/ethernet/stmicro/stmmac/descs_com.h | 126 +++++++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 22 ++--
> drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 20 +--
> drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 126 +++++++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 130 ++++++++------------
> 10 files changed, 491 insertions(+), 105 deletions(-)
> create mode 100644 drivers/net/ethernet/stmicro/stmmac/chain_mode.c
> create mode 100644 drivers/net/ethernet/stmicro/stmmac/descs_com.h
> create mode 100644 drivers/net/ethernet/stmicro/stmmac/ring_mode.c
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
> index 8cd9dde..ac6f190 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
> +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
> @@ -63,4 +63,22 @@ config STMMAC_RTC_TIMER
>
> endchoice
>
> +choice
> + prompt "Select the DMA TX/RX descriptor operating modes"
> + depends on STMMAC_ETH
> + ---help---
> + This driver supports DMA descriptor to operate both in dual buffer
> + (RING) and linked-list(CHAINED) mode. In RING mode each descriptor
> + points to two data buffer pointers whereas in CHAINED mode they
> + points to only one data buffer pointer.
> +
> +config STMMAC_RING
> + bool "Enable Descriptor Ring Mode"
> +
> +config STMMAC_CHAINED
> + bool "Enable Descriptor Chained Mode"
> +
> +endchoice
> +
> +
> endif
> diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
> index 0f23d95..d7c4516 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
> +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
> @@ -1,5 +1,7 @@
> obj-$(CONFIG_STMMAC_ETH) += stmmac.o
> stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
> +stmmac-$(CONFIG_STMMAC_RING) += ring_mode.o
> +stmmac-$(CONFIG_STMMAC_CHAINED) += chain_mode.o
> stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
> dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
> dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
> diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
> new file mode 100644
> index 0000000..0668659
> --- /dev/null
> +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
> @@ -0,0 +1,137 @@
> +/*******************************************************************************
> + Specialised functions for managing Chained mode
> +
> + Copyright(C) 2011 STMicroelectronics Ltd
> +
> + It defines all the functions used to handle the normal/enhanced
> + descriptors in case of the DMA is configured to work in chained or
> + in ring mode.
> +
> + This program is free software; you can redistribute it and/or modify it
> + under the terms and conditions of the GNU General Public License,
> + version 2, as published by the Free Software Foundation.
> +
> + This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
> + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
> +
> + The full GNU General Public License is included in this distribution in
> + the file called "COPYING".
> +
> + Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> +*******************************************************************************/
> +
> +#include "stmmac.h"
> +
> +unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
> +{
> + struct stmmac_priv *priv = (struct stmmac_priv *) p;
> + unsigned int txsize = priv->dma_tx_size;
> + unsigned int entry = priv->cur_tx % txsize;
> + struct dma_desc *desc = priv->dma_tx + entry;
> + unsigned int nopaged_len = skb_headlen(skb);
> + unsigned int bmax;
> + unsigned int i = 1, len;
> +
> + if (priv->plat->enh_desc)
> + bmax = BUF_SIZE_8KiB;
> + else
> + bmax = BUF_SIZE_2KiB;
> +
> + len = nopaged_len - bmax;
> +
> + desc->des2 = dma_map_single(priv->device, skb->data,
> + bmax, DMA_TO_DEVICE);
> + priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum);
> +
> + while (len != 0) {
> + entry = (++priv->cur_tx) % txsize;
> + desc = priv->dma_tx + entry;
> +
> + if (len > bmax) {
> + desc->des2 = dma_map_single(priv->device,
> + (skb->data + bmax * i),
> + bmax, DMA_TO_DEVICE);
> + priv->hw->desc->prepare_tx_desc(desc, 0, bmax,
> + csum);
> + priv->hw->desc->set_tx_owner(desc);
> + priv->tx_skbuff[entry] = NULL;
> + len -= bmax;
> + i++;
> + } else {
> + desc->des2 = dma_map_single(priv->device,
> + (skb->data + bmax * i), len,
> + DMA_TO_DEVICE);
> + priv->hw->desc->prepare_tx_desc(desc, 0, len,
> + csum);
> + priv->hw->desc->set_tx_owner(desc);
> + priv->tx_skbuff[entry] = NULL;
> + len = 0;
> + }
> + }
> + return entry;
> +}
> +
> +static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
> +{
> + unsigned int ret = 0;
> +
> + if ((enh_desc && (len > BUF_SIZE_8KiB)) ||
> + (!enh_desc && (len > BUF_SIZE_2KiB))) {
> + ret = 1;
> + }
> +
> + return ret;
> +}
> +
> +static void stmmac_refill_desc3(int bfsize, struct dma_desc *p)
> +{
> +}
> +
> +static void stmmac_init_desc3(int des3_as_data_buf, struct dma_desc *p)
> +{
> +}
> +
> +static void stmmac_clean_desc3(struct dma_desc *p)
> +{
> +}
> +
> +static void stmmac_init_dma_chain(struct dma_desc *des, dma_addr_t phy_addr,
> + unsigned int size)
> +{
> + /*
> + * In chained mode the des3 points to the next element in the ring.
> + * The latest element has to point to the head.
> + */
> + int i;
> + struct dma_desc *p = des;
> + dma_addr_t dma_phy = phy_addr;
> +
> + for (i = 0; i < (size - 1); i++) {
> + dma_phy += sizeof(struct dma_desc);
> + p->des3 = (unsigned int)dma_phy;
> + p++;
> + }
> + p->des3 = (unsigned int)phy_addr;
> +}
> +
> +static int stmmac_set_16kib_bfsize(int mtu)
> +{
> + /* Not supported */
> + return 0;
> +}
> +
> +const struct stmmac_ring_mode_ops ring_mode_ops = {
> + .is_jumbo_frm = stmmac_is_jumbo_frm,
> + .jumbo_frm = stmmac_jumbo_frm,
> + .refill_desc3 = stmmac_refill_desc3,
> + .init_desc3 = stmmac_init_desc3,
> + .init_dma_chain = stmmac_init_dma_chain,
> + .clean_desc3 = stmmac_clean_desc3,
> + .set_16kib_bfsize = stmmac_set_16kib_bfsize,
> +};
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index ffba014..9100c10 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -287,10 +287,22 @@ struct mii_regs {
> unsigned int data; /* MII Data */
> };
>
> +struct stmmac_ring_mode_ops {
> + unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
> + unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum);
> + void (*refill_desc3) (int bfsize, struct dma_desc *p);
> + void (*init_desc3) (int des3_as_data_buf, struct dma_desc *p);
> + void (*init_dma_chain) (struct dma_desc *des, dma_addr_t phy_addr,
> + unsigned int size);
> + void (*clean_desc3) (struct dma_desc *p);
> + int (*set_16kib_bfsize) (int mtu);
> +};
> +
> struct mac_device_info {
> const struct stmmac_ops *mac;
> const struct stmmac_desc_ops *desc;
> const struct stmmac_dma_ops *dma;
> + const struct stmmac_ring_mode_ops *ring;
> struct mii_regs mii; /* MII register Addresses */
> struct mac_link link;
> unsigned int synopsys_uid;
> @@ -304,3 +316,4 @@ extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
> extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
> unsigned int high, unsigned int low);
> extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
> +extern const struct stmmac_ring_mode_ops ring_mode_ops;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h
> new file mode 100644
> index 0000000..1652c86
> --- /dev/null
> +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h
> @@ -0,0 +1,126 @@
> +/*******************************************************************************
> + Header File to describe Normal/enhanced descriptor functions used for RING
> + and CHAINED modes.
> +
> + Copyright(C) 2011 STMicroelectronics Ltd
> +
> + It defines all the functions used to handle the normal/enhanced
> + descriptors in case of the DMA is configured to work in chained or
> + in ring mode.
> +
> + This program is free software; you can redistribute it and/or modify it
> + under the terms and conditions of the GNU General Public License,
> + version 2, as published by the Free Software Foundation.
> +
> + This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
> + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
> +
> + The full GNU General Public License is included in this distribution in
> + the file called "COPYING".
> +
> + Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> +*******************************************************************************/
> +
> +#if defined(CONFIG_STMMAC_RING)
> +static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end)
> +{
> + p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
> + if (end)
> + p->des01.erx.end = 1;
> +}
> +
> +static inline void ehn_desc_tx_set_on_ring_chain(struct dma_desc *p, int end)
> +{
> + if (end)
> + p->des01.etx.end = 1;
> +}
> +
> +static inline void enh_desc_end_tx_desc(struct dma_desc *p, int ter)
> +{
> + p->des01.etx.end = ter;
> +}
> +
> +static inline void enh_set_tx_desc_len(struct dma_desc *p, int len)
> +{
> + if (unlikely(len > BUF_SIZE_4KiB)) {
> + p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
> + p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
> + } else
> + p->des01.etx.buffer1_size = len;
> +}
> +
> +static inline void ndesc_rx_set_on_ring_chain(struct dma_desc *p, int end)
> +{
> + p->des01.rx.buffer2_size = BUF_SIZE_2KiB - 1;
> + if (end)
> + p->des01.rx.end = 1;
> +}
> +
> +static inline void ndesc_tx_set_on_ring_chain(struct dma_desc *p, int end)
> +{
> + if (end)
> + p->des01.tx.end = 1;
> +}
> +
> +static inline void ndesc_end_tx_desc(struct dma_desc *p, int ter)
> +{
> + p->des01.tx.end = ter;
> +}
> +
> +static inline void norm_set_tx_desc_len(struct dma_desc *p, int len)
> +{
> + if (unlikely(len > BUF_SIZE_2KiB)) {
> + p->des01.etx.buffer1_size = BUF_SIZE_2KiB - 1;
> + p->des01.etx.buffer2_size = len - p->des01.etx.buffer1_size;
> + } else
> + p->des01.tx.buffer1_size = len;
> +}
> +
> +#else
> +
> +static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end)
> +{
> + p->des01.erx.second_address_chained = 1;
> +}
> +
> +static inline void ehn_desc_tx_set_on_ring_chain(struct dma_desc *p, int end)
> +{
> + p->des01.etx.second_address_chained = 1;
> +}
> +
> +static inline void enh_desc_end_tx_desc(struct dma_desc *p, int ter)
> +{
> + p->des01.etx.second_address_chained = 1;
> +}
> +
> +static inline void enh_set_tx_desc_len(struct dma_desc *p, int len)
> +{
> + p->des01.etx.buffer1_size = len;
> +}
> +
> +static inline void ndesc_rx_set_on_ring_chain(struct dma_desc *p, int end)
> +{
> + p->des01.rx.second_address_chained = 1;
> +}
> +
> +static inline void ndesc_tx_set_on_ring_chain(struct dma_desc *p, int ring_size)
> +{
> + p->des01.tx.second_address_chained = 1;
> +}
> +
> +static inline void ndesc_end_tx_desc(struct dma_desc *p, int ter)
> +{
> + p->des01.tx.second_address_chained = 1;
> +}
> +
> +static inline void norm_set_tx_desc_len(struct dma_desc *p, int len)
> +{
> + p->des01.tx.buffer1_size = len;
> +}
> +#endif
> diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
> index e5dfb6a..d879763 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
> @@ -23,6 +23,7 @@
> *******************************************************************************/
>
> #include "common.h"
> +#include "descs_com.h"
>
> static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x,
> struct dma_desc *p, void __iomem *ioaddr)
> @@ -233,10 +234,9 @@ static void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
> for (i = 0; i < ring_size; i++) {
> p->des01.erx.own = 1;
> p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
> - /* To support jumbo frames */
> - p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
> - if (i == ring_size - 1)
> - p->des01.erx.end_ring = 1;
> +
> + ehn_desc_rx_set_on_ring_chain(p, (i == ring_size - 1));
> +
> if (disable_rx_ic)
> p->des01.erx.disable_ic = 1;
> p++;
> @@ -249,8 +249,7 @@ static void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
>
> for (i = 0; i < ring_size; i++) {
> p->des01.etx.own = 0;
> - if (i == ring_size - 1)
> - p->des01.etx.end_ring = 1;
> + ehn_desc_tx_set_on_ring_chain(p, (i == ring_size - 1));
> p++;
> }
> }
> @@ -285,19 +284,16 @@ static void enh_desc_release_tx_desc(struct dma_desc *p)
> int ter = p->des01.etx.end_ring;
>
> memset(p, 0, offsetof(struct dma_desc, des2));
> - p->des01.etx.end_ring = ter;
> + enh_desc_end_tx_desc(p, ter);
> }
>
> static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
> int csum_flag)
> {
> p->des01.etx.first_segment = is_fs;
> - if (unlikely(len > BUF_SIZE_4KiB)) {
> - p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
> - p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
> - } else {
> - p->des01.etx.buffer1_size = len;
> - }
> +
> + enh_set_tx_desc_len(p, len);
> +
> if (likely(csum_flag))
> p->des01.etx.checksum_insertion = cic_full;
> }
> diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
> index e13226b..f7e8ba7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
> @@ -23,6 +23,7 @@
> *******************************************************************************/
>
> #include "common.h"
> +#include "descs_com.h"
>
> static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
> struct dma_desc *p, void __iomem *ioaddr)
> @@ -126,9 +127,9 @@ static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
> for (i = 0; i < ring_size; i++) {
> p->des01.rx.own = 1;
> p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
> - p->des01.rx.buffer2_size = BUF_SIZE_2KiB - 1;
> - if (i == ring_size - 1)
> - p->des01.rx.end_ring = 1;
> +
> + ndesc_rx_set_on_ring_chain(p, (i == ring_size - 1));
> +
> if (disable_rx_ic)
> p->des01.rx.disable_ic = 1;
> p++;
> @@ -140,8 +141,7 @@ static void ndesc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
> int i;
> for (i = 0; i < ring_size; i++) {
> p->des01.tx.own = 0;
> - if (i == ring_size - 1)
> - p->des01.tx.end_ring = 1;
> + ndesc_tx_set_on_ring_chain(p, (i == (ring_size - 1)));
> p++;
> }
> }
> @@ -176,20 +176,14 @@ static void ndesc_release_tx_desc(struct dma_desc *p)
> int ter = p->des01.tx.end_ring;
>
> memset(p, 0, offsetof(struct dma_desc, des2));
> - /* set termination field */
> - p->des01.tx.end_ring = ter;
> + ndesc_end_tx_desc(p, ter);
> }
>
> static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
> int csum_flag)
> {
> p->des01.tx.first_segment = is_fs;
> -
> - if (unlikely(len > BUF_SIZE_2KiB)) {
> - p->des01.etx.buffer1_size = BUF_SIZE_2KiB - 1;
> - p->des01.etx.buffer2_size = len - p->des01.etx.buffer1_size;
> - } else
> - p->des01.tx.buffer1_size = len;
> + norm_set_tx_desc_len(p, len);
> }
>
> static void ndesc_clear_tx_ic(struct dma_desc *p)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
> new file mode 100644
> index 0000000..fb8377d
> --- /dev/null
> +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
> @@ -0,0 +1,126 @@
> +/*******************************************************************************
> + Specialised functions for managing Ring mode
> +
> + Copyright(C) 2011 STMicroelectronics Ltd
> +
> + It defines all the functions used to handle the normal/enhanced
> + descriptors in case of the DMA is configured to work in chained or
> + in ring mode.
> +
> + This program is free software; you can redistribute it and/or modify it
> + under the terms and conditions of the GNU General Public License,
> + version 2, as published by the Free Software Foundation.
> +
> + This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
> + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
> +
> + The full GNU General Public License is included in this distribution in
> + the file called "COPYING".
> +
> + Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> +*******************************************************************************/
> +
> +#include "stmmac.h"
> +
> +static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
> +{
> + struct stmmac_priv *priv = (struct stmmac_priv *) p;
> + unsigned int txsize = priv->dma_tx_size;
> + unsigned int entry = priv->cur_tx % txsize;
> + struct dma_desc *desc = priv->dma_tx + entry;
> + unsigned int nopaged_len = skb_headlen(skb);
> + unsigned int bmax, len;
> +
> + if (priv->plat->enh_desc)
> + bmax = BUF_SIZE_8KiB;
> + else
> + bmax = BUF_SIZE_2KiB;
> +
> + len = nopaged_len - bmax;
> +
> + if (nopaged_len > BUF_SIZE_8KiB) {
> +
> + desc->des2 = dma_map_single(priv->device, skb->data,
> + bmax, DMA_TO_DEVICE);
> + desc->des3 = desc->des2 + BUF_SIZE_4KiB;
> + priv->hw->desc->prepare_tx_desc(desc, 1, bmax,
> + csum);
> +
> + entry = (++priv->cur_tx) % txsize;
> + desc = priv->dma_tx + entry;
> +
> + desc->des2 = dma_map_single(priv->device, skb->data + bmax,
> + len, DMA_TO_DEVICE);
> + desc->des3 = desc->des2 + BUF_SIZE_4KiB;
> + priv->hw->desc->prepare_tx_desc(desc, 0, len, csum);
> + priv->hw->desc->set_tx_owner(desc);
> + priv->tx_skbuff[entry] = NULL;
> + } else {
> + desc->des2 = dma_map_single(priv->device, skb->data,
> + nopaged_len, DMA_TO_DEVICE);
> + desc->des3 = desc->des2 + BUF_SIZE_4KiB;
> + priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum);
> + }
> +
> + return entry;
> +}
> +
> +static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
> +{
> + unsigned int ret = 0;
> +
> + if (len >= BUF_SIZE_4KiB)
> + ret = 1;
> +
> + return ret;
> +}
> +
> +static void stmmac_refill_desc3(int bfsize, struct dma_desc *p)
> +{
> + /* Fill DES3 in case of RING mode */
> + if (bfsize >= BUF_SIZE_8KiB)
> + p->des3 = p->des2 + BUF_SIZE_8KiB;
> +}
> +
> +/* In ring mode we need to fill the desc3 because it is used
> + * as buffer */
> +static void stmmac_init_desc3(int des3_as_data_buf, struct dma_desc *p)
> +{
> + if (unlikely(des3_as_data_buf))
> + p->des3 = p->des2 + BUF_SIZE_8KiB;
> +}
> +
> +static void stmmac_init_dma_chain(struct dma_desc *des, dma_addr_t phy_addr,
> + unsigned int size)
> +{
> +}
> +
> +static void stmmac_clean_desc3(struct dma_desc *p)
> +{
> + if (unlikely(p->des3))
> + p->des3 = 0;
> +}
> +
> +static int stmmac_set_16kib_bfsize(int mtu)
> +{
> + int ret = 0;
> + if (unlikely(mtu >= BUF_SIZE_8KiB))
> + ret = BUF_SIZE_16KiB;
> + return ret;
> +}
> +
> +const struct stmmac_ring_mode_ops ring_mode_ops = {
> + .is_jumbo_frm = stmmac_is_jumbo_frm,
> + .jumbo_frm = stmmac_jumbo_frm,
> + .refill_desc3 = stmmac_refill_desc3,
> + .init_desc3 = stmmac_init_desc3,
> + .init_dma_chain = stmmac_init_dma_chain,
> + .clean_desc3 = stmmac_clean_desc3,
> + .set_16kib_bfsize = stmmac_set_16kib_bfsize,
> +};
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index 49a4af3..9bafa6c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -22,7 +22,7 @@
>
> #define DRV_MODULE_VERSION "Oct_2011"
> #include <linux/stmmac.h>
> -
> +#include <linux/phy.h>
> #include "common.h"
> #ifdef CONFIG_STMMAC_TIMER
> #include "stmmac_timer.h"
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 7325256..1848a16 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -2,7 +2,7 @@
> This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
> ST Ethernet IPs are built around a Synopsys IP Core.
>
> - Copyright (C) 2007-2009 STMicroelectronics Ltd
> + Copyright(C) 2007-2011 STMicroelectronics Ltd
>
> This program is free software; you can redistribute it and/or modify it
> under the terms and conditions of the GNU General Public License,
> @@ -41,17 +41,16 @@
> #include <linux/if_ether.h>
> #include <linux/crc32.h>
> #include <linux/mii.h>
> -#include <linux/phy.h>
> #include <linux/if.h>
> #include <linux/if_vlan.h>
> #include <linux/dma-mapping.h>
> #include <linux/slab.h>
> #include <linux/prefetch.h>
> -#include "stmmac.h"
> #ifdef CONFIG_STMMAC_DEBUG_FS
> #include <linux/debugfs.h>
> #include <linux/seq_file.h>
> #endif
> +#include "stmmac.h"
>
> #define STMMAC_RESOURCE_NAME "stmmaceth"
>
> @@ -388,11 +387,28 @@ static void display_ring(struct dma_desc *p, int size)
> }
> }
>
> +static int stmmac_set_bfsize(int mtu, int bufsize)
> +{
> + int ret = bufsize;
> +
> + if (mtu >= BUF_SIZE_4KiB)
> + ret = BUF_SIZE_8KiB;
> + else if (mtu >= BUF_SIZE_2KiB)
> + ret = BUF_SIZE_4KiB;
> + else if (mtu >= DMA_BUFFER_SIZE)
> + ret = BUF_SIZE_2KiB;
> + else
> + ret = DMA_BUFFER_SIZE;
> +
> + return ret;
> +}
> +
> /**
> * init_dma_desc_rings - init the RX/TX descriptor rings
> * @dev: net device structure
> * Description: this function initializes the DMA RX/TX descriptors
> - * and allocates the socket buffers.
> + * and allocates the socket buffers. It suppors the chained and ring
> + * modes.
> */
> static void init_dma_desc_rings(struct net_device *dev)
> {
> @@ -401,31 +417,24 @@ static void init_dma_desc_rings(struct net_device *dev)
> struct sk_buff *skb;
> unsigned int txsize = priv->dma_tx_size;
> unsigned int rxsize = priv->dma_rx_size;
> - unsigned int bfsize = priv->dma_buf_sz;
> - int buff2_needed = 0, dis_ic = 0;
> + unsigned int bfsize;
> + int dis_ic = 0;
> + int des3_as_data_buf = 0;
>
> - /* Set the Buffer size according to the MTU;
> - * indeed, in case of jumbo we need to bump-up the buffer sizes.
> - */
> - if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
> - bfsize = BUF_SIZE_16KiB;
> - else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
> - bfsize = BUF_SIZE_8KiB;
> - else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
> - bfsize = BUF_SIZE_4KiB;
> - else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
> - bfsize = BUF_SIZE_2KiB;
> + /* Set the max buffer size according to the DESC mode
> + * and the MTU. Note that RING mode allows 16KiB bsize. */
> + bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu);
> +
> + if (bfsize == BUF_SIZE_16KiB)
> + des3_as_data_buf = 1;
> else
> - bfsize = DMA_BUFFER_SIZE;
> + bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
>
> #ifdef CONFIG_STMMAC_TIMER
> /* Disable interrupts on completion for the reception if timer is on */
> if (likely(priv->tm->enable))
> dis_ic = 1;
> #endif
> - /* If the MTU exceeds 8k so use the second buffer in the chain */
> - if (bfsize >= BUF_SIZE_8KiB)
> - buff2_needed = 1;
>
> DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
> txsize, rxsize, bfsize);
> @@ -453,7 +462,7 @@ static void init_dma_desc_rings(struct net_device *dev)
> return;
> }
>
> - DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
> + DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, "
> "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
> dev->name, priv->dma_rx, priv->dma_tx,
> (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
> @@ -475,8 +484,9 @@ static void init_dma_desc_rings(struct net_device *dev)
> bfsize, DMA_FROM_DEVICE);
>
> p->des2 = priv->rx_skbuff_dma[i];
> - if (unlikely(buff2_needed))
> - p->des3 = p->des2 + BUF_SIZE_8KiB;
> +
> + priv->hw->ring->init_desc3(des3_as_data_buf, p);
> +
> DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
> priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
> }
> @@ -490,6 +500,12 @@ static void init_dma_desc_rings(struct net_device *dev)
> priv->tx_skbuff[i] = NULL;
> priv->dma_tx[i].des2 = 0;
> }
> +
> + /* In case of Chained mode this sets the des3 to the next
> + * element in the chain */
> + priv->hw->ring->init_dma_chain(priv->dma_rx, priv->dma_rx_phy, rxsize);
> + priv->hw->ring->init_dma_chain(priv->dma_tx, priv->dma_tx_phy, txsize);
> +
> priv->dirty_tx = 0;
> priv->cur_tx = 0;
>
> @@ -620,8 +636,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
> dma_unmap_single(priv->device, p->des2,
> priv->hw->desc->get_tx_len(p),
> DMA_TO_DEVICE);
> - if (unlikely(p->des3))
> - p->des3 = 0;
> + priv->hw->ring->clean_desc3(p);
>
> if (likely(skb != NULL)) {
> /*
> @@ -728,7 +743,6 @@ static void stmmac_no_timer_stopped(void)
> */
> static void stmmac_tx_err(struct stmmac_priv *priv)
> {
> -
> netif_stop_queue(priv->dev);
>
> priv->hw->dma->stop_tx(priv->ioaddr);
> @@ -1028,47 +1042,6 @@ static int stmmac_release(struct net_device *dev)
> return 0;
> }
>
> -static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
> - struct net_device *dev,
> - int csum_insertion)
> -{
> - struct stmmac_priv *priv = netdev_priv(dev);
> - unsigned int nopaged_len = skb_headlen(skb);
> - unsigned int txsize = priv->dma_tx_size;
> - unsigned int entry = priv->cur_tx % txsize;
> - struct dma_desc *desc = priv->dma_tx + entry;
> -
> - if (nopaged_len > BUF_SIZE_8KiB) {
> -
> - int buf2_size = nopaged_len - BUF_SIZE_8KiB;
> -
> - desc->des2 = dma_map_single(priv->device, skb->data,
> - BUF_SIZE_8KiB, DMA_TO_DEVICE);
> - desc->des3 = desc->des2 + BUF_SIZE_4KiB;
> - priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
> - csum_insertion);
> -
> - entry = (++priv->cur_tx) % txsize;
> - desc = priv->dma_tx + entry;
> -
> - desc->des2 = dma_map_single(priv->device,
> - skb->data + BUF_SIZE_8KiB,
> - buf2_size, DMA_TO_DEVICE);
> - desc->des3 = desc->des2 + BUF_SIZE_4KiB;
> - priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size,
> - csum_insertion);
> - priv->hw->desc->set_tx_owner(desc);
> - priv->tx_skbuff[entry] = NULL;
> - } else {
> - desc->des2 = dma_map_single(priv->device, skb->data,
> - nopaged_len, DMA_TO_DEVICE);
> - desc->des3 = desc->des2 + BUF_SIZE_4KiB;
> - priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
> - csum_insertion);
> - }
> - return entry;
> -}
> -
> /**
> * stmmac_xmit:
> * @skb : the socket buffer
> @@ -1083,6 +1056,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
> int i, csum_insertion = 0;
> int nfrags = skb_shinfo(skb)->nr_frags;
> struct dma_desc *desc, *first;
> + unsigned int nopaged_len = skb_headlen(skb);
>
> if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
> if (!netif_queue_stopped(dev)) {
> @@ -1103,7 +1077,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
> pr_info("stmmac xmit:\n"
> "\tskb addr %p - len: %d - nopaged_len: %d\n"
> "\tn_frags: %d - ip_summed: %d - %s gso\n",
> - skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
> + skb, skb->len, nopaged_len, nfrags, skb->ip_summed,
> !skb_is_gso(skb) ? "isn't" : "is");
> #endif
>
> @@ -1116,14 +1090,14 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
> if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
> pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
> "\t\tn_frags: %d, ip_summed: %d\n",
> - skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
> + skb->len, nopaged_len, nfrags, skb->ip_summed);
> #endif
> priv->tx_skbuff[entry] = skb;
> - if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
> - entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
> +
> + if (priv->hw->ring->is_jumbo_frm(skb->len, priv->plat->enh_desc)) {
> + entry = priv->hw->ring->jumbo_frm(priv, skb, csum_insertion);
> desc = priv->dma_tx + entry;
> } else {
> - unsigned int nopaged_len = skb_headlen(skb);
> desc->des2 = dma_map_single(priv->device, skb->data,
> nopaged_len, DMA_TO_DEVICE);
> priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
> @@ -1214,11 +1188,10 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
> DMA_FROM_DEVICE);
>
> (p + entry)->des2 = priv->rx_skbuff_dma[entry];
> - if (unlikely(priv->plat->has_gmac)) {
> - if (bfsize >= BUF_SIZE_8KiB)
> - (p + entry)->des3 =
> - (p + entry)->des2 + BUF_SIZE_8KiB;
> - }
> +
> + if (unlikely(priv->plat->has_gmac))
> + priv->hw->ring->refill_desc3(bfsize, p + entry);
> +
> RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
> }
> wmb();
> @@ -1795,6 +1768,7 @@ static int stmmac_mac_device_setup(struct net_device *dev)
> device->desc = &ndesc_ops;
>
> priv->hw = device;
> + priv->hw->ring = &ring_mode_ops;
>
> if (device_can_wakeup(priv->device)) {
> priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
^ permalink raw reply
* Re: [PATCH] Fix guest memory leak and panic
From: Ian Campbell @ 2011-10-18 9:47 UTC (permalink / raw)
To: Krishna Kumar
Cc: rusty@rustcorp.com.au, mst@redhat.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org,
virtualization@lists.linux-foundation.org, davem@davemloft.net
In-Reply-To: <1318927016.16132.49.camel@zakaz.uk.xensource.com>
On Tue, 2011-10-18 at 09:36 +0100, Ian Campbell wrote:
> I think the best thing might be to remove the additional ref taking from
> the setter function and audit the previous changes to ensure they
> conform. I'll do that right away and post a fixup patch ASAP.
Sigh, only one out of the ten callers of (__)skb_frag_set_page expects
skb_frag_set_page to take a new reference. I think that's pretty
comprehensive evidence that the current behaviour is unexpected and
wrong.
Sorry about this.
Ian.
8<---------------------------------------------------------
>From 42c26b7ca640bd5cb6f9c3bc76db96c92ed8ff82 Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@citrix.com>
Date: Tue, 18 Oct 2011 09:59:37 +0100
Subject: [PATCH] net: do not take an additional reference in skb_frag_set_page
I audited all of the callers in the tree and only one of them (pktgen) expects
it to do so. Taking this reference is pretty obviously confusing and error
prone.
In particular I looked at the following commits which switched callers of
(__)skb_frag_set_page to the skb paged fragment api:
6a930b9f163d7e6d9ef692e05616c4ede65038ec cxgb3: convert to SKB paged frag API.
5dc3e196ea21e833128d51eb5b788a070fea1f28 myri10ge: convert to SKB paged frag API.
0e0634d20dd670a89af19af2a686a6cce943ac14 vmxnet3: convert to SKB paged frag API.
86ee8130a46769f73f8f423f99dbf782a09f9233 virtionet: convert to SKB paged frag API.
4a22c4c919c201c2a7f4ee09e672435a3072d875 sfc: convert to SKB paged frag API.
18324d690d6a5028e3c174fc1921447aedead2b8 cassini: convert to SKB paged frag API.
b061b39e3ae18ad75466258cf2116e18fa5bbd80 benet: convert to SKB paged frag API.
b7b6a688d217936459ff5cf1087b2361db952509 bnx2: convert to SKB paged frag API.
804cf14ea5ceca46554d5801e2817bba8116b7e5 net: xfrm: convert to SKB frag APIs
ea2ab69379a941c6f8884e290fdd28c93936a778 net: convert core to skb paged frag APIs
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
include/linux/skbuff.h | 1 -
net/core/pktgen.c | 1 +
2 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 64f8695..78741da 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1765,7 +1765,6 @@ static inline void *skb_frag_address_safe(const skb_frag_t *frag)
static inline void __skb_frag_set_page(skb_frag_t *frag, struct page *page)
{
frag->page = page;
- __skb_frag_ref(frag);
}
/**
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 796044a..c4effd4 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2603,6 +2603,7 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
break;
}
skb_frag_set_page(skb, i, pkt_dev->page);
+ skb_frag_ref(skb, i);
skb_shinfo(skb)->frags[i].page_offset = 0;
/*last fragment, fill rest of data*/
if (i == (frags - 1))
--
1.7.2.5
^ permalink raw reply related
* Re: [PATCH v13 0/6] flexcan: Add support for powerpc flexcan (freescale p1010)
From: Robin Holt @ 2011-10-18 9:43 UTC (permalink / raw)
To: Kumar Gala
Cc: Robin Holt, David S. Miller, Wolfgang Grandegger,
Marc Kleine-Budde, U Bhaskar-B22300, socketcan-core, netdev,
PPC list
In-Reply-To: <16FBAA47-5133-43A1-80CE-C6D63B79FB5D@kernel.crashing.org>
On Tue, Oct 18, 2011 at 12:44:07AM -0500, Kumar Gala wrote:
>
> On Aug 16, 2011, at 10:32 PM, Robin Holt wrote:
>
> > David,
> >
> > The following set of patches have been reviewed by the above parties and
> > all comments have been integrated. Although the patches stray from the
> > drivers/net/can directory, the diversions are related to changes for
> > the flexcan driver.
> >
> > The patch set is based upon your net-next-2.6 tree's commit 6c37e46.
> >
> > Could you please queue these up for the next appropriate push to Linus'
> > tree?
> >
> > Thanks,
> > Robin Holt
>
> Robin,
>
> Do you remember why we went with just 'fsl,p1010-flexcan' as the device tree compatible? Do we feel the flex can on P1010 isn't the same as on MPC5xxx? or the ARM SoCs?
The decision was due to the fact there is no true "generic" fsl.flexcan
chip free of any SOC implementation and therefore not something which
could be separately defined. That decision was made by Grant Likely.
I will inline that email below.
Robin
On Mon, Aug 15, 2011 at 09:13:50AM -0600, Grant Likely wrote:
> On Mon, Aug 15, 2011 at 9:03 AM, Robin Holt <holt@sgi.com> wrote:
> > Grant,
> >
> > Earlier, you had asked for a more specific name for the compatible
> > property of the Freescale flexcan device. I still have not gotten a
> > more specific answer. Hopefully Marc can give you more details about
> > the flexcan implementations.
>
> If there is no ip core version, then just stick with the
> fsl,<soc>-flexcan name and drop "fsl,flexcan". Marketing may say
> flexcan is flexcan, but hardware engineers like to change things.
> Trying to be too generic in compatible values will just lead to
> problems in the future.
Thanks,
Robin
^ permalink raw reply
* Re: PROBLEM: System call 'sendmsg' of process ospfd (quagga) causes kernel oops
From: Herbert Xu @ 2011-10-18 9:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Elmar Vonlanthen, linux-kernel, netdev, Timo Teräs
In-Reply-To: <1318905032.2571.35.camel@edumazet-laptop>
On Tue, Oct 18, 2011 at 04:30:32AM +0200, Eric Dumazet wrote:
>
> If David/Herbert/Timo agree, then patch should find its way into current
> kernel, then to stable trees as well.
Actually, I think we should instead fix the users of needed_headroom
to not read it twice which is causing problems here.
GRE tunnels by their nature do not have a fixed value for
needed_headroom. As the underlying routes change the necessary
headroom may need to be adjusted due to further encapsulation such
as IPsec.
Keeping it constant from tunnel creation may result in suboptimal
performance due to unnecessary header reallocations.
However, until we audit the stack to see if there are further
instances of double-readings such as the one causing the crash
here, I'm fine with your patch making it constant.
Once we're sure that all of the double-readings are gone we
can revert to a dynamic needed_headroom.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [net-next 4/7] stmmac: allow mtu bigger than 1500 in case of normal desc (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 9:26 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, davem, Deepak SIKRI
In-Reply-To: <1318928605.2657.18.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Hello Eric,
On 10/18/2011 11:03 AM, Eric Dumazet wrote:
> Le mardi 18 octobre 2011 à 10:42 +0200, Giuseppe CAVALLARO a écrit :
>> This patch allows to set the mtu bigger than 1500
>> in case of normal descriptors.
>> This is helping some SPEAr customers.
>>
>> Signed-off-by: Deepak SIKRI <deepak.sikri@st.com>
>> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>> ---
>> drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 8 +++++++-
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
>> 2 files changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
>> index 029c2a2..e13226b 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
>> @@ -126,6 +126,7 @@ static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
>> for (i = 0; i < ring_size; i++) {
>> p->des01.rx.own = 1;
>> p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
>> + p->des01.rx.buffer2_size = BUF_SIZE_2KiB - 1;
>> if (i == ring_size - 1)
>> p->des01.rx.end_ring = 1;
>> if (disable_rx_ic)
>> @@ -183,7 +184,12 @@ static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
>> int csum_flag)
>> {
>> p->des01.tx.first_segment = is_fs;
>> - p->des01.tx.buffer1_size = len;
>> +
>> + if (unlikely(len > BUF_SIZE_2KiB)) {
>> + p->des01.etx.buffer1_size = BUF_SIZE_2KiB - 1;
>> + p->des01.etx.buffer2_size = len - p->des01.etx.buffer1_size;
>> + } else
>> + p->des01.tx.buffer1_size = len;
>> }
>>
>> static void ndesc_clear_tx_ic(struct dma_desc *p)
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index d0af002..622b7ac 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -1412,10 +1412,10 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
>> return -EBUSY;
>> }
>>
>> - if (priv->plat->has_gmac)
>> + if (priv->plat->enh_desc)
>> max_mtu = JUMBO_LEN;
>> else
>> - max_mtu = ETH_DATA_LEN;
>> + max_mtu = BUF_SIZE_4KiB;
>>
>> if ((new_mtu < 46) || (new_mtu > max_mtu)) {
>> pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
>
> Problem using big mtu around 4096 bytes is you end allocating (4096
> +NET_SKB_PAD + NET_IP_ALIGN + sizeof(struct skb_shared_info) bytes ->
> 8192 bytes : order-1 pages
yes.
>
> Maybe it would be better to limit your mtu to SKB_MAX_HEAD(NET_SKB_PAD),
> to have no more than one page per skb ?
ok! ;-)
> I would suggest changing netdev_alloc_skb_ip_align() done in
> init_dma_desc_rings() to use a variant allowing GFP_KERNEL allocations
> and allow your driver to load even in case of memory pressure.
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index c0ee6b6..8ec8057 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -458,11 +458,12 @@ static void init_dma_desc_rings(struct net_device *dev)
> for (i = 0; i < rxsize; i++) {
> struct dma_desc *p = priv->dma_rx + i;
>
> - skb = netdev_alloc_skb_ip_align(dev, bfsize);
> + skb = __netdev_alloc_skb(dev, bfsize + NET_IP_ALIGN, GFP_KERNEL);
> if (unlikely(skb == NULL)) {
> pr_err("%s: Rx init fails; skb is NULL\n", __func__);
> break;
> }
> + skb_reserve(skb, NET_IP_ALIGN);
> priv->rx_skbuff[i] = skb;
> priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
> bfsize, DMA_FROM_DEVICE);
>
>
>
Agree! I'm reviewing the patches and send all again.
Many thanks
Regards
Peppe
^ permalink raw reply
* Re: [PATCH] route:ip_rt_frag_needed always return unzero
From: Eric Dumazet @ 2011-10-18 9:23 UTC (permalink / raw)
To: Gao feng; +Cc: davem, kuznet, jmorris, netdev
In-Reply-To: <1318921469-25599-1-git-send-email-gaofeng@cn.fujitsu.com>
Le mardi 18 octobre 2011 à 15:04 +0800, Gao feng a écrit :
> int function ip_rt_frag_need,if peer is null,
> there is no need to do ipprot->err_handler.
> I am right?
>
> Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
> ---
> net/ipv4/route.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 075212e..6cde0fa 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -1574,7 +1574,7 @@ unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
>
> atomic_inc(&__rt_peer_genid);
> }
> - return est_mtu ? : new_mtu;
> + return est_mtu;
> }
>
> static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer)
No idea why you want this, your changelog is a bit cryptic :)
Wont this bypass the raw_icmp_error(skb, protocol, info);
call in icmp_unreach() as well ?
^ permalink raw reply
* Re: [PATCH net-next] neigh: fix rcu splat in neigh_update()
From: Eric Dumazet @ 2011-10-18 9:11 UTC (permalink / raw)
To: roy.qing.li; +Cc: ari.m.savolainen, netdev
In-Reply-To: <1318926762-14563-1-git-send-email-roy.qing.li@gmail.com>
Le mardi 18 octobre 2011 à 16:32 +0800, roy.qing.li@gmail.com a écrit :
> when use dst_get_neighbour to get neighbour, we need
> rcu_read_lock to protect, since dst_get_neighbour uses
> rcu_dereference.
>
> The bug was reported by Ari Savolainen <ari.m.savolainen@gmail.com>
>
...
>
> Reported-by: Ari Savolainen <ari.m.savolainen@gmail.com>
> Signed-off-by: RongQing <roy.qing.li@gmail.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
^ permalink raw reply
* RE: [PATCH 6/7] mlx4_en: Adding rxhash support
From: Yevgeny Petrilin @ 2011-10-18 8:59 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <1318926870.2657.5.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
>
> What is the gain using random values ?
>
> Usually, we tend to have same hardware in a single machine, or we use
> active-backup bonding mode, and an active slave flip can change rxhash
> values with litle effect, since this happens not often.
>
> I really prefer not random values, because it allows to have replayable
> configurations : For a given tcp flow, the same rxhash value is given
> and same cpu target in RPS. Its way easier to tune your machine for some workloads.
>
There is no gain in random values,
I'll make the change to have static value for RSS function.
We might consider how to ensure consistency across the different drivers in this aspect.
^ permalink raw reply
* Re: [net-next 4/7] stmmac: allow mtu bigger than 1500 in case of normal desc (V3)
From: Eric Dumazet @ 2011-10-18 9:03 UTC (permalink / raw)
To: Giuseppe CAVALLARO; +Cc: netdev, davem, Deepak SIKRI
In-Reply-To: <1318927331-20855-5-git-send-email-peppe.cavallaro@st.com>
Le mardi 18 octobre 2011 à 10:42 +0200, Giuseppe CAVALLARO a écrit :
> This patch allows to set the mtu bigger than 1500
> in case of normal descriptors.
> This is helping some SPEAr customers.
>
> Signed-off-by: Deepak SIKRI <deepak.sikri@st.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 8 +++++++-
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
> 2 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
> index 029c2a2..e13226b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
> @@ -126,6 +126,7 @@ static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
> for (i = 0; i < ring_size; i++) {
> p->des01.rx.own = 1;
> p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
> + p->des01.rx.buffer2_size = BUF_SIZE_2KiB - 1;
> if (i == ring_size - 1)
> p->des01.rx.end_ring = 1;
> if (disable_rx_ic)
> @@ -183,7 +184,12 @@ static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
> int csum_flag)
> {
> p->des01.tx.first_segment = is_fs;
> - p->des01.tx.buffer1_size = len;
> +
> + if (unlikely(len > BUF_SIZE_2KiB)) {
> + p->des01.etx.buffer1_size = BUF_SIZE_2KiB - 1;
> + p->des01.etx.buffer2_size = len - p->des01.etx.buffer1_size;
> + } else
> + p->des01.tx.buffer1_size = len;
> }
>
> static void ndesc_clear_tx_ic(struct dma_desc *p)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index d0af002..622b7ac 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1412,10 +1412,10 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
> return -EBUSY;
> }
>
> - if (priv->plat->has_gmac)
> + if (priv->plat->enh_desc)
> max_mtu = JUMBO_LEN;
> else
> - max_mtu = ETH_DATA_LEN;
> + max_mtu = BUF_SIZE_4KiB;
>
> if ((new_mtu < 46) || (new_mtu > max_mtu)) {
> pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
Problem using big mtu around 4096 bytes is you end allocating (4096
+NET_SKB_PAD + NET_IP_ALIGN + sizeof(struct skb_shared_info) bytes ->
8192 bytes : order-1 pages
Maybe it would be better to limit your mtu to SKB_MAX_HEAD(NET_SKB_PAD),
to have no more than one page per skb ?
I would suggest changing netdev_alloc_skb_ip_align() done in
init_dma_desc_rings() to use a variant allowing GFP_KERNEL allocations
and allow your driver to load even in case of memory pressure.
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c0ee6b6..8ec8057 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -458,11 +458,12 @@ static void init_dma_desc_rings(struct net_device *dev)
for (i = 0; i < rxsize; i++) {
struct dma_desc *p = priv->dma_rx + i;
- skb = netdev_alloc_skb_ip_align(dev, bfsize);
+ skb = __netdev_alloc_skb(dev, bfsize + NET_IP_ALIGN, GFP_KERNEL);
if (unlikely(skb == NULL)) {
pr_err("%s: Rx init fails; skb is NULL\n", __func__);
break;
}
+ skb_reserve(skb, NET_IP_ALIGN);
priv->rx_skbuff[i] = skb;
priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
bfsize, DMA_FROM_DEVICE);
^ permalink raw reply related
* Re: [PATCH v2 0/2] MAINTAINERS: can: the mailinglist moved to vger.kernel.org
From: Marc Kleine-Budde @ 2011-10-18 9:00 UTC (permalink / raw)
To: David Miller; +Cc: linux-can, netdev
In-Reply-To: <20111017.192304.702126748312724567.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]
On 10/18/2011 01:23 AM, David Miller wrote:
> From: Marc Kleine-Budde <mkl@pengutronix.de>
> Date: Mon, 17 Oct 2011 21:31:58 +0200
>
>> Hello,
>>
>> the BerliOS project will close with the end of the year, so we moved our
>> mailinglist to vger.kernel.org, it's now linux-can@vger.kernel.org.
>>
>> This patch series change the mailinglist in MAINTAINERS and remove all other
>> references from the source tree. As David pointed out, automated tool will
>> use MAINTAINERS to gather this information.
>>
>> cheers, Marc
>>
>> The following changes since commit fd38f734cb8200529e281338514945fcbff2364b:
>>
>> igbvf: convert to ndo_fix_features (2011-10-16 13:18:47 -0700)
>>
>> are available in the git repository at:
>> git.pengutronix.de:/git/mkl/linux-2.6.git can/mailinglist-for-net-next
>
> That URL prompts me for a password, so I applied these patches by hand
> to net-next, thanks.
Sorry - my fault. That was my commit address.
regards, Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply
* RE: [PATCH 3/7] mlx4_en: Incoming traffic alignment optimizations
From: Yevgeny Petrilin @ 2011-10-18 8:52 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <1318927207.2657.10.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
>
> Oh my...
>
> Of course you are aware that the 'truesize' stuff around means that using big frag size will probably lower your performance number, unless you allow protocol stacks to use more ram ?
>
> Only possible drawback using 512 bytes instead of 2048 is the cache-line bounce on the page->_count field. So I would say your change hides a performance issue of your driver.
>
> Maybe you should make sure you dont touch it too often [ You should use a single add per allocated PAGE, not 2 (for 2048-bytes frags) or 8 (for 512-bytes frags) ]
>
>
Thanks Eric,
I'll check this.
In the meanwhile will resubmit the series without this change.
^ permalink raw reply
* Re: [net-next 0/7] stmmac: update to Oct 2011 version (V2)
From: Giuseppe CAVALLARO @ 2011-10-18 8:44 UTC (permalink / raw)
To: netdev; +Cc: davem
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
Sorry this is the V3 :-(
Peppe
On 10/18/2011 10:42 AM, Giuseppe CAVALLARO wrote:
> This patches update the driver adding the chained
> descriptor mode and some new useful fixes.
>
> I've reviewed some patches after the V1 and V2:
>
> stmmac: allow mtu bigger than 1500 in case of normal desc (V3)
> |-> removed the useless max_mtu init: Thx Eric's feedback
>
> stmmac: add CHAINED descriptor mode support (V3)
> |-> removed ifdef in the C and added small routines
> specialised for chained/ring modes. See comment
> within the patch itself. Thx David's feedback.
>
> stmmac: allow mmc usage only if feature actually available (V3)
> |-> added a check if interface is NULL
>
> In the end, I added two new small patches:
>
> stmmac: use predefined macros for HW cap register fields (V3)
> stmmac: allow mmc usage only if feature actually available (V3)
>
> made by Rayagond and reviewed/reworked by myself
>
> Let me know if it's ok.
>
> Giuseppe Cavallaro (5):
> stmmac: protect tx process with lock (V3)
> stmmac: update the driver version and doc (V3)
> stmmac: allow mtu bigger than 1500 in case of normal desc (V3)
> stmmac: allow mmc usage only if feature actually available (V3)
> stmmac: add CHAINED descriptor mode support (V3)
>
> Rayagond Kokatanur (1):
> stmmac: use predefined macros for HW cap register fields (V3)
>
> Srinivas Kandagatla (1):
> stmmac: Stop advertising 1000Base capabilties for non GMII iface
> (V3).
>
> Documentation/networking/stmmac.txt | 11 +-
> drivers/net/ethernet/stmicro/stmmac/Kconfig | 18 ++
> drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +
> drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 137 +++++++++++++
> drivers/net/ethernet/stmicro/stmmac/common.h | 43 ++++
> drivers/net/ethernet/stmicro/stmmac/descs_com.h | 126 ++++++++++++
> drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 22 +--
> drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 14 +-
> drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 126 ++++++++++++
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 5 +-
> .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 24 ++-
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 212 ++++++++++----------
> 12 files changed, 602 insertions(+), 138 deletions(-)
> create mode 100644 drivers/net/ethernet/stmicro/stmmac/chain_mode.c
> create mode 100644 drivers/net/ethernet/stmicro/stmmac/descs_com.h
> create mode 100644 drivers/net/ethernet/stmicro/stmmac/ring_mode.c
>
^ permalink raw reply
* [net-next 6/7] stmmac: allow mmc usage only if feature actually available (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro, Rayagond Kokatanur
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
Enable the MMC support if it is actually available from the
HW capability register.
Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 24 +++++++++++--------
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +-
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index aedff9a..406404f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -96,7 +96,7 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
{ #m, FIELD_SIZEOF(struct stmmac_counters, m), \
offsetof(struct stmmac_priv, mmc.m)}
-static const struct stmmac_stats stmmac_gstr_mmc[] = {
+static const struct stmmac_stats stmmac_mmc[] = {
STMMAC_MMC_STAT(mmc_tx_octetcount_gb),
STMMAC_MMC_STAT(mmc_tx_framecount_gb),
STMMAC_MMC_STAT(mmc_tx_broadcastframe_g),
@@ -177,7 +177,7 @@ static const struct stmmac_stats stmmac_gstr_mmc[] = {
STMMAC_MMC_STAT(mmc_rx_icmp_gd_octets),
STMMAC_MMC_STAT(mmc_rx_icmp_err_octets),
};
-#define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_gstr_mmc)
+#define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_mmc)
static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
@@ -348,13 +348,17 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
priv->ioaddr);
else {
/* If supported, for new GMAC chips expose the MMC counters */
- dwmac_mmc_read(priv->ioaddr, &priv->mmc);
+ if (priv->dma_cap.rmon) {
+ dwmac_mmc_read(priv->ioaddr, &priv->mmc);
- for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
- char *p = (char *)priv + stmmac_gstr_mmc[i].stat_offset;
+ for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
+ char *p;
+ p = (char *)priv + stmmac_mmc[i].stat_offset;
- data[j++] = (stmmac_gstr_mmc[i].sizeof_stat ==
- sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
+ data[j++] = (stmmac_mmc[i].sizeof_stat ==
+ sizeof(u64)) ? (*(u64 *)p) :
+ (*(u32 *)p);
+ }
}
}
for (i = 0; i < STMMAC_STATS_LEN; i++) {
@@ -373,7 +377,7 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_STATS:
len = STMMAC_STATS_LEN;
- if (priv->plat->has_gmac)
+ if (priv->dma_cap.rmon)
len += STMMAC_MMC_STATS_LEN;
return len;
@@ -390,9 +394,9 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
switch (stringset) {
case ETH_SS_STATS:
- if (priv->plat->has_gmac)
+ if (priv->dma_cap.rmon)
for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
- memcpy(p, stmmac_gstr_mmc[i].stat_string,
+ memcpy(p, stmmac_mmc[i].stat_string,
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 125a177..7325256 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -946,7 +946,8 @@ static int stmmac_open(struct net_device *dev)
memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
priv->xstats.threshold = tc;
- stmmac_mmc_setup(priv);
+ if (priv->dma_cap.rmon)
+ stmmac_mmc_setup(priv);
/* Start the ball rolling... */
DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
--
1.7.4.4
^ permalink raw reply related
* [net-next 7/7] stmmac: add CHAINED descriptor mode support (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro, Rayagond Kokatanur
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
This patch enhances the STMMAC driver to support CHAINED mode of
descriptor.
STMMAC supports DMA descriptor to operate both in dual buffer(RING)
and linked-list(CHAINED) mode. In RING mode (default) each descriptor
points to two data buffer pointers whereas in CHAINED mode they point
to only one data buffer pointer.
In CHAINED mode each descriptor will have pointer to next descriptor in
the list, hence creating the explicit chaining in the descriptor itself,
whereas such explicit chaining is not possible in RING mode.
First version of this work has been done by Rayagond.
Then the patch has been reworked avoiding ifdef inside the C code.
A new header file has been added to define all the functions needed for
managing enhanced and normal descriptors.
In fact, these have to be specialized according to the ring/chain usage.
Two new C files have been also added to implement the helper routines
needed to manage: jumbo frames, chain and ring setup (i.e. desc3).
Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/Kconfig | 18 +++
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 137 +++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/common.h | 13 ++
drivers/net/ethernet/stmicro/stmmac/descs_com.h | 126 +++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 22 ++--
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 20 +--
drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 126 +++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 130 ++++++++------------
10 files changed, 491 insertions(+), 105 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/chain_mode.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/descs_com.h
create mode 100644 drivers/net/ethernet/stmicro/stmmac/ring_mode.c
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 8cd9dde..ac6f190 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -63,4 +63,22 @@ config STMMAC_RTC_TIMER
endchoice
+choice
+ prompt "Select the DMA TX/RX descriptor operating modes"
+ depends on STMMAC_ETH
+ ---help---
+ This driver supports DMA descriptor to operate both in dual buffer
+ (RING) and linked-list(CHAINED) mode. In RING mode each descriptor
+ points to two data buffer pointers whereas in CHAINED mode they
+ points to only one data buffer pointer.
+
+config STMMAC_RING
+ bool "Enable Descriptor Ring Mode"
+
+config STMMAC_CHAINED
+ bool "Enable Descriptor Chained Mode"
+
+endchoice
+
+
endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 0f23d95..d7c4516 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -1,5 +1,7 @@
obj-$(CONFIG_STMMAC_ETH) += stmmac.o
stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
+stmmac-$(CONFIG_STMMAC_RING) += ring_mode.o
+stmmac-$(CONFIG_STMMAC_CHAINED) += chain_mode.o
stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
new file mode 100644
index 0000000..0668659
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ Specialised functions for managing Chained mode
+
+ Copyright(C) 2011 STMicroelectronics Ltd
+
+ It defines all the functions used to handle the normal/enhanced
+ descriptors in case of the DMA is configured to work in chained or
+ in ring mode.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include "stmmac.h"
+
+unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
+{
+ struct stmmac_priv *priv = (struct stmmac_priv *) p;
+ unsigned int txsize = priv->dma_tx_size;
+ unsigned int entry = priv->cur_tx % txsize;
+ struct dma_desc *desc = priv->dma_tx + entry;
+ unsigned int nopaged_len = skb_headlen(skb);
+ unsigned int bmax;
+ unsigned int i = 1, len;
+
+ if (priv->plat->enh_desc)
+ bmax = BUF_SIZE_8KiB;
+ else
+ bmax = BUF_SIZE_2KiB;
+
+ len = nopaged_len - bmax;
+
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ bmax, DMA_TO_DEVICE);
+ priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum);
+
+ while (len != 0) {
+ entry = (++priv->cur_tx) % txsize;
+ desc = priv->dma_tx + entry;
+
+ if (len > bmax) {
+ desc->des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i),
+ bmax, DMA_TO_DEVICE);
+ priv->hw->desc->prepare_tx_desc(desc, 0, bmax,
+ csum);
+ priv->hw->desc->set_tx_owner(desc);
+ priv->tx_skbuff[entry] = NULL;
+ len -= bmax;
+ i++;
+ } else {
+ desc->des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i), len,
+ DMA_TO_DEVICE);
+ priv->hw->desc->prepare_tx_desc(desc, 0, len,
+ csum);
+ priv->hw->desc->set_tx_owner(desc);
+ priv->tx_skbuff[entry] = NULL;
+ len = 0;
+ }
+ }
+ return entry;
+}
+
+static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
+{
+ unsigned int ret = 0;
+
+ if ((enh_desc && (len > BUF_SIZE_8KiB)) ||
+ (!enh_desc && (len > BUF_SIZE_2KiB))) {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static void stmmac_refill_desc3(int bfsize, struct dma_desc *p)
+{
+}
+
+static void stmmac_init_desc3(int des3_as_data_buf, struct dma_desc *p)
+{
+}
+
+static void stmmac_clean_desc3(struct dma_desc *p)
+{
+}
+
+static void stmmac_init_dma_chain(struct dma_desc *des, dma_addr_t phy_addr,
+ unsigned int size)
+{
+ /*
+ * In chained mode the des3 points to the next element in the ring.
+ * The latest element has to point to the head.
+ */
+ int i;
+ struct dma_desc *p = des;
+ dma_addr_t dma_phy = phy_addr;
+
+ for (i = 0; i < (size - 1); i++) {
+ dma_phy += sizeof(struct dma_desc);
+ p->des3 = (unsigned int)dma_phy;
+ p++;
+ }
+ p->des3 = (unsigned int)phy_addr;
+}
+
+static int stmmac_set_16kib_bfsize(int mtu)
+{
+ /* Not supported */
+ return 0;
+}
+
+const struct stmmac_ring_mode_ops ring_mode_ops = {
+ .is_jumbo_frm = stmmac_is_jumbo_frm,
+ .jumbo_frm = stmmac_jumbo_frm,
+ .refill_desc3 = stmmac_refill_desc3,
+ .init_desc3 = stmmac_init_desc3,
+ .init_dma_chain = stmmac_init_dma_chain,
+ .clean_desc3 = stmmac_clean_desc3,
+ .set_16kib_bfsize = stmmac_set_16kib_bfsize,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index ffba014..9100c10 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -287,10 +287,22 @@ struct mii_regs {
unsigned int data; /* MII Data */
};
+struct stmmac_ring_mode_ops {
+ unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
+ unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum);
+ void (*refill_desc3) (int bfsize, struct dma_desc *p);
+ void (*init_desc3) (int des3_as_data_buf, struct dma_desc *p);
+ void (*init_dma_chain) (struct dma_desc *des, dma_addr_t phy_addr,
+ unsigned int size);
+ void (*clean_desc3) (struct dma_desc *p);
+ int (*set_16kib_bfsize) (int mtu);
+};
+
struct mac_device_info {
const struct stmmac_ops *mac;
const struct stmmac_desc_ops *desc;
const struct stmmac_dma_ops *dma;
+ const struct stmmac_ring_mode_ops *ring;
struct mii_regs mii; /* MII register Addresses */
struct mac_link link;
unsigned int synopsys_uid;
@@ -304,3 +316,4 @@ extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
unsigned int high, unsigned int low);
extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
+extern const struct stmmac_ring_mode_ops ring_mode_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h
new file mode 100644
index 0000000..1652c86
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ Header File to describe Normal/enhanced descriptor functions used for RING
+ and CHAINED modes.
+
+ Copyright(C) 2011 STMicroelectronics Ltd
+
+ It defines all the functions used to handle the normal/enhanced
+ descriptors in case of the DMA is configured to work in chained or
+ in ring mode.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#if defined(CONFIG_STMMAC_RING)
+static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end)
+{
+ p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
+ if (end)
+ p->des01.erx.end = 1;
+}
+
+static inline void ehn_desc_tx_set_on_ring_chain(struct dma_desc *p, int end)
+{
+ if (end)
+ p->des01.etx.end = 1;
+}
+
+static inline void enh_desc_end_tx_desc(struct dma_desc *p, int ter)
+{
+ p->des01.etx.end = ter;
+}
+
+static inline void enh_set_tx_desc_len(struct dma_desc *p, int len)
+{
+ if (unlikely(len > BUF_SIZE_4KiB)) {
+ p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
+ p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
+ } else
+ p->des01.etx.buffer1_size = len;
+}
+
+static inline void ndesc_rx_set_on_ring_chain(struct dma_desc *p, int end)
+{
+ p->des01.rx.buffer2_size = BUF_SIZE_2KiB - 1;
+ if (end)
+ p->des01.rx.end = 1;
+}
+
+static inline void ndesc_tx_set_on_ring_chain(struct dma_desc *p, int end)
+{
+ if (end)
+ p->des01.tx.end = 1;
+}
+
+static inline void ndesc_end_tx_desc(struct dma_desc *p, int ter)
+{
+ p->des01.tx.end = ter;
+}
+
+static inline void norm_set_tx_desc_len(struct dma_desc *p, int len)
+{
+ if (unlikely(len > BUF_SIZE_2KiB)) {
+ p->des01.etx.buffer1_size = BUF_SIZE_2KiB - 1;
+ p->des01.etx.buffer2_size = len - p->des01.etx.buffer1_size;
+ } else
+ p->des01.tx.buffer1_size = len;
+}
+
+#else
+
+static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end)
+{
+ p->des01.erx.second_address_chained = 1;
+}
+
+static inline void ehn_desc_tx_set_on_ring_chain(struct dma_desc *p, int end)
+{
+ p->des01.etx.second_address_chained = 1;
+}
+
+static inline void enh_desc_end_tx_desc(struct dma_desc *p, int ter)
+{
+ p->des01.etx.second_address_chained = 1;
+}
+
+static inline void enh_set_tx_desc_len(struct dma_desc *p, int len)
+{
+ p->des01.etx.buffer1_size = len;
+}
+
+static inline void ndesc_rx_set_on_ring_chain(struct dma_desc *p, int end)
+{
+ p->des01.rx.second_address_chained = 1;
+}
+
+static inline void ndesc_tx_set_on_ring_chain(struct dma_desc *p, int ring_size)
+{
+ p->des01.tx.second_address_chained = 1;
+}
+
+static inline void ndesc_end_tx_desc(struct dma_desc *p, int ter)
+{
+ p->des01.tx.second_address_chained = 1;
+}
+
+static inline void norm_set_tx_desc_len(struct dma_desc *p, int len)
+{
+ p->des01.tx.buffer1_size = len;
+}
+#endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index e5dfb6a..d879763 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -23,6 +23,7 @@
*******************************************************************************/
#include "common.h"
+#include "descs_com.h"
static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x,
struct dma_desc *p, void __iomem *ioaddr)
@@ -233,10 +234,9 @@ static void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
for (i = 0; i < ring_size; i++) {
p->des01.erx.own = 1;
p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
- /* To support jumbo frames */
- p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
- if (i == ring_size - 1)
- p->des01.erx.end_ring = 1;
+
+ ehn_desc_rx_set_on_ring_chain(p, (i == ring_size - 1));
+
if (disable_rx_ic)
p->des01.erx.disable_ic = 1;
p++;
@@ -249,8 +249,7 @@ static void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
for (i = 0; i < ring_size; i++) {
p->des01.etx.own = 0;
- if (i == ring_size - 1)
- p->des01.etx.end_ring = 1;
+ ehn_desc_tx_set_on_ring_chain(p, (i == ring_size - 1));
p++;
}
}
@@ -285,19 +284,16 @@ static void enh_desc_release_tx_desc(struct dma_desc *p)
int ter = p->des01.etx.end_ring;
memset(p, 0, offsetof(struct dma_desc, des2));
- p->des01.etx.end_ring = ter;
+ enh_desc_end_tx_desc(p, ter);
}
static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
int csum_flag)
{
p->des01.etx.first_segment = is_fs;
- if (unlikely(len > BUF_SIZE_4KiB)) {
- p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
- p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
- } else {
- p->des01.etx.buffer1_size = len;
- }
+
+ enh_set_tx_desc_len(p, len);
+
if (likely(csum_flag))
p->des01.etx.checksum_insertion = cic_full;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index e13226b..f7e8ba7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -23,6 +23,7 @@
*******************************************************************************/
#include "common.h"
+#include "descs_com.h"
static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
struct dma_desc *p, void __iomem *ioaddr)
@@ -126,9 +127,9 @@ static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
for (i = 0; i < ring_size; i++) {
p->des01.rx.own = 1;
p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
- p->des01.rx.buffer2_size = BUF_SIZE_2KiB - 1;
- if (i == ring_size - 1)
- p->des01.rx.end_ring = 1;
+
+ ndesc_rx_set_on_ring_chain(p, (i == ring_size - 1));
+
if (disable_rx_ic)
p->des01.rx.disable_ic = 1;
p++;
@@ -140,8 +141,7 @@ static void ndesc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
int i;
for (i = 0; i < ring_size; i++) {
p->des01.tx.own = 0;
- if (i == ring_size - 1)
- p->des01.tx.end_ring = 1;
+ ndesc_tx_set_on_ring_chain(p, (i == (ring_size - 1)));
p++;
}
}
@@ -176,20 +176,14 @@ static void ndesc_release_tx_desc(struct dma_desc *p)
int ter = p->des01.tx.end_ring;
memset(p, 0, offsetof(struct dma_desc, des2));
- /* set termination field */
- p->des01.tx.end_ring = ter;
+ ndesc_end_tx_desc(p, ter);
}
static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
int csum_flag)
{
p->des01.tx.first_segment = is_fs;
-
- if (unlikely(len > BUF_SIZE_2KiB)) {
- p->des01.etx.buffer1_size = BUF_SIZE_2KiB - 1;
- p->des01.etx.buffer2_size = len - p->des01.etx.buffer1_size;
- } else
- p->des01.tx.buffer1_size = len;
+ norm_set_tx_desc_len(p, len);
}
static void ndesc_clear_tx_ic(struct dma_desc *p)
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
new file mode 100644
index 0000000..fb8377d
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ Specialised functions for managing Ring mode
+
+ Copyright(C) 2011 STMicroelectronics Ltd
+
+ It defines all the functions used to handle the normal/enhanced
+ descriptors in case of the DMA is configured to work in chained or
+ in ring mode.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include "stmmac.h"
+
+static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
+{
+ struct stmmac_priv *priv = (struct stmmac_priv *) p;
+ unsigned int txsize = priv->dma_tx_size;
+ unsigned int entry = priv->cur_tx % txsize;
+ struct dma_desc *desc = priv->dma_tx + entry;
+ unsigned int nopaged_len = skb_headlen(skb);
+ unsigned int bmax, len;
+
+ if (priv->plat->enh_desc)
+ bmax = BUF_SIZE_8KiB;
+ else
+ bmax = BUF_SIZE_2KiB;
+
+ len = nopaged_len - bmax;
+
+ if (nopaged_len > BUF_SIZE_8KiB) {
+
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ bmax, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->hw->desc->prepare_tx_desc(desc, 1, bmax,
+ csum);
+
+ entry = (++priv->cur_tx) % txsize;
+ desc = priv->dma_tx + entry;
+
+ desc->des2 = dma_map_single(priv->device, skb->data + bmax,
+ len, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->hw->desc->prepare_tx_desc(desc, 0, len, csum);
+ priv->hw->desc->set_tx_owner(desc);
+ priv->tx_skbuff[entry] = NULL;
+ } else {
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ nopaged_len, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum);
+ }
+
+ return entry;
+}
+
+static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
+{
+ unsigned int ret = 0;
+
+ if (len >= BUF_SIZE_4KiB)
+ ret = 1;
+
+ return ret;
+}
+
+static void stmmac_refill_desc3(int bfsize, struct dma_desc *p)
+{
+ /* Fill DES3 in case of RING mode */
+ if (bfsize >= BUF_SIZE_8KiB)
+ p->des3 = p->des2 + BUF_SIZE_8KiB;
+}
+
+/* In ring mode we need to fill the desc3 because it is used
+ * as buffer */
+static void stmmac_init_desc3(int des3_as_data_buf, struct dma_desc *p)
+{
+ if (unlikely(des3_as_data_buf))
+ p->des3 = p->des2 + BUF_SIZE_8KiB;
+}
+
+static void stmmac_init_dma_chain(struct dma_desc *des, dma_addr_t phy_addr,
+ unsigned int size)
+{
+}
+
+static void stmmac_clean_desc3(struct dma_desc *p)
+{
+ if (unlikely(p->des3))
+ p->des3 = 0;
+}
+
+static int stmmac_set_16kib_bfsize(int mtu)
+{
+ int ret = 0;
+ if (unlikely(mtu >= BUF_SIZE_8KiB))
+ ret = BUF_SIZE_16KiB;
+ return ret;
+}
+
+const struct stmmac_ring_mode_ops ring_mode_ops = {
+ .is_jumbo_frm = stmmac_is_jumbo_frm,
+ .jumbo_frm = stmmac_jumbo_frm,
+ .refill_desc3 = stmmac_refill_desc3,
+ .init_desc3 = stmmac_init_desc3,
+ .init_dma_chain = stmmac_init_dma_chain,
+ .clean_desc3 = stmmac_clean_desc3,
+ .set_16kib_bfsize = stmmac_set_16kib_bfsize,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 49a4af3..9bafa6c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -22,7 +22,7 @@
#define DRV_MODULE_VERSION "Oct_2011"
#include <linux/stmmac.h>
-
+#include <linux/phy.h>
#include "common.h"
#ifdef CONFIG_STMMAC_TIMER
#include "stmmac_timer.h"
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7325256..1848a16 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2,7 +2,7 @@
This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
ST Ethernet IPs are built around a Synopsys IP Core.
- Copyright (C) 2007-2009 STMicroelectronics Ltd
+ Copyright(C) 2007-2011 STMicroelectronics Ltd
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -41,17 +41,16 @@
#include <linux/if_ether.h>
#include <linux/crc32.h>
#include <linux/mii.h>
-#include <linux/phy.h>
#include <linux/if.h>
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/prefetch.h>
-#include "stmmac.h"
#ifdef CONFIG_STMMAC_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#endif
+#include "stmmac.h"
#define STMMAC_RESOURCE_NAME "stmmaceth"
@@ -388,11 +387,28 @@ static void display_ring(struct dma_desc *p, int size)
}
}
+static int stmmac_set_bfsize(int mtu, int bufsize)
+{
+ int ret = bufsize;
+
+ if (mtu >= BUF_SIZE_4KiB)
+ ret = BUF_SIZE_8KiB;
+ else if (mtu >= BUF_SIZE_2KiB)
+ ret = BUF_SIZE_4KiB;
+ else if (mtu >= DMA_BUFFER_SIZE)
+ ret = BUF_SIZE_2KiB;
+ else
+ ret = DMA_BUFFER_SIZE;
+
+ return ret;
+}
+
/**
* init_dma_desc_rings - init the RX/TX descriptor rings
* @dev: net device structure
* Description: this function initializes the DMA RX/TX descriptors
- * and allocates the socket buffers.
+ * and allocates the socket buffers. It suppors the chained and ring
+ * modes.
*/
static void init_dma_desc_rings(struct net_device *dev)
{
@@ -401,31 +417,24 @@ static void init_dma_desc_rings(struct net_device *dev)
struct sk_buff *skb;
unsigned int txsize = priv->dma_tx_size;
unsigned int rxsize = priv->dma_rx_size;
- unsigned int bfsize = priv->dma_buf_sz;
- int buff2_needed = 0, dis_ic = 0;
+ unsigned int bfsize;
+ int dis_ic = 0;
+ int des3_as_data_buf = 0;
- /* Set the Buffer size according to the MTU;
- * indeed, in case of jumbo we need to bump-up the buffer sizes.
- */
- if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
- bfsize = BUF_SIZE_16KiB;
- else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
- bfsize = BUF_SIZE_8KiB;
- else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
- bfsize = BUF_SIZE_4KiB;
- else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
- bfsize = BUF_SIZE_2KiB;
+ /* Set the max buffer size according to the DESC mode
+ * and the MTU. Note that RING mode allows 16KiB bsize. */
+ bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu);
+
+ if (bfsize == BUF_SIZE_16KiB)
+ des3_as_data_buf = 1;
else
- bfsize = DMA_BUFFER_SIZE;
+ bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
#ifdef CONFIG_STMMAC_TIMER
/* Disable interrupts on completion for the reception if timer is on */
if (likely(priv->tm->enable))
dis_ic = 1;
#endif
- /* If the MTU exceeds 8k so use the second buffer in the chain */
- if (bfsize >= BUF_SIZE_8KiB)
- buff2_needed = 1;
DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
txsize, rxsize, bfsize);
@@ -453,7 +462,7 @@ static void init_dma_desc_rings(struct net_device *dev)
return;
}
- DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
+ DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, "
"Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
dev->name, priv->dma_rx, priv->dma_tx,
(unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
@@ -475,8 +484,9 @@ static void init_dma_desc_rings(struct net_device *dev)
bfsize, DMA_FROM_DEVICE);
p->des2 = priv->rx_skbuff_dma[i];
- if (unlikely(buff2_needed))
- p->des3 = p->des2 + BUF_SIZE_8KiB;
+
+ priv->hw->ring->init_desc3(des3_as_data_buf, p);
+
DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
}
@@ -490,6 +500,12 @@ static void init_dma_desc_rings(struct net_device *dev)
priv->tx_skbuff[i] = NULL;
priv->dma_tx[i].des2 = 0;
}
+
+ /* In case of Chained mode this sets the des3 to the next
+ * element in the chain */
+ priv->hw->ring->init_dma_chain(priv->dma_rx, priv->dma_rx_phy, rxsize);
+ priv->hw->ring->init_dma_chain(priv->dma_tx, priv->dma_tx_phy, txsize);
+
priv->dirty_tx = 0;
priv->cur_tx = 0;
@@ -620,8 +636,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
dma_unmap_single(priv->device, p->des2,
priv->hw->desc->get_tx_len(p),
DMA_TO_DEVICE);
- if (unlikely(p->des3))
- p->des3 = 0;
+ priv->hw->ring->clean_desc3(p);
if (likely(skb != NULL)) {
/*
@@ -728,7 +743,6 @@ static void stmmac_no_timer_stopped(void)
*/
static void stmmac_tx_err(struct stmmac_priv *priv)
{
-
netif_stop_queue(priv->dev);
priv->hw->dma->stop_tx(priv->ioaddr);
@@ -1028,47 +1042,6 @@ static int stmmac_release(struct net_device *dev)
return 0;
}
-static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
- struct net_device *dev,
- int csum_insertion)
-{
- struct stmmac_priv *priv = netdev_priv(dev);
- unsigned int nopaged_len = skb_headlen(skb);
- unsigned int txsize = priv->dma_tx_size;
- unsigned int entry = priv->cur_tx % txsize;
- struct dma_desc *desc = priv->dma_tx + entry;
-
- if (nopaged_len > BUF_SIZE_8KiB) {
-
- int buf2_size = nopaged_len - BUF_SIZE_8KiB;
-
- desc->des2 = dma_map_single(priv->device, skb->data,
- BUF_SIZE_8KiB, DMA_TO_DEVICE);
- desc->des3 = desc->des2 + BUF_SIZE_4KiB;
- priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
- csum_insertion);
-
- entry = (++priv->cur_tx) % txsize;
- desc = priv->dma_tx + entry;
-
- desc->des2 = dma_map_single(priv->device,
- skb->data + BUF_SIZE_8KiB,
- buf2_size, DMA_TO_DEVICE);
- desc->des3 = desc->des2 + BUF_SIZE_4KiB;
- priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size,
- csum_insertion);
- priv->hw->desc->set_tx_owner(desc);
- priv->tx_skbuff[entry] = NULL;
- } else {
- desc->des2 = dma_map_single(priv->device, skb->data,
- nopaged_len, DMA_TO_DEVICE);
- desc->des3 = desc->des2 + BUF_SIZE_4KiB;
- priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
- csum_insertion);
- }
- return entry;
-}
-
/**
* stmmac_xmit:
* @skb : the socket buffer
@@ -1083,6 +1056,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
int i, csum_insertion = 0;
int nfrags = skb_shinfo(skb)->nr_frags;
struct dma_desc *desc, *first;
+ unsigned int nopaged_len = skb_headlen(skb);
if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
if (!netif_queue_stopped(dev)) {
@@ -1103,7 +1077,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
pr_info("stmmac xmit:\n"
"\tskb addr %p - len: %d - nopaged_len: %d\n"
"\tn_frags: %d - ip_summed: %d - %s gso\n",
- skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
+ skb, skb->len, nopaged_len, nfrags, skb->ip_summed,
!skb_is_gso(skb) ? "isn't" : "is");
#endif
@@ -1116,14 +1090,14 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
"\t\tn_frags: %d, ip_summed: %d\n",
- skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
+ skb->len, nopaged_len, nfrags, skb->ip_summed);
#endif
priv->tx_skbuff[entry] = skb;
- if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
- entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
+
+ if (priv->hw->ring->is_jumbo_frm(skb->len, priv->plat->enh_desc)) {
+ entry = priv->hw->ring->jumbo_frm(priv, skb, csum_insertion);
desc = priv->dma_tx + entry;
} else {
- unsigned int nopaged_len = skb_headlen(skb);
desc->des2 = dma_map_single(priv->device, skb->data,
nopaged_len, DMA_TO_DEVICE);
priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
@@ -1214,11 +1188,10 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
DMA_FROM_DEVICE);
(p + entry)->des2 = priv->rx_skbuff_dma[entry];
- if (unlikely(priv->plat->has_gmac)) {
- if (bfsize >= BUF_SIZE_8KiB)
- (p + entry)->des3 =
- (p + entry)->des2 + BUF_SIZE_8KiB;
- }
+
+ if (unlikely(priv->plat->has_gmac))
+ priv->hw->ring->refill_desc3(bfsize, p + entry);
+
RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
}
wmb();
@@ -1795,6 +1768,7 @@ static int stmmac_mac_device_setup(struct net_device *dev)
device->desc = &ndesc_ops;
priv->hw = device;
+ priv->hw->ring = &ring_mode_ops;
if (device_can_wakeup(priv->device)) {
priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
--
1.7.4.4
^ permalink raw reply related
* [net-next 5/7] stmmac: use predefined macros for HW cap register fields (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Rayagond Kokatanur, Giuseppe Cavallaro
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
From: Rayagond Kokatanur <rayagond@vayavyalabs.com>
Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 30 +++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 54 +++++++++++++--------
2 files changed, 63 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 22c61b2..ffba014 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -103,6 +103,36 @@ struct stmmac_extra_stats {
#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
+/* DAM HW feature register fields */
+#define DMA_HW_FEAT_MIISEL 0x00000001 /* 10/100 Mbps Support */
+#define DMA_HW_FEAT_GMIISEL 0x00000002 /* 1000 Mbps Support */
+#define DMA_HW_FEAT_HDSEL 0x00000004 /* Half-Duplex Support */
+#define DMA_HW_FEAT_EXTHASHEN 0x00000008 /* Expanded DA Hash Filter */
+#define DMA_HW_FEAT_HASHSEL 0x00000010 /* HASH Filter */
+#define DMA_HW_FEAT_ADDMACADRSEL 0x00000020 /* Multiple MAC Addr Reg */
+#define DMA_HW_FEAT_PCSSEL 0x00000040 /* PCS registers */
+#define DMA_HW_FEAT_L3L4FLTREN 0x00000080 /* Layer 3 & Layer 4 Feature */
+#define DMA_HW_FEAT_SMASEL 0x00000100 /* SMA(MDIO) Interface */
+#define DMA_HW_FEAT_RWKSEL 0x00000200 /* PMT Remote Wakeup */
+#define DMA_HW_FEAT_MGKSEL 0x00000400 /* PMT Magic Packet */
+#define DMA_HW_FEAT_MMCSEL 0x00000800 /* RMON Module */
+#define DMA_HW_FEAT_TSVER1SEL 0x00001000 /* Only IEEE 1588-2002 Timestamp */
+#define DMA_HW_FEAT_TSVER2SEL 0x00002000 /* IEEE 1588-2008 Adv Timestamp */
+#define DMA_HW_FEAT_EEESEL 0x00004000 /* Energy Efficient Ethernet */
+#define DMA_HW_FEAT_AVSEL 0x00008000 /* AV Feature */
+#define DMA_HW_FEAT_TXCOESEL 0x00010000 /* Checksum Offload in Tx */
+#define DMA_HW_FEAT_RXTYP1COE 0x00020000 /* IP csum Offload(Type 1) in Rx */
+#define DMA_HW_FEAT_RXTYP2COE 0x00040000 /* IP csum Offload(Type 2) in Rx */
+#define DMA_HW_FEAT_RXFIFOSIZE 0x00080000 /* Rx FIFO > 2048 Bytes */
+#define DMA_HW_FEAT_RXCHCNT 0x00300000 /* No. of additional Rx Channels */
+#define DMA_HW_FEAT_TXCHCNT 0x00c00000 /* No. of additional Tx Channels */
+#define DMA_HW_FEAT_ENHDESSEL 0x01000000 /* Alternate (Enhanced Descriptor) */
+#define DMA_HW_FEAT_INTTSEN 0x02000000 /* Timestamping with Internal
+ System Time */
+#define DMA_HW_FEAT_FLEXIPPSEN 0x04000000 /* Flexible PPS Output */
+#define DMA_HW_FEAT_SAVLANINS 0x08000000 /* Source Addr or VLAN Insertion */
+#define DMA_HW_FEAT_ACTPHYIF 0x70000000 /* Active/selected PHY interface */
+
enum rx_frame_status { /* IPC status */
good_frame = 0,
discard_frame = 1,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 622b7ac..125a177 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -799,33 +799,45 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
u32 hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
if (likely(hw_cap)) {
- priv->dma_cap.mbps_10_100 = (hw_cap & 0x1);
- priv->dma_cap.mbps_1000 = (hw_cap & 0x2) >> 1;
- priv->dma_cap.half_duplex = (hw_cap & 0x4) >> 2;
- priv->dma_cap.hash_filter = (hw_cap & 0x10) >> 4;
- priv->dma_cap.multi_addr = (hw_cap & 0x20) >> 5;
- priv->dma_cap.pcs = (hw_cap & 0x40) >> 6;
- priv->dma_cap.sma_mdio = (hw_cap & 0x100) >> 8;
- priv->dma_cap.pmt_remote_wake_up = (hw_cap & 0x200) >> 9;
- priv->dma_cap.pmt_magic_frame = (hw_cap & 0x400) >> 10;
- priv->dma_cap.rmon = (hw_cap & 0x800) >> 11; /* MMC */
+ priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
+ priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
+ priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
+ priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
+ priv->dma_cap.multi_addr =
+ (hw_cap & DMA_HW_FEAT_ADDMACADRSEL) >> 5;
+ priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
+ priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
+ priv->dma_cap.pmt_remote_wake_up =
+ (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
+ priv->dma_cap.pmt_magic_frame =
+ (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
+ /*MMC*/
+ priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
/* IEEE 1588-2002*/
- priv->dma_cap.time_stamp = (hw_cap & 0x1000) >> 12;
+ priv->dma_cap.time_stamp =
+ (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
/* IEEE 1588-2008*/
- priv->dma_cap.atime_stamp = (hw_cap & 0x2000) >> 13;
+ priv->dma_cap.atime_stamp =
+ (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
/* 802.3az - Energy-Efficient Ethernet (EEE) */
- priv->dma_cap.eee = (hw_cap & 0x4000) >> 14;
- priv->dma_cap.av = (hw_cap & 0x8000) >> 15;
+ priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
+ priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
/* TX and RX csum */
- priv->dma_cap.tx_coe = (hw_cap & 0x10000) >> 16;
- priv->dma_cap.rx_coe_type1 = (hw_cap & 0x20000) >> 17;
- priv->dma_cap.rx_coe_type2 = (hw_cap & 0x40000) >> 18;
- priv->dma_cap.rxfifo_over_2048 = (hw_cap & 0x80000) >> 19;
+ priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
+ priv->dma_cap.rx_coe_type1 =
+ (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
+ priv->dma_cap.rx_coe_type2 =
+ (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
+ priv->dma_cap.rxfifo_over_2048 =
+ (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
/* TX and RX number of channels */
- priv->dma_cap.number_rx_channel = (hw_cap & 0x300000) >> 20;
- priv->dma_cap.number_tx_channel = (hw_cap & 0xc00000) >> 22;
+ priv->dma_cap.number_rx_channel =
+ (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
+ priv->dma_cap.number_tx_channel =
+ (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
/* Alternate (enhanced) DESC mode*/
- priv->dma_cap.enh_desc = (hw_cap & 0x1000000) >> 24;
+ priv->dma_cap.enh_desc =
+ (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
} else
pr_debug("\tNo HW DMA feature register supported");
--
1.7.4.4
^ permalink raw reply related
* [net-next 4/7] stmmac: allow mtu bigger than 1500 in case of normal desc (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro, Deepak SIKRI
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
This patch allows to set the mtu bigger than 1500
in case of normal descriptors.
This is helping some SPEAr customers.
Signed-off-by: Deepak SIKRI <deepak.sikri@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 8 +++++++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index 029c2a2..e13226b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -126,6 +126,7 @@ static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
for (i = 0; i < ring_size; i++) {
p->des01.rx.own = 1;
p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
+ p->des01.rx.buffer2_size = BUF_SIZE_2KiB - 1;
if (i == ring_size - 1)
p->des01.rx.end_ring = 1;
if (disable_rx_ic)
@@ -183,7 +184,12 @@ static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
int csum_flag)
{
p->des01.tx.first_segment = is_fs;
- p->des01.tx.buffer1_size = len;
+
+ if (unlikely(len > BUF_SIZE_2KiB)) {
+ p->des01.etx.buffer1_size = BUF_SIZE_2KiB - 1;
+ p->des01.etx.buffer2_size = len - p->des01.etx.buffer1_size;
+ } else
+ p->des01.tx.buffer1_size = len;
}
static void ndesc_clear_tx_ic(struct dma_desc *p)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d0af002..622b7ac 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1412,10 +1412,10 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
return -EBUSY;
}
- if (priv->plat->has_gmac)
+ if (priv->plat->enh_desc)
max_mtu = JUMBO_LEN;
else
- max_mtu = ETH_DATA_LEN;
+ max_mtu = BUF_SIZE_4KiB;
if ((new_mtu < 46) || (new_mtu > max_mtu)) {
pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
--
1.7.4.4
^ permalink raw reply related
* [net-next 3/7] stmmac: update the driver version and doc (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
Documentation/networking/stmmac.txt | 11 ++++++++++-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index 40ec92c..8d67980 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -76,7 +76,16 @@ core.
4.5) DMA descriptors
Driver handles both normal and enhanced descriptors. The latter has been only
-tested on DWC Ether MAC 10/100/1000 Universal version 3.41a.
+tested on DWC Ether MAC 10/100/1000 Universal version 3.41a and later.
+
+STMMAC supports DMA descriptor to operate both in dual buffer (RING)
+and linked-list(CHAINED) mode. In RING each descriptor points to two
+data buffer pointers whereas in CHAINED mode they point to only one data
+buffer pointer. RING mode is the default.
+
+In CHAINED mode each descriptor will have pointer to next descriptor in
+the list, hence creating the explicit chaining in the descriptor itself,
+whereas such explicit chaining is not possible in RING mode.
4.6) Ethtool support
Ethtool is supported. Driver statistics and internal errors can be taken using:
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 50e95d8..49a4af3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -20,7 +20,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
-#define DRV_MODULE_VERSION "Aug_2011"
+#define DRV_MODULE_VERSION "Oct_2011"
#include <linux/stmmac.h>
#include "common.h"
--
1.7.4.4
^ permalink raw reply related
* [net-next 2/7] stmmac: protect tx process with lock (V3)
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
This patch fixes a problem raised on Orly ARM SMP platform
where, in case of fragmented frames, the descriptors
in the TX ring resulted broken. This was due to a missing lock
protection in the tx process.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Tested-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++++
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1434bdb..50e95d8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -70,6 +70,7 @@ struct stmmac_priv {
u32 msg_enable;
spinlock_t lock;
+ spinlock_t tx_lock;
int wolopts;
int wolenabled;
int wol_irq;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 229fe44..d0af002 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -588,6 +588,8 @@ static void stmmac_tx(struct stmmac_priv *priv)
{
unsigned int txsize = priv->dma_tx_size;
+ spin_lock(&priv->tx_lock);
+
while (priv->dirty_tx != priv->cur_tx) {
int last;
unsigned int entry = priv->dirty_tx % txsize;
@@ -651,6 +653,7 @@ static void stmmac_tx(struct stmmac_priv *priv)
}
netif_tx_unlock(priv->dev);
}
+ spin_unlock(&priv->tx_lock);
}
static inline void stmmac_enable_irq(struct stmmac_priv *priv)
@@ -1078,6 +1081,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
+ spin_lock(&priv->tx_lock);
+
entry = priv->cur_tx % txsize;
#ifdef STMMAC_XMIT_DEBUG
@@ -1166,6 +1171,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
priv->hw->dma->enable_dma_transmission(priv->ioaddr);
+ spin_unlock(&priv->tx_lock);
+
return NETDEV_TX_OK;
}
@@ -1731,6 +1738,7 @@ static int stmmac_probe(struct net_device *dev)
"please, use ifconfig or nwhwconfig!\n");
spin_lock_init(&priv->lock);
+ spin_lock_init(&priv->tx_lock);
ret = register_netdev(dev);
if (ret) {
--
1.7.4.4
^ permalink raw reply related
* [net-next 1/7] stmmac: Stop advertising 1000Base capabilties for non GMII iface (V3).
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Srinivas Kandagatla, Giuseppe Cavallaro
In-Reply-To: <1318927331-20855-1-git-send-email-peppe.cavallaro@st.com>
From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
This patch stops advertising 1000Base capablities if GMAC is either
configured for MII or RMII mode and on board there is a GPHY plugged on.
Without this patch if an GBit switch is connected on MII interface,
Ethernet stops working at all.
Discovered as part of
https://bugzilla.stlinux.com/show_bug.cgi?id=14148 triage
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c0ee6b6..229fe44 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -304,7 +304,7 @@ static int stmmac_init_phy(struct net_device *dev)
struct phy_device *phydev;
char phy_id[MII_BUS_ID_SIZE + 3];
char bus_id[MII_BUS_ID_SIZE];
-
+ int interface = priv->plat->interface;
priv->oldlink = 0;
priv->speed = 0;
priv->oldduplex = -1;
@@ -314,14 +314,21 @@ static int stmmac_init_phy(struct net_device *dev)
priv->plat->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
- phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
- priv->plat->interface);
+ phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface);
if (IS_ERR(phydev)) {
pr_err("%s: Could not attach to PHY\n", dev->name);
return PTR_ERR(phydev);
}
+ /* Stop Advertising 1000BASE Capability if interface is not GMII */
+ if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) ||
+ (interface == PHY_INTERFACE_MODE_RMII))) {
+ phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ priv->phydev->advertising = priv->phydev->supported;
+ }
+
/*
* Broken HW is sometimes missing the pull-up resistor on the
* MDIO line, which results in reads to non-existent devices returning
--
1.7.4.4
^ permalink raw reply related
* [net-next 0/7] stmmac: update to Oct 2011 version (V2)
From: Giuseppe CAVALLARO @ 2011-10-18 8:42 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro
This patches update the driver adding the chained
descriptor mode and some new useful fixes.
I've reviewed some patches after the V1 and V2:
stmmac: allow mtu bigger than 1500 in case of normal desc (V3)
|-> removed the useless max_mtu init: Thx Eric's feedback
stmmac: add CHAINED descriptor mode support (V3)
|-> removed ifdef in the C and added small routines
specialised for chained/ring modes. See comment
within the patch itself. Thx David's feedback.
stmmac: allow mmc usage only if feature actually available (V3)
|-> added a check if interface is NULL
In the end, I added two new small patches:
stmmac: use predefined macros for HW cap register fields (V3)
stmmac: allow mmc usage only if feature actually available (V3)
made by Rayagond and reviewed/reworked by myself
Let me know if it's ok.
Giuseppe Cavallaro (5):
stmmac: protect tx process with lock (V3)
stmmac: update the driver version and doc (V3)
stmmac: allow mtu bigger than 1500 in case of normal desc (V3)
stmmac: allow mmc usage only if feature actually available (V3)
stmmac: add CHAINED descriptor mode support (V3)
Rayagond Kokatanur (1):
stmmac: use predefined macros for HW cap register fields (V3)
Srinivas Kandagatla (1):
stmmac: Stop advertising 1000Base capabilties for non GMII iface
(V3).
Documentation/networking/stmmac.txt | 11 +-
drivers/net/ethernet/stmicro/stmmac/Kconfig | 18 ++
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 137 +++++++++++++
drivers/net/ethernet/stmicro/stmmac/common.h | 43 ++++
drivers/net/ethernet/stmicro/stmmac/descs_com.h | 126 ++++++++++++
drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 22 +--
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 14 +-
drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 126 ++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 5 +-
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 24 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 212 ++++++++++----------
12 files changed, 602 insertions(+), 138 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/chain_mode.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/descs_com.h
create mode 100644 drivers/net/ethernet/stmicro/stmmac/ring_mode.c
--
1.7.4.4
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox