* [PATCH v2 -next 3/4] tg3: Add hwmon support
From: Michael Chan @ 2012-06-27 0:53 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
In-Reply-To: <1340758415-10746-2-git-send-email-mchan@broadcom.com>
Some tg3 devices have management firmware that can export sensor data such
as temperature and other real time diagnostics data. Export temperature
sensor reading via hwmon sysfs.
[hwmon interface suggested by Ben Hutchings <bhutchings@solarflare.com>]
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 189 +++++++++++++++++++++++++++++++++++
drivers/net/ethernet/broadcom/tg3.h | 63 ++++++++++++
2 files changed, 252 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 693a584..6b51e3a 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -44,6 +44,10 @@
#include <linux/prefetch.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
+#if IS_ENABLED(CONFIG_HWMON)
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#endif
#include <net/checksum.h>
#include <net/ip.h>
@@ -9538,6 +9542,182 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy)
return tg3_reset_hw(tp, reset_phy);
}
+static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
+{
+ int i;
+
+ for (i = 0; i < TG3_SD_NUM_RECS; i++, ocir++) {
+ u32 off = i * TG3_OCIR_LEN, len = TG3_OCIR_LEN;
+
+ tg3_ape_scratchpad_read(tp, (u32 *) ocir, off, len);
+ off += len;
+
+ if (ocir->signature != TG3_OCIR_SIG_MAGIC ||
+ !(ocir->version_flags & TG3_OCIR_FLAG_ACTIVE))
+ memset(ocir, 0, TG3_OCIR_LEN);
+ }
+}
+
+#if IS_ENABLED(CONFIG_HWMON)
+/* sysfs attributes for hwmon */
+static ssize_t tg3_show_temp(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct tg3 *tp = netdev_priv(netdev);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ u32 temperature;
+
+ spin_lock_bh(&tp->lock);
+ tg3_ape_scratchpad_read(tp, &temperature, attr->index,
+ sizeof(temperature));
+ spin_unlock_bh(&tp->lock);
+ return sprintf(buf, "%u\n", temperature);
+}
+
+#define TG3_TEMP_SENSOR_OFFSET 0xd4
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tg3_show_temp, NULL,
+ TG3_TEMP_SENSOR_OFFSET);
+static struct attribute *tg3_attributes[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group tg3_group = {
+ .attrs = tg3_attributes,
+};
+
+static void tg3_hwmon_open(struct tg3 *tp)
+{
+ int err;
+ struct tg3_sd *sd = tp->sd;
+ struct pci_dev *pdev = tp->pdev;
+
+ /* Register hwmon sysfs hooks */
+ err = sysfs_create_group(&pdev->dev.kobj, &tg3_group);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n");
+ return;
+ }
+
+ sd->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(sd->hwmon_dev)) {
+ sd->hwmon_dev = NULL;
+ dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n");
+ sysfs_remove_group(&pdev->dev.kobj, &tg3_group);
+ }
+}
+#endif
+
+static int tg3_sd_init(struct tg3 *tp)
+{
+ int i;
+ u32 size = 0;
+ struct tg3_sd *sd;
+ struct tg3_ocir ocirs[TG3_SD_NUM_RECS];
+
+ if (!tg3_flag(tp, ENABLE_APE))
+ return 0;
+
+ tp->sd = kzalloc(sizeof(struct tg3_sd), GFP_KERNEL);
+ if (!tp->sd)
+ return -ENOMEM;
+
+ sd = tp->sd;
+ tg3_sd_scan_scratchpad(tp, ocirs);
+
+ for (i = 0; i < TG3_SD_NUM_RECS; i++) {
+ u32 val = 1;
+ struct tg3_sd_record *rec = &sd->rec[i];
+
+ if (!ocirs[i].src_data_length)
+ continue;
+
+ rec->hdr_len = ocirs[i].src_hdr_length;
+ rec->hdr_off = ocirs[i].src_hdr_offset;
+ rec->data_len = ocirs[i].src_data_length;
+ rec->data_off = ocirs[i].src_data_offset;
+
+ size += ocirs[i].src_hdr_length;
+ size += ocirs[i].src_data_length;
+
+ rec->utmr_off = i * TG3_OCIR_LEN + TG3_OCIR_UPDATE_TMR_OFF;
+ rec->rtmr_off = i * TG3_OCIR_LEN + TG3_OCIR_REFRESH_TMR_OFF;
+ rec->rtmr_int = ocirs[i].refresh_int;
+
+ /* Initialize utmr_off to non-zero so that we read the region
+ * at least once */
+ if (tg3_ape_scratchpad_write(tp, rec->utmr_off, &val, 4))
+ netdev_err(tp->dev, "write scratchpad error\n");
+
+ ocirs[i].update_tmr = 0;
+ }
+ if (!size) {
+ kfree(sd);
+ tp->sd = NULL;
+ return -ENODEV;
+ }
+
+ size += sizeof(ocirs);
+
+ sd->buf = kzalloc(size, GFP_KERNEL);
+ if (!sd->buf) {
+ kfree(sd);
+ tp->sd = NULL;
+ return -ENOMEM;
+ }
+
+ sd->buf_size = size;
+ memcpy(sd->buf, ocirs, sizeof(ocirs));
+
+ sd->sd_flags_off = 2 * TG3_OCIR_LEN + (tp->pci_fn * sizeof(u32)) +
+ TG3_OCIR_PORT0_FLGS_OFF;
+
+ return 0;
+}
+
+static void tg3_sd_fini(struct tg3 *tp)
+{
+ struct tg3_sd *sd = tp->sd;
+
+ if (!sd)
+ return;
+
+ kfree(sd->buf);
+ kfree(sd);
+ tp->sd = NULL;
+}
+
+static void tg3_sd_close(struct tg3 *tp)
+{
+ struct tg3_sd *sd = tp->sd;
+
+ if (!sd)
+ return;
+
+#if IS_ENABLED(CONFIG_HWMON)
+ if (sd->hwmon_dev) {
+ hwmon_device_unregister(sd->hwmon_dev);
+ sd->hwmon_dev = NULL;
+ sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
+ }
+#endif
+}
+
+static int tg3_sd_open(struct tg3 *tp)
+{
+ struct tg3_sd *sd = tp->sd;
+
+ if (!sd)
+ return -ENODEV;
+
+#if IS_ENABLED(CONFIG_HWMON)
+ tg3_hwmon_open(tp);
+#endif
+ return 0;
+}
+
#define TG3_STAT_ADD32(PSTAT, REG) \
do { u32 __val = tr32(REG); \
(PSTAT)->low += __val; \
@@ -10246,6 +10426,8 @@ static int tg3_open(struct net_device *dev)
tg3_phy_start(tp);
+ tg3_sd_open(tp);
+
tg3_full_lock(tp, 0);
tg3_timer_start(tp);
@@ -10295,6 +10477,8 @@ static int tg3_close(struct net_device *dev)
tg3_timer_stop(tp);
+ tg3_sd_close(tp);
+
tg3_phy_stop(tp);
tg3_full_lock(tp, 1);
@@ -15945,6 +16129,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tg3_timer_init(tp);
+ tg3_sd_init(tp);
+
err = register_netdev(dev);
if (err) {
dev_err(&pdev->dev, "Cannot register net device, aborting\n");
@@ -16039,6 +16225,9 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
}
unregister_netdev(dev);
+
+ tg3_sd_fini(tp);
+
if (tp->aperegs) {
iounmap(tp->aperegs);
tp->aperegs = NULL;
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index d167a1c..a3a51c9 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2379,6 +2379,18 @@
#define TG3_APE_LOCK_PHY3 5
#define TG3_APE_LOCK_GPIO 7
+/* SD flags */
+#define TG3_OCIR_SIG_MAGIC 0x5253434f
+#define TG3_OCIR_FLAG_ACTIVE 0x00000001
+
+#define TG3_OCIR_DRVR_FEAT_CSUM 0x00000001
+#define TG3_OCIR_DRVR_FEAT_TSO 0x00000002
+#define TG3_OCIR_DRVR_FEAT_MASK 0xff
+
+#define TG3_OCIR_REFRESH_TMR_OFF 0x00000008
+#define TG3_OCIR_UPDATE_TMR_OFF 0x0000000c
+#define TG3_OCIR_PORT0_FLGS_OFF 0x0000002c
+
#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10
@@ -2677,6 +2689,55 @@ struct tg3_hw_stats {
u8 __reserved4[0xb00-0x9c8];
};
+#define TG3_SD_NUM_RECS 3
+#define TG3_OCIR_LEN (sizeof(struct tg3_ocir))
+
+
+struct tg3_ocir {
+ u32 signature;
+ u16 version_flags;
+ u16 refresh_int;
+ u32 refresh_tmr;
+ u32 update_tmr;
+ u32 dst_base_addr;
+ u16 src_hdr_offset;
+ u16 src_hdr_length;
+ u16 src_data_offset;
+ u16 src_data_length;
+ u16 dst_hdr_offset;
+ u16 dst_data_offset;
+ u16 dst_reg_upd_offset;
+ u16 dst_sem_offset;
+ u32 reserved1[2];
+ u32 port0_flags;
+ u32 port1_flags;
+ u32 port2_flags;
+ u32 port3_flags;
+ u32 reserved2[1];
+};
+
+struct tg3_sd_record {
+ u16 hdr_off;
+ u16 hdr_len;
+ u16 data_off;
+ u16 data_len;
+ u32 updated_seq;
+ u16 utmr_off;
+ u16 rtmr_off;
+ u32 rtmr_val;
+ u16 rtmr_int;
+};
+
+struct tg3_sd {
+#if IS_ENABLED(CONFIG_HWMON)
+ struct device *hwmon_dev;
+#endif
+ struct tg3_sd_record rec[TG3_SD_NUM_RECS];
+ u32 sd_flags_off;
+ int buf_size;
+ u8 *buf;
+};
+
/* 'mapping' is superfluous as the chip does not write into
* the tx/rx post rings so we could just fetch it from there.
* But the cache behavior is better how we are doing it now.
@@ -3212,6 +3273,8 @@ struct tg3 {
const char *fw_needed;
const struct firmware *fw;
u32 fw_len; /* includes BSS */
+
+ struct tg3_sd *sd;
};
#endif /* !(_T3_H) */
--
1.7.1
^ permalink raw reply related
* [PATCH v2 -next 4/4] tg3: Add binary sysfs file to export bulk sensor data
From: Michael Chan @ 2012-06-27 0:53 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
In-Reply-To: <1340758415-10746-3-git-send-email-mchan@broadcom.com>
The bulk of the sensor data is exported as binary data to sysfs for
userspace access.
[binary sysfs suggested by Ben Hutchings <bhutchings@solarflare.com>]
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 130 ++++++++++++++++++++++++++++++++++-
1 files changed, 129 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 6b51e3a..109a7cb 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -9542,6 +9542,48 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy)
return tg3_reset_hw(tp, reset_phy);
}
+static void tg3_sd_xfer(struct tg3 *tp, u32 off, u32 size)
+{
+ struct tg3_sd *sd = tp->sd;
+
+ if (!size)
+ return;
+
+ tg3_ape_scratchpad_read(tp, (u32 *) &sd->buf[off], off, size);
+}
+
+static void tg3_sd_update_host(struct tg3 *tp, struct tg3_sd_record *rec)
+{
+ tg3_sd_xfer(tp, rec->data_off, rec->data_len);
+ tg3_sd_xfer(tp, rec->hdr_off, rec->hdr_len);
+}
+
+static void tg3_sd_update_drvflags(struct tg3 *tp, bool unloading)
+{
+ struct tg3_sd *sd = tp->sd;
+ u32 flags;
+
+ if (!sd || !sd->sd_flags_off)
+ return;
+
+ tg3_ape_scratchpad_read(tp, &flags, sd->sd_flags_off, 4);
+
+ flags &= ~TG3_OCIR_DRVR_FEAT_MASK;
+
+ if (!unloading) {
+ u32 mask = NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM;
+
+ if (tp->dev->features & mask)
+ flags |= TG3_OCIR_DRVR_FEAT_CSUM;
+
+ if (tp->dev->features & NETIF_F_ALL_TSO)
+ flags |= TG3_OCIR_DRVR_FEAT_TSO;
+ }
+
+ tg3_ape_scratchpad_write(tp, sd->sd_flags_off, &flags, 4);
+}
+
static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
{
int i;
@@ -9610,6 +9652,32 @@ static void tg3_hwmon_open(struct tg3 *tp)
}
#endif
+static ssize_t tg3_sd_read(struct file *filep, struct kobject *kobj,
+ struct bin_attribute *attr, char *buff,
+ loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct tg3 *tp = netdev_priv(netdev);
+ struct tg3_sd *sd = tp->sd;
+ int len = size < sd->buf_size ? size : sd->buf_size;
+
+ if (offset > sd->buf_size)
+ return 0;
+
+ if (offset + len > sd->buf_size)
+ len = sd->buf_size - offset;
+
+ memcpy(buff, sd->buf + offset, len);
+ return len;
+}
+
+static struct bin_attribute bin_attr_tg3_sd = {
+ .attr = {.name = "tg3_sd", .mode = S_IRUSR},
+ .read = tg3_sd_read,
+};
+
static int tg3_sd_init(struct tg3 *tp)
{
int i;
@@ -9674,6 +9742,7 @@ static int tg3_sd_init(struct tg3 *tp)
sd->sd_flags_off = 2 * TG3_OCIR_LEN + (tp->pci_fn * sizeof(u32)) +
TG3_OCIR_PORT0_FLGS_OFF;
+ tg3_sd_update_drvflags(tp, false);
return 0;
}
@@ -9684,6 +9753,8 @@ static void tg3_sd_fini(struct tg3 *tp)
if (!sd)
return;
+ tg3_sd_update_drvflags(tp, true);
+
kfree(sd->buf);
kfree(sd);
tp->sd = NULL;
@@ -9703,6 +9774,7 @@ static void tg3_sd_close(struct tg3 *tp)
sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
}
#endif
+ device_remove_bin_file(&tp->pdev->dev, &bin_attr_tg3_sd);
}
static int tg3_sd_open(struct tg3 *tp)
@@ -9715,7 +9787,7 @@ static int tg3_sd_open(struct tg3 *tp)
#if IS_ENABLED(CONFIG_HWMON)
tg3_hwmon_open(tp);
#endif
- return 0;
+ return device_create_bin_file(&tp->pdev->dev, &bin_attr_tg3_sd);
}
#define TG3_STAT_ADD32(PSTAT, REG) \
@@ -9803,6 +9875,59 @@ static void tg3_chk_missed_msi(struct tg3 *tp)
}
}
+
+static void tg3_sd_timer(struct tg3 *tp)
+{
+ int i;
+ u32 val;
+ struct tg3_sd *sd = tp->sd;
+ struct tg3_ocir *ocirp = (struct tg3_ocir *) sd->buf;
+
+ if (!netif_running(tp->dev))
+ return;
+
+ for (i = 0; i < TG3_SD_NUM_RECS; i++, ocirp++) {
+ struct tg3_sd_record *rec = &sd->rec[i];
+
+ if (!rec->data_len)
+ continue;
+
+ tg3_ape_scratchpad_read(tp, &val, rec->utmr_off, 4);
+ /* Check if data has changed */
+ if (val) {
+
+ if (!rec->rtmr_int) {
+ tg3_sd_update_host(tp, rec);
+
+ rec->updated_seq++;
+ ocirp->update_tmr = rec->updated_seq;
+ } else {
+ u32 curr;
+ unsigned long tgt;
+
+ curr = tg3_ape_read32(tp, TG3_APE_STICKY_TMR);
+ tgt = rec->rtmr_val + rec->rtmr_int;
+ if (time_after((unsigned long) curr, tgt)) {
+ tg3_sd_update_host(tp, rec);
+
+ rec->rtmr_val = curr;
+ tg3_ape_scratchpad_write(tp,
+ rec->rtmr_off,
+ &curr, 4);
+
+ rec->updated_seq++;
+ ocirp->update_tmr = rec->updated_seq;
+ }
+ }
+
+ val = 0;
+ if (tg3_ape_scratchpad_write(tp, rec->utmr_off,
+ &val, 4))
+ netdev_err(tp->dev, "write scratchpad error\n");
+ }
+ }
+}
+
static void tg3_timer(unsigned long __opaque)
{
struct tg3 *tp = (struct tg3 *) __opaque;
@@ -9841,6 +9966,9 @@ static void tg3_timer(unsigned long __opaque)
if (tg3_flag(tp, 5705_PLUS))
tg3_periodic_fetch_stats(tp);
+ if (tp->sd)
+ tg3_sd_timer(tp);
+
if (tp->setlpicnt && !--tp->setlpicnt)
tg3_phy_eee_enable(tp);
--
1.7.1
^ permalink raw reply related
* [PATCH v2 -next 2/4] tg3: Add APE scratchpad read and write functions.
From: Michael Chan @ 2012-06-27 0:53 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
In-Reply-To: <1340758415-10746-1-git-send-email-mchan@broadcom.com>
From: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 137 +++++++++++++++++++++++++++++++++++
drivers/net/ethernet/broadcom/tg3.h | 10 ++-
2 files changed, 145 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 7c515db..693a584 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -751,6 +751,143 @@ static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us)
return timeout_us ? 0 : -EBUSY;
}
+static int tg3_ape_wait_for_event(struct tg3 *tp, u32 timeout_us)
+{
+ u32 i, apedata;
+
+ for (i = 0; i < timeout_us / 10; i++) {
+ apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);
+
+ if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
+ break;
+
+ udelay(10);
+ }
+
+ return i == timeout_us / 10;
+}
+
+int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off, u32 len)
+{
+ int err;
+ u32 i, bufoff, msgoff, maxlen, apedata;
+
+ if (!tg3_flag(tp, APE_HAS_NCSI))
+ return 0;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
+ if (apedata != APE_SEG_SIG_MAGIC)
+ return -ENODEV;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+ if (!(apedata & APE_FW_STATUS_READY))
+ return -EAGAIN;
+
+ bufoff = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_OFF) +
+ TG3_APE_SHMEM_BASE;
+ msgoff = bufoff + 2 * sizeof(u32);
+ maxlen = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_LEN);
+
+ while (len) {
+ u32 length;
+
+ /* Cap xfer sizes to scratchpad limits. */
+ length = (len > maxlen) ? maxlen : len;
+ len -= length;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+ if (!(apedata & APE_FW_STATUS_READY))
+ return -EAGAIN;
+
+ /* Wait for up to 1 msec for APE to service previous event. */
+ err = tg3_ape_event_lock(tp, 1000);
+ if (err)
+ return err;
+
+ apedata = APE_EVENT_STATUS_DRIVER_EVNT |
+ APE_EVENT_STATUS_SCRTCHPD_READ |
+ APE_EVENT_STATUS_EVENT_PENDING;
+ tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, apedata);
+
+ tg3_ape_write32(tp, bufoff, base_off);
+ tg3_ape_write32(tp, bufoff + sizeof(u32), length);
+
+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+ tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
+
+ base_off += length;
+
+ if (tg3_ape_wait_for_event(tp, 30000))
+ return -EAGAIN;
+
+ for (i = 0; length; i += 4, length -= 4) {
+ u32 val = tg3_ape_read32(tp, msgoff + i);
+ memcpy(data, &val, sizeof(u32));
+ data++;
+ }
+ }
+
+ return 0;
+}
+
+int tg3_ape_scratchpad_write(struct tg3 *tp, u32 dstoff, u32 *data, u32 len)
+{
+ u32 i, bufoff, msgoff, maxlen, apedata;
+
+ if (!tg3_flag(tp, APE_HAS_NCSI))
+ return 0;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
+ if (apedata != APE_SEG_SIG_MAGIC)
+ return -ENODEV;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+ if (!(apedata & APE_FW_STATUS_READY))
+ return -EAGAIN;
+
+ bufoff = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_OFF) +
+ TG3_APE_SHMEM_BASE;
+ msgoff = bufoff + 2 * sizeof(u32);
+ maxlen = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_LEN);
+
+ while (len) {
+ int err;
+ u32 length;
+
+ /* Cap xfer sizes to scratchpad limits. */
+ length = (len > maxlen) ? maxlen : len;
+ len -= length;
+
+ /* Wait for up to 1 millisecond for
+ * APE to service previous event.
+ */
+ err = tg3_ape_event_lock(tp, 1000);
+ if (err)
+ return err;
+
+ tg3_ape_write32(tp, bufoff, dstoff);
+ tg3_ape_write32(tp, bufoff + sizeof(u32), length);
+ apedata = msgoff;
+
+ dstoff += length;
+
+ for (i = 0; length; i += 4, length -= sizeof(u32)) {
+ tg3_ape_write32(tp, apedata, *data++);
+ apedata += sizeof(u32);
+ }
+
+ apedata = APE_EVENT_STATUS_DRIVER_EVNT |
+ APE_EVENT_STATUS_SCRTCHPD_WRITE |
+ APE_EVENT_STATUS_EVENT_PENDING;
+ tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, apedata);
+
+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+ tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
+ }
+
+ return 0;
+}
+
static int tg3_ape_send_event(struct tg3 *tp, u32 event)
{
int err;
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 93865f8..d167a1c 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2311,10 +2311,12 @@
#define APE_LOCK_REQ_DRIVER 0x00001000
#define TG3_APE_LOCK_GRANT 0x004c
#define APE_LOCK_GRANT_DRIVER 0x00001000
-#define TG3_APE_SEG_SIG 0x4000
-#define APE_SEG_SIG_MAGIC 0x41504521
+#define TG3_APE_STICKY_TMR 0x00b0
/* APE shared memory. Accessible through BAR1 */
+#define TG3_APE_SHMEM_BASE 0x4000
+#define TG3_APE_SEG_SIG 0x4000
+#define APE_SEG_SIG_MAGIC 0x41504521
#define TG3_APE_FW_STATUS 0x400c
#define APE_FW_STATUS_READY 0x00000100
#define TG3_APE_FW_FEATURES 0x4010
@@ -2327,6 +2329,8 @@
#define APE_FW_VERSION_REVMSK 0x0000ff00
#define APE_FW_VERSION_REVSFT 8
#define APE_FW_VERSION_BLDMSK 0x000000ff
+#define TG3_APE_SEG_MSG_BUF_OFF 0x401c
+#define TG3_APE_SEG_MSG_BUF_LEN 0x4020
#define TG3_APE_HOST_SEG_SIG 0x4200
#define APE_HOST_SEG_SIG_MAGIC 0x484f5354
#define TG3_APE_HOST_SEG_LEN 0x4204
@@ -2353,6 +2357,8 @@
#define APE_EVENT_STATUS_DRIVER_EVNT 0x00000010
#define APE_EVENT_STATUS_STATE_CHNGE 0x00000500
+#define APE_EVENT_STATUS_SCRTCHPD_READ 0x00001600
+#define APE_EVENT_STATUS_SCRTCHPD_WRITE 0x00001700
#define APE_EVENT_STATUS_STATE_START 0x00010000
#define APE_EVENT_STATUS_STATE_UNLOAD 0x00020000
#define APE_EVENT_STATUS_STATE_WOL 0x00030000
--
1.7.1
^ permalink raw reply related
* [PATCH v2 -next 1/4] tg3: Add common function tg3_ape_event_lock()
From: Michael Chan @ 2012-06-27 0:53 UTC (permalink / raw)
To: davem; +Cc: netdev, nsujir
From: Matt Carlson <mcarlson@broadcom.com>
by refactoring code in tg3_ape_send_event(). The common function will
be used in subsequent patches.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 56 ++++++++++++++++++++---------------
1 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index e47ff8b..7c515db 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -730,44 +730,52 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
tg3_ape_write32(tp, gnt + 4 * locknum, bit);
}
-static void tg3_ape_send_event(struct tg3 *tp, u32 event)
+static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us)
{
- int i;
u32 apedata;
- /* NCSI does not support APE events */
- if (tg3_flag(tp, APE_HAS_NCSI))
- return;
+ while (timeout_us) {
+ if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM))
+ return -EBUSY;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);
+ if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
+ break;
+
+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+
+ udelay(10);
+ timeout_us -= (timeout_us > 10) ? 10 : timeout_us;
+ }
+
+ return timeout_us ? 0 : -EBUSY;
+}
+
+static int tg3_ape_send_event(struct tg3 *tp, u32 event)
+{
+ int err;
+ u32 apedata;
apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
if (apedata != APE_SEG_SIG_MAGIC)
- return;
+ return -EAGAIN;
apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
if (!(apedata & APE_FW_STATUS_READY))
- return;
+ return -EAGAIN;
/* Wait for up to 1 millisecond for APE to service previous event. */
- for (i = 0; i < 10; i++) {
- if (tg3_ape_lock(tp, TG3_APE_LOCK_MEM))
- return;
-
- apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);
-
- if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
- tg3_ape_write32(tp, TG3_APE_EVENT_STATUS,
- event | APE_EVENT_STATUS_EVENT_PENDING);
+ err = tg3_ape_event_lock(tp, 1000);
+ if (err)
+ return err;
- tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+ tg3_ape_write32(tp, TG3_APE_EVENT_STATUS,
+ event | APE_EVENT_STATUS_EVENT_PENDING);
- if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
- break;
+ tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
+ tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
- udelay(100);
- }
-
- if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
- tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);
+ return 0;
}
static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 0/2] flexcan driver updates
From: Shawn Guo @ 2012-06-27 0:26 UTC (permalink / raw)
To: Oliver Hartkopp
Cc: David S. Miller, Marc Kleine-Budde, netdev, linux-arm-kernel
In-Reply-To: <4FE9E981.2080402@hartkopp.net>
On 27 June 2012 00:55, Oliver Hartkopp <socketcan@hartkopp.net> wrote:
> So please post your suggested changes for the flexcan driver on the mailing
> lists linux-can@vger.kernel.org and devicetree-discuss@lists.ozlabs.org
>
Yes, you are right. Will resend. Thanks.
Regards,
Shawn
^ permalink raw reply
* Re: [patch] net: qmi_wwan: simplify a check in qmi_wwan_bind()
From: David Miller @ 2012-06-27 0:13 UTC (permalink / raw)
To: dan.carpenter; +Cc: netdev, bjorn
In-Reply-To: <20120626083945.GA8946@elgon.mountain>
From: Dan Carpenter <dan.carpenter@oracle.com>
Date: Tue, 26 Jun 2012 11:39:45 +0300
> This code is easier to read if we specify which flags we want at the
> condition instead of at the top of the function.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> Acked-by: Bjørn Mork <bjorn@mork.no>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next] udp: Add socket early demux support
From: Vijay Subramanian @ 2012-06-27 0:06 UTC (permalink / raw)
To: David Miller; +Cc: netdev, shemminger, eric.dumazet, alexander.h.duyck
In-Reply-To: <20120626.143401.445148198931339546.davem@davemloft.net>
Thanks for the reviews and feedback, Dave and Eric. They were very helpful.
On 26 June 2012 14:34, David Miller <davem@davemloft.net> wrote:
>
> You can't do this.
>
> If the UDP socket has wildcards, that means the source address of the
> route will not be validated. This means we will start accepting
> spoofed packets. It also means the route you are caching is going
> to be the wrong route since the keys are variable.
Thanks for this explanation.
I see why Eric wanted me to test with DNS server bound to wildcard
address. I guess the same issue exists with multicast too which I had
not even considered.
>
> You can only do an early demux where all the keys are fully specified
> and there are no wildcards. That why for TCP we only early demux for
> established sockets.
I guess for UDP, early demux will work only if server binds to a
specific address and port instead of wildcard. But I believe
a lot of UDP servers use wildcard addresses, so use of early demux for
UDP may be limited.
Thanks,
Vijay
^ permalink raw reply
* Re: [net] ixgbe: Do not pad FCoE frames as this can cause issues with FCoE DDP
From: David Miller @ 2012-06-26 23:45 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: alexander.h.duyck, netdev, gospo, sassmann, stable
In-Reply-To: <1340697286-3047-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue, 26 Jun 2012 00:54:46 -0700
> From: Alexander Duyck <alexander.h.duyck@intel.com>
>
> FCoE target mode was experiencing issues due to the fact that we were
> sending up data frames that were padded to 60 bytes after the DDP logic had
> already stripped the frame down to 52 or 56 depending on the use of VLANs.
> This was resulting in the FCoE DDP logic having issues since it thought the
> frame still had data in it due to the padding.
>
> To resolve this, adding code so that we do not pad FCoE frames prior to
> handling them to the stack.
>
> CC: <stable@vger.kernel.org>
> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> Tested-by: Ross Brattain <ross.b.brattain@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] net: l2tp_eth: use LLTX to avoid LOCKDEP splats
From: David Miller @ 2012-06-26 23:43 UTC (permalink / raw)
To: eric.dumazet; +Cc: denys, netdev, honkiko, jchapman, romieu
In-Reply-To: <1340638545.10893.70.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 25 Jun 2012 17:35:45 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> Denys Fedoryshchenko reported a LOCKDEP issue with l2tp code.
...
> It appears that like most virtual devices, l2tp should be converted to
> LLTX mode.
>
> This patch takes care of statistics using atomic_long in both RX and TX
> paths, and fix a bug in l2tp_eth_dev_recv(), which was caching skb->data
> before a pskb_may_pull() call.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
> Cc: James Chapman <jchapman@katalix.com>
> Cc: Hong zhi guo <honkiko@gmail.com>
> Cc: Francois Romieu <romieu@fr.zoreil.com>
> ---
> Should be applied after "net: l2tp_eth: fix l2tp_eth_dev_xmit race"
Applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH] r8169: RxConfig hack for the 8168evl.
From: David Miller @ 2012-06-26 23:41 UTC (permalink / raw)
To: romieu; +Cc: hayeswang, netdev, thomas.pi
In-Reply-To: <20120626092251.GA1854@electric-eye.fr.zoreil.com>
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Tue, 26 Jun 2012 11:22:51 +0200
> hayeswang <hayeswang@realtek.com> :
> [...]
>> The definition of the IO 0x44 bit 14 is opposite for new chips.
>> For 8111C, 0 means fetching one Rx descriptor, and 1 means fetching
>> multi-descriptors.
>> For 8111D and the later chips, 0 means fetching multi-descriptors, and 1 means
>> fetching one Rx descriptor.
>
> Ok. Is there much point fetching one Rx descriptor versus several ?
It can help if the chip accesses enough at a time to fill a full cache
line.
In drivers I've written for chips that can do this, I've had the code
only post RX descriptors in chunks rather than one at a time, to
facilitate this even further.
^ permalink raw reply
* [PATCH] ipv4: Cache ip_error() routes even when not forwarding.
From: David Miller @ 2012-06-26 23:37 UTC (permalink / raw)
To: netdev
And account for the fact that, when we are not forwarding, we should
bump statistic counters rather than emit an ICMP response.
RP-filter rejected lookups are still not cached.
Since -EHOSTUNREACH and -ENETUNREACH can now no longer be seen in
ip_rcv_finish(), remove those checks.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
It seems pretty clear to me that we should cache things consistently
regardless of whether we are forwarding on an interface or not.
I noticed this while monitoring the routing cache the other day. If
you have some misconfigured host on your network (as I did :-), this
change increases diagnosability because you'll be able to see the
reject routes in /proc/net/rt_cache with the specific IPs involved.
It was actually a surprise to me that we do not cache RP-filtered
lookups. It's probably a toss-up whether caching or not caching these
is better or not. So I haven't touched that case for now. If we do
start to cache those, it will be nice in that we can streamline the
logic of ip_rcv_finish() completely by removing all the special error
code checks and counter bumps. Only the -EXDEV RP-filter one remains.
Committed to net-next
net/ipv4/ip_input.c | 8 +-------
net/ipv4/route.c | 30 +++++++++++++++++++-----------
2 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index bca2517..2a39204 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -342,13 +342,7 @@ static int ip_rcv_finish(struct sk_buff *skb)
err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
iph->tos, skb->dev);
if (unlikely(err)) {
- if (err == -EHOSTUNREACH)
- IP_INC_STATS_BH(dev_net(skb->dev),
- IPSTATS_MIB_INADDRERRORS);
- else if (err == -ENETUNREACH)
- IP_INC_STATS_BH(dev_net(skb->dev),
- IPSTATS_MIB_INNOROUTES);
- else if (err == -EXDEV)
+ if (err == -EXDEV)
NET_INC_STATS_BH(dev_net(skb->dev),
LINUX_MIB_IPRPFILTER);
goto drop;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 846961c..81533e3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1609,12 +1609,28 @@ void ip_rt_send_redirect(struct sk_buff *skb)
static int ip_error(struct sk_buff *skb)
{
+ struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
struct rtable *rt = skb_rtable(skb);
struct inet_peer *peer;
unsigned long now;
+ struct net *net;
bool send;
int code;
+ net = dev_net(rt->dst.dev);
+ if (!IN_DEV_FORWARD(in_dev)) {
+ switch (rt->dst.error) {
+ case EHOSTUNREACH:
+ IP_INC_STATS_BH(net, IPSTATS_MIB_INADDRERRORS);
+ break;
+
+ case ENETUNREACH:
+ IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES);
+ break;
+ }
+ goto out;
+ }
+
switch (rt->dst.error) {
case EINVAL:
default:
@@ -1624,8 +1640,7 @@ static int ip_error(struct sk_buff *skb)
break;
case ENETUNREACH:
code = ICMP_NET_UNREACH;
- IP_INC_STATS_BH(dev_net(rt->dst.dev),
- IPSTATS_MIB_INNOROUTES);
+ IP_INC_STATS_BH(net, IPSTATS_MIB_INNOROUTES);
break;
case EACCES:
code = ICMP_PKT_FILTERED;
@@ -2255,11 +2270,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
fl4.daddr = daddr;
fl4.saddr = saddr;
err = fib_lookup(net, &fl4, &res);
- if (err != 0) {
- if (!IN_DEV_FORWARD(in_dev))
- goto e_hostunreach;
+ if (err != 0)
goto no_route;
- }
RT_CACHE_STAT_INC(in_slow_tot);
@@ -2279,7 +2291,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
}
if (!IN_DEV_FORWARD(in_dev))
- goto e_hostunreach;
+ goto no_route;
if (res.type != RTN_UNICAST)
goto martian_destination;
@@ -2367,10 +2379,6 @@ martian_destination:
&daddr, &saddr, dev->name);
#endif
-e_hostunreach:
- err = -EHOSTUNREACH;
- goto out;
-
e_inval:
err = -EINVAL;
goto out;
--
1.7.10
^ permalink raw reply related
* Re: HSR: How to set IF_OPER_LOWERLAYERDOWN?
From: Stephen Hemminger @ 2012-06-26 22:33 UTC (permalink / raw)
To: Arvid Brodin; +Cc: netdev@vger.kernel.org, Javier Boticario, Bruno Ferreira
In-Reply-To: <4FEA37A0.309@xdin.com>
On Tue, 26 Jun 2012 22:28:51 +0000
Arvid Brodin <Arvid.Brodin@xdin.com> wrote:
> Hi,
>
> According to Documentation/networking/operstates.txt a network interface have an
> operational state and an administrative state.
>
> If I understand things correctly the administrative state is the desired state set by
> userspace, and the operational state is the actual state which depends on things like the
> administrative state, whether a carrier is present, or (for virtual interfaces lite VLAN)
> whether the lower interface is available.
>
>
> In the driver I'm writing (for the "HSR" redundancy protocol) a hsr (virtual) interface is
> useable as long as any of its (physical) slaves are useable. I.e. the operstate of a hsr
> device might be set like this:
>
> void hsr_set_operstate()
> {
> if (!is_admin_up(hsr_dev)) /* Check IFF_UP */ {
> set_operstate(hsr_dev, IF_OPER_DOWN);
> return;
> }
>
> if (is_operstate_up(slave1) || is_operstate_up(slave2)) /* Check IF_OPER_UP */
> set_operstate(hsr_dev, IF_OPER_UP);
> else
> set_operstate(hsr_dev, IF_OPER_LOWERLAYERDOWN);
> }
According to 802.1X example in documentation to set it down you need to set IF_OPER_DORMANT
not IF_OPER_LOWERLAYERDOWN. Probably a kernel bug in there somwhere.
^ permalink raw reply
* HSR: How to set IF_OPER_LOWERLAYERDOWN?
From: Arvid Brodin @ 2012-06-26 22:28 UTC (permalink / raw)
To: netdev@vger.kernel.org, Stephen Hemminger
Cc: Javier Boticario, Bruno Ferreira
Hi,
According to Documentation/networking/operstates.txt a network interface have an
operational state and an administrative state.
If I understand things correctly the administrative state is the desired state set by
userspace, and the operational state is the actual state which depends on things like the
administrative state, whether a carrier is present, or (for virtual interfaces lite VLAN)
whether the lower interface is available.
In the driver I'm writing (for the "HSR" redundancy protocol) a hsr (virtual) interface is
useable as long as any of its (physical) slaves are useable. I.e. the operstate of a hsr
device might be set like this:
void hsr_set_operstate()
{
if (!is_admin_up(hsr_dev)) /* Check IFF_UP */ {
set_operstate(hsr_dev, IF_OPER_DOWN);
return;
}
if (is_operstate_up(slave1) || is_operstate_up(slave2)) /* Check IF_OPER_UP */
set_operstate(hsr_dev, IF_OPER_UP);
else
set_operstate(hsr_dev, IF_OPER_LOWERLAYERDOWN);
}
However, the function set_operstate() (in net/core/rtnetlink.c) only accept transitions to
IF_OPER_UP and IF_OPER_DORMANT - other transitions are ignored. (There is a function
rfc2863_policy() (net/core/link_watch.c) that may return IF_OPER_LOWERLAYERDOWN iff
(!netif_carrier_ok(dev) && (dev->ifindex != dev->iflink)), but I don't know what that means.)
So how do I signal my interface as being IF_OPER_LOWERLAYERDOWN?
In another, related matter, I'm wondering if I should set the carrier state of my virtual
interface so that it shows netif_carrier_ok() when it is possible to get the interface to
IF_OPER_UP:
void hsr_set_carrier()
{
if (is_operstate_up(slave1) || is_operstate_up(slave2))
netif_carrier_on(hsr_dev);
else
netif_carrier_off(hsr_dev);
}
Thanks,
--
Arvid Brodin | Consultant (Linux)
XDIN AB | Jan Stenbecks Torg 17 | SE-164 40 Kista | Sweden | xdin.com
^ permalink raw reply
* Re: [PATCH net-next] udp: Add socket early demux support
From: David Miller @ 2012-06-26 21:34 UTC (permalink / raw)
To: subramanian.vijay; +Cc: netdev, shemminger, eric.dumazet, alexander.h.duyck
In-Reply-To: <1340739826-3363-1-git-send-email-subramanian.vijay@gmail.com>
You can't do this.
If the UDP socket has wildcards, that means the source address of the
route will not be validated. This means we will start accepting
spoofed packets. It also means the route you are caching is going
to be the wrong route since the keys are variable.
You can only do an early demux where all the keys are fully specified
and there are no wildcards. That why for TCP we only early demux for
established sockets.
^ permalink raw reply
* Re: [PATCH net-next] em_canid: Ematch rule to match CAN frames according to their CAN IDs
From: Thomas Graf @ 2012-06-26 21:32 UTC (permalink / raw)
To: Oliver Hartkopp
Cc: Rostislav Lisovy, Eric Dumazet, netdev, linux-can, lartc, pisa,
sojkam1
In-Reply-To: <4FEA169C.1070709@hartkopp.net>
On Tue, Jun 26, 2012 at 10:07:56PM +0200, Oliver Hartkopp wrote:
> > With no extra filter/qdisc configured, median of the time spent in can_send()
> > was about 27 us -- with prio qdisc with 5 bands and 5 appropriate cls_can
> > filters (previous patch), it was about 30 us -- with prio qdisc with 5 bands
> > and 5 appropriate em_can filters (this patch), it was about 34 us.
>
>
> Hm that's more than twice the time consumed for classification ...
>
> cls_can: 3 us more
> em_can: 7 us more
>
> @Eric: Is this still the better approach then?
If there is overhead, we should get rid of that overhead and not
abandon an established subsystem.
Rostislav: Can you provide some details on where the time is spent?
> > + /* Process EFF frame rules*/
> > + for (i = 0; i < cm->rules_count; i++) {
> > + if ((conf[i].can_id & CAN_EFF_FLAG) &&
> > + (conf[i].can_mask & CAN_EFF_FLAG)) {
> > + memcpy(cm->rules_raw + cm->eff_rules_count,
>
>
> Oops. Shouldn't this be
>
> cm->rules_raw + cm->eff_rules_count * sizeof(struct can_filter),
>
> ???
Looks like correct pointer arithmetic to me. Your suggestion
would only be valid if rules_raw was a void pointer.
> > +static void em_canid_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
> > +{
> > + struct canid_match *cm = em_canid_priv(m);
> > +
>
>
> Check for cm == NULL not needed ?
kfree() has that check embeddded. Also, for destroy() can only be called
if the match was added to the tree and that requires a successful call
to ->change(). Therefore it will never be NULL.
> > +static int em_canid_dump(struct sk_buff *skb, struct tcf_ematch *m)
> > +{
> > + struct canid_match *cm = em_canid_priv(m);
> > +
>
>
> Check for cm == NULL not needed ?
>
> Can a dump happen before the matches are added??
Nope, ->dump() is only ever called if the match has been added to the tree.
> > + /*
> > + * When configuring this ematch 'rules_count' is set not to exceed
> > + * 'rules_raw' array size
> > + */
> > + if (nla_put_nohdr(skb, sizeof(cm->rules_raw[0]) * cm->rules_count,
>
>
> better sizeof(struct can_filter) instead of sizeof(cm->rules_raw[0]) ??
>
> > + &cm->rules_raw) < 0)
> > + goto nla_put_failure;
No need for a goto here, just return -EMSGSIZE.
^ permalink raw reply
* RE: [RFC] iwmc3200top: remove driver for unavailable hardware
From: Perez-Gonzalez, Inaky @ 2012-06-26 21:21 UTC (permalink / raw)
To: John W. Linville, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Ortiz, Samuel,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1340740397-18119-1-git-send-email-linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Hi John
> From: John W. Linville [mailto:linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org]
> Subject: [RFC] iwmc3200top: remove driver for unavailable hardware
>
> From: "John W. Linville" <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
>
> This hardware never became available to normal humans. Leaving this
> driver imposes unwelcome maintenance costs for no clear benefit.
>
> Signed-off-by: John W. Linville <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
> ---
> Can't remove this just yet, as it is selected by the i2400m wimax
> driver. The 3200 bits of that driver seem a bit intertwined with the
> rest of the driver.
>
> Are there any other SDIO parts for i2400m? Does anyone have any other
> guidance on how I can safely make i2400m be independent of iwmc3200
> support?
It should be pretty straight forward: remove the dependency. In fact, you
are very right--all the sdio code should be removed, as there are no SDIO
parts in the market, to the best of my knowledge.
Yank anything hitting a grep on sdio in i2400m/ (*sdio*) and the Makefile
entries, as well as the Kconfig. That should take care of it.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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
* RE: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Huang, Xiong @ 2012-06-26 20:55 UTC (permalink / raw)
To: Rodriguez, Luis
Cc: Ren, Cloud, davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, qca-linux-team, nic-devel
In-Reply-To: <20120626205436.GJ5070@tux>
Understand, thank you !
> -----Original Message-----
> From: Rodriguez, Luis
> Sent: Wednesday, June 27, 2012 4:55
> To: Huang, Xiong
> Cc: Ren, Cloud; davem@davemloft.net; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; qca-linux-team; nic-devel
> Subject: Re: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
>
> On Tue, Jun 26, 2012 at 01:41:11PM -0700, Huang, Xiong wrote:
> > Luis
> > It should be a stable fix, but as Ben Hutchings mentioned in
> > another mail, Maybe, removing netif_stop_queue when cable link down is a
> better choice.
> >
> > Do you mean we need add 'cc:stable@vger.kernel.org' just before 'some
> people report ...' ?
>
> Nope, see commit 4f7a67e2dd49fbfba002c453bc24bf00e701cc71
> as an example of how to do this. This is a random commit that has been
> marked as stable.
>
> commit 4f7a67e2dd49fbfba002c453bc24bf00e701cc71
> Author: Ricardo Martins <rasm@fe.up.pt>
> Date: Tue May 22 18:02:03 2012 +0100
>
> USB: fix PS3 EHCI systems
>
> After commit aaa0ef289afe9186f81e2340114ea413eef0492a "PS3 EHCI
> QH
> read work-around", Terratec Grabby (em28xx) stopped working with AMD
> Geode LX 800 (USB controller AMD CS5536). Since this is a PS3 only
> fix, the following patch adds a conditional block around it.
>
> Signed-off-by: Ricardo Martins <rasm@fe.up.pt>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>
> Cc: stable <stable@vger.kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>
> Sometimes it helps if you specify the oldest stable kernel to apply patches to,
> so for example:
>
> commit 80b08a8d8829a58b5db14b1417151094cc28face
> Author: Felix Fietkau <nbd@openwrt.org>
> Date: Fri Jun 15 03:04:53 2012 +0200
>
> ath9k: fix invalid pointer access in the tx path
>
> After setup_frame_info has been called, only info->control.rates is still
> valid, other control fields have been overwritten by the ath_frame_info
> data. Move the access to info->control.vif for checking short preamble
> to setup_frame_info before it gets overwritten.
>
> This regression was introduced in commit d47a61aa
> "ath9k: Fix multi-VIF BSS handling"
>
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> Reported-by: Thomas Hühn <thomas@net.t-labs.tu-berlin.de>
> Acked-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
> Cc: stable@vger.kernel.org [3.4]
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
>
> To be clear, this is not a Cc: in the e-mail but instead a Cc line in the commit
> log entry.
>
> Luis
^ permalink raw reply
* Re: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Luis R. Rodriguez @ 2012-06-26 20:54 UTC (permalink / raw)
To: Huang, Xiong
Cc: Ren, Cloud, davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, qca-linux-team, nic-devel
In-Reply-To: <157393863283F442885425D2C454285623DB49B7@NASANEXD02A.na.qualcomm.com>
On Tue, Jun 26, 2012 at 01:41:11PM -0700, Huang, Xiong wrote:
> Luis
> It should be a stable fix, but as Ben Hutchings mentioned in another mail,
> Maybe, removing netif_stop_queue when cable link down is a better choice.
>
> Do you mean we need add 'cc:stable@vger.kernel.org' just before 'some people report ...' ?
Nope, see commit 4f7a67e2dd49fbfba002c453bc24bf00e701cc71
as an example of how to do this. This is a random commit
that has been marked as stable.
commit 4f7a67e2dd49fbfba002c453bc24bf00e701cc71
Author: Ricardo Martins <rasm@fe.up.pt>
Date: Tue May 22 18:02:03 2012 +0100
USB: fix PS3 EHCI systems
After commit aaa0ef289afe9186f81e2340114ea413eef0492a "PS3 EHCI QH
read work-around", Terratec Grabby (em28xx) stopped working with AMD
Geode LX 800 (USB controller AMD CS5536). Since this is a PS3 only
fix, the following patch adds a conditional block around it.
Signed-off-by: Ricardo Martins <rasm@fe.up.pt>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Sometimes it helps if you specify the oldest stable kernel
to apply patches to, so for example:
commit 80b08a8d8829a58b5db14b1417151094cc28face
Author: Felix Fietkau <nbd@openwrt.org>
Date: Fri Jun 15 03:04:53 2012 +0200
ath9k: fix invalid pointer access in the tx path
After setup_frame_info has been called, only info->control.rates is still
valid, other control fields have been overwritten by the ath_frame_info
data. Move the access to info->control.vif for checking short preamble
to setup_frame_info before it gets overwritten.
This regression was introduced in commit d47a61aa
"ath9k: Fix multi-VIF BSS handling"
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Reported-by: Thomas Hühn <thomas@net.t-labs.tu-berlin.de>
Acked-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Cc: stable@vger.kernel.org [3.4]
Signed-off-by: John W. Linville <linville@tuxdriver.com>
To be clear, this is not a Cc: in the e-mail but instead a
Cc line in the commit log entry.
Luis
^ permalink raw reply
* Re: [PATCH net-next] udp: Add socket early demux support
From: Eric Dumazet @ 2012-06-26 20:49 UTC (permalink / raw)
To: Vijay Subramanian; +Cc: netdev, davem, shemminger, alexander.h.duyck
In-Reply-To: <1340739826-3363-1-git-send-email-subramanian.vijay@gmail.com>
On Tue, 2012-06-26 at 12:43 -0700, Vijay Subramanian wrote:
> Based on the recent TCP socket early demux code, this patch provides similar
> support for UDP.
>
> Signed-off-by: Vijay Subramanian <subramanian.vijay@gmail.com>
> ---
> This has been tested on x86 with UDP iperf flows and seemed to work. If this is
> accepted, I plan to submit one more patch moving common code from TCP and UDP
> early demux code into common helper functions.
> Thanks in advance for feedback.
Hmm... I cant see how it can work.
Have you tested a router can still route DNS packets if you also have a
DNS server on it, listening on 0.0.0.0:53 ?
Most UDP applications are using unconnected sockets.
(In fact few programmers are aware UDP sockets can be connected)
Try to bench how this is going to work with random IP sources, instead
of UDP iperf flows using a single IP ?
And what about multicast ?
^ permalink raw reply
* RE: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Huang, Xiong @ 2012-06-26 20:41 UTC (permalink / raw)
To: Rodriguez, Luis, Ren, Cloud
Cc: davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, qca-linux-team, nic-devel
In-Reply-To: <20120626180311.GC5070@tux>
Luis
It should be a stable fix, but as Ben Hutchings mentioned in another mail,
Maybe, removing netif_stop_queue when cable link down is a better choice.
Do you mean we need add 'cc:stable@vger.kernel.org' just before 'some people report ...' ?
Thanks
Xiong
> -----Original Message-----
> From: Rodriguez, Luis
> Sent: Wednesday, June 27, 2012 2:03
> To: Ren, Cloud
> Cc: davem@davemloft.net; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; qca-linux-team; nic-devel; Huang, Xiong
> Subject: Re: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
>
> On Tue, Jun 26, 2012 at 12:33:06PM -0300, Ren, Cloud wrote:
> > From: xiong <xiong@qca.qualcomm.com>
> >
> > some people report atl1c could cause system hang with following kernel
> > trace info:
> > ---------------------------------------
> > WARNING: at.../net/sched/sch_generic.c:258
> > dev_watchdog+0x1db/0x1d0()
> > ...
> > NETDEV WATCHDOG: eth0 (atl1c): transmit queue 0 timed out ...
> > ---------------------------------------
> > This is caused by netif_stop_queue calling when cable Link is down but
> > netif_wake_queue isn't called when cable Link is resume.
> >
> > Signed-off-by: xiong <xiong@qca.qualcomm.com>
> > Signed-off-by: Cloud Ren <cjren@qca.qualcomm.com>
>
> If this fixes a system hang then this could be a stable fix -- that is, this should
> be propagated to older stable kernels, no?
>
> If so then please add to the commit log a line like this:
>
> Cc: stable@vger.kernel.org [3.4]
>
> Note: this is for the commit log! Right above the line below that has "---"
>
> Luis
^ permalink raw reply
* [PATCH] sctp: be mroe restrictive in transport selection on bundled sacks
From: Neil Horman @ 2012-06-26 20:31 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, Vlad Yaseivch, David S. Miller, linux-sctp
It was noticed recently that when we send data on a transport, its possible that
we might bundle a sack that arrived on a different transport. While this isn't
a major problem, it does go against the SHOULD requirement in section 6.4 of RFC
2960:
An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK,
etc.) to the same destination transport address from which it
received the DATA or control chunk to which it is replying. This
rule should also be followed if the endpoint is bundling DATA chunks
together with the reply chunk.
This patch seeks to correct that. It restricts the bundling of sack operations
to only those transports which have moved the ctsn of the association forward
since the last sack. By doing this we guarantee that we only bundle outbound
saks on a transport that has received a chunk since the last sack. This brings
us into stricter compliance with the RFC.
Vlad had initially suggested that we strictly allow only sack bundling on the
transport that last moved the ctsn forward. While this makes sense, I was
concerned that doing so prevented us from bundling in the case where we had
received chunks that moved the ctsn on multiple transports. In those cases, the
RFC allows us to select any of the transports having received chunks to bundle
the sack on. so I've modified the approach to allow for that, by adding a state
variable to each transport that tracks weather it has moved the ctsn since the
last sack. This I think keeps our behavior (and performance), close enough to
our current profile that I think we can do this without a sysctl knob to
enable/disable it.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Vlad Yaseivch <vyasevich@gmail.com>
CC: David S. Miller <davem@davemloft.net>
CC: linux-sctp@vger.kernel.org
Reported-by: Michele Baldessari <michele@redhat.com>
Reported-by: sorin serban <sserban@redhat.com>
---
include/net/sctp/structs.h | 5 ++++-
include/net/sctp/tsnmap.h | 3 ++-
net/sctp/output.c | 9 +++++++--
net/sctp/sm_make_chunk.c | 8 ++++++++
net/sctp/sm_sideeffect.c | 2 +-
net/sctp/tsnmap.c | 5 ++++-
net/sctp/ulpevent.c | 3 ++-
net/sctp/ulpqueue.c | 2 +-
8 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index e4652fe..712bf09 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -910,7 +910,10 @@ struct sctp_transport {
pmtu_pending:1,
/* Is this structure kfree()able? */
- malloced:1;
+ malloced:1,
+
+ /* Has this transport moved the ctsn since we last sacked */
+ moved_ctsn:1;
struct flowi fl;
diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h
index e7728bc..2c5d2b4 100644
--- a/include/net/sctp/tsnmap.h
+++ b/include/net/sctp/tsnmap.h
@@ -117,7 +117,8 @@ void sctp_tsnmap_free(struct sctp_tsnmap *map);
int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
/* Mark this TSN as seen. */
-int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn);
+int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn,
+ struct sctp_transport *trans);
/* Mark this TSN and all lower as seen. */
void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn);
diff --git a/net/sctp/output.c b/net/sctp/output.c
index f1b7d4b..c9f47b6 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -240,15 +240,20 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
*/
if (sctp_chunk_is_data(chunk) && !pkt->has_sack &&
!pkt->has_cookie_echo) {
- struct sctp_association *asoc;
struct timer_list *timer;
- asoc = pkt->transport->asoc;
+ struct sctp_association *asoc = pkt->transport->asoc;
+ struct sctp_transport *trans;
+
timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
/* If the SACK timer is running, we have a pending SACK */
if (timer_pending(timer)) {
struct sctp_chunk *sack;
asoc->a_rwnd = asoc->rwnd;
+
+ if (chunk->transport && !chunk->transport->moved_ctsn)
+ return retval;
+
sack = sctp_make_sack(asoc);
if (sack) {
retval = sctp_packet_append_chunk(pkt, sack);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index a85eeeb..bad469b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -736,6 +736,7 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
__u16 num_gabs, num_dup_tsns;
struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
struct sctp_gap_ack_block gabs[SCTP_MAX_GABS];
+ struct sctp_transport *trans;
memset(gabs, 0, sizeof(gabs));
ctsn = sctp_tsnmap_get_ctsn(map);
@@ -805,6 +806,13 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns,
sctp_tsnmap_get_dups(map));
+ /*
+ * Once we have a sack generated, clear the moved_tsn information
+ * from all the transports
+ */
+ list_for_each_entry(trans, &asoc->peer.transport_addr_list, transports) {
+ trans->moved_ctsn = 0;
+ }
nodata:
return retval;
}
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index c96d1a8..8716da1 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1268,7 +1268,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
case SCTP_CMD_REPORT_TSN:
/* Record the arrival of a TSN. */
error = sctp_tsnmap_mark(&asoc->peer.tsn_map,
- cmd->obj.u32);
+ cmd->obj.u32, NULL);
break;
case SCTP_CMD_REPORT_FWDTSN:
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
index f1e40ceb..619c638 100644
--- a/net/sctp/tsnmap.c
+++ b/net/sctp/tsnmap.c
@@ -114,7 +114,8 @@ int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn)
/* Mark this TSN as seen. */
-int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn)
+int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn,
+ struct sctp_transport *trans)
{
u16 gap;
@@ -133,6 +134,8 @@ int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn)
*/
map->max_tsn_seen++;
map->cumulative_tsn_ack_point++;
+ if (trans)
+ trans->moved_ctsn = 1;
map->base_tsn++;
} else {
/* Either we already have a gap, or about to record a gap, so
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 8a84017..33d8947 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -715,7 +715,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
* can mark it as received so the tsn_map is updated correctly.
*/
if (sctp_tsnmap_mark(&asoc->peer.tsn_map,
- ntohl(chunk->subh.data_hdr->tsn)))
+ ntohl(chunk->subh.data_hdr->tsn),
+ chunk->transport))
goto fail_mark;
/* First calculate the padding, so we don't inadvertently
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index f2d1de7..f5a6a4f 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -1051,7 +1051,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
if (chunk && (freed >= needed)) {
__u32 tsn;
tsn = ntohl(chunk->subh.data_hdr->tsn);
- sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn);
+ sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport);
sctp_ulpq_tail_data(ulpq, chunk, gfp);
sctp_ulpq_partial_delivery(ulpq, chunk, gfp);
--
1.7.7.6
^ permalink raw reply related
* RE: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Huang, Xiong @ 2012-06-26 20:26 UTC (permalink / raw)
To: Ben Hutchings, Ren, Cloud
Cc: davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, qca-linux-team, nic-devel
In-Reply-To: <157393863283F442885425D2C454285623DB4982@NASANEXD02A.na.qualcomm.com>
Sorry, my mean , another fix is to remove netif_stop_queue when cable link is down.
Thanks
Xiong
> -----Original Message-----
> From: Huang, Xiong
> Sent: Wednesday, June 27, 2012 4:25
> To: Ben Hutchings; Ren, Cloud
> Cc: davem@davemloft.net; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; qca-linux-team; nic-devel
> Subject: RE: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
>
> Yes, another fix to remove netif_stop_queue when cable link is down.
>
> -Xiong
>
> > -----Original Message-----
> > From: Ben Hutchings [mailto:bhutchings@solarflare.com]
> > Sent: Wednesday, June 27, 2012 4:24
> > To: Ren, Cloud
> > Cc: davem@davemloft.net; netdev@vger.kernel.org; linux-
> > kernel@vger.kernel.org; qca-linux-team; nic-devel; Huang, Xiong
> > Subject: Re: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed
> > out
> >
> > On Tue, 2012-06-26 at 12:33 -0300, Ren, Cloud wrote:
> > > From: xiong <xiong@qca.qualcomm.com>
> > >
> > > some people report atl1c could cause system hang with following
> > > kernel trace info:
> > > ---------------------------------------
> > > WARNING: at.../net/sched/sch_generic.c:258
> > > dev_watchdog+0x1db/0x1d0()
> > > ...
> > > NETDEV WATCHDOG: eth0 (atl1c): transmit queue 0 timed out ...
> > > ---------------------------------------
> > > This is caused by netif_stop_queue calling when cable Link is down
> > > but netif_wake_queue isn't called when cable Link is resume.
> > >
> > > Signed-off-by: xiong <xiong@qca.qualcomm.com>
> > > Signed-off-by: Cloud Ren <cjren@qca.qualcomm.com>
> > > ---
> > > drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 ++
> > > 1 files changed, 2 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > > b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > > index 85717cb..c2736c4 100644
> > > --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > > +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > > @@ -351,6 +351,8 @@ static void atl1c_common_task(struct work_struct
> > *work)
> > > atl1c_irq_disable(adapter);
> > > atl1c_check_link_status(adapter);
> > > atl1c_irq_enable(adapter);
> > > + if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
> > > + netif_wake_queue(netdev);
> > > }
> > > }
> > >
> >
> > Why explicitly stop/start the queue when the link changes? That's
> > what link_watch is for.
> >
> > Ben.
> >
> > --
> > Ben Hutchings, Staff Engineer, Solarflare Not speaking for my
> > employer; that's the marketing department's job.
> > They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* RE: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Huang, Xiong @ 2012-06-26 20:25 UTC (permalink / raw)
To: Ben Hutchings, Ren, Cloud
Cc: davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, qca-linux-team, nic-devel
In-Reply-To: <1340742224.2644.1.camel@bwh-desktop.uk.solarflarecom.com>
Yes, another fix to remove netif_stop_queue when cable link is down.
-Xiong
> -----Original Message-----
> From: Ben Hutchings [mailto:bhutchings@solarflare.com]
> Sent: Wednesday, June 27, 2012 4:24
> To: Ren, Cloud
> Cc: davem@davemloft.net; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; qca-linux-team; nic-devel; Huang, Xiong
> Subject: Re: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
>
> On Tue, 2012-06-26 at 12:33 -0300, Ren, Cloud wrote:
> > From: xiong <xiong@qca.qualcomm.com>
> >
> > some people report atl1c could cause system hang with following kernel
> > trace info:
> > ---------------------------------------
> > WARNING: at.../net/sched/sch_generic.c:258
> > dev_watchdog+0x1db/0x1d0()
> > ...
> > NETDEV WATCHDOG: eth0 (atl1c): transmit queue 0 timed out ...
> > ---------------------------------------
> > This is caused by netif_stop_queue calling when cable Link is down but
> > netif_wake_queue isn't called when cable Link is resume.
> >
> > Signed-off-by: xiong <xiong@qca.qualcomm.com>
> > Signed-off-by: Cloud Ren <cjren@qca.qualcomm.com>
> > ---
> > drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 ++
> > 1 files changed, 2 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > index 85717cb..c2736c4 100644
> > --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> > @@ -351,6 +351,8 @@ static void atl1c_common_task(struct work_struct
> *work)
> > atl1c_irq_disable(adapter);
> > atl1c_check_link_status(adapter);
> > atl1c_irq_enable(adapter);
> > + if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
> > + netif_wake_queue(netdev);
> > }
> > }
> >
>
> Why explicitly stop/start the queue when the link changes? That's what
> link_watch is for.
>
> Ben.
>
> --
> Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer; that's
> the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Ben Hutchings @ 2012-06-26 20:23 UTC (permalink / raw)
To: Ren, Cloud; +Cc: davem, netdev, linux-kernel, qca-linux-team, nic-devel, xiong
In-Reply-To: <1340724786-3819-1-git-send-email-cjren@qca.qualcomm.com>
On Tue, 2012-06-26 at 12:33 -0300, Ren, Cloud wrote:
> From: xiong <xiong@qca.qualcomm.com>
>
> some people report atl1c could cause system hang with following
> kernel trace info:
> ---------------------------------------
> WARNING: at.../net/sched/sch_generic.c:258
> dev_watchdog+0x1db/0x1d0()
> ...
> NETDEV WATCHDOG: eth0 (atl1c): transmit queue 0 timed out
> ...
> ---------------------------------------
> This is caused by netif_stop_queue calling when cable Link is down
> but netif_wake_queue isn't called when cable Link is resume.
>
> Signed-off-by: xiong <xiong@qca.qualcomm.com>
> Signed-off-by: Cloud Ren <cjren@qca.qualcomm.com>
> ---
> drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> index 85717cb..c2736c4 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
> @@ -351,6 +351,8 @@ static void atl1c_common_task(struct work_struct *work)
> atl1c_irq_disable(adapter);
> atl1c_check_link_status(adapter);
> atl1c_irq_enable(adapter);
> + if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
> + netif_wake_queue(netdev);
> }
> }
>
Why explicitly stop/start the queue when the link changes? That's what
link_watch is for.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH 11/16] netvm: Propagate page->pfmemalloc from skb_alloc_page to skb
From: Sebastian Andrzej Siewior @ 2012-06-26 20:13 UTC (permalink / raw)
To: Mel Gorman
Cc: Andrew Morton, Linux-MM, Linux-Netdev, LKML, David Miller,
Neil Brown, Peter Zijlstra, Mike Christie, Eric B Munson,
Eric Dumazet
In-Reply-To: <1340375443-22455-12-git-send-email-mgorman@suse.de>
On Fri, Jun 22, 2012 at 03:30:38PM +0100, Mel Gorman wrote:
> drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +-
> drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 2 +-
> drivers/net/ethernet/intel/igb/igb_main.c | 2 +-
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-
> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 +-
> drivers/net/usb/cdc-phonet.c | 2 +-
> drivers/usb/gadget/f_phonet.c | 2 +-
You did not touch all drivers which use alloc_page(s)() like e1000(e). Was
this on purpose?
Sebastian
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ 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