* Dedicated server rental
From: eric @ 2012-05-14 4:14 UTC (permalink / raw)
Dear Sir/Madam,
Please see below our Server Rental Package,
HKD1980/month + one-time setup fee HKD2000
Dell? PowerEdge? Enterprise Rack Mount Server
- Intel(R) Xeon(R) E3-1220 Processor (3.10GHz, 8M Cache, Turbo, 4C/4T, 80W)
- 4GB RAM, 1x4GB, 1333MHz, DDR-3, Single Ranked UDIMMs
- 500GB, 3.5", SATA II x 1 Enterprise Hard Disk
- Remote KVM (iDRAC6 Enterprise)
- 8x SATA slim DVD-ROM Drive
- Dell OpenManage
- Broadcom 5716 dual-port Gigabit Ethernet without TOE enabled
- Dell BMC Info Mod
Software Specification
- CentOS 5/6 Linux Operating System
Data Center Facilities
- 1Gbps Share Internet Connectivity with 10/BASE-T
- One IP Addresses Allocation
- Un-interruptible Power Supply (UPS) backed up by private diesel generator
- FM200 gas¡Vbased fire suppression system
- 24x7 CRAC Air Conditioning and Humidity Control
- 24x7 Security Control
Should you have any query, please feel free to contact me. Thanks.
Best,
Eric Chan
Senior Sales Executive
If you do not wish to further receive this event message, meail subscriber@dedicatedserver.com.hk to unsubscribe this message.
^ permalink raw reply
* Re: [PATCH v2 4/5] net: sh_eth: add support for set_ringparam/get_ringparam
From: Shimoda, Yoshihiro @ 2012-05-14 6:13 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, SH-Linux
In-Reply-To: <1336750030.2874.65.camel@bwh-desktop.uk.solarflarecom.com>
2012/05/12 0:27, Ben Hutchings wrote:
> On Fri, 2012-05-11 at 17:38 +0900, Shimoda, Yoshihiro wrote:
>> This patch supports the ethtool's set_ringparam() and get_ringparam().
> [...]
>> +static int sh_eth_set_ringparam(struct net_device *ndev,
>> + struct ethtool_ringparam *ring)
>> +{
< snip >
>> + if (netif_running(ndev)) {
>> + /* Disable interrupts by clearing the interrupt mask. */
>> + sh_eth_write(ndev, 0x0000, EESIPR);
>> + /* Stop the chip's Tx and Rx processes. */
>> + sh_eth_write(ndev, 0, EDTRR);
>> + sh_eth_write(ndev, 0, EDRRR);
>
> You'll also need to call netif_tx_disable() and synchronize_irq().
Thank you for the point. I will fix it.
>> + sh_eth_ring_init(ndev);
>> + sh_eth_dev_init(ndev);
>
> And what if either of these fails?
Oh, I should have added error handling.
I checked this driver, and I found that the driver should change
the value of the pointer to NULL. So, I will submit such a patch first.
>> + if (netif_running(ndev)) {
>> + sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
>> + /* Setting the Rx mode will start the Rx process. */
>> + sh_eth_write(ndev, EDRRR_R, EDRRR);
>
> You'll need to call netif_wake_queue().
I will fix it.
>> + }
>> +
>> + return 0;
>> +}
> [...]
>
> Ben.
>
Best regards,
Yoshihiro Shimoda
^ permalink raw reply
* Re: [PATCH v2 5/5] net: sh_eth: use NAPI
From: Shimoda, Yoshihiro @ 2012-05-14 6:13 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, SH-Linux
In-Reply-To: <1336750529.2874.69.camel@bwh-desktop.uk.solarflarecom.com>
2012/05/12 0:35, Ben Hutchings wrote:
> On Fri, 2012-05-11 at 17:38 +0900, Shimoda, Yoshihiro wrote:
>> This patch modifies the driver to use NAPI.
> [...]
>> +static int sh_eth_poll(struct napi_struct *napi, int budget)
>> +{
< snip >
>> + /* check whether the controller doesn't have any events */
>> + if (!txfree_num && !(intr_status & cd->eesr_err_check) &&
>> + work_done < budget) {
>> + napi_complete(napi);
>
> If and only if you return a value less than the budget then you *must*
> call napi_complete(). You can't add these extra conditions.
Thank you for the point. I will fix it.
< snip >
>
> You will also need to call napi_disable() and napi_enable() in the
> set_ringparam implementation.
I will add the code in sh_eth_set_ringparam().
> Ben.
>
Best regards,
Yoshihiro Shimoda
^ permalink raw reply
* [PATCH v3 1/6] net: sh_eth: remove unnecessary function
From: Shimoda, Yoshihiro @ 2012-05-14 6:46 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
The sh_eth_timer() called mod_timer() for itself.
So, this patch removes the function.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
about v3:
- this patch is the same as v2
drivers/net/ethernet/renesas/sh_eth.c | 22 ----------------------
drivers/net/ethernet/renesas/sh_eth.h | 1 -
2 files changed, 0 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index be3c221..c35084a 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1289,14 +1289,6 @@ other_irq:
return ret;
}
-static void sh_eth_timer(unsigned long data)
-{
- struct net_device *ndev = (struct net_device *)data;
- struct sh_eth_private *mdp = netdev_priv(ndev);
-
- mod_timer(&mdp->timer, jiffies + (10 * HZ));
-}
-
/* PHY state control function */
static void sh_eth_adjust_link(struct net_device *ndev)
{
@@ -1544,11 +1536,6 @@ static int sh_eth_open(struct net_device *ndev)
if (ret)
goto out_free_irq;
- /* Set the timer to check for link beat. */
- init_timer(&mdp->timer);
- mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
- setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev);
-
return ret;
out_free_irq:
@@ -1573,9 +1560,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
/* tx_errors count up */
ndev->stats.tx_errors++;
- /* timer off */
- del_timer_sync(&mdp->timer);
-
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
rxdesc = &mdp->rx_ring[i];
@@ -1593,10 +1577,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
/* device init */
sh_eth_dev_init(ndev);
-
- /* timer on */
- mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
- add_timer(&mdp->timer);
}
/* Packet transmit function */
@@ -1669,8 +1649,6 @@ static int sh_eth_close(struct net_device *ndev)
free_irq(ndev->irq, ndev);
- del_timer_sync(&mdp->timer);
-
/* Free all the skbuffs in the Rx queue. */
sh_eth_ring_free(ndev);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 57b8e1f..9e8e4d5 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -771,7 +771,6 @@ struct sh_eth_private {
struct sh_eth_txdesc *tx_ring;
struct sk_buff **rx_skbuff;
struct sk_buff **tx_skbuff;
- struct timer_list timer;
spinlock_t lock;
u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */
u32 cur_tx, dirty_tx;
--
1.7.1
^ permalink raw reply related
* [PATCH v3 2/6] net: sh_eth: remove unnecessary members/definitions
From: Shimoda, Yoshihiro @ 2012-05-14 6:46 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This patch removes unnecessary members in sh_th_private.
This patch also removes unnecessary definitions in sh_eth.h
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
about v3:
- this patch is the same as v2
drivers/net/ethernet/renesas/sh_eth.c | 7 +---
drivers/net/ethernet/renesas/sh_eth.h | 69 ---------------------------------
2 files changed, 1 insertions(+), 75 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index c35084a..10f2a89 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -898,7 +898,6 @@ static int sh_eth_dev_init(struct net_device *ndev)
{
int ret = 0;
struct sh_eth_private *mdp = netdev_priv(ndev);
- u_int32_t rx_int_var, tx_int_var;
u32 val;
/* Soft Reset */
@@ -926,9 +925,7 @@ static int sh_eth_dev_init(struct net_device *ndev)
/* Frame recv control */
sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);
- rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
- tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
- sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);
+ sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER);
if (mdp->cd->bculr)
sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */
@@ -2286,8 +2283,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
/* debug message level */
mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
- mdp->post_rx = POST_RX >> (devno << 1);
- mdp->post_fw = POST_FW >> (devno << 1);
/* read and set MAC address */
read_mac_address(ndev, pd->mac_addr);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 9e8e4d5..9525199 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -585,71 +585,6 @@ enum RPADIR_BIT {
/* FDR */
#define DEFAULT_FDR_INIT 0x00000707
-enum phy_offsets {
- PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
- PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
- PHY_16 = 16,
-};
-
-/* PHY_CTRL */
-enum PHY_CTRL_BIT {
- PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000,
- PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400,
- PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080,
-};
-#define DM9161_PHY_C_ANEGEN 0 /* auto nego special */
-
-/* PHY_STAT */
-enum PHY_STAT_BIT {
- PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000,
- PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020,
- PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004,
- PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001,
-};
-
-/* PHY_ANA */
-enum PHY_ANA_BIT {
- PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
- PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
- PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
- PHY_A_SEL = 0x001e,
-};
-/* PHY_ANL */
-enum PHY_ANL_BIT {
- PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000,
- PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100,
- PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020,
- PHY_L_SEL = 0x001f,
-};
-
-/* PHY_ANE */
-enum PHY_ANE_BIT {
- PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004,
- PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001,
-};
-
-/* DM9161 */
-enum PHY_16_BIT {
- PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000,
- PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800,
- PHY_16_TXselect = 0x0400,
- PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100,
- PHY_16_Force100LNK = 0x0080,
- PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020,
- PHY_16_RPDCTR_EN = 0x0010,
- PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004,
- PHY_16_Sleepmode = 0x0002,
- PHY_16_RemoteLoopOut = 0x0001,
-};
-
-#define POST_RX 0x08
-#define POST_FW 0x04
-#define POST0_RX (POST_RX)
-#define POST0_FW (POST_FW)
-#define POST1_RX (POST_RX >> 2)
-#define POST1_FW (POST_FW >> 2)
-#define POST_ALL (POST0_RX | POST0_FW | POST1_RX | POST1_FW)
-
/* ARSTR */
enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, };
@@ -785,10 +720,6 @@ struct sh_eth_private {
int msg_enable;
int speed;
int duplex;
- u32 rx_int_var, tx_int_var; /* interrupt control variables */
- char post_rx; /* POST receive */
- char post_fw; /* POST forward */
- struct net_device_stats tsu_stats; /* TSU forward status */
int port; /* for TSU */
int vlan_num_ids; /* for VLAN tag filter */
--
1.7.1
^ permalink raw reply related
* [PATCH v3 3/6] net: sh_eth: fix the rxdesc pointer when rx descriptor empty happens
From: Shimoda, Yoshihiro @ 2012-05-14 6:46 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
When Receive Descriptor Empty happens, rxdesc pointer of the driver
and actual next descriptor of the controller may be mismatch.
This patch fixes it.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
about v3:
- this patch is the same as v2
drivers/net/ethernet/renesas/sh_eth.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 10f2a89..906e410 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1098,8 +1098,12 @@ static int sh_eth_rx(struct net_device *ndev)
/* Restart Rx engine if stopped. */
/* If we don't need to check status, don't. -KDU */
- if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
+ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
+ /* fix the values for the next receiving */
+ mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) -
+ sh_eth_read(ndev, RDLAR)) >> 4;
sh_eth_write(ndev, EDRRR_R, EDRRR);
+ }
return 0;
}
@@ -1196,8 +1200,6 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
/* Receive Descriptor Empty int */
ndev->stats.rx_over_errors++;
- if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R)
- sh_eth_write(ndev, EDRRR_R, EDRRR);
if (netif_msg_rx_err(mdp))
dev_err(&ndev->dev, "Receive Descriptor Empty\n");
}
--
1.7.1
^ permalink raw reply related
* [PATCH v3 4/6] net: sh_eth: fix up the buffer pointers
From: Shimoda, Yoshihiro @ 2012-05-14 6:46 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
After freeing the buffer, the driver should change the value of
the pointer to NULL.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
about v3:
- a new patch
drivers/net/ethernet/renesas/sh_eth.c | 31 ++++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 906e410..ff5a4a9 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -745,6 +745,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
}
}
kfree(mdp->rx_skbuff);
+ mdp->rx_skbuff = NULL;
/* Free Tx skb ringbuffer */
if (mdp->tx_skbuff) {
@@ -754,6 +755,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
}
}
kfree(mdp->tx_skbuff);
+ mdp->tx_skbuff = NULL;
}
/* format skb and descriptor buffer */
@@ -890,10 +892,31 @@ desc_ring_free:
skb_ring_free:
/* Free Rx and Tx skb ring buffer */
sh_eth_ring_free(ndev);
+ mdp->tx_ring = NULL;
+ mdp->rx_ring = NULL;
return ret;
}
+static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
+{
+ int ringsize;
+
+ if (mdp->rx_ring) {
+ ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ dma_free_coherent(NULL, ringsize, mdp->rx_ring,
+ mdp->rx_desc_dma);
+ mdp->rx_ring = NULL;
+ }
+
+ if (mdp->tx_ring) {
+ ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ dma_free_coherent(NULL, ringsize, mdp->tx_ring,
+ mdp->tx_desc_dma);
+ mdp->tx_ring = NULL;
+ }
+}
+
static int sh_eth_dev_init(struct net_device *ndev)
{
int ret = 0;
@@ -1629,7 +1652,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
static int sh_eth_close(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- int ringsize;
netif_stop_queue(ndev);
@@ -1652,12 +1674,7 @@ static int sh_eth_close(struct net_device *ndev)
sh_eth_ring_free(ndev);
/* free DMA buffer */
- ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
- dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma);
-
- /* free DMA buffer */
- ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
- dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
+ sh_eth_free_dma_buffer(mdp);
pm_runtime_put_sync(&mdp->pdev->dev);
--
1.7.1
^ permalink raw reply related
* [PATCH v3 5/6] net: sh_eth: add support for set_ringparam/get_ringparam
From: Shimoda, Yoshihiro @ 2012-05-14 6:47 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This patch supports the ethtool's set_ringparam() and get_ringparam().
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
about v3:
- call netif_tx_disable, synchronize_irq and netif_wake_queue in
the sh_eth_set_ringparam()
- add error handling in the sh_eth_set_ringparam()
- modify the sh_eth_dev_init() not to enable the interrupt when
it is called in the sh_eth_set_ringparam()
drivers/net/ethernet/renesas/sh_eth.c | 139 +++++++++++++++++++++++++--------
drivers/net/ethernet/renesas/sh_eth.h | 6 ++
2 files changed, 112 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index ff5a4a9..c64a31c 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -739,7 +739,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* Free Rx skb ringbuffer */
if (mdp->rx_skbuff) {
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_rx_ring; i++) {
if (mdp->rx_skbuff[i])
dev_kfree_skb(mdp->rx_skbuff[i]);
}
@@ -749,7 +749,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* Free Tx skb ringbuffer */
if (mdp->tx_skbuff) {
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_tx_ring; i++) {
if (mdp->tx_skbuff[i])
dev_kfree_skb(mdp->tx_skbuff[i]);
}
@@ -766,8 +766,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
struct sk_buff *skb;
struct sh_eth_rxdesc *rxdesc = NULL;
struct sh_eth_txdesc *txdesc = NULL;
- int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE;
- int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE;
+ int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring;
+ int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring;
mdp->cur_rx = mdp->cur_tx = 0;
mdp->dirty_rx = mdp->dirty_tx = 0;
@@ -775,7 +775,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
memset(mdp->rx_ring, 0, rx_ringsize);
/* build Rx ring buffer */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_rx_ring; i++) {
/* skb */
mdp->rx_skbuff[i] = NULL;
skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
@@ -801,7 +801,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
}
}
- mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
+ mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);
/* Mark the last entry as wrapping the ring. */
rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
@@ -809,7 +809,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
memset(mdp->tx_ring, 0, tx_ringsize);
/* build Tx ring buffer */
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_tx_ring; i++) {
mdp->tx_skbuff[i] = NULL;
txdesc = &mdp->tx_ring[i];
txdesc->status = cpu_to_edmac(mdp, TD_TFP);
@@ -843,7 +843,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->rx_buf_sz += NET_IP_ALIGN;
/* Allocate RX and TX skb rings */
- mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
+ mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * mdp->num_rx_ring,
GFP_KERNEL);
if (!mdp->rx_skbuff) {
dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
@@ -851,7 +851,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
return ret;
}
- mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
+ mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * mdp->num_tx_ring,
GFP_KERNEL);
if (!mdp->tx_skbuff) {
dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
@@ -860,7 +860,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
}
/* Allocate all Rx descriptors. */
- rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
GFP_KERNEL);
@@ -874,7 +874,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->dirty_rx = 0;
/* Allocate all Tx descriptors. */
- tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
GFP_KERNEL);
if (!mdp->tx_ring) {
@@ -903,21 +903,21 @@ static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
int ringsize;
if (mdp->rx_ring) {
- ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
dma_free_coherent(NULL, ringsize, mdp->rx_ring,
mdp->rx_desc_dma);
mdp->rx_ring = NULL;
}
if (mdp->tx_ring) {
- ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
dma_free_coherent(NULL, ringsize, mdp->tx_ring,
mdp->tx_desc_dma);
mdp->tx_ring = NULL;
}
}
-static int sh_eth_dev_init(struct net_device *ndev)
+static int sh_eth_dev_init(struct net_device *ndev, bool start)
{
int ret = 0;
struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -963,7 +963,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
RFLR);
sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
- sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+ if (start)
+ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
/* PAUSE Prohibition */
val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
@@ -978,7 +979,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
/* E-MAC Interrupt Enable register */
- sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
+ if (start)
+ sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
/* Set MAC address */
update_mac_address(ndev);
@@ -991,10 +993,12 @@ static int sh_eth_dev_init(struct net_device *ndev)
if (mdp->cd->tpauser)
sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
- /* Setting the Rx mode will start the Rx process. */
- sh_eth_write(ndev, EDRRR_R, EDRRR);
+ if (start) {
+ /* Setting the Rx mode will start the Rx process. */
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
- netif_start_queue(ndev);
+ netif_start_queue(ndev);
+ }
return ret;
}
@@ -1008,7 +1012,7 @@ static int sh_eth_txfree(struct net_device *ndev)
int entry = 0;
for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
- entry = mdp->dirty_tx % TX_RING_SIZE;
+ entry = mdp->dirty_tx % mdp->num_tx_ring;
txdesc = &mdp->tx_ring[entry];
if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
break;
@@ -1021,7 +1025,7 @@ static int sh_eth_txfree(struct net_device *ndev)
freeNum++;
}
txdesc->status = cpu_to_edmac(mdp, TD_TFP);
- if (entry >= TX_RING_SIZE - 1)
+ if (entry >= mdp->num_tx_ring - 1)
txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
ndev->stats.tx_packets++;
@@ -1036,8 +1040,8 @@ static int sh_eth_rx(struct net_device *ndev)
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_rxdesc *rxdesc;
- int entry = mdp->cur_rx % RX_RING_SIZE;
- int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
+ int entry = mdp->cur_rx % mdp->num_rx_ring;
+ int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx;
struct sk_buff *skb;
u16 pkt_len = 0;
u32 desc_status;
@@ -1088,13 +1092,13 @@ static int sh_eth_rx(struct net_device *ndev)
ndev->stats.rx_bytes += pkt_len;
}
rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
- entry = (++mdp->cur_rx) % RX_RING_SIZE;
+ entry = (++mdp->cur_rx) % mdp->num_rx_ring;
rxdesc = &mdp->rx_ring[entry];
}
/* Refill the Rx ring buffers. */
for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
- entry = mdp->dirty_rx % RX_RING_SIZE;
+ entry = mdp->dirty_rx % mdp->num_rx_ring;
rxdesc = &mdp->rx_ring[entry];
/* The size of the buffer is 16 byte boundary. */
rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
@@ -1111,7 +1115,7 @@ static int sh_eth_rx(struct net_device *ndev)
skb_checksum_none_assert(skb);
rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
}
- if (entry >= RX_RING_SIZE - 1)
+ if (entry >= mdp->num_rx_ring - 1)
rxdesc->status |=
cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
else
@@ -1509,6 +1513,71 @@ static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
}
}
+static void sh_eth_get_ringparam(struct net_device *ndev,
+ struct ethtool_ringparam *ring)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ ring->rx_max_pending = RX_RING_MAX;
+ ring->tx_max_pending = TX_RING_MAX;
+ ring->rx_pending = mdp->num_rx_ring;
+ ring->tx_pending = mdp->num_tx_ring;
+}
+
+static int sh_eth_set_ringparam(struct net_device *ndev,
+ struct ethtool_ringparam *ring)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ int ret;
+
+ if (ring->tx_pending > TX_RING_MAX ||
+ ring->rx_pending > RX_RING_MAX ||
+ ring->tx_pending < TX_RING_MIN ||
+ ring->rx_pending < RX_RING_MIN)
+ return -EINVAL;
+ if (ring->rx_mini_pending || ring->rx_jumbo_pending)
+ return -EINVAL;
+
+ if (netif_running(ndev)) {
+ netif_tx_disable(ndev);
+ /* Disable interrupts by clearing the interrupt mask. */
+ sh_eth_write(ndev, 0x0000, EESIPR);
+ /* Stop the chip's Tx and Rx processes. */
+ sh_eth_write(ndev, 0, EDTRR);
+ sh_eth_write(ndev, 0, EDRRR);
+ synchronize_irq(ndev->irq);
+ }
+
+ /* Free all the skbuffs in the Rx queue. */
+ sh_eth_ring_free(ndev);
+ /* Free DMA buffer */
+ sh_eth_free_dma_buffer(mdp);
+
+ /* Set new parameters */
+ mdp->num_rx_ring = ring->rx_pending;
+ mdp->num_tx_ring = ring->tx_pending;
+
+ ret = sh_eth_ring_init(ndev);
+ if (ret < 0) {
+ dev_err(&ndev->dev, "%s: sh_eth_ring_init failed.\n", __func__);
+ return ret;
+ }
+ ret = sh_eth_dev_init(ndev, false);
+ if (ret < 0) {
+ dev_err(&ndev->dev, "%s: sh_eth_dev_init failed.\n", __func__);
+ return ret;
+ }
+
+ if (netif_running(ndev)) {
+ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+ /* Setting the Rx mode will start the Rx process. */
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
+ netif_wake_queue(ndev);
+ }
+
+ return 0;
+}
+
static const struct ethtool_ops sh_eth_ethtool_ops = {
.get_settings = sh_eth_get_settings,
.set_settings = sh_eth_set_settings,
@@ -1519,6 +1588,8 @@ static const struct ethtool_ops sh_eth_ethtool_ops = {
.get_strings = sh_eth_get_strings,
.get_ethtool_stats = sh_eth_get_ethtool_stats,
.get_sset_count = sh_eth_get_sset_count,
+ .get_ringparam = sh_eth_get_ringparam,
+ .set_ringparam = sh_eth_set_ringparam,
};
/* network device open function */
@@ -1549,7 +1620,7 @@ static int sh_eth_open(struct net_device *ndev)
goto out_free_irq;
/* device init */
- ret = sh_eth_dev_init(ndev);
+ ret = sh_eth_dev_init(ndev, true);
if (ret)
goto out_free_irq;
@@ -1583,7 +1654,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
ndev->stats.tx_errors++;
/* Free all the skbuffs in the Rx queue. */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_rx_ring; i++) {
rxdesc = &mdp->rx_ring[i];
rxdesc->status = 0;
rxdesc->addr = 0xBADF00D0;
@@ -1591,14 +1662,14 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
dev_kfree_skb(mdp->rx_skbuff[i]);
mdp->rx_skbuff[i] = NULL;
}
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_tx_ring; i++) {
if (mdp->tx_skbuff[i])
dev_kfree_skb(mdp->tx_skbuff[i]);
mdp->tx_skbuff[i] = NULL;
}
/* device init */
- sh_eth_dev_init(ndev);
+ sh_eth_dev_init(ndev, true);
}
/* Packet transmit function */
@@ -1610,7 +1681,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
unsigned long flags;
spin_lock_irqsave(&mdp->lock, flags);
- if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) {
+ if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
if (!sh_eth_txfree(ndev)) {
if (netif_msg_tx_queued(mdp))
dev_warn(&ndev->dev, "TxFD exhausted.\n");
@@ -1621,7 +1692,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
spin_unlock_irqrestore(&mdp->lock, flags);
- entry = mdp->cur_tx % TX_RING_SIZE;
+ entry = mdp->cur_tx % mdp->num_tx_ring;
mdp->tx_skbuff[entry] = skb;
txdesc = &mdp->tx_ring[entry];
/* soft swap. */
@@ -1635,7 +1706,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
else
txdesc->buffer_length = skb->len;
- if (entry >= TX_RING_SIZE - 1)
+ if (entry >= mdp->num_tx_ring - 1)
txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
else
txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
@@ -2265,6 +2336,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
ether_setup(ndev);
mdp = netdev_priv(ndev);
+ mdp->num_tx_ring = TX_RING_SIZE;
+ mdp->num_rx_ring = RX_RING_SIZE;
mdp->addr = ioremap(res->start, resource_size(res));
if (mdp->addr == NULL) {
ret = -ENOMEM;
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 9525199..f1dbc27 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -27,6 +27,10 @@
#define TX_TIMEOUT (5*HZ)
#define TX_RING_SIZE 64 /* Tx ring size */
#define RX_RING_SIZE 64 /* Rx ring size */
+#define TX_RING_MIN 64
+#define RX_RING_MIN 64
+#define TX_RING_MAX 1024
+#define RX_RING_MAX 1024
#define ETHERSMALL 60
#define PKT_BUF_SZ 1538
#define SH_ETH_TSU_TIMEOUT_MS 500
@@ -700,6 +704,8 @@ struct sh_eth_private {
const u16 *reg_offset;
void __iomem *addr;
void __iomem *tsu_addr;
+ u32 num_rx_ring;
+ u32 num_tx_ring;
dma_addr_t rx_desc_dma;
dma_addr_t tx_desc_dma;
struct sh_eth_rxdesc *rx_ring;
--
1.7.1
^ permalink raw reply related
* [PATCH v3 6/6] net: sh_eth: use NAPI
From: Shimoda, Yoshihiro @ 2012-05-14 6:47 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This patch modifies the driver to use NAPI.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
about v3:
- fix the condition to call the napi_complete()
- call napi_disable/enable in the sh_eth_set_ringparam()
drivers/net/ethernet/renesas/sh_eth.c | 85 +++++++++++++++++++++++----------
drivers/net/ethernet/renesas/sh_eth.h | 3 +
2 files changed, 62 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index c64a31c..3ee170a 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1035,7 +1035,7 @@ static int sh_eth_txfree(struct net_device *ndev)
}
/* Packet receive function */
-static int sh_eth_rx(struct net_device *ndev)
+static int sh_eth_rx(struct net_device *ndev, int *work, int budget)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_rxdesc *rxdesc;
@@ -1047,7 +1047,8 @@ static int sh_eth_rx(struct net_device *ndev)
u32 desc_status;
rxdesc = &mdp->rx_ring[entry];
- while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
+ while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT)) &&
+ *work < budget) {
desc_status = edmac_to_cpu(mdp, rxdesc->status);
pkt_len = rxdesc->frame_length;
@@ -1087,13 +1088,17 @@ static int sh_eth_rx(struct net_device *ndev)
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len);
skb->protocol = eth_type_trans(skb, ndev);
- netif_rx(skb);
- ndev->stats.rx_packets++;
- ndev->stats.rx_bytes += pkt_len;
+ if (netif_receive_skb(skb) == NET_RX_DROP) {
+ ndev->stats.rx_dropped++;
+ } else {
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += pkt_len;
+ }
}
rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
entry = (++mdp->cur_rx) % mdp->num_rx_ring;
rxdesc = &mdp->rx_ring[entry];
+ (*work)++;
}
/* Refill the Rx ring buffers. */
@@ -1125,7 +1130,7 @@ static int sh_eth_rx(struct net_device *ndev)
/* Restart Rx engine if stopped. */
/* If we don't need to check status, don't. -KDU */
- if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
+ if (*work < budget && !(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
/* fix the values for the next receiving */
mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) -
sh_eth_read(ndev, RDLAR)) >> 4;
@@ -1281,38 +1286,57 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
/* Get interrpt stat */
intr_status = sh_eth_read(ndev, EESR);
- /* Clear interrupt */
if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
cd->tx_check | cd->eesr_err_check)) {
- sh_eth_write(ndev, intr_status, EESR);
+ if (napi_schedule_prep(&mdp->napi)) {
+ /* Disable interrupts of the channel */
+ sh_eth_write(ndev, 0, EESIPR);
+ __napi_schedule(&mdp->napi);
+ }
ret = IRQ_HANDLED;
- } else
- goto other_irq;
-
- if (intr_status & (EESR_FRC | /* Frame recv*/
- EESR_RMAF | /* Multi cast address recv*/
- EESR_RRF | /* Bit frame recv */
- EESR_RTLF | /* Long frame recv*/
- EESR_RTSF | /* short frame recv */
- EESR_PRE | /* PHY-LSI recv error */
- EESR_CERF)){ /* recv frame CRC error */
- sh_eth_rx(ndev);
}
- /* Tx Check */
- if (intr_status & cd->tx_check) {
- sh_eth_txfree(ndev);
+ spin_unlock(&mdp->lock);
+
+ return ret;
+}
+
+static int sh_eth_poll(struct napi_struct *napi, int budget)
+{
+ struct sh_eth_private *mdp = container_of(napi, struct sh_eth_private,
+ napi);
+ struct net_device *ndev = mdp->ndev;
+ struct sh_eth_cpu_data *cd = mdp->cd;
+ int work_done = 0, txfree_num;
+ u32 intr_status = sh_eth_read(ndev, EESR);
+
+ /* Clear interrupt flags */
+ sh_eth_write(ndev, intr_status, EESR);
+
+ /* check txdesc */
+ txfree_num = sh_eth_txfree(ndev);
+ if (txfree_num)
netif_wake_queue(ndev);
- }
+ /* check rxdesc */
+ sh_eth_rx(ndev, &work_done, budget);
+
+ /* check error flags */
if (intr_status & cd->eesr_err_check)
sh_eth_error(ndev, intr_status);
-other_irq:
- spin_unlock(&mdp->lock);
+ /* get current interrupt flags */
+ intr_status = sh_eth_read(ndev, EESR);
- return ret;
+ /* check whether this driver should call napi_complete() */
+ if (work_done < budget) {
+ napi_complete(napi);
+ /* Enable all interrupts */
+ sh_eth_write(ndev, cd->eesipr_value, EESIPR);
+ }
+
+ return work_done;
}
/* PHY state control function */
@@ -1545,6 +1569,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
/* Stop the chip's Tx and Rx processes. */
sh_eth_write(ndev, 0, EDTRR);
sh_eth_write(ndev, 0, EDRRR);
+ napi_disable(&mdp->napi);
synchronize_irq(ndev->irq);
}
@@ -1569,6 +1594,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
}
if (netif_running(ndev)) {
+ napi_enable(&mdp->napi);
sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
/* Setting the Rx mode will start the Rx process. */
sh_eth_write(ndev, EDRRR_R, EDRRR);
@@ -1600,6 +1626,8 @@ static int sh_eth_open(struct net_device *ndev)
pm_runtime_get_sync(&mdp->pdev->dev);
+ napi_enable(&mdp->napi);
+
ret = request_irq(ndev->irq, sh_eth_interrupt,
#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7764) || \
@@ -1739,6 +1767,8 @@ static int sh_eth_close(struct net_device *ndev)
phy_disconnect(mdp->phydev);
}
+ napi_disable(&mdp->napi);
+
free_irq(ndev->irq, ndev);
/* Free all the skbuffs in the Rx queue. */
@@ -2368,6 +2398,9 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
#endif
sh_eth_set_default_cpu_data(mdp->cd);
+ mdp->ndev = ndev;
+ netif_napi_add(ndev, &mdp->napi, sh_eth_poll, SH_ETH_NAPI_WEIGHT);
+
/* set function */
ndev->netdev_ops = &sh_eth_netdev_ops;
SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index f1dbc27..93dad7b 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -35,6 +35,7 @@
#define PKT_BUF_SZ 1538
#define SH_ETH_TSU_TIMEOUT_MS 500
#define SH_ETH_TSU_CAM_ENTRIES 32
+#define SH_ETH_NAPI_WEIGHT 32
enum {
/* E-DMAC registers */
@@ -728,6 +729,8 @@ struct sh_eth_private {
int duplex;
int port; /* for TSU */
int vlan_num_ids; /* for VLAN tag filter */
+ struct napi_struct napi;
+ struct net_device *ndev;
unsigned no_ether_link:1;
unsigned ether_link_active_low:1;
--
1.7.1
^ permalink raw reply related
* [PATCH 1/8] batman-adv: avoid skb_linearise() if not needed
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
Whenever we want to access headers only, we do not need to linearise the whole
packet. Instead we can use pskb_may_pull()
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/routing.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 7ed9d8f..4c6467d 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -916,8 +916,9 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
/* Check whether I have to reroute the packet */
if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) {
- /* Linearize the skb before accessing it */
- if (skb_linearize(skb) < 0)
+ /* check if there is enough data before accessing it */
+ if (pskb_may_pull(skb, sizeof(struct unicast_packet) +
+ ETH_HLEN) < 0)
return 0;
ethhdr = (struct ethhdr *)(skb->data +
--
1.7.9.4
^ permalink raw reply related
* [PATCH 2/8] batman-adv: improve unicast packet (re)routing
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
In case of a client X roaming from a generic node A to another node B, it is
possible that a third node C gets A's OGM but not B's. At this point in time, if
C wants to send data to X it will send a unicast packet destined to A. The
packet header will contain A's last ttvn (C got A's OGM and so it knows it).
The packet will travel towards A without being intercepted because the ttvn
contained in its header is the newest for A.
Once A will receive the packet, A's state will not report to be in a "roaming
phase" (because, after a roaming, once A sends out its OGM, all the changes are
committed and the node is considered not to be in the roaming state anymore)
and it will match the ttvn carried by the packet. Therefore there is no reason
for A to try to alter the packet's route, thus dropping the packet because the
destination client is not there anymore.
However, C is well aware that it's routing information towards the client X is
outdated as it received an OGM from A saying that the client roamed away.
Thanks to this detail, this patch introduces a small change in behaviour: as
long as C is in the state of not knowing the new location of client X it will
forward the traffic to its last known location using ttvn-1 of the destination.
By using an older ttvn node A will be forced to re-route the packet.
Intermediate nodes are also allowed to update the packet's destination as long
as they have the information about the client's new location.
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/routing.c | 7 +++++++
net/batman-adv/translation-table.c | 19 +++++++++++++++++++
net/batman-adv/translation-table.h | 2 ++
net/batman-adv/unicast.c | 8 ++++++++
4 files changed, 36 insertions(+)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 4c6467d..b1824bb 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -923,6 +923,13 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
ethhdr = (struct ethhdr *)(skb->data +
sizeof(struct unicast_packet));
+
+ /* we don't have an updated route for this client, so we should
+ * not try to reroute the packet!!
+ */
+ if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
+ return 1;
+
orig_node = transtable_search(bat_priv, NULL, ethhdr->h_dest);
if (!orig_node) {
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 2cb46f0..b3fb597 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -2117,3 +2117,22 @@ request_table:
}
}
}
+
+/* returns true whether we know that the client has moved from its old
+ * originator to another one. This entry is kept is still kept for consistency
+ * purposes
+ */
+bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr)
+{
+ struct tt_global_entry *tt_global_entry;
+ bool ret = false;
+
+ tt_global_entry = tt_global_hash_find(bat_priv, addr);
+ if (!tt_global_entry)
+ goto out;
+
+ ret = tt_global_entry->common.flags & TT_CLIENT_ROAM;
+ tt_global_entry_free_ref(tt_global_entry);
+out:
+ return ret;
+}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 593d1b3..c43374d 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -53,5 +53,7 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst);
void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
const unsigned char *tt_buff, uint8_t tt_num_changes,
uint8_t ttvn, uint16_t tt_crc);
+bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr);
+
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 676f6a6..74175c2 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -331,6 +331,14 @@ find_router:
unicast_packet->ttvn =
(uint8_t)atomic_read(&orig_node->last_ttvn);
+ /* inform the destination node that we are still missing a correct route
+ * for this client. The destination will receive this packet and will
+ * try to reroute it because the ttvn contained in the header is less
+ * than the current one
+ */
+ if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
+ unicast_packet->ttvn = unicast_packet->ttvn - 1;
+
if (atomic_read(&bat_priv->fragmentation) &&
data_len + sizeof(*unicast_packet) >
neigh_node->if_incoming->net_dev->mtu) {
--
1.7.9.4
^ permalink raw reply related
* [PATCH 3/8] batman-adv: prepare lq_update_lock to be shared among different protocols
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
From: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/bat_iv_ogm.c | 9 ++++-----
net/batman-adv/originator.c | 1 +
net/batman-adv/types.h | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index abd10c4..dc53798 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -43,7 +43,6 @@ static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface,
goto out;
INIT_LIST_HEAD(&neigh_node->bonding_list);
- spin_lock_init(&neigh_node->tq_lock);
neigh_node->orig_node = orig_neigh;
neigh_node->if_incoming = hard_iface;
@@ -637,12 +636,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
if (is_duplicate)
continue;
- spin_lock_bh(&tmp_neigh_node->tq_lock);
+ spin_lock_bh(&tmp_neigh_node->lq_update_lock);
ring_buffer_set(tmp_neigh_node->tq_recv,
&tmp_neigh_node->tq_index, 0);
tmp_neigh_node->tq_avg =
ring_buffer_avg(tmp_neigh_node->tq_recv);
- spin_unlock_bh(&tmp_neigh_node->tq_lock);
+ spin_unlock_bh(&tmp_neigh_node->lq_update_lock);
}
if (!neigh_node) {
@@ -668,12 +667,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
orig_node->flags = batman_ogm_packet->flags;
neigh_node->last_seen = jiffies;
- spin_lock_bh(&neigh_node->tq_lock);
+ spin_lock_bh(&neigh_node->lq_update_lock);
ring_buffer_set(neigh_node->tq_recv,
&neigh_node->tq_index,
batman_ogm_packet->tq);
neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
- spin_unlock_bh(&neigh_node->tq_lock);
+ spin_unlock_bh(&neigh_node->lq_update_lock);
if (!is_duplicate) {
orig_node->last_ttl = batman_ogm_packet->header.ttl;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index f4b6201..41147942 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -99,6 +99,7 @@ struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface,
INIT_HLIST_NODE(&neigh_node->list);
memcpy(neigh_node->addr, neigh_addr, ETH_ALEN);
+ spin_lock_init(&neigh_node->lq_update_lock);
/* extra reference for return */
atomic_set(&neigh_node->refcount, 2);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 66a3750..61308e8 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -137,7 +137,7 @@ struct neigh_node {
struct rcu_head rcu;
struct orig_node *orig_node;
struct hard_iface *if_incoming;
- spinlock_t tq_lock; /* protects: tq_recv, tq_index */
+ spinlock_t lq_update_lock; /* protects: tq_recv, tq_index */
};
#ifdef CONFIG_BATMAN_ADV_BLA
--
1.7.9.4
^ permalink raw reply related
* [PATCH 4/8] batman-adv: refactor window_protected to avoid unnecessary return statement
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
From: Marek Lindner <lindner_marek@yahoo.de>
Reported-by: David Laight <David.Laight@aculab.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/routing.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index b1824bb..840e2c6 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -234,17 +234,14 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
{
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) ||
(seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
- if (has_timed_out(*last_reset, RESET_PROTECTION_MS)) {
-
- *last_reset = jiffies;
- bat_dbg(DBG_BATMAN, bat_priv,
- "old packet received, start protection\n");
-
- return 0;
- } else {
+ if (!has_timed_out(*last_reset, RESET_PROTECTION_MS))
return 1;
- }
+
+ *last_reset = jiffies;
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "old packet received, start protection\n");
}
+
return 0;
}
--
1.7.9.4
^ permalink raw reply related
* [PATCH 5/8] batman-adv: use shorter pr_warn instead of pr_warning
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
From: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/hard-interface.c | 6 +++---
net/batman-adv/send.c | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 0b84bb1..dc334fa 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -173,9 +173,9 @@ static void check_known_mac_addr(const struct net_device *net_dev)
net_dev->dev_addr))
continue;
- pr_warning("The newly added mac address (%pM) already exists on: %s\n",
- net_dev->dev_addr, hard_iface->net_dev->name);
- pr_warning("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
+ pr_warn("The newly added mac address (%pM) already exists on: %s\n",
+ net_dev->dev_addr, hard_iface->net_dev->name);
+ pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
}
rcu_read_unlock();
}
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 8e74d97..f47299f 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -45,8 +45,8 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
goto send_skb_err;
if (!(hard_iface->net_dev->flags & IFF_UP)) {
- pr_warning("Interface %s is not up - can't send packet via that interface!\n",
- hard_iface->net_dev->name);
+ pr_warn("Interface %s is not up - can't send packet via that interface!\n",
+ hard_iface->net_dev->name);
goto send_skb_err;
}
--
1.7.9.4
^ permalink raw reply related
* [PATCH 7/8] batman-adv: README cleanups
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
From: Sven Eckelmann <sven@narfation.org>
- Add routing_algo
- Remove date from README:
The date has to be updated when a patch touches the README. Therefore, nearly
every feature will modify this date. It can happens quite often that not only
one feature is currently in development or waiting on the mailinglist. This
creates merge conflicts when applying a patchset.
The date itself doesn't provide any additional information when this file is
only available in a release tarball or as part of a SCM repository.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
Documentation/networking/batman-adv.txt | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt
index 220a58c..75a5923 100644
--- a/Documentation/networking/batman-adv.txt
+++ b/Documentation/networking/batman-adv.txt
@@ -1,5 +1,3 @@
-[state: 21-08-2011]
-
BATMAN-ADV
----------
@@ -68,10 +66,11 @@ All mesh wide settings can be found in batman's own interface
folder:
# ls /sys/class/net/bat0/mesh/
-# aggregated_ogms fragmentation hop_penalty
-# ap_isolation gw_bandwidth log_level
-# bonding gw_mode orig_interval
-# bridge_loop_avoidance gw_sel_class vis_mode
+# aggregated_ogms gw_bandwidth log_level
+# ap_isolation gw_mode orig_interval
+# bonding gw_sel_class routing_algo
+# bridge_loop_avoidance hop_penalty vis_mode
+# fragmentation
There is a special folder for debugging information:
--
1.7.9.4
^ permalink raw reply related
* [PATCH 6/8] batman-adv: Start new development cycle
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
From: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/main.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index fd83acd..f4a3ec0 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -28,7 +28,7 @@
#define DRIVER_DEVICE "batman-adv"
#ifndef SOURCE_VERSION
-#define SOURCE_VERSION "2012.1.0"
+#define SOURCE_VERSION "2012.2.0"
#endif
/* B.A.T.M.A.N. parameters */
--
1.7.9.4
^ permalink raw reply related
* [PATCH 8/8] batman-adv: unset the TT_CLIENT_PENDING flag if the new local entry already exists
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1336979858-13928-1-git-send-email-ordex@autistici.org>
When trying to add a new tt_local_entry, if such entry already exists, we have
to ensure that the TT_CLIENT_PENDING flag is not set, otherwise the entry will
be deleted soon.
Reported-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
net/batman-adv/translation-table.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index b3fb597..a66c2dc 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -206,6 +206,8 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
if (tt_local_entry) {
tt_local_entry->last_seen = jiffies;
+ /* possibly unset the TT_CLIENT_PENDING flag */
+ tt_local_entry->common.flags &= ~TT_CLIENT_PENDING;
goto out;
}
--
1.7.9.4
^ permalink raw reply related
* pull request: batman-adv 2012-05-14
From: Antonio Quartulli @ 2012-05-14 7:17 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Hello David,
here is our last set of changes intended for net-next/linux-3.5.
In this patchset there are:
1) several minor cleanups and fixes
2) an optimisation that avoid to linearise the whole packet when not needed
3) an optimisation for client traffic rerouting after a roaming event.
Patches that modify the whole naming schema will be sent later for merging
with linux-3.6.
Thank you,
Antonio
The following changes since commit f96a8a0b78548c0ec06b0b4b438db6ee895d67e9:
igb: Add Support for new i210/i211 devices. (2012-05-12 13:17:13 -0700)
are available in the git repository at:
git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem
for you to fetch changes up to 521251f2f5fa16747cc21e71580e404af855d140:
batman-adv: unset the TT_CLIENT_PENDING flag if the new local entry already exists (2012-05-14 09:05:08 +0200)
----------------------------------------------------------------
Included changes:
* an improvement to avoid to linearise the whole received packet when not needed
* an improvement for client traffic rerouting after roaming
* a fix for the local translation table state-machine
* minor cleanups and fixes
----------------------------------------------------------------
Antonio Quartulli (3):
batman-adv: avoid skb_linearise() if not needed
batman-adv: improve unicast packet (re)routing
batman-adv: unset the TT_CLIENT_PENDING flag if the new local entry already exists
Marek Lindner (2):
batman-adv: prepare lq_update_lock to be shared among different protocols
batman-adv: refactor window_protected to avoid unnecessary return statement
Sven Eckelmann (3):
batman-adv: use shorter pr_warn instead of pr_warning
batman-adv: Start new development cycle
batman-adv: README cleanups
Documentation/networking/batman-adv.txt | 11 +++++------
net/batman-adv/bat_iv_ogm.c | 9 ++++-----
net/batman-adv/hard-interface.c | 6 +++---
net/batman-adv/main.h | 2 +-
net/batman-adv/originator.c | 1 +
net/batman-adv/routing.c | 27 ++++++++++++++++-----------
net/batman-adv/send.c | 4 ++--
net/batman-adv/translation-table.c | 21 +++++++++++++++++++++
net/batman-adv/translation-table.h | 2 ++
net/batman-adv/types.h | 2 +-
net/batman-adv/unicast.c | 8 ++++++++
11 files changed, 64 insertions(+), 29 deletions(-)
^ permalink raw reply
* Re: [net-next 2/2] stmmac: add mixed burst for DMA
From: Giuseppe CAVALLARO @ 2012-05-14 7:22 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120511.181259.845221725995971870.davem@davemloft.net>
On 5/12/2012 12:12 AM, David Miller wrote:
> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Mon, 7 May 2012 11:12:33 +0200
>
>> - int (*init) (void __iomem *ioaddr, int pbl, int fb, int burst_len,
>> - u32 dma_tx, u32 dma_rx);
>> + int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb,
>> + int burst_len, u32 dma_tx, u32 dma_rx);
>
> Fix the indentation of the arguments on the second line,
> the first character must line up with the first column after
> the function's openning parenthesis on the previous line.
Yes, my fault and fixed at once.
>
>> -static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb,
>> +static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
>> int burst_len, u32 dma_tx, u32 dma_rx)
>
> While you're here fix up that issue in the existing code here as well.
>
>> -static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb,
>> +static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
>> int burst_len, u32 dma_tx, u32 dma_rx)
>
> Likewise.
After applying the patch the argument "int burst_len" is aligned with
the first column after the opening parenthesis.
Anyway I've just re-looked at the code and verified that.
>
>> - int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0;
>> + int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0,
>> + mixed_burst = 0;
>
> This is gross, just make a new "int" declaration for mixed_burst.
fixed :-(
I'm resending the patches now.
Thanks for your review and sorry for these kind of errors.
peppe
>
>
>
^ permalink raw reply
* Re: [patch] netfilter: potential NULL dereference in get_inner_hdr()
From: Hans Schillstrom @ 2012-05-14 7:36 UTC (permalink / raw)
To: Dan Carpenter
Cc: Pablo Neira Ayuso, Patrick McHardy, David S. Miller,
netfilter-devel@vger.kernel.org, netfilter@vger.kernel.org,
coreteam@netfilter.org, netdev@vger.kernel.org,
kernel-janitors@vger.kernel.org
In-Reply-To: <20120512110003.GB19472@elgon.mountain>
On Saturday 12 May 2012 13:00:03 Dan Carpenter wrote:
> There is a typo in the error checking and "&&" was used instead of "||".
> If skb_header_pointer() returns NULL then it leads to a NULL
> dereference.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Ack-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
> ---
> Btw, this is new code and Sparse complains about endian bugs.
Can you give me some hints here, arch , compiler version etc.
I guess it was input to hmark_addr_mask() that complains ?
>
> diff --git a/net/netfilter/xt_HMARK.c b/net/netfilter/xt_HMARK.c
> index 32fbd73..5817d03 100644
> --- a/net/netfilter/xt_HMARK.c
> +++ b/net/netfilter/xt_HMARK.c
> @@ -223,7 +223,7 @@ static int get_inner_hdr(const struct sk_buff *skb, int iphsz, int *nhoff)
>
> /* Not enough header? */
> icmph = skb_header_pointer(skb, *nhoff + iphsz, sizeof(_ih), &_ih);
> - if (icmph == NULL && icmph->type > NR_ICMP_TYPES)
> + if (icmph == NULL || icmph->type > NR_ICMP_TYPES)
> return 0;
>
> /* Error message? */
> --
> 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
>
--
Regards
Hans Schillstrom <hans.schillstrom@ericsson.com>
^ permalink raw reply
* Re: [patch] netfilter: potential NULL dereference in get_inner_hdr()
From: David Miller @ 2012-05-14 7:38 UTC (permalink / raw)
To: hans.schillstrom
Cc: dan.carpenter, pablo, kaber, netfilter-devel, netfilter, coreteam,
netdev, kernel-janitors
In-Reply-To: <201205140936.56960.hans.schillstrom@ericsson.com>
From: Hans Schillstrom <hans.schillstrom@ericsson.com>
Date: Mon, 14 May 2012 09:36:55 +0200
> On Saturday 12 May 2012 13:00:03 Dan Carpenter wrote:
>> There is a typo in the error checking and "&&" was used instead of "||".
>> If skb_header_pointer() returns NULL then it leads to a NULL
>> dereference.
>>
>> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> Ack-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
>
>> ---
>> Btw, this is new code and Sparse complains about endian bugs.
>
> Can you give me some hints here, arch , compiler version etc.
> I guess it was input to hmark_addr_mask() that complains ?
He said what he's using, "sparse", the semantic parser, which
is largely arch agnostic.
I guarantee you will see the warnings if you run it on your
system on this code.
^ permalink raw reply
* Re: [PATCH] CS89x0 : Use ioread16/iowrite16 on all platforms
From: Arnd Bergmann @ 2012-05-14 7:42 UTC (permalink / raw)
To: Jaccon Bastiaansen
Cc: s.hauer, gfm, davem, festevam, linux-arm-kernel, netdev
In-Reply-To: <1336947279-10769-1-git-send-email-jaccon.bastiaansen@gmail.com>
On Sunday 13 May 2012, Jaccon Bastiaansen wrote:
> The use of the inw/outw functions by the cs89x0 platform driver
> results in NULL pointer references.
>
> Signed-off-by: Jaccon Bastiaansen <jaccon.bastiaansen@gmail.com>
Hi Jaccon,
Thanks for taking on this patch. I think it needs some more work, but you are on
the right track.
First of all, the description about should be more specific. I would recommend
adding at least the specific platform on which you saw it, and something like
[results in NULL pointer references] on platforms that do not provide ISA-style
programmed I/O accessors, and accesses the wrong address space on platforms
that have a PCI I/O space that is not identity-mapped into the physical address
space.
I would also recommend building the driver with "make C=1" after installing "sparse",
so you can detect any location where you potentially use the wrong pointer.
> diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
> index b9406cb..5a1e5d7 100644
> --- a/drivers/net/ethernet/cirrus/cs89x0.c
> +++ b/drivers/net/ethernet/cirrus/cs89x0.c
> @@ -222,6 +222,7 @@ struct net_local {
> int send_underrun; /* keep track of how many underruns in a row we get */
> int force; /* force various values; see FORCE* above. */
> spinlock_t lock;
> + unsigned long phys_addr;/* CS89x0 I/O port or physical address. */
> #if ALLOW_DMA
> int use_dma; /* Flag: we're using dma */
> int dma; /* DMA channel */
> @@ -231,8 +232,6 @@ struct net_local {
> unsigned char *rx_dma_ptr; /* points to the next packet */
> #endif
> #ifdef CONFIG_CS89x0_PLATFORM
> - void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */
> - unsigned long phys_addr;/* Physical address for accessing the CS89x0. */
> unsigned long size; /* Length of CS89x0 memory region. */
> #endif
> };
I think it makes sense to remove the #ifdef here and just leave the "size" member
next to "phys_addr".
More importantly, I would rename the "base_addr" member to "virt_addr" and change
the type to void __iomem *. This will let you remove a lot of type casts and
catch potentially broken accesses where the __iomem token still gets passed into
inw/outw.
> @@ -279,6 +278,47 @@ static int __init dma_fn(char *str)
> __setup("cs89x0_dma=", dma_fn);
> #endif /* !defined(MODULE) && (ALLOW_DMA != 0) */
>
> +#ifndef CONFIG_CS89x0_PLATFORM
> +/*
> + * This function converts the I/O port addres used by the cs89x0_probe() and
> + * init_module() functions to the I/O memory address used by the
> + * cs89x0_probe1() function.
> + */
> +static int __init
> +cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular)
> +{
> + struct net_local *lp = netdev_priv(dev);
> + int ret = 0;
> + void __iomem *io_mem;
> +
> + if (!lp)
> + return -ENOMEM;
> +
> + lp->phys_addr = ioport;
> +
> + if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) {
> + ret = -EBUSY;
> + goto out;
> + }
> +
> + io_mem = ioport_map(ioport, NETCARD_IO_EXTENT);
> + if (!io_mem) {
> + ret = -ENOMEM;
> + goto release;
> + }
> +
> + ret = cs89x0_probe1(dev, ret, modular);
> + if (!ret)
> + goto out;
> +
> + ioport_unmap(io_mem);
> +release:
> + release_region(ioport, NETCARD_IO_EXTENT);
> +out:
> + return ret;
> +}
> +#endif
You don't seem to actually assign the io_mem pointer to base_addr here, so the
accesses will go to the wrong address in the ISA case. It's generally better
not to initially "ret" to zero in cases like this, so the compiler can catch
this kind of bug.
> @@ -373,13 +412,13 @@ writeword(unsigned long base_addr, int portno, u16 value)
> static u16
> readword(unsigned long base_addr, int portno)
> {
> - return inw(base_addr + portno);
> + return ioread16((void __iomem *)base_addr + portno);
> }
>
> static void
> writeword(unsigned long base_addr, int portno, u16 value)
> {
> - outw(value, base_addr + portno);
> + iowrite16(value, (void __iomem *)(base_addr + portno));
> }
> #endif
These functions (and others) should just get changed to take a "void __iomem *"
pointer instead. In fact, you can remove them now and just call iowrite16 directly,
since the ixp2000 case in the #ifdef is now obsolete as the platform is getting
removed and everything just uses ioread/iowrite.
Arnd
^ permalink raw reply
* [PATCH 1/2] driver core: Add dev_*_ratelimited() family
From: Hiroshi DOYU @ 2012-05-14 7:47 UTC (permalink / raw)
To: hdoyu-DDmLM1+adcrQT0dZR+AlfA
Cc: joe-6d6DIl74uiNBDgjK7y7TUQ, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
Greg Kroah-Hartman, Grant Likely, Randy Dunlap, Rafael J. Wysocki,
David S. Miller, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120514.104512.775373956832728793.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Add dev_*_ratelimited() family, dev_* version of pr_*_ratelimited().
Using Joe Perches's proposal/implementation.
Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
---
include/linux/device.h | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/include/linux/device.h b/include/linux/device.h
index 8b9d03a..d3aafdb 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -23,6 +23,7 @@
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/atomic.h>
+#include <linux/ratelimit.h>
#include <asm/device.h>
struct device;
@@ -937,6 +938,32 @@ int _dev_info(const struct device *dev, const char *fmt, ...)
#endif
+#define dev_level_ratelimited(dev_level, dev, fmt, ...) \
+do { \
+ static DEFINE_RATELIMIT_STATE(_rs, \
+ DEFAULT_RATELIMIT_INTERVAL, \
+ DEFAULT_RATELIMIT_BURST); \
+ if (__ratelimit(&_rs)) \
+ dev_level(dev, fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define dev_emerg_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__)
+#define dev_alert_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__)
+#define dev_crit_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__)
+#define dev_err_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
+#define dev_warn_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__)
+#define dev_notice_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__)
+#define dev_info_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
+#define dev_dbg_ratelimited(dev, fmt, ...) \
+ dev_level_ratelimited(dev_dbg, dev, fmt, ##__VA_ARGS__)
+
/*
* Stupid hackaround for existing uses of non-printk uses dev_info
*
--
1.7.5.4
^ permalink raw reply related
* Re: [patch] netfilter: potential NULL dereference in get_inner_hdr()
From: Eric Dumazet @ 2012-05-14 7:53 UTC (permalink / raw)
To: David Miller
Cc: hans.schillstrom, dan.carpenter, pablo, kaber, netfilter-devel,
netfilter, coreteam, netdev, kernel-janitors
In-Reply-To: <20120514.033853.1089019132135043947.davem@davemloft.net>
On Mon, 2012-05-14 at 03:38 -0400, David Miller wrote:
> He said what he's using, "sparse", the semantic parser, which
> is largely arch agnostic.
>
> I guarantee you will see the warnings if you run it on your
> system on this code.
Some more info :
http://lwn.net/Articles/205624/
make C=2 CF=-D__CHECK_ENDIAN__ net/netfilter/xt_HMARK.o
CHECK net/netfilter/xt_HMARK.c
net/netfilter/xt_HMARK.c:87:21: warning: incorrect type in assignment (different base types)
net/netfilter/xt_HMARK.c:87:21: expected unsigned short [unsigned] [usertype] src
net/netfilter/xt_HMARK.c:87:21: got restricted __be16 [usertype] all
net/netfilter/xt_HMARK.c:88:21: warning: incorrect type in assignment (different base types)
net/netfilter/xt_HMARK.c:88:21: expected unsigned short [unsigned] [usertype] dst
net/netfilter/xt_HMARK.c:88:21: got restricted __be16 [usertype] all
net/netfilter/xt_HMARK.c:170:27: warning: incorrect type in argument 2 (different signedness)
net/netfilter/xt_HMARK.c:170:27: expected int *offset
net/netfilter/xt_HMARK.c:170:27: got unsigned int *<noident>
net/netfilter/xt_HMARK.c:181:28: warning: incorrect type in argument 1 (different base types)
net/netfilter/xt_HMARK.c:181:28: expected unsigned int const [usertype] *addr32
net/netfilter/xt_HMARK.c:181:28: got restricted __be32 *<noident>
net/netfilter/xt_HMARK.c:182:28: warning: incorrect type in argument 1 (different base types)
net/netfilter/xt_HMARK.c:182:28: expected unsigned int const [usertype] *addr32
net/netfilter/xt_HMARK.c:182:28: got restricted __be32 *<noident>
net/netfilter/xt_HMARK.c:261:9: warning: invalid assignment: &=
net/netfilter/xt_HMARK.c:261:9: left side has type unsigned int
net/netfilter/xt_HMARK.c:261:9: right side has type restricted __be32
net/netfilter/xt_HMARK.c:262:9: warning: invalid assignment: &=
net/netfilter/xt_HMARK.c:262:9: left side has type unsigned int
net/netfilter/xt_HMARK.c:262:9: right side has type restricted __be32
^ permalink raw reply
* [RFC net-next 0/2] net: Use net_<level>_ratelimit
From: Joe Perches @ 2012-05-14 7:56 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-decnet-user-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
netfilter-devel-u79uwXL29TY76Z2rM5mHXA,
netfilter-u79uwXL29TY76Z2rM5mHXA, coreteam-Cap9r6Oaw4JrovVCs/uTlw,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, dev-yBygre7rU0TnMu66kgdUjQ,
linux-sctp-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA
net_ratelimit() like __ratelimit() is too easy to misuse.
Add simplifying macros similar to pr_<level>_ratelimited
that combines the test of net_ratelimit and logging.
Joe Perches (2):
net: Add net_ratelimited_function and net_<level>_ratelimited macros
net: Convert net_ratelimit uses to net_<level>_ratelimited
include/linux/net.h | 23 +++++++++++
net/atm/ioctl.c | 8 +--
net/caif/caif_socket.c | 10 ++---
net/core/dev.c | 30 ++++++--------
net/core/pktgen.c | 7 +--
net/core/rtnetlink.c | 8 +--
net/core/skbuff.c | 11 ++---
net/decnet/dn_fib.c | 5 +-
net/decnet/dn_neigh.c | 22 ++++-------
net/decnet/dn_nsp_in.c | 11 +++--
net/decnet/dn_nsp_out.c | 5 +-
net/decnet/dn_route.c | 15 ++-----
net/decnet/dn_table.c | 4 +-
net/decnet/netfilter/dn_rtmsg.c | 3 +-
net/ipv4/icmp.c | 20 ++++-----
net/ipv4/ip_fragment.c | 3 +-
net/ipv4/ip_input.c | 13 +++---
net/ipv4/ip_options.c | 6 ++-
net/ipv4/ip_output.c | 4 +-
net/ipv4/ipconfig.c | 11 ++---
net/ipv4/ipmr.c | 3 +-
net/ipv4/netfilter/arp_tables.c | 5 +-
net/ipv4/netfilter/ip_tables.c | 3 +-
net/ipv4/netfilter/ipt_CLUSTERIP.c | 3 +-
net/ipv4/netfilter/nf_nat_h323.c | 26 ++++--------
net/ipv4/netfilter/nf_nat_snmp_basic.c | 8 +--
net/ipv4/route.c | 40 ++++++++-----------
net/ipv4/tcp.c | 14 +++---
net/ipv4/tcp_input.c | 7 +--
net/ipv4/tcp_ipv4.c | 11 ++---
net/ipv4/tcp_output.c | 3 +-
net/ipv6/addrconf.c | 17 +++-----
net/ipv6/ah6.c | 4 +-
net/ipv6/ip6_output.c | 3 +-
net/ipv6/ip6_tunnel.c | 33 +++++----------
net/ipv6/ip6mr.c | 3 +-
net/ipv6/netfilter/ip6_tables.c | 3 +-
net/ipv6/netfilter/ip6t_REJECT.c | 6 +--
net/ipv6/netfilter/ip6table_mangle.c | 3 +-
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 3 +-
net/ipv6/netfilter/nf_conntrack_reasm.c | 7 +--
net/ipv6/reassembly.c | 6 +--
net/ipv6/route.c | 12 +----
net/ipv6/sit.c | 6 +--
net/ipv6/tcp_ipv6.c | 10 ++---
net/llc/af_llc.c | 7 +--
net/mac80211/agg-rx.c | 13 ++----
net/mac80211/ht.c | 8 ++--
net/mac80211/ibss.c | 10 ++---
net/mac80211/mlme.c | 12 ++---
net/mac80211/rx.c | 11 ++---
net/mac80211/tx.c | 17 +++-----
net/netfilter/nf_conntrack_amanda.c | 3 +-
net/netfilter/nf_conntrack_core.c | 5 +--
net/netfilter/nf_conntrack_expect.c | 4 +-
net/netfilter/nf_conntrack_h323_main.c | 9 +---
net/netfilter/nf_conntrack_irc.c | 8 +--
net/netfilter/nfnetlink_queue.c | 9 +---
net/netfilter/xt_TCPMSS.c | 10 ++---
net/netfilter/xt_hashlimit.c | 3 +-
net/openvswitch/vport-netdev.c | 6 +-
net/sched/act_ipt.c | 7 +--
net/sched/act_mirred.c | 5 +-
net/sched/cls_u32.c | 3 +-
net/sched/ematch.c | 4 +-
net/sched/sch_api.c | 10 ++---
net/sched/sch_generic.c | 11 ++---
net/sched/sch_gred.c | 12 ++----
net/sctp/sm_sideeffect.c | 5 +-
net/sctp/sm_statefuns.c | 18 ++++-----
net/sctp/socket.c | 6 +--
net/socket.c | 3 +-
net/sunrpc/svc.c | 18 ++++-----
net/sunrpc/svc_xprt.c | 13 ++----
net/sunrpc/svcsock.c | 28 +++++--------
net/wireless/lib80211_crypt_ccmp.c | 33 +++++----------
net/wireless/lib80211_crypt_tkip.c | 50 ++++++++----------------
77 files changed, 329 insertions(+), 490 deletions(-)
--
1.7.8.111.gad25c.dirty
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ 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