* [net-next 0/5] stmmac: update to Oct 2011 version (V2)
@ 2011-10-12 13:38 Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2) Giuseppe CAVALLARO
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-12 13:38 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro
This patches update the driver adding the chained
descriptor mode and some new useful fixes.
Chained / Ring modes have been reworked after D. Miller
advice and removing the ifdef selection within the C
code.
Giuseppe Cavallaro (4):
stmmac: add CHAINED descriptor mode support
stmmac: allow mtu bigger than 1500 in case of normal desc.
stmmac: protect tx process with lock
stmmac: update the driver version and doc
Srinivas Kandagatla (1):
stmmac: Stop advertising 1000Base capabilties for non GMII iface
(v2).
Documentation/networking/stmmac.txt | 11 +-
drivers/net/ethernet/stmicro/stmmac/Kconfig | 18 +
drivers/net/ethernet/stmicro/stmmac/common.h | 19 +
drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 51 ---
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 42 --
drivers/net/ethernet/stmicro/stmmac/ring_mode.h | 450 +++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 148 +++----
8 files changed, 564 insertions(+), 178 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/ring_mode.h
--
1.7.4.4
^ permalink raw reply [flat|nested] 10+ messages in thread
* [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2)
2011-10-12 13:38 [net-next 0/5] stmmac: update to Oct 2011 version (V2) Giuseppe CAVALLARO
@ 2011-10-12 13:38 ` Giuseppe CAVALLARO
2011-10-13 20:39 ` David Miller
2011-10-12 13:38 ` [net-next 2/5] stmmac: allow mtu bigger than 1500 in case of normal desc (V2) Giuseppe CAVALLARO
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-12 13:38 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro, Rayagond Kokatanur
This patch enhances the STMMAC driver to support CHAINED mode of
descriptor (useful also on validation side).
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; I've reworked
the whole support and added a new header file to implement the
helper routines specialised for chained/ring modes (as D. Miller
suggested).
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/common.h | 19 +
drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 51 ---
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 42 --
drivers/net/ethernet/stmicro/stmmac/ring_mode.h | 450 +++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 121 ++----
6 files changed, 531 insertions(+), 170 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/ring_mode.h
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/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 22c61b2..90ba81a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -152,6 +152,7 @@ struct dma_features {
#define BUF_SIZE_8KiB 8192
#define BUF_SIZE_4KiB 4096
#define BUF_SIZE_2KiB 2048
+#define DMA_BUFFER_SIZE BUF_SIZE_2KiB
/* Power Down and WOL */
#define PMT_NOT_SUPPORTED 0
@@ -261,6 +262,7 @@ 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;
@@ -274,3 +276,20 @@ 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 void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic);
+extern void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+ int csum_flag);
+extern void enh_desc_release_tx_desc(struct dma_desc *p);
+extern void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size);
+extern void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic);
+extern void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+ int csum_flag);
+extern void ndesc_release_tx_desc(struct dma_desc *p);
+extern void ndesc_init_tx_desc(struct dma_desc *p, unsigned int ring_size);
+extern void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic);
+
+
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index e5dfb6a..f378b3b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -226,35 +226,6 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x,
return ret;
}
-static void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
- int disable_rx_ic)
-{
- int i;
- 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;
- if (disable_rx_ic)
- p->des01.erx.disable_ic = 1;
- p++;
- }
-}
-
-static void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
-{
- int i;
-
- for (i = 0; i < ring_size; i++) {
- p->des01.etx.own = 0;
- if (i == ring_size - 1)
- p->des01.etx.end_ring = 1;
- p++;
- }
-}
-
static int enh_desc_get_tx_owner(struct dma_desc *p)
{
return p->des01.etx.own;
@@ -280,28 +251,6 @@ static int enh_desc_get_tx_ls(struct dma_desc *p)
return p->des01.etx.last_segment;
}
-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;
-}
-
-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;
- }
- if (likely(csum_flag))
- p->des01.etx.checksum_insertion = cic_full;
-}
-
static void enh_desc_clear_tx_ic(struct dma_desc *p)
{
p->des01.etx.interrupt = 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index 029c2a2..1cd985f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -119,32 +119,6 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x,
return ret;
}
-static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
- int disable_rx_ic)
-{
- int i;
- for (i = 0; i < ring_size; i++) {
- p->des01.rx.own = 1;
- p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
- if (i == ring_size - 1)
- p->des01.rx.end_ring = 1;
- if (disable_rx_ic)
- p->des01.rx.disable_ic = 1;
- p++;
- }
-}
-
-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;
- p++;
- }
-}
-
static int ndesc_get_tx_owner(struct dma_desc *p)
{
return p->des01.tx.own;
@@ -170,22 +144,6 @@ static int ndesc_get_tx_ls(struct dma_desc *p)
return p->des01.tx.last_segment;
}
-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;
-}
-
-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;
-}
-
static void ndesc_clear_tx_ic(struct dma_desc *p)
{
p->des01.tx.interrupt = 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.h b/drivers/net/ethernet/stmicro/stmmac/ring_mode.h
new file mode 100644
index 0000000..32fe688
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.h
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ Header File to describe the DMA descriptor ring/chain(s)
+
+ 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 unsigned int stmmac_jumbo_frm(struct stmmac_priv *priv,
+ struct sk_buff *skb, int csum_insertion)
+{
+ 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 buf_max_size, len;
+
+ if (priv->plat->enh_desc)
+ buf_max_size = BUF_SIZE_8KiB;
+ else
+ buf_max_size = BUF_SIZE_2KiB;
+
+ len = nopaged_len - buf_max_size;
+
+ if (nopaged_len > BUF_SIZE_8KiB) {
+
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ buf_max_size, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->hw->desc->prepare_tx_desc(desc, 1, buf_max_size,
+ csum_insertion);
+
+ entry = (++priv->cur_tx) % txsize;
+ desc = priv->dma_tx + entry;
+
+ desc->des2 = dma_map_single(priv->device,
+ skb->data + buf_max_size,
+ len, DMA_TO_DEVICE);
+ desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+ priv->hw->desc->prepare_tx_desc(desc, 0, len, 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;
+}
+
+static unsigned int stmmac_is_jumbo_frame(struct stmmac_priv *priv,
+ struct sk_buff *skb,
+ int csum, struct dma_desc *desc)
+{
+ unsigned int ret = 0;
+
+ if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
+ unsigned int entry = stmmac_jumbo_frm(priv, skb, csum);
+ desc = priv->dma_tx + entry;
+ 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_bfsize(int mtu, int bufsize)
+{
+ int ret = bufsize;
+
+ if (unlikely(mtu >= BUF_SIZE_8KiB))
+ ret = BUF_SIZE_16KiB;
+ else if (unlikely(mtu >= BUF_SIZE_4KiB))
+ ret = BUF_SIZE_8KiB;
+ else if (unlikely(mtu >= BUF_SIZE_2KiB))
+ ret = BUF_SIZE_4KiB;
+ else if (unlikely(mtu >= DMA_BUFFER_SIZE))
+ ret = BUF_SIZE_2KiB;
+ else
+ ret = DMA_BUFFER_SIZE;
+
+ return ret;
+}
+
+/* Normal/enhanced descriptor functions for RING mode */
+
+inline void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic)
+{
+ int i;
+ 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;
+ if (disable_rx_ic)
+ p->des01.erx.disable_ic = 1;
+ p++;
+ }
+}
+
+inline void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+ int i;
+
+ for (i = 0; i < ring_size; i++) {
+ p->des01.etx.own = 0;
+ if (i == (ring_size - 1))
+ p->des01.etx.end_ring = 1;
+ p++;
+ }
+}
+
+inline 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;
+}
+
+inline 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;
+
+ if (likely(csum_flag))
+ p->des01.etx.checksum_insertion = cic_full;
+}
+
+inline void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic)
+{
+ int i;
+ 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)
+ p->des01.rx.disable_ic = 1;
+ p++;
+ }
+}
+
+inline 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;
+ p++;
+ }
+}
+
+inline 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;
+}
+
+inline 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;
+}
+
+#else
+
+/* Chained mode functions */
+
+static unsigned int stmmac_jumbo_frm(struct stmmac_priv *priv,
+ struct sk_buff *skb, int csum_insertion)
+{
+ 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 buf_max_size;
+ unsigned int i = 1, len;
+
+ if (priv->plat->enh_desc)
+ buf_max_size = BUF_SIZE_8KiB;
+ else
+ buf_max_size = BUF_SIZE_2KiB;
+
+ len = nopaged_len - buf_max_size;
+
+ desc->des2 = dma_map_single(priv->device, skb->data,
+ buf_max_size, DMA_TO_DEVICE);
+ priv->hw->desc->prepare_tx_desc(desc, 1, buf_max_size, csum_insertion);
+
+ while (len != 0) {
+ entry = (++priv->cur_tx) % txsize;
+ desc = priv->dma_tx + entry;
+
+ if (len > buf_max_size) {
+ desc->des2 = dma_map_single(priv->device,
+ (skb->data +
+ buf_max_size * i),
+ buf_max_size,
+ DMA_TO_DEVICE);
+ priv->hw->desc->prepare_tx_desc(desc, 0, buf_max_size,
+ csum_insertion);
+ priv->hw->desc->set_tx_owner(desc);
+ priv->tx_skbuff[entry] = NULL;
+ len -= buf_max_size;
+ i++;
+ } else {
+ desc->des2 = dma_map_single(priv->device,
+ (skb->data +
+ buf_max_size * i), len,
+ DMA_TO_DEVICE);
+ priv->hw->desc->prepare_tx_desc(desc, 0, len,
+ csum_insertion);
+ priv->hw->desc->set_tx_owner(desc);
+ priv->tx_skbuff[entry] = NULL;
+ len = 0;
+ }
+ }
+ return entry;
+}
+
+static unsigned int stmmac_is_jumbo_frame(struct stmmac_priv *priv,
+ struct sk_buff *skb,
+ int csum, struct dma_desc *desc)
+{
+ unsigned int ret = 0;
+
+ if ((priv->plat->enh_desc && unlikely(skb->len > BUF_SIZE_8KiB)) ||
+ (!priv->plat->enh_desc && unlikely(skb->len > BUF_SIZE_2KiB))) {
+ unsigned int entry = stmmac_jumbo_frm(priv, skb, csum);
+ desc = priv->dma_tx + entry;
+ 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)
+{
+}
+
+/* In chained mode des3 points to the next element in the ring.
+ * The latest element has to point to the head.
+ */
+static void stmmac_init_dma_chain(struct dma_desc *des, dma_addr_t phy_addr,
+ unsigned int size)
+{
+ 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_bfsize(int mtu, int bufsize)
+{
+ int ret = bufsize;
+
+ if (unlikely(mtu >= BUF_SIZE_4KiB))
+ ret = BUF_SIZE_8KiB;
+ else if (unlikely(mtu >= BUF_SIZE_2KiB))
+ ret = BUF_SIZE_4KiB;
+ else if (unlikely(mtu >= DMA_BUFFER_SIZE))
+ ret = BUF_SIZE_2KiB;
+ else
+ ret = DMA_BUFFER_SIZE;
+
+ return ret;
+}
+
+/* Normal/enhanced descriptor functions for RING mode */
+
+inline void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic)
+{
+ int i;
+ 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.second_address_chained = 1;
+ if (disable_rx_ic)
+ p->des01.erx.disable_ic = 1;
+ p++;
+ }
+}
+
+inline void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+ int i;
+
+ for (i = 0; i < ring_size; i++) {
+ p->des01.etx.own = 0;
+ p->des01.etx.second_address_chained = 1;
+ p++;
+ }
+}
+
+inline void enh_desc_release_tx_desc(struct dma_desc *p)
+{
+ memset(p, 0, offsetof(struct dma_desc, des2));
+ p->des01.etx.second_address_chained = 1;
+}
+
+inline 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;
+ p->des01.etx.buffer1_size = len;
+
+ if (likely(csum_flag))
+ p->des01.etx.checksum_insertion = cic_full;
+}
+
+inline void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+ int disable_rx_ic)
+{
+ int i;
+ 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)
+ p->des01.rx.disable_ic = 1;
+ p++;
+ }
+}
+
+inline 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;
+ p++;
+ }
+}
+
+inline void ndesc_release_tx_desc(struct dma_desc *p)
+{
+ memset(p, 0, offsetof(struct dma_desc, des2));
+ p->des01.tx.second_address_chained = 1;
+}
+
+inline 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;
+}
+#endif
+
+struct stmmac_ring_mode_ops {
+ unsigned int (*is_jumbo_frame) (struct stmmac_priv *priv,
+ struct sk_buff *skb,
+ int csum, struct dma_desc *desc);
+ 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_bfsize) (int mtu, int bufsize);
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c0ee6b6..ba7af2c 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,
@@ -47,11 +47,12 @@
#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"
+#include "ring_mode.h"
#define STMMAC_RESOURCE_NAME "stmmaceth"
@@ -131,7 +132,6 @@ module_param(tmrate, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
#endif
-#define DMA_BUFFER_SIZE BUF_SIZE_2KiB
static int buf_sz = DMA_BUFFER_SIZE;
module_param(buf_sz, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(buf_sz, "DMA buffer size");
@@ -142,6 +142,16 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
+/* Functions used for chained/ring modes */
+static const struct stmmac_ring_mode_ops ring_mode_ops = {
+ .is_jumbo_frame = stmmac_is_jumbo_frame,
+ .refill_desc3 = stmmac_refill_desc3,
+ .init_desc3 = stmmac_init_desc3,
+ .init_dma_chain = stmmac_init_dma_chain,
+ .clean_desc3 = stmmac_clean_desc3,
+ .set_bfsize = stmmac_set_bfsize,
+};
+
/**
* stmmac_verify_args - verify the driver parameters.
* Description: it verifies if some wrong parameter is passed to the driver.
@@ -385,7 +395,8 @@ static void display_ring(struct dma_desc *p, int size)
* 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)
{
@@ -394,31 +405,22 @@ 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;
- else
- bfsize = DMA_BUFFER_SIZE;
+ /* Set the max buffer size according to the DESC mode used
+ * and the MTU. */
+ bfsize = priv->hw->ring->set_bfsize(dev->mtu, priv->dma_buf_sz);
+
+ if (bfsize == BUF_SIZE_16KiB)
+ des3_as_data_buf = 1;
#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);
@@ -446,7 +448,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);
@@ -468,8 +470,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]);
}
@@ -483,6 +486,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;
@@ -611,8 +620,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)) {
/*
@@ -1005,47 +1013,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
@@ -1094,10 +1061,10 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
skb->len, skb_headlen(skb), 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);
- desc = priv->dma_tx + entry;
- } else {
+
+ /* Manage Jumbo frames depending on the descriptor mode
+ * actually used (chained or ring). */
+ if (!priv->hw->ring->is_jumbo_frame(priv, skb, csum_insertion, desc)) {
unsigned int nopaged_len = skb_headlen(skb);
desc->des2 = dma_map_single(priv->device, skb->data,
nopaged_len, DMA_TO_DEVICE);
@@ -1187,11 +1154,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();
@@ -1767,6 +1733,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 [flat|nested] 10+ messages in thread
* [net-next 2/5] stmmac: allow mtu bigger than 1500 in case of normal desc (V2).
2011-10-12 13:38 [net-next 0/5] stmmac: update to Oct 2011 version (V2) Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2) Giuseppe CAVALLARO
@ 2011-10-12 13:38 ` Giuseppe CAVALLARO
2011-10-12 19:58 ` Eric Dumazet
2011-10-12 13:38 ` [net-next 3/5] stmmac: protect tx process with lock (V2) Giuseppe CAVALLARO
` (2 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-12 13:38 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro, Deepak SIKRI
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/stmmac_main.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ba7af2c..de3e536 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1357,17 +1357,17 @@ static void stmmac_set_rx_mode(struct net_device *dev)
static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
{
struct stmmac_priv *priv = netdev_priv(dev);
- int max_mtu;
+ int max_mtu = ETH_DATA_LEN;
if (netif_running(dev)) {
pr_err("%s: must be stopped to change its MTU\n", dev->name);
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 [flat|nested] 10+ messages in thread
* [net-next 3/5] stmmac: protect tx process with lock (V2)
2011-10-12 13:38 [net-next 0/5] stmmac: update to Oct 2011 version (V2) Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2) Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 2/5] stmmac: allow mtu bigger than 1500 in case of normal desc (V2) Giuseppe CAVALLARO
@ 2011-10-12 13:38 ` Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 4/5] stmmac: Stop advertising 1000Base capabilties for non GMII iface (V2) Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 5/5] stmmac: update the driver version and doc (V2) Giuseppe CAVALLARO
4 siblings, 0 replies; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-12 13:38 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro
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 de3e536..7b3b6c9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -590,6 +590,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;
@@ -652,6 +654,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)
@@ -1038,6 +1041,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
@@ -1126,6 +1131,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;
}
@@ -1690,6 +1697,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 [flat|nested] 10+ messages in thread
* [net-next 4/5] stmmac: Stop advertising 1000Base capabilties for non GMII iface (V2).
2011-10-12 13:38 [net-next 0/5] stmmac: update to Oct 2011 version (V2) Giuseppe CAVALLARO
` (2 preceding siblings ...)
2011-10-12 13:38 ` [net-next 3/5] stmmac: protect tx process with lock (V2) Giuseppe CAVALLARO
@ 2011-10-12 13:38 ` Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 5/5] stmmac: update the driver version and doc (V2) Giuseppe CAVALLARO
4 siblings, 0 replies; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-12 13:38 UTC (permalink / raw)
To: netdev; +Cc: davem, Srinivas Kandagatla, Giuseppe Cavallaro
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 7b3b6c9..08dc116 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -314,7 +314,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;
@@ -324,14 +324,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 == 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 [flat|nested] 10+ messages in thread
* [net-next 5/5] stmmac: update the driver version and doc (V2)
2011-10-12 13:38 [net-next 0/5] stmmac: update to Oct 2011 version (V2) Giuseppe CAVALLARO
` (3 preceding siblings ...)
2011-10-12 13:38 ` [net-next 4/5] stmmac: Stop advertising 1000Base capabilties for non GMII iface (V2) Giuseppe CAVALLARO
@ 2011-10-12 13:38 ` Giuseppe CAVALLARO
4 siblings, 0 replies; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-12 13:38 UTC (permalink / raw)
To: netdev; +Cc: davem, Giuseppe Cavallaro
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 [flat|nested] 10+ messages in thread
* Re: [net-next 2/5] stmmac: allow mtu bigger than 1500 in case of normal desc (V2).
2011-10-12 13:38 ` [net-next 2/5] stmmac: allow mtu bigger than 1500 in case of normal desc (V2) Giuseppe CAVALLARO
@ 2011-10-12 19:58 ` Eric Dumazet
2011-10-14 7:15 ` Giuseppe CAVALLARO
0 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2011-10-12 19:58 UTC (permalink / raw)
To: Giuseppe CAVALLARO; +Cc: netdev, davem, Deepak SIKRI
Le mercredi 12 octobre 2011 à 15:38 +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/stmmac_main.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index ba7af2c..de3e536 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1357,17 +1357,17 @@ static void stmmac_set_rx_mode(struct net_device *dev)
> static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
> {
> struct stmmac_priv *priv = netdev_priv(dev);
> - int max_mtu;
> + int max_mtu = ETH_DATA_LEN;
Why are you setting max_mtu to ETH_DATA_LEN here ?
>
> if (netif_running(dev)) {
> pr_err("%s: must be stopped to change its MTU\n", dev->name);
> 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;
Since later you init to completely different values...
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2)
2011-10-12 13:38 ` [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2) Giuseppe CAVALLARO
@ 2011-10-13 20:39 ` David Miller
2011-10-14 7:10 ` Giuseppe CAVALLARO
0 siblings, 1 reply; 10+ messages in thread
From: David Miller @ 2011-10-13 20:39 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev, rayagond
From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Wed, 12 Oct 2011 15:38:04 +0200
> +#if defined(CONFIG_STMMAC_RING)
> +
> +static unsigned int stmmac_jumbo_frm(struct stmmac_priv *priv,
> + struct sk_buff *skb, int csum_insertion)
> +{
This is not exactly what I meant.
In your original patch, two or three line snippets of code were conditionalized.
That's what I wanted you to do here. Keep as much common code around as possible
in the driver *.c file, but the small 2 or 3 line conditional parts are implemented
in very small well contained inline functions implemented in a header file.
These small, 2 or 3 line, inline functions are where the ifdefs go.
I didn't mean to replicate all of the functions, in their entirety, into some
header file.
You might was well put the entire driver into a header file, then you can add
all the ifdefs you want :-)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2)
2011-10-13 20:39 ` David Miller
@ 2011-10-14 7:10 ` Giuseppe CAVALLARO
0 siblings, 0 replies; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-14 7:10 UTC (permalink / raw)
To: David Miller; +Cc: netdev, rayagond
On 10/13/2011 10:39 PM, David Miller wrote:
> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Wed, 12 Oct 2011 15:38:04 +0200
>
>> +#if defined(CONFIG_STMMAC_RING)
>> +
>> +static unsigned int stmmac_jumbo_frm(struct stmmac_priv *priv,
>> + struct sk_buff *skb, int csum_insertion)
>> +{
>
> This is not exactly what I meant.
>
> In your original patch, two or three line snippets of code were conditionalized.
>
> That's what I wanted you to do here. Keep as much common code around as possible
> in the driver *.c file, but the small 2 or 3 line conditional parts are implemented
> in very small well contained inline functions implemented in a header file.
>
> These small, 2 or 3 line, inline functions are where the ifdefs go.
>
> I didn't mean to replicate all of the functions, in their entirety, into some
> header file.
This is what I wanted to do indeed. :-(
I had added new small functions like where possible (used in the main):
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)
I guess this is what you actually wanted.
In other cases, I had put two implementation of the same function
specialized for ring and chained mode. This was the case of the enhanced
and normal descriptors. Instead of implementing new inline funtcs I
direcly moved the functions themselves into the header because small enough.
For example
inline void enh_desc_release_tx_desc(struct dma_desc *p)
{
memset(p, 0, offsetof(struct dma_desc, des2));
p->des01.etx.second_address_chained = 1;
}
and
inline 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;
}
Unfortunately, jumbo frame function is big :-( and I agree with you that
it's not good to have this in the Header.
At any rate, I'll try to reduce the code in the header as much possible
although this makes more complex the driver's API.
Thanks for your feedback.
Let me know for other advice and comments
Regards
Peppe
>
> You might was well put the entire driver into a header file, then you can add
> all the ifdefs you want :-)
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [net-next 2/5] stmmac: allow mtu bigger than 1500 in case of normal desc (V2).
2011-10-12 19:58 ` Eric Dumazet
@ 2011-10-14 7:15 ` Giuseppe CAVALLARO
0 siblings, 0 replies; 10+ messages in thread
From: Giuseppe CAVALLARO @ 2011-10-14 7:15 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, davem, Deepak SIKRI
Hello Eric
On 10/12/2011 9:58 PM, Eric Dumazet wrote:
> Le mercredi 12 octobre 2011 à 15:38 +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/stmmac_main.c | 6 +++---
>> 1 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index ba7af2c..de3e536 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -1357,17 +1357,17 @@ static void stmmac_set_rx_mode(struct net_device *dev)
>> static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
>> {
>> struct stmmac_priv *priv = netdev_priv(dev);
>> - int max_mtu;
>> + int max_mtu = ETH_DATA_LEN;
>
> Why are you setting max_mtu to ETH_DATA_LEN here ?
>
>>
>> if (netif_running(dev)) {
>> pr_err("%s: must be stopped to change its MTU\n", dev->name);
>> 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;
>
> Since later you init to completely different values...
Hmm, yes you are right. it's not needed to initialized the max_mtu.
Thanks! I'll rework the patch and send it again in the V3.
Thx
Regards
Peppe
>
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-10-14 7:15 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-12 13:38 [net-next 0/5] stmmac: update to Oct 2011 version (V2) Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 1/5] stmmac: add CHAINED descriptor mode support (V2) Giuseppe CAVALLARO
2011-10-13 20:39 ` David Miller
2011-10-14 7:10 ` Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 2/5] stmmac: allow mtu bigger than 1500 in case of normal desc (V2) Giuseppe CAVALLARO
2011-10-12 19:58 ` Eric Dumazet
2011-10-14 7:15 ` Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 3/5] stmmac: protect tx process with lock (V2) Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 4/5] stmmac: Stop advertising 1000Base capabilties for non GMII iface (V2) Giuseppe CAVALLARO
2011-10-12 13:38 ` [net-next 5/5] stmmac: update the driver version and doc (V2) Giuseppe CAVALLARO
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).