Netdev List
 help / color / mirror / Atom feed
* [PATCHv1 NEXT 4/7] qlcnic: add eswitch statistics support
From: Amit Kumar Salecha @ 2010-08-12 11:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1281612527-27838-1-git-send-email-amit.salecha@qlogic.com>

Adding eswitch statistics support. User can get
whole eswitch stats or stats of func belong to that eswitch.

Added:
o command to get statistics of eswitch and function.
o sysfs support to export eswitch and func statatistics.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |   31 +++++++++
 drivers/net/qlcnic/qlcnic_ctx.c  |  125 ++++++++++++++++++++++++++++++++++++
 drivers/net/qlcnic/qlcnic_main.c |  132 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 287 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 9703893..7f4e11b 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -555,6 +555,7 @@ struct qlcnic_recv_context {
 #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS	0x00000026
 #define QLCNIC_CDRP_CMD_SET_PORTMIRRORING	0x00000027
 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH	0x00000028
+#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS	0x0000002a
 
 #define QLCNIC_RCODE_SUCCESS		0
 #define QLCNIC_RCODE_TIMEOUT		17
@@ -1126,6 +1127,31 @@ struct qlcnic_esw_func_cfg {
 	u8	reserved;
 };
 
+#define QLCNIC_STATS_VERSION		1
+#define QLCNIC_STATS_PORT		1
+#define QLCNIC_STATS_ESWITCH		2
+#define QLCNIC_QUERY_RX_COUNTER		0
+#define QLCNIC_QUERY_TX_COUNTER		1
+struct __qlcnic_esw_statistics {
+	__le16 context_id;
+	__le16 version;
+	__le16 size;
+	__le16 unused;
+	__le64 unicast_frames;
+	__le64 multicast_frames;
+	__le64 broadcast_frames;
+	__le64 dropped_frames;
+	__le64 errors;
+	__le64 local_frames;
+	__le64 numbytes;
+	__le64 rsvd[3];
+};
+
+struct qlcnic_esw_statistics {
+	struct __qlcnic_esw_statistics rx;
+	struct __qlcnic_esw_statistics tx;
+};
+
 int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val);
 int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val);
 
@@ -1252,6 +1278,11 @@ int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8);
 int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8,
 			u8, u8, u16);
 int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
+int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8,
+					struct __qlcnic_esw_statistics *);
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8,
+					struct __qlcnic_esw_statistics *);
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8);
 extern int qlcnic_config_tso;
 
 /*
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index cc5d861..57c9b09 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -983,3 +983,128 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
 
 	return err;
 }
+
+int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func,
+		const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
+
+	size_t stats_size = sizeof(struct __qlcnic_esw_statistics);
+	dma_addr_t stats_dma_t;
+	void *stats_addr;
+	u32 arg1;
+	int err;
+
+	if (esw_stats == NULL)
+		return -ENOMEM;
+
+	if (adapter->op_mode != QLCNIC_MGMT_FUNC &&
+	    func != adapter->ahw.pci_func) {
+		dev_err(&adapter->pdev->dev,
+			"Not privilege to query stats for func=%d", func);
+		return -EIO;
+	}
+
+	stats_addr = pci_alloc_consistent(adapter->pdev, stats_size,
+			&stats_dma_t);
+	if (!stats_addr) {
+		dev_err(&adapter->pdev->dev, "Unable to allocate memory\n");
+		return -ENOMEM;
+	}
+	memset(stats_addr, 0, stats_size);
+
+	arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12;
+	arg1 |= rx_tx << 15 | stats_size << 16;
+
+	err = qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			adapter->fw_hal_version,
+			arg1,
+			MSD(stats_dma_t),
+			LSD(stats_dma_t),
+			QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
+
+	if (!err)
+		memcpy(esw_stats, stats_addr, stats_size);
+
+	pci_free_consistent(adapter->pdev, stats_size, stats_addr,
+		stats_dma_t);
+	return err;
+}
+
+int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch,
+		const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) {
+
+	struct __qlcnic_esw_statistics port_stats;
+	u8 i;
+	int ret = -EIO;
+
+	if (esw_stats == NULL)
+		return -ENOMEM;
+	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+		return -EIO;
+	if (adapter->npars == NULL)
+		return -EIO;
+
+	memset(esw_stats, 0, sizeof(struct __qlcnic_esw_statistics));
+	esw_stats->context_id = eswitch;
+
+	for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
+		if (adapter->npars[i].phy_port != eswitch)
+			continue;
+
+		memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics));
+		if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats))
+			continue;
+
+		esw_stats->size = port_stats.size;
+		esw_stats->version = port_stats.version;
+		esw_stats->unicast_frames += port_stats.unicast_frames;
+		esw_stats->multicast_frames += port_stats.multicast_frames;
+		esw_stats->broadcast_frames += port_stats.broadcast_frames;
+		esw_stats->dropped_frames += port_stats.dropped_frames;
+		esw_stats->errors += port_stats.errors;
+		esw_stats->local_frames += port_stats.local_frames;
+		esw_stats->numbytes += port_stats.numbytes;
+
+		ret = 0;
+	}
+	return ret;
+}
+
+int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw,
+		const u8 port, const u8 rx_tx)
+{
+
+	u32 arg1;
+
+	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
+		return -EIO;
+
+	if (func_esw == QLCNIC_STATS_PORT) {
+		if (port >= QLCNIC_MAX_PCI_FUNC)
+			goto err_ret;
+	} else if (func_esw == QLCNIC_STATS_ESWITCH) {
+		if (port >= QLCNIC_NIU_MAX_XG_PORTS)
+			goto err_ret;
+	} else {
+		goto err_ret;
+	}
+
+	if (rx_tx > QLCNIC_QUERY_TX_COUNTER)
+		goto err_ret;
+
+	arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12;
+	arg1 |= BIT_14 | rx_tx << 15;
+
+	return qlcnic_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			adapter->fw_hal_version,
+			arg1,
+			0,
+			0,
+			QLCNIC_CDRP_CMD_GET_ESWITCH_STATS);
+
+err_ret:
+	dev_err(&adapter->pdev->dev, "Invalid argument func_esw=%d port=%d"
+		"rx_ctx=%d\n", func_esw, port, rx_tx);
+	return -EIO;
+}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index f98c4cf..692641e 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -3368,6 +3368,115 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj,
 }
 
 static ssize_t
+qlcnic_sysfs_get_port_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	struct qlcnic_esw_statistics port_stats;
+	int ret;
+
+	if (size != sizeof(struct qlcnic_esw_statistics))
+		return QL_STATUS_INVALID_PARAM;
+
+	if (offset >= QLCNIC_MAX_PCI_FUNC)
+		return QL_STATUS_INVALID_PARAM;
+
+	memset(&port_stats, 0, size);
+	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+								&port_stats.rx);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+								&port_stats.tx);
+	if (ret)
+		return ret;
+
+	memcpy(buf, &port_stats, size);
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_get_esw_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	struct qlcnic_esw_statistics esw_stats;
+	int ret;
+
+	if (size != sizeof(struct qlcnic_esw_statistics))
+		return QL_STATUS_INVALID_PARAM;
+
+	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+		return QL_STATUS_INVALID_PARAM;
+
+	memset(&esw_stats, 0, size);
+	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER,
+								&esw_stats.rx);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER,
+								&esw_stats.tx);
+	if (ret)
+		return ret;
+
+	memcpy(buf, &esw_stats, size);
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_esw_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	int ret;
+
+	if (offset >= QLCNIC_NIU_MAX_XG_PORTS)
+		return QL_STATUS_INVALID_PARAM;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+						QLCNIC_QUERY_RX_COUNTER);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset,
+						QLCNIC_QUERY_TX_COUNTER);
+	if (ret)
+		return ret;
+
+	return size;
+}
+
+static ssize_t
+qlcnic_sysfs_clear_port_stats(struct file *file, struct kobject *kobj,
+	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
+{
+
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	int ret;
+
+	if (offset >= QLCNIC_MAX_PCI_FUNC)
+		return QL_STATUS_INVALID_PARAM;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+						QLCNIC_QUERY_RX_COUNTER);
+	if (ret)
+		return ret;
+
+	ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset,
+						QLCNIC_QUERY_TX_COUNTER);
+	if (ret)
+		return ret;
+
+	return size;
+}
+
+static ssize_t
 qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj,
 	struct bin_attribute *attr, char *buf, loff_t offset, size_t size)
 {
@@ -3410,6 +3519,20 @@ static struct bin_attribute bin_attr_pci_config = {
 	.write = NULL,
 };
 
+static struct bin_attribute bin_attr_port_stats = {
+	.attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = qlcnic_sysfs_get_port_stats,
+	.write = qlcnic_sysfs_clear_port_stats,
+};
+
+static struct bin_attribute bin_attr_esw_stats = {
+	.attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)},
+	.size = 0,
+	.read = qlcnic_sysfs_get_esw_stats,
+	.write = qlcnic_sysfs_clear_esw_stats,
+};
+
 static struct bin_attribute bin_attr_esw_config = {
 	.attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)},
 	.size = 0,
@@ -3449,6 +3572,9 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
 
+	if (device_create_bin_file(dev, &bin_attr_port_stats))
+		dev_info(dev, "failed to create port stats sysfs entry");
+
 	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
 		return;
 	if (device_create_file(dev, &dev_attr_diag_mode))
@@ -3468,7 +3594,8 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter)
 		dev_info(dev, "failed to create esw config sysfs entry");
 	if (device_create_bin_file(dev, &bin_attr_pm_config))
 		dev_info(dev, "failed to create pm config sysfs entry");
-
+	if (device_create_bin_file(dev, &bin_attr_esw_stats))
+		dev_info(dev, "failed to create eswitch stats sysfs entry");
 }
 
 static void
@@ -3476,6 +3603,8 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 {
 	struct device *dev = &adapter->pdev->dev;
 
+	device_remove_bin_file(dev, &bin_attr_port_stats);
+
 	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
 		return;
 	device_remove_file(dev, &dev_attr_diag_mode);
@@ -3488,6 +3617,7 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter)
 	device_remove_bin_file(dev, &bin_attr_npar_config);
 	device_remove_bin_file(dev, &bin_attr_esw_config);
 	device_remove_bin_file(dev, &bin_attr_pm_config);
+	device_remove_bin_file(dev, &bin_attr_esw_stats);
 }
 
 #ifdef CONFIG_INET
-- 
1.6.0.2


^ permalink raw reply related

* [PATCHv1 NEXT 5/7] qlcnic: fix link status message
From: Amit Kumar Salecha @ 2010-08-12 11:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Sony Chacko
In-Reply-To: <1281612527-27838-1-git-send-email-amit.salecha@qlogic.com>

From: Sony Chacko <sony.chacko@qlogic.com>

Display interface name for link status message.
With dev_info pci number get printed.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 692641e..28985a9 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1934,14 +1934,16 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup)
 	struct net_device *netdev = adapter->netdev;
 
 	if (adapter->ahw.linkup && !linkup) {
-		dev_info(&netdev->dev, "NIC Link is down\n");
+		printk(KERN_INFO "%s: %s NIC Link is down\n",
+		       qlcnic_driver_name, netdev->name);
 		adapter->ahw.linkup = 0;
 		if (netif_running(netdev)) {
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 		}
 	} else if (!adapter->ahw.linkup && linkup) {
-		dev_info(&netdev->dev, "NIC Link is up\n");
+		printk(KERN_INFO "%s: %s NIC Link is up\n",
+		       qlcnic_driver_name, netdev->name);
 		adapter->ahw.linkup = 1;
 		if (netif_running(netdev)) {
 			netif_carrier_on(netdev);
-- 
1.6.0.2


^ permalink raw reply related

* [PATCHv1 NEXT 1/7] qlcnic: fix aer for virtual func
From: Amit Kumar Salecha @ 2010-08-12 11:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1281612527-27838-1-git-send-email-amit.salecha@qlogic.com>

Virtual function are not privilge to initialize firmware.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index b9615bd..9cc8732 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2723,7 +2723,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
 	if (qlcnic_api_lock(adapter))
 		return -EINVAL;
 
-	if (first_func) {
+	if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) {
 		adapter->need_fw_reset = 1;
 		set_bit(__QLCNIC_START_FW, &adapter->state);
 		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
-- 
1.6.0.2


^ permalink raw reply related

* [PATCHv1 NEXT 3/7] qlcnic: fix for setting function modes
From: Amit Kumar Salecha @ 2010-08-12 11:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman, Rajesh Borundia
In-Reply-To: <1281612527-27838-1-git-send-email-amit.salecha@qlogic.com>

From: Rajesh Borundia <rajesh.borundia@qlogic.com>

function modes was not working with CNA device, in CNA mode
other function(FCOE) can be enabled before nic.

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index b062188..f98c4cf 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -533,8 +533,6 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
 	ret = qlcnic_api_lock(adapter);
 	if (ret)
 		goto err_lock;
-	if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func))
-		goto err_npar;
 
 	if (qlcnic_config_npars) {
 		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
@@ -552,7 +550,6 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
 			adapter->ahw.pci_func));
 	}
 	writel(data, priv_op);
-err_npar:
 	qlcnic_api_unlock(adapter);
 err_lock:
 	return ret;
-- 
1.6.0.2


^ permalink raw reply related

* [PATCHv1 NEXT 2/7] qlcnic: device state management fixes for virtual func
From: Amit Kumar Salecha @ 2010-08-12 11:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman
In-Reply-To: <1281612527-27838-1-git-send-email-amit.salecha@qlogic.com>

o NPAR state should be set to operationl by Mangement function only.
o NPAR state should be set to non operational before device reset.
o VF function should wait for NPAR state to be operational.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_hdr.h  |    5 +-
 drivers/net/qlcnic/qlcnic_main.c |   80 +++++++++++++++++++++++---------------
 2 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h
index 15fc320..bd346d9 100644
--- a/drivers/net/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/qlcnic/qlcnic_hdr.h
@@ -718,8 +718,9 @@ enum {
 #define QLCNIC_DEV_FAILED		0x6
 #define QLCNIC_DEV_QUISCENT		0x7
 
-#define QLCNIC_DEV_NPAR_NOT_RDY	0
-#define QLCNIC_DEV_NPAR_RDY		1
+#define QLCNIC_DEV_NPAR_NON_OPER	0 /* NON Operational */
+#define QLCNIC_DEV_NPAR_OPER		1 /* NPAR Operational */
+#define QLCNIC_DEV_NPAR_OPER_TIMEO	30 /* Operational time out */
 
 #define QLC_DEV_CHECK_ACTIVE(VAL, FN)		((VAL) &= (1 << (FN * 4)))
 #define QLC_DEV_SET_REF_CNT(VAL, FN)		((VAL) |= (1 << (FN * 4)))
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 9cc8732..b062188 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2388,7 +2388,7 @@ qlcnic_fwinit_work(struct work_struct *work)
 {
 	struct qlcnic_adapter *adapter = container_of(work,
 			struct qlcnic_adapter, fw_work.work);
-	u32 dev_state = 0xf, npar_state;
+	u32 dev_state = 0xf;
 
 	if (qlcnic_api_lock(adapter))
 		goto err_ret;
@@ -2402,16 +2402,8 @@ qlcnic_fwinit_work(struct work_struct *work)
 	}
 
 	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
-		npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
-		if (npar_state == QLCNIC_DEV_NPAR_RDY) {
-			qlcnic_api_unlock(adapter);
-			goto wait_npar;
-		} else {
-			qlcnic_schedule_work(adapter, qlcnic_fwinit_work,
-				FW_POLL_DELAY);
-			qlcnic_api_unlock(adapter);
-			return;
-		}
+		qlcnic_api_unlock(adapter);
+		goto wait_npar;
 	}
 
 	if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
@@ -2460,20 +2452,17 @@ wait_npar:
 	QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
 
 	switch (dev_state) {
-	case QLCNIC_DEV_QUISCENT:
-	case QLCNIC_DEV_NEED_QUISCENT:
-	case QLCNIC_DEV_NEED_RESET:
-		qlcnic_schedule_work(adapter,
-			qlcnic_fwinit_work, FW_POLL_DELAY);
-		return;
-	case QLCNIC_DEV_FAILED:
-		break;
-
-	default:
+	case QLCNIC_DEV_READY:
 		if (!adapter->nic_ops->start_firmware(adapter)) {
 			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
 			return;
 		}
+	case QLCNIC_DEV_FAILED:
+		break;
+	default:
+		qlcnic_schedule_work(adapter,
+			qlcnic_fwinit_work, FW_POLL_DELAY);
+		return;
 	}
 
 err_ret:
@@ -2520,6 +2509,22 @@ err_ret:
 
 }
 
+/*Transit NPAR state to NON Operational */
+static void
+qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
+{
+	u32 state;
+
+	state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+	if (state == QLCNIC_DEV_NPAR_NON_OPER)
+		return;
+
+	if (qlcnic_api_lock(adapter))
+		return;
+	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
+	qlcnic_api_unlock(adapter);
+}
+
 /*Transit to RESET state from READY state only */
 static void
 qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
@@ -2538,6 +2543,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 		qlcnic_idc_debug_info(adapter, 0);
 	}
 
+	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER);
 	qlcnic_api_unlock(adapter);
 }
 
@@ -2545,21 +2551,14 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 static void
 qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter)
 {
-	u32 state;
-
 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
-		adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
+	    adapter->op_mode != QLCNIC_MGMT_FUNC)
 		return;
 	if (qlcnic_api_lock(adapter))
 		return;
 
-	state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
-
-	if (state != QLCNIC_DEV_NPAR_RDY) {
-		QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE,
-			QLCNIC_DEV_NPAR_RDY);
-		QLCDB(adapter, DRV, "NPAR READY state set\n");
-	}
+	QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER);
+	QLCDB(adapter, DRV, "NPAR operational state set\n");
 
 	qlcnic_api_unlock(adapter);
 }
@@ -2621,8 +2620,11 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 		qlcnic_dev_request_reset(adapter);
 
 	state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
-	if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT)
+	if (state == QLCNIC_DEV_NEED_RESET ||
+	    state == QLCNIC_DEV_NEED_QUISCENT) {
+		qlcnic_set_npar_non_operational(adapter);
 		adapter->need_fw_reset = 1;
+	}
 
 	heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER);
 	if (heartbit != adapter->heartbit) {
@@ -2812,11 +2814,25 @@ static int
 qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
 {
 	int err;
+	u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO;
+	u32 npar_state;
 
 	err = qlcnic_can_start_firmware(adapter);
 	if (err)
 		return err;
 
+	npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+	while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) {
+		msleep(1000);
+		npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE);
+	}
+
+	if (!npar_opt_timeo) {
+		dev_err(&adapter->pdev->dev,
+			"Waiting for NPAR state to opertional timeout\n");
+		return -EIO;
+	}
+
 	qlcnic_check_options(adapter);
 
 	adapter->need_fw_reset = 0;
-- 
1.6.0.2


^ permalink raw reply related

* [PATCHv1 NEXT 0/7]qlcnic: enhancement and fixes
From: Amit Kumar Salecha @ 2010-08-12 11:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, ameen.rahman

Hi
	Series v1 of 7 patches to fix minor bugs and to add statistics
	support. Please apply them on net-next.
-amit

^ permalink raw reply

* Re: [patch net-next-2.6] bridge: allow hub-like behaviour
From: Jiri Pirko @ 2010-08-12 11:15 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, shemminger, bridge, davem
In-Reply-To: <20100811120741.27e13248@s6510>

Wed, Aug 11, 2010 at 06:07:41PM CEST, shemminger@vyatta.com wrote:
>NO. unnecessary
>
>Already possible, without patch. Just set the hold time
>on the bridge to 0!

Sorry, but could you please point me a sysfs node where should I do this
setting? Unable to find this.

Thanks.


^ permalink raw reply

* Re: e1000e crashes with 2.6.34.x and ThinkPad T60
From: Marc Haber @ 2010-08-12 10:50 UTC (permalink / raw)
  To: Allan, Bruce W
  Cc: Tantilov, Emil S, Linux Kernel Developers,
	Linux Kernel Network Developers, e1000-devel@lists.sf.net
In-Reply-To: <8DD2590731AB5D4C9DBF71A877482A900164D9279F@orsmsx509.amr.corp.intel.com>

Hi,

On Tue, Aug 10, 2010 at 09:34:52AM -0700, Allan, Bruce W wrote:
> [adding e1000-devel, the Intel wired ethernet developers mailing list]

Thanks.

> We have had other recent reports of issues with this part that are due to
> ASPM L1 being enabled.  Would you please try disabling L1 after the driver
> is loaded as follows (assuming your adapter is still PCI bus/device/number
> 02:00.0 as indicated in the lspci output you provided earlier):
> 1) First check the hexadecimal value of the LnkCtl register -
> # setpci -s 2:0.0 0xf0

$ sudo setpci --version
setpci version 3.1.7                   
$ sudo setpci -s 2:0.0 0xf0
setpci: Missing width.
Try `setpci --help' for more information.
$

Looking at --help doesn't help me, sorry.

Greetings
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190

^ permalink raw reply

* Re: [PATCH 0/1] netfilter: xt_condition: add condition target
From: Luciano Coelho @ 2010-08-12 10:14 UTC (permalink / raw)
  To: ext Jan Engelhardt
  Cc: netfilter-devel@vger.kernel.org, netdev@vger.kernel.org,
	kaber@trash.net, sameo@linux.intel.com,
	Ylalehto Janne (Nokia-MS/Tampere)
In-Reply-To: <alpine.LSU.2.01.1008121202320.31027@obet.zrqbmnf.qr>

On Thu, 2010-08-12 at 12:10 +0200, ext Jan Engelhardt wrote:
> On Thursday 2010-08-12 08:37, Luciano Coelho wrote:
> >
> >One thing that came to my mind was whether it would make sense to
> >rename this match/target combo to "variable" instead of "condition".
> >To me it makes more sense to call it variable than condition, since
> >I have changed the value from boolean to u32. On the other hand, it
> >could become very confusing because it used to be called condition
> >in its xtables-addons days...
> 
> To improve matters, POSIX has something called "condition variables".
> So oh well let's just leave it as-is :)

:D

Okay, let's keep it like this, I guess it would just complicate things
more if we change it.

-- 
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH 0/1] netfilter: xt_condition: add condition target
From: Jan Engelhardt @ 2010-08-12 10:10 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: netfilter-devel, netdev, kaber, sameo, janne.ylalehto
In-Reply-To: <1281595021-24310-1-git-send-email-luciano.coelho@nokia.com>


On Thursday 2010-08-12 08:37, Luciano Coelho wrote:
>
>One thing that came to my mind was whether it would make sense to
>rename this match/target combo to "variable" instead of "condition".
>To me it makes more sense to call it variable than condition, since
>I have changed the value from boolean to u32. On the other hand, it
>could become very confusing because it used to be called condition
>in its xtables-addons days...

To improve matters, POSIX has something called "condition variables".
So oh well let's just leave it as-is :)

^ permalink raw reply

* Re: [PATCH] iproute2: dont filter cached routes on iproute_get
From: Ulrich Weber @ 2010-08-12  9:20 UTC (permalink / raw)
  To: Fabio Comolli; +Cc: Andreas Henriksson, shemminger, netdev
In-Reply-To: <AANLkTikKbNPXv+F6SuR79Q9qcS1WD1DOYLGuOtuLkzuK@mail.gmail.com>

The patch should be applied on top of iproute2 v2.6.35.

Cheers
 Ulrich

On 08/12/2010 11:12 AM, Fabio Comolli wrote:
> Hi.
> Is this patch supposed to be applied on top of plain iproute2 v2.6.35
> or on top of the previous Andreas' patch?
> 
> 
> 
> On Thu, Aug 12, 2010 at 11:05 AM, Ulrich Weber <uweber@astaro.com> wrote:
>> iproute_get will return cloned routes for IPv4
>> and cloned as well non-cloned routes for IPv6.
>>
>> Therefore RTM_F_CLONED flag should not be checked
>> for iproute_get routes. Check in print_route will
>> always fail because valid values are 0 and 1.
>>
>> Signed-off-by: Ulrich Weber <uweber@astaro.com>
>> ---
>>  ip/iproute.c |    1 +
>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/ip/iproute.c b/ip/iproute.c
>> index 711576e..b43933c 100644
>> --- a/ip/iproute.c
>> +++ b/ip/iproute.c
>> @@ -1286,6 +1286,7 @@ int iproute_get(int argc, char **argv)
>>        memset(&req, 0, sizeof(req));
>>
>>        iproute_reset_filter();
>> +       filter.cloned = 2;
>>
>>        req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
>>        req.n.nlmsg_flags = NLM_F_REQUEST;
>> --
>> 1.7.0.4
>>
>>


-- 
Ulrich Weber | uweber@astaro.com | Software Engineer
Astaro GmbH & Co. KG | www.astaro.com | Phone +49-721-25516-0 | Fax –200
An der RaumFabrik 33a | 76227 Karlsruhe | Germany

^ permalink raw reply

* [PATCH] iproute2: dont filter cached routes on iproute_get
From: Ulrich Weber @ 2010-08-12  9:05 UTC (permalink / raw)
  To: Andreas Henriksson, shemminger; +Cc: Fabio Comolli, netdev
In-Reply-To: <1281297165.4116.19.camel@amd64.fatal.se>

iproute_get will return cloned routes for IPv4
and cloned as well non-cloned routes for IPv6.

Therefore RTM_F_CLONED flag should not be checked
for iproute_get routes. Check in print_route will
always fail because valid values are 0 and 1.

Signed-off-by: Ulrich Weber <uweber@astaro.com>
---
 ip/iproute.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/ip/iproute.c b/ip/iproute.c
index 711576e..b43933c 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -1286,6 +1286,7 @@ int iproute_get(int argc, char **argv)
 	memset(&req, 0, sizeof(req));
 
 	iproute_reset_filter();
+	filter.cloned = 2;
 
 	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
 	req.n.nlmsg_flags = NLM_F_REQUEST;
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] iproute2: dont filter cached routes on iproute_get
From: Fabio Comolli @ 2010-08-12  9:12 UTC (permalink / raw)
  To: Ulrich Weber; +Cc: Andreas Henriksson, shemminger, netdev
In-Reply-To: <20100812090519.GA13769@babylon>

Hi.
Is this patch supposed to be applied on top of plain iproute2 v2.6.35
or on top of the previous Andreas' patch?



On Thu, Aug 12, 2010 at 11:05 AM, Ulrich Weber <uweber@astaro.com> wrote:
> iproute_get will return cloned routes for IPv4
> and cloned as well non-cloned routes for IPv6.
>
> Therefore RTM_F_CLONED flag should not be checked
> for iproute_get routes. Check in print_route will
> always fail because valid values are 0 and 1.
>
> Signed-off-by: Ulrich Weber <uweber@astaro.com>
> ---
>  ip/iproute.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/ip/iproute.c b/ip/iproute.c
> index 711576e..b43933c 100644
> --- a/ip/iproute.c
> +++ b/ip/iproute.c
> @@ -1286,6 +1286,7 @@ int iproute_get(int argc, char **argv)
>        memset(&req, 0, sizeof(req));
>
>        iproute_reset_filter();
> +       filter.cloned = 2;
>
>        req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
>        req.n.nlmsg_flags = NLM_F_REQUEST;
> --
> 1.7.0.4
>
>

^ permalink raw reply

* Re: [MeeGo-Dev][PATCH] Topcliff: Update PCH_CAN driver to 2.6.35
From: Wolfgang Grandegger @ 2010-08-12  9:03 UTC (permalink / raw)
  To: Wang, Qi
  Cc: Khor, Andrew Chih Howe,
	socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org,
	netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	gregkh-l3A5Bk7waGM@public.gmane.org, Wang, Yong Y, Masayuki Ohtak,
	meego-dev-WXzIur8shnEAvxtiuMwx3w@public.gmane.org,
	arjan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org
In-Reply-To: <D5AB6E638E5A3E4B8F4406B113A5A19A28EA26EB-QQHDSDV1ERZpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>

On 08/12/2010 03:42 AM, Wang, Qi wrote:
>> -----Original Message-----
>> From: Daniel Baluta [mailto:daniel.baluta-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org]
>> Sent: Wednesday, August 11, 2010 6:37 PM
>> To: Masayuki Ohtak
>> Cc: meego-dev-WXzIur8shnEAvxtiuMwx3w@public.gmane.org; Wolfgang Grandegger;
>> socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org; netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Khor, Andrew Chih
>> Howe; gregkh-l3A5Bk7waGM@public.gmane.org; arjan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org; Wang, Qi; Wang, Yong Y
>> Subject: Re: [MeeGo-Dev][PATCH] Topcliff: Update PCH_CAN driver to 2.6.35
>>
>> Hi,
>>
>> 2010/8/11 Masayuki Ohtak <masa-korg-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>:
>>> CAN driver of Topcliff PCH
>>>
>>> Topcliff PCH is the platform controller hub that is going to be used in
>>> Intel's upcoming general embedded platform. All IO peripherals in
>>> Topcliff PCH are actually devices sitting on AMBA bus.
>>> Topcliff PCH has CAN I/F. This driver enables CAN function.
>>>
>>> Signed-off-by: Masayuki Ohtake <masa-korg-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
>>
>> I have a few questions:
>>
>> 1. Is your code based on Intel's CAN EP80579 ([1]) ?
> No.

For curiosity, is the controller similar to the OKI MSM9225 or ML9620?

>> 2. Why don't you use kernel existing kfifo infrastructure? ([2]).
> Just take a look at kfifo.h. This structure has been changed. I remembered there was a spin_lock from kfifo previously. Currently it's been removed, good.
> OKI-sans, would you please take a look at ./include/linux/kfifo.h, and try to use this structure and APIs?

As I see it, the code related to that fifo is not used (== dead code)?

> Daniel,
> 
> We're anxious to integrate those codes now. Perhaps it'll take us quite a long time to use kfifo. How about implementing it with the next version?

See above. What do you mean with the next version. The driver posted by
Masayuki is far away from being accepted as it does not yet comply with
the Socket-CAN driver API, to say the least.

Wolfgang.

^ permalink raw reply

* Re: Latest iproute2 breaks "ip route get" command
From: Ulrich Weber @ 2010-08-12  9:02 UTC (permalink / raw)
  To: Andreas Henriksson, shemminger; +Cc: Fabio Comolli, netdev
In-Reply-To: <1281297165.4116.19.camel@amd64.fatal.se>

Hi Andreas,

your fix will work for IPv4 but will display the IPv6 cached routes
again with "ip -6 route show" what I was trying to fix with
447928279c88b6581ae4cdc1b5ac0a9e755aff64

Will send another patch which makes the filter.cloned check not matching
for iproute_get routes.

Best regards
 Ulrich

On 08/08/2010 09:52 PM, Andreas Henriksson wrote:
> On sön, 2010-08-08 at 21:31 +0200, Fabio Comolli wrote:
>> Yup, that seems to fix it.
>> You can add my Tested-By in case you need it.
> 
> I'll let Ulrich Weber confirm it's the right fix and forward to Stephen
> Hemminger. Just received an "out of office" notice saying he'll be back
> 11 august (wednesday), so I guess we'll have to wait a couple of days
> for that.
> 
> //Andreas
> 


-- 
Ulrich Weber | uweber@astaro.com | Software Engineer
Astaro GmbH & Co. KG | www.astaro.com | Phone +49-721-25516-0 | Fax –200
An der RaumFabrik 33a | 76227 Karlsruhe | Germany

^ permalink raw reply

* [PATCH 6/6 v2] au1000-eth: remove volatiles, switch to I/O accessors
From: Florian Fainelli @ 2010-08-12  8:10 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


Remove all the volatile keywords where they were used, switch to using the
proper readl/writel accessors.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 7b823c9..4ccdde3 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -163,10 +163,10 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
 	spin_lock_irqsave(&aup->lock, flags);
 
 	if (force_reset || (!aup->mac_enabled)) {
-		*aup->enable = MAC_EN_CLOCK_ENABLE;
+		writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
 		au_sync_delay(2);
-		*aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
-				| MAC_EN_CLOCK_ENABLE);
+		writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
+				| MAC_EN_CLOCK_ENABLE), &aup->enable);
 		au_sync_delay(2);
 
 		aup->mac_enabled = 1;
@@ -181,12 +181,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
 static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 {
 	struct au1000_private *aup = netdev_priv(dev);
-	volatile u32 *const mii_control_reg = &aup->mac->mii_control;
-	volatile u32 *const mii_data_reg = &aup->mac->mii_data;
+	u32 *const mii_control_reg = &aup->mac->mii_control;
+	u32 *const mii_data_reg = &aup->mac->mii_data;
 	u32 timedout = 20;
 	u32 mii_control;
 
-	while (*mii_control_reg & MAC_MII_BUSY) {
+	while (readl(mii_control_reg) & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
 			netdev_err(dev, "read_MII busy timeout!!\n");
@@ -197,29 +197,29 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 	mii_control = MAC_SET_MII_SELECT_REG(reg) |
 		MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ;
 
-	*mii_control_reg = mii_control;
+	writel(mii_control, mii_control_reg);
 
 	timedout = 20;
-	while (*mii_control_reg & MAC_MII_BUSY) {
+	while (readl(mii_control_reg) & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
 			netdev_err(dev, "mdio_read busy timeout!!\n");
 			return -1;
 		}
 	}
-	return (int)*mii_data_reg;
+	return readl(mii_data_reg);
 }
 
 static void au1000_mdio_write(struct net_device *dev, int phy_addr,
 			      int reg, u16 value)
 {
 	struct au1000_private *aup = netdev_priv(dev);
-	volatile u32 *const mii_control_reg = &aup->mac->mii_control;
-	volatile u32 *const mii_data_reg = &aup->mac->mii_data;
+	u32 *const mii_control_reg = &aup->mac->mii_control;
+	u32 *const mii_data_reg = &aup->mac->mii_data;
 	u32 timedout = 20;
 	u32 mii_control;
 
-	while (*mii_control_reg & MAC_MII_BUSY) {
+	while (readl(mii_control_reg) & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
 			netdev_err(dev, "mdio_write busy timeout!!\n");
@@ -230,8 +230,8 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr,
 	mii_control = MAC_SET_MII_SELECT_REG(reg) |
 		MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE;
 
-	*mii_data_reg = value;
-	*mii_control_reg = mii_control;
+	writel(value, mii_data_reg);
+	writel(mii_control, mii_control_reg);
 }
 
 static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
@@ -268,20 +268,26 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
 static void au1000_hard_stop(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
+	u32 reg;
 
 	netif_dbg(aup, drv, dev, "hard stop\n");
 
-	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+	reg = readl(&aup->mac->control);
+	reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+	writel(reg, &aup->mac->control);
 	au_sync_delay(10);
 }
 
 static void au1000_enable_rx_tx(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
+	u32 reg;
 
 	netif_dbg(aup, hw, dev, "enable_rx_tx\n");
 
-	aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+	reg = readl(&aup->mac->control);
+	reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+	writel(reg, &aup->mac->control);
 	au_sync_delay(10);
 }
 
@@ -291,6 +297,7 @@ au1000_adjust_link(struct net_device *dev)
 	struct au1000_private *aup = netdev_priv(dev);
 	struct phy_device *phydev = aup->phy_dev;
 	unsigned long flags;
+	u32 reg;
 
 	int status_change = 0;
 
@@ -322,14 +329,15 @@ au1000_adjust_link(struct net_device *dev)
 		/* switching duplex mode requires to disable rx and tx! */
 		au1000_hard_stop(dev);
 
-		if (DUPLEX_FULL == phydev->duplex)
-			aup->mac->control = ((aup->mac->control
-					     | MAC_FULL_DUPLEX)
-					     & ~MAC_DISABLE_RX_OWN);
-		else
-			aup->mac->control = ((aup->mac->control
-					      & ~MAC_FULL_DUPLEX)
-					     | MAC_DISABLE_RX_OWN);
+		reg = readl(&aup->mac->control);
+		if (DUPLEX_FULL == phydev->duplex) {
+			reg |= MAC_FULL_DUPLEX;
+			reg &= ~MAC_DISABLE_RX_OWN;
+		} else {
+			reg &= ~MAC_FULL_DUPLEX;
+			reg |= MAC_DISABLE_RX_OWN;
+		}
+		writel(reg, &aup->mac->control);
 		au_sync_delay(1);
 
 		au1000_enable_rx_tx(dev);
@@ -495,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
 
 	au1000_hard_stop(dev);
 
-	*aup->enable = MAC_EN_CLOCK_ENABLE;
+	writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
 	au_sync_delay(2);
-	*aup->enable = 0;
+	writel(0, &aup->enable);
 	au_sync_delay(2);
 
 	aup->tx_full = 0;
@@ -541,12 +549,12 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
 
 	for (i = 0; i < NUM_RX_DMA; i++) {
 		aup->rx_dma_ring[i] =
-			(volatile struct rx_dma *)
+			(struct rx_dma *)
 					(rx_base + sizeof(struct rx_dma)*i);
 	}
 	for (i = 0; i < NUM_TX_DMA; i++) {
 		aup->tx_dma_ring[i] =
-			(volatile struct tx_dma *)
+			(struct tx_dma *)
 					(tx_base + sizeof(struct tx_dma)*i);
 	}
 }
@@ -635,14 +643,16 @@ static int au1000_init(struct net_device *dev)
 
 	spin_lock_irqsave(&aup->lock, flags);
 
-	aup->mac->control = 0;
+	writel(0, &aup->mac->control);
 	aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
 	aup->tx_tail = aup->tx_head;
 	aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;
 
-	aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4];
-	aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
-		dev->dev_addr[1]<<8 | dev->dev_addr[0];
+	writel(dev->dev_addr[5]<<8 | dev->dev_addr[4],
+					&aup->mac->mac_addr_high);
+	writel(dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
+		dev->dev_addr[1]<<8 | dev->dev_addr[0],
+					&aup->mac->mac_addr_low);
 
 
 	for (i = 0; i < NUM_RX_DMA; i++)
@@ -663,8 +673,8 @@ static int au1000_init(struct net_device *dev)
 		control |= MAC_FULL_DUPLEX;
 	}
 
-	aup->mac->control = control;
-	aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
+	writel(control, &aup->mac->control);
+	writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */
 	au_sync();
 
 	spin_unlock_irqrestore(&aup->lock, flags);
@@ -701,7 +711,7 @@ static int au1000_rx(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 	struct sk_buff *skb;
-	volatile struct rx_dma *prxd;
+	struct rx_dma *prxd;
 	u32 buff_stat, status;
 	struct db_dest *pDB;
 	u32	frmlen;
@@ -797,7 +807,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status)
 static void au1000_tx_ack(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
-	volatile struct tx_dma *ptxd;
+	struct tx_dma *ptxd;
 
 	ptxd = aup->tx_dma_ring[aup->tx_tail];
 
@@ -896,7 +906,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 	struct net_device_stats *ps = &dev->stats;
-	volatile struct tx_dma *ptxd;
+	struct tx_dma *ptxd;
 	u32 buff_stat;
 	struct db_dest *pDB;
 	int i;
@@ -958,15 +968,18 @@ static void au1000_tx_timeout(struct net_device *dev)
 static void au1000_multicast_list(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
+	u32 reg;
 
 	netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n",
 							dev->flags);
+
+	reg = readl(&aup->mac->control);
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
-		aup->mac->control |= MAC_PROMISCUOUS;
+		reg |= MAC_PROMISCUOUS;
 	} else if ((dev->flags & IFF_ALLMULTI)  ||
 			   netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
-		aup->mac->control |= MAC_PASS_ALL_MULTI;
-		aup->mac->control &= ~MAC_PROMISCUOUS;
+		reg |= MAC_PASS_ALL_MULTI;
+		reg &= ~MAC_PROMISCUOUS;
 		netdev_info(dev, "Pass all multicast\n");
 	} else {
 		struct netdev_hw_addr *ha;
@@ -976,11 +989,12 @@ static void au1000_multicast_list(struct net_device *dev)
 		netdev_for_each_mc_addr(ha, dev)
 			set_bit(ether_crc(ETH_ALEN, ha->addr)>>26,
 					(long *)mc_filter);
-		aup->mac->multi_hash_high = mc_filter[1];
-		aup->mac->multi_hash_low = mc_filter[0];
-		aup->mac->control &= ~MAC_PROMISCUOUS;
-		aup->mac->control |= MAC_HASH_MODE;
+		writel(mc_filter[1], &aup->mac->multi_hash_high);
+		writel(mc_filter[0], &aup->mac->multi_hash_low);
+		reg &= ~MAC_PROMISCUOUS;
+		reg |= MAC_HASH_MODE;
 	}
+	writel(reg, &aup->mac->control);
 }
 
 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1083,7 +1097,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	}
 
 	/* aup->mac is the base address of the MAC's registers */
-	aup->mac = (volatile struct mac_reg *)
+	aup->mac = (struct mac_reg *)
 			ioremap_nocache(base->start, resource_size(base));
 	if (!aup->mac) {
 		dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
@@ -1092,7 +1106,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	}
 
 	/* Setup some variables for quick register address access */
-	aup->enable = (volatile u32 *)ioremap_nocache(macen->start,
+	aup->enable = (u32 *)ioremap_nocache(macen->start,
 						resource_size(macen));
 	if (!aup->enable) {
 		dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
@@ -1121,7 +1135,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
 	dev->dev_addr[5] += pdev->id;
 
-	*aup->enable = 0;
+	writel(0, &aup->enable);
 	aup->mac_enabled = 0;
 
 	pd = pdev->dev.platform_data;
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index 38c1d88..4b638df 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -46,7 +46,7 @@
  */
 struct db_dest {
 	struct db_dest *pnext;
-	volatile u32 *vaddr;
+	u32 *vaddr;
 	dma_addr_t dma_addr;
 };
 
@@ -88,8 +88,8 @@ struct mac_reg {
 struct au1000_private {
 	struct db_dest *pDBfree;
 	struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS];
-	volatile struct rx_dma *rx_dma_ring[NUM_RX_DMA];
-	volatile struct tx_dma *tx_dma_ring[NUM_TX_DMA];
+	struct rx_dma *rx_dma_ring[NUM_RX_DMA];
+	struct tx_dma *tx_dma_ring[NUM_TX_DMA];
 	struct db_dest *rx_db_inuse[NUM_RX_DMA];
 	struct db_dest *tx_db_inuse[NUM_TX_DMA];
 	u32 rx_head;
@@ -120,8 +120,8 @@ struct au1000_private {
 
 	/* These variables are just for quick access
 	 * to certain regs addresses. */
-	volatile struct mac_reg *mac;  /* mac registers                      */
-	volatile u32 *enable;     /* address of MAC Enable Register     */
+	struct mac_reg *mac;  /* mac registers                      */
+	u32 *enable;     /* address of MAC Enable Register     */
 
 	u32 vaddr;                /* virtual address of rx/tx buffers   */
 	dma_addr_t dma_addr;      /* dma address of rx/tx buffers       */



^ permalink raw reply related

* [PATCH 5/6 v2] au1000-eth: fix asm -> linux headers inclusion
From: Florian Fainelli @ 2010-08-12  8:10 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


Replace asm/io.h and asm/cpu.h wih linux/io.h and linux/cpu.h

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 7625573..7b823c9 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -58,11 +58,11 @@
 #include <linux/crc32.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/io.h>
 
-#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/processor.h>
 
 #include <au1000.h>



^ permalink raw reply related

* [PATCH 4/6 v2] au1000-eth: fix bad printk usages
From: Florian Fainelli @ 2010-08-12  8:10 UTC (permalink / raw)
  To: netdev, Joe Perches; +Cc: David Miller


Use pr_(info|err) and pr_cont where required instead of calls to printk.
Add missing pr_fmt to the driver.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
Changes since v1:
- add missing pr_fmt
- rework the pr_err() and pr_cont() usages

diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 9a0515d..7625573 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -34,6 +34,8 @@
  *
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/capability.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
@@ -732,24 +734,26 @@ static int au1000_rx(struct net_device *dev)
 			netif_rx(skb);	/* pass the packet to upper layers */
 		} else {
 			if (au1000_debug > 4) {
+				pr_err("rx_error(s):");
 				if (status & RX_MISSED_FRAME)
-					printk("rx miss\n");
+					pr_cont(" miss");
 				if (status & RX_WDOG_TIMER)
-					printk("rx wdog\n");
+					pr_cont(" wdog");
 				if (status & RX_RUNT)
-					printk("rx runt\n");
+					pr_cont(" runt");
 				if (status & RX_OVERLEN)
-					printk("rx overlen\n");
+					pr_cont(" overlen");
 				if (status & RX_COLL)
-					printk("rx coll\n");
+					pr_cont(" coll");
 				if (status & RX_MII_ERROR)
-					printk("rx mii error\n");
+					pr_cont(" mii error");
 				if (status & RX_CRC_ERROR)
-					printk("rx crc error\n");
+					pr_cont(" crc error");
 				if (status & RX_LEN_ERROR)
-					printk("rx len error\n");
+					pr_cont(" len error");
 				if (status & RX_U_CNTRL_FRAME)
-					printk("rx u control frame\n");
+					pr_cont(" u control frame");
+				pr_cont("\n");
 			}
 		}
 		prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
@@ -1225,7 +1229,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n",
 			(unsigned long)base->start, irq);
 	if (version_printed++ == 0)
-		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+		pr_info("%s version %s %s\n",
+					DRV_NAME, DRV_VERSION, DRV_AUTHOR);
 
 	return 0;
 



^ permalink raw reply related

* [PATCH 3/6 v2] au1000-eth: fix all "line over 80 characters warnings"
From: Florian Fainelli @ 2010-08-12  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index b5f992a..9a0515d 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -377,12 +377,15 @@ static int au1000_mii_probe(struct net_device *dev)
 	} else {
 		int phy_addr;
 
-		/* find the first (lowest address) PHY on the current MAC's MII bus */
-		for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+		/* find the first (lowest address) PHY
+		 * on the current MAC's MII bus */
+		for (phy_addr = 0;
+			phy_addr < PHY_MAX_ADDR; phy_addr++)
 			if (aup->mii_bus->phy_map[phy_addr]) {
 				phydev = aup->mii_bus->phy_map[phy_addr];
 				if (!aup->phy_search_highest_addr)
-					break; /* break out with first one found */
+					/* break out with first one found */
+					break;
 			}
 
 		if (aup->phy1_search_mac0) {
@@ -390,22 +393,26 @@ static int au1000_mii_probe(struct net_device *dev)
 			if (!phydev && (aup->mac_id == 1)) {
 				/* no PHY found, maybe we have a dual PHY? */
 				dev_info(&dev->dev, ": no PHY found on MAC1, "
-					"let's see if it's attached to MAC0...\n");
+					"let's see if it's attached to MAC0..."
+					"\n");
 
-				/* find the first (lowest address) non-attached PHY on
-				 * the MAC0 MII bus */
-				for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+				/* find the first (lowest address) non-attached
+				 * PHY on the MAC0 MII bus */
+				for (phy_addr = 0; phy_addr < PHY_MAX_ADDR;
+								phy_addr++) {
 					struct phy_device *const tmp_phydev =
-							aup->mii_bus->phy_map[phy_addr];
+						aup->mii_bus->phy_map[phy_addr];
 
 					if (aup->mac_id == 1)
 						break;
 
+					/* no PHY here... */
 					if (!tmp_phydev)
-						continue; /* no PHY here... */
+						continue;
 
+					/* already claimed by MAC0 */
 					if (tmp_phydev->attached_dev)
-						continue; /* already claimed by MAC0 */
+						continue;
 
 					phydev = tmp_phydev;
 					break; /* found it */
@@ -532,11 +539,13 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
 
 	for (i = 0; i < NUM_RX_DMA; i++) {
 		aup->rx_dma_ring[i] =
-			(volatile struct rx_dma *) (rx_base + sizeof(struct rx_dma)*i);
+			(volatile struct rx_dma *)
+					(rx_base + sizeof(struct rx_dma)*i);
 	}
 	for (i = 0; i < NUM_TX_DMA; i++) {
 		aup->tx_dma_ring[i] =
-			(volatile struct tx_dma *) (tx_base + sizeof(struct tx_dma)*i);
+			(volatile struct tx_dma *)
+					(tx_base + sizeof(struct tx_dma)*i);
 	}
 }
 
@@ -633,6 +642,7 @@ static int au1000_init(struct net_device *dev)
 	aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
 		dev->dev_addr[1]<<8 | dev->dev_addr[0];
 
+
 	for (i = 0; i < NUM_RX_DMA; i++)
 		aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
 
@@ -709,7 +719,8 @@ static int au1000_rx(struct net_device *dev)
 			frmlen -= 4; /* Remove FCS */
 			skb = dev_alloc_skb(frmlen + 2);
 			if (skb == NULL) {
-				netdev_err(dev, "Memory squeeze, dropping packet.\n");
+				netdev_err(dev, "Memory squeeze,"
+							" dropping packet.\n");
 				dev->stats.rx_dropped++;
 				continue;
 			}
@@ -944,8 +955,8 @@ static void au1000_multicast_list(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 
-	netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n", dev->flags);
-
+	netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n",
+							dev->flags);
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		aup->mac->control |= MAC_PROMISCUOUS;
 	} else if ((dev->flags & IFF_ALLMULTI)  ||
@@ -1025,14 +1036,18 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	if (!request_mem_region(base->start, resource_size(base), pdev->name)) {
-		dev_err(&pdev->dev, "failed to request memory region for base registers\n");
+	if (!request_mem_region(base->start, resource_size(base),
+							pdev->name)) {
+		dev_err(&pdev->dev, "failed to request memory region for"
+						" base registers\n");
 		err = -ENXIO;
 		goto out;
 	}
 
-	if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) {
-		dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n");
+	if (!request_mem_region(macen->start, resource_size(macen),
+							pdev->name)) {
+		dev_err(&pdev->dev, "failed to request memory region for"
+						" MAC enable register\n");
 		err = -ENXIO;
 		goto err_request;
 	}
@@ -1049,7 +1064,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	aup = netdev_priv(dev);
 
 	spin_lock_init(&aup->lock);
-	aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug);
+	aup->msg_enable = (au1000_debug < 4 ?
+				AU1000_DEF_MSG_ENABLE : au1000_debug);
 
 	/* Allocate the data buffers */
 	/* Snooping works fine with eth on all au1xxx */
@@ -1063,7 +1079,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	}
 
 	/* aup->mac is the base address of the MAC's registers */
-	aup->mac = (volatile struct mac_reg *)ioremap_nocache(base->start, resource_size(base));
+	aup->mac = (volatile struct mac_reg *)
+			ioremap_nocache(base->start, resource_size(base));
 	if (!aup->mac) {
 		dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
 		err = -ENXIO;
@@ -1071,7 +1088,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	}
 
 	/* Setup some variables for quick register address access */
-	aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
+	aup->enable = (volatile u32 *)ioremap_nocache(macen->start,
+						resource_size(macen));
 	if (!aup->enable) {
 		dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
 		err = -ENXIO;
@@ -1081,7 +1099,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	if (pdev->id == 0) {
 		if (prom_get_ethernet_addr(ethaddr) == 0)
-			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
+			memcpy(au1000_mac_addr, ethaddr,
+						sizeof(au1000_mac_addr));
 		else {
 			netdev_info(dev, "No MAC address found\n");
 				/* Use the hard coded MAC addresses */
@@ -1103,7 +1122,8 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	pd = pdev->dev.platform_data;
 	if (!pd) {
-		dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n");
+		dev_info(&pdev->dev, "no platform_data passed,"
+					" PHY search on MAC0\n");
 		aup->phy1_search_mac0 = 1;
 	} else {
 		aup->phy_static_config = pd->phy_static_config;
@@ -1116,7 +1136,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	if (aup->phy_busid && aup->phy_busid > 0) {
 		dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII"
-				"bus not supported yet\n");
+				" bus not supported yet\n");
 		err = -ENODEV;
 		goto err_mdiobus_alloc;
 	}
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index 44003e4..38c1d88 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -99,7 +99,8 @@ struct au1000_private {
 
 	int mac_id;
 
-	int mac_enabled;       /* whether MAC is currently enabled and running (req. for mdio) */
+	int mac_enabled;       /* whether MAC is currently enabled and running
+				 (req. for mdio) */
 
 	int old_link;          /* used by au1000_adjust_link */
 	int old_speed;
@@ -117,7 +118,8 @@ struct au1000_private {
 	int phy_busid;
 	int phy_irq;
 
-	/* These variables are just for quick access to certain regs addresses. */
+	/* These variables are just for quick access
+	 * to certain regs addresses. */
 	volatile struct mac_reg *mac;  /* mac registers                      */
 	volatile u32 *enable;     /* address of MAC Enable Register     */
 



^ permalink raw reply related

* [PATCH 2/6 v2] au1000-eth: stylistic fixes
From: Florian Fainelli @ 2010-08-12  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


This patch fixes the following checkpatch.pl warnings:
- spaces after tabs
- space between function and arguments
- one-line statement braces
- tabs instead of spaces

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 8b79635..b5f992a 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -13,7 +13,7 @@
  *  converted to use linux-2.6.x's PHY framework
  *
  * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ *		ppopov@mvista.com or source@mvista.com
  *
  * ########################################################################
  *
@@ -160,7 +160,7 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
 
 	spin_lock_irqsave(&aup->lock, flags);
 
-	if(force_reset || (!aup->mac_enabled)) {
+	if (force_reset || (!aup->mac_enabled)) {
 		*aup->enable = MAC_EN_CLOCK_ENABLE;
 		au_sync_delay(2);
 		*aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
@@ -361,7 +361,7 @@ au1000_adjust_link(struct net_device *dev)
 	}
 }
 
-static int au1000_mii_probe (struct net_device *dev)
+static int au1000_mii_probe(struct net_device *dev)
 {
 	struct au1000_private *const aup = netdev_priv(dev);
 	struct phy_device *phydev = NULL;
@@ -465,9 +465,9 @@ static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup)
 	struct db_dest *pDB;
 	pDB = aup->pDBfree;
 
-	if (pDB) {
+	if (pDB)
 		aup->pDBfree = pDB->pnext;
-	}
+
 	return pDB;
 }
 
@@ -515,7 +515,7 @@ static void au1000_reset_mac(struct net_device *dev)
 
 	spin_lock_irqsave(&aup->lock, flags);
 
-	au1000_reset_mac_unlocked (dev);
+	au1000_reset_mac_unlocked(dev);
 
 	spin_unlock_irqrestore(&aup->lock, flags);
 }
@@ -633,9 +633,9 @@ static int au1000_init(struct net_device *dev)
 	aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
 		dev->dev_addr[1]<<8 | dev->dev_addr[0];
 
-	for (i = 0; i < NUM_RX_DMA; i++) {
+	for (i = 0; i < NUM_RX_DMA; i++)
 		aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
-	}
+
 	au_sync();
 
 	control = MAC_RX_ENABLE | MAC_TX_ENABLE;
@@ -862,7 +862,7 @@ static int au1000_close(struct net_device *dev)
 
 	spin_lock_irqsave(&aup->lock, flags);
 
-	au1000_reset_mac_unlocked (dev);
+	au1000_reset_mac_unlocked(dev);
 
 	/* stop the device */
 	netif_stop_queue(dev);
@@ -910,9 +910,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 	pDB = aup->tx_db_inuse[aup->tx_head];
 	skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
 	if (skb->len < ETH_ZLEN) {
-		for (i = skb->len; i < ETH_ZLEN; i++) {
+		for (i = skb->len; i < ETH_ZLEN; i++)
 			((char *)pDB->vaddr)[i] = 0;
-		}
+
 		ptxd->len = ETH_ZLEN;
 	} else
 		ptxd->len = skb->len;
@@ -1070,7 +1070,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 		goto err_remap1;
 	}
 
-        /* Setup some variables for quick register address access */
+	/* Setup some variables for quick register address access */
 	aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen));
 	if (!aup->enable) {
 		dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
@@ -1168,17 +1168,17 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	for (i = 0; i < NUM_RX_DMA; i++) {
 		pDB = au1000_GetFreeDB(aup);
-		if (!pDB) {
+		if (!pDB)
 			goto err_out;
-		}
+
 		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
 		aup->rx_db_inuse[i] = pDB;
 	}
 	for (i = 0; i < NUM_TX_DMA; i++) {
 		pDB = au1000_GetFreeDB(aup);
-		if (!pDB) {
+		if (!pDB)
 			goto err_out;
-		}
+
 		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
 		aup->tx_dma_ring[i]->len = 0;
 		aup->tx_db_inuse[i] = pDB;



^ permalink raw reply related

* [PATCH 1/6 v2] au1000-eth: typedefs removal
From: Florian Fainelli @ 2010-08-12  8:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller


Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 386d4fe..8b79635 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -460,9 +460,9 @@ static int au1000_mii_probe (struct net_device *dev)
  * has the virtual and dma address of a buffer suitable for
  * both, receive and transmit operations.
  */
-static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup)
+static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup)
 {
-	db_dest_t *pDB;
+	struct db_dest *pDB;
 	pDB = aup->pDBfree;
 
 	if (pDB) {
@@ -471,9 +471,9 @@ static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup)
 	return pDB;
 }
 
-void au1000_ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
+void au1000_ReleaseDB(struct au1000_private *aup, struct db_dest *pDB)
 {
-	db_dest_t *pDBfree = aup->pDBfree;
+	struct db_dest *pDBfree = aup->pDBfree;
 	if (pDBfree)
 		pDBfree->pnext = pDB;
 	aup->pDBfree = pDB;
@@ -532,11 +532,11 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
 
 	for (i = 0; i < NUM_RX_DMA; i++) {
 		aup->rx_dma_ring[i] =
-			(volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
+			(volatile struct rx_dma *) (rx_base + sizeof(struct rx_dma)*i);
 	}
 	for (i = 0; i < NUM_TX_DMA; i++) {
 		aup->tx_dma_ring[i] =
-			(volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
+			(volatile struct tx_dma *) (tx_base + sizeof(struct tx_dma)*i);
 	}
 }
 
@@ -689,9 +689,9 @@ static int au1000_rx(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 	struct sk_buff *skb;
-	volatile rx_dma_t *prxd;
+	volatile struct rx_dma *prxd;
 	u32 buff_stat, status;
-	db_dest_t *pDB;
+	struct db_dest *pDB;
 	u32	frmlen;
 
 	netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head);
@@ -782,7 +782,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status)
 static void au1000_tx_ack(struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
-	volatile tx_dma_t *ptxd;
+	volatile struct tx_dma *ptxd;
 
 	ptxd = aup->tx_dma_ring[aup->tx_tail];
 
@@ -881,9 +881,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 	struct net_device_stats *ps = &dev->stats;
-	volatile tx_dma_t *ptxd;
+	volatile struct tx_dma *ptxd;
 	u32 buff_stat;
-	db_dest_t *pDB;
+	struct db_dest *pDB;
 	int i;
 
 	netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n",
@@ -999,7 +999,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	struct au1000_private *aup = NULL;
 	struct au1000_eth_platform_data *pd;
 	struct net_device *dev = NULL;
-	db_dest_t *pDB, *pDBfree;
+	struct db_dest *pDB, *pDBfree;
 	int irq, i, err = 0;
 	struct resource *base, *macen;
 	char ethaddr[6];
@@ -1063,7 +1063,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 	}
 
 	/* aup->mac is the base address of the MAC's registers */
-	aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base));
+	aup->mac = (volatile struct mac_reg *)ioremap_nocache(base->start, resource_size(base));
 	if (!aup->mac) {
 		dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
 		err = -ENXIO;
diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
index d06ec00..44003e4 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/au1000_eth.h
@@ -44,34 +44,34 @@
  * Data Buffer Descriptor. Data buffers must be aligned on 32 byte
  * boundary for both, receive and transmit.
  */
-typedef struct db_dest {
+struct db_dest {
 	struct db_dest *pnext;
 	volatile u32 *vaddr;
 	dma_addr_t dma_addr;
-} db_dest_t;
+};
 
 /*
  * The transmit and receive descriptors are memory
  * mapped registers.
  */
-typedef struct tx_dma {
+struct tx_dma {
 	u32 status;
 	u32 buff_stat;
 	u32 len;
 	u32 pad;
-} tx_dma_t;
+};
 
-typedef struct rx_dma {
+struct rx_dma {
 	u32 status;
 	u32 buff_stat;
 	u32 pad[2];
-} rx_dma_t;
+};
 
 
 /*
  * MAC control registers, memory mapped.
  */
-typedef struct mac_reg {
+struct mac_reg {
 	u32 control;
 	u32 mac_addr_high;
 	u32 mac_addr_low;
@@ -82,16 +82,16 @@ typedef struct mac_reg {
 	u32 flow_control;
 	u32 vlan1_tag;
 	u32 vlan2_tag;
-} mac_reg_t;
+};
 
 
 struct au1000_private {
-	db_dest_t *pDBfree;
-	db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS];
-	volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA];
-	volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA];
-	db_dest_t *rx_db_inuse[NUM_RX_DMA];
-	db_dest_t *tx_db_inuse[NUM_TX_DMA];
+	struct db_dest *pDBfree;
+	struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS];
+	volatile struct rx_dma *rx_dma_ring[NUM_RX_DMA];
+	volatile struct tx_dma *tx_dma_ring[NUM_TX_DMA];
+	struct db_dest *rx_db_inuse[NUM_RX_DMA];
+	struct db_dest *tx_db_inuse[NUM_TX_DMA];
 	u32 rx_head;
 	u32 tx_head;
 	u32 tx_tail;
@@ -118,7 +118,7 @@ struct au1000_private {
 	int phy_irq;
 
 	/* These variables are just for quick access to certain regs addresses. */
-	volatile mac_reg_t *mac;  /* mac registers                      */
+	volatile struct mac_reg *mac;  /* mac registers                      */
 	volatile u32 *enable;     /* address of MAC Enable Register     */
 
 	u32 vaddr;                /* virtual address of rx/tx buffers   */



^ permalink raw reply related

* Re: [PATCH (for some future time)] drivers/net: Convert unbounded kzalloc calls to kcalloc
From: Luciano Coelho @ 2010-08-12  6:48 UTC (permalink / raw)
  To: ext Joe Perches; +Cc: netdev, linux-wireless, linux-kernel@vger.kernel.org
In-Reply-To: <1281546168.3976.39.camel@Joe-Laptop.home>

On Wed, 2010-08-11 at 19:02 +0200, ext Joe Perches wrote:
> These changes may be slightly safer in some instances.
> 
> There are other kzalloc calls with a multiply, but those
> calls are typically "small fixed #" * sizeof(some pointer)"
> and those are not converted.
> 
> Signed-off-by: Joe Perches <joe@perches.com>
> ---

[...]

>  drivers/net/wireless/wl12xx/wl1271_scan.c |    2 +-

[...]

> diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c
> index fec43ee..30dc100 100644
> --- a/drivers/net/wireless/wl12xx/wl1271_scan.c
> +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c
> @@ -248,7 +248,7 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
> 
>         wl->scan.req = req;
> 
> -       wl->scan.scanned_ch = kzalloc(req->n_channels *
> +       wl->scan.scanned_ch = kcalloc(req->n_channels,
>                                       sizeof(*wl->scan.scanned_ch),
>                                       GFP_KERNEL);
>         wl1271_scan_stm(wl);

For the wl1271 part:

Acked-by: Luciano Coelho <luciano.coelho@nokia.com>

-- 
Cheers,
Luca.

^ permalink raw reply

* [PATCH 1/1] netfilter: xt_condition: add condition target support
From: Luciano Coelho @ 2010-08-12  6:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, kaber, jengelh, sameo, janne.ylalehto
In-Reply-To: <1281595021-24310-1-git-send-email-luciano.coelho@nokia.com>

This patch implements a condition target to the xt_condition module,
which let's the user set netfilter rules that change the variables
used by the condition match.  Originally, the condition match only
allowed the variable to be changed via procfs.  This new target makes
it easy to change the condition value depending on the rules set.

Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
 include/linux/netfilter/xt_condition.h |   13 ++-
 net/netfilter/Kconfig                  |   19 ++--
 net/netfilter/Makefile                 |    2 +-
 net/netfilter/xt_condition.c           |  194 +++++++++++++++++++++++---------
 4 files changed, 165 insertions(+), 63 deletions(-)

diff --git a/include/linux/netfilter/xt_condition.h b/include/linux/netfilter/xt_condition.h
index c4fe899..946d43a 100644
--- a/include/linux/netfilter/xt_condition.h
+++ b/include/linux/netfilter/xt_condition.h
@@ -3,8 +3,10 @@
 
 #include <linux/types.h>
 
+#define XT_CONDITION_MAX_NAME_SIZE 27
+
 struct xt_condition_mtinfo {
-	char name[27];
+	char name[XT_CONDITION_MAX_NAME_SIZE];
 	__u8 invert;
 	__u32 value;
 
@@ -12,4 +14,13 @@ struct xt_condition_mtinfo {
 	void *condvar __attribute__((aligned(8)));
 };
 
+struct condition_tginfo {
+	char name[XT_CONDITION_MAX_NAME_SIZE];
+	__u8 padding;
+	__u32 value;
+
+	/* Used internally by the kernel */
+	void *condvar __attribute__((aligned(8)));
+};
+
 #endif /* _XT_CONDITION_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 5044dd6..d9a17eb 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -310,6 +310,17 @@ config NETFILTER_XT_MARK
 	"Use netfilter MARK value as routing key") and can also be used by
 	other subsystems to change their behavior.
 
+config NETFILTER_XT_CONDITION
+       tristate '"condition" match and target support'
+       depends on NETFILTER_ADVANCED
+       depends on PROC_FS
+       ---help---
+       This option adds the "CONDITION" target and "condition" match.
+
+       It allows you to match rules against condition variables
+       stored in the /proc/net/nf_condition directory. It also allows
+       you to set the variables using the target.
+
 config NETFILTER_XT_CONNMARK
 	tristate 'ctmark target and match support'
 	depends on NF_CONNTRACK
@@ -621,14 +632,6 @@ config NETFILTER_XT_MATCH_COMMENT
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
-config NETFILTER_XT_MATCH_CONDITION
-	tristate '"condition" match support'
-	depends on NETFILTER_ADVANCED
-	depends on PROC_FS
-	---help---
-	This option allows you to match firewall rules against condition
-	variables stored in the /proc/net/nf_condition directory.
-
 config NETFILTER_XT_MATCH_CONNBYTES
 	tristate  '"connbytes" per-connection counter match support'
 	depends on NF_CONNTRACK
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index bbf72bb..146a05f 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 # combos
 obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o
 obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o
+obj-$(CONFIG_NETFILTER_XT_CONDITION) += xt_condition.o
 
 # targets
 obj-$(CONFIG_NETFILTER_XT_TARGET_CHECKSUM) += xt_CHECKSUM.o
@@ -67,7 +68,6 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o
 # matches
 obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_CONDITION) += xt_condition.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
diff --git a/net/netfilter/xt_condition.c b/net/netfilter/xt_condition.c
index cc9ada9..06205aa 100644
--- a/net/netfilter/xt_condition.c
+++ b/net/netfilter/xt_condition.c
@@ -2,15 +2,20 @@
  *	"condition" match extension for Xtables
  *
  *	Description: This module allows firewall rules to match using
- *	condition variables available through procfs.
+ *	condition variables available through procfs.  It also allows
+ *	target rules to set the condition variable.
  *
  *	Authors:
  *	Stephane Ouellette <ouellettes [at] videotron ca>, 2002-10-22
  *	Massimiliano Hofer <max [at] nucleus it>, 2006-05-15
+ *	Luciano Coelho <luciano.coelho@nokia.com>, 2010-08-11
  *
  *	This program is free software; you can redistribute it and/or modify it
  *	under the terms of the GNU General Public License; either version 2
  *	or 3 of the License, as published by the Free Software Foundation.
+ *
+ *	Portion Copyright 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *	File modified on 2010-08-11.
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/kernel.h>
@@ -33,7 +38,8 @@ static unsigned int condition_gid_perms = 0;
 MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
 MODULE_AUTHOR("Massimiliano Hofer <max@nucleus.it>");
 MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
-MODULE_DESCRIPTION("Allows rules to match against condition variables");
+MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
+MODULE_DESCRIPTION("Allows rules to set and match condition variables");
 MODULE_LICENSE("GPL");
 module_param(condition_list_perms, uint, S_IRUSR | S_IWUSR);
 MODULE_PARM_DESC(condition_list_perms, "default permissions on /proc/net/nf_condition/* files");
@@ -104,29 +110,11 @@ static int condition_proc_write(struct file *file, const char __user *input,
 	return length;
 }
 
-static bool
-condition_mt(const struct sk_buff *skb, struct xt_action_param *par)
-{
-	const struct xt_condition_mtinfo *info = par->matchinfo;
-	const struct condition_variable *var   = info->condvar;
-
-	return (var->value == info->value) ^ info->invert;
-}
-
-static int condition_mt_check(const struct xt_mtchk_param *par)
+static struct
+condition_variable *xt_condition_insert(const char *name,
+					struct condition_net *cond_net)
 {
-	struct xt_condition_mtinfo *info = par->matchinfo;
 	struct condition_variable *var;
-	struct condition_net *cond_net = condition_pernet(par->net);
-
-	/* Forbid certain names */
-	if (*info->name == '\0' || *info->name == '.' ||
-	    info->name[sizeof(info->name)-1] != '\0' ||
-	    memchr(info->name, '/', sizeof(info->name)) != NULL) {
-		pr_info("name not allowed or too long: \"%.*s\"\n",
-			(unsigned int)sizeof(info->name), info->name);
-		return -EINVAL;
-	}
 
 	/*
 	 * Let's acquire the lock, check for the condition and add it
@@ -134,29 +122,24 @@ static int condition_mt_check(const struct xt_mtchk_param *par)
 	 */
 	mutex_lock(&proc_lock);
 	list_for_each_entry(var, &cond_net->list, list) {
-		if (strcmp(info->name, var->status_proc->name) == 0) {
+		if (strcmp(name, var->status_proc->name) == 0) {
 			++var->refcount;
-			mutex_unlock(&proc_lock);
-			info->condvar = var;
-			return 0;
+			goto out;
 		}
 	}
 
 	/* At this point, we need to allocate a new condition variable. */
 	var = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
-	if (var == NULL) {
-		mutex_unlock(&proc_lock);
-		return -ENOMEM;
-	}
+	if (var == NULL)
+		goto out;
 
 	/* Create the condition variable's proc file entry. */
-	var->status_proc = create_proc_entry(info->name,
-					     condition_list_perms,
+	var->status_proc = create_proc_entry(name, condition_list_perms,
 					     cond_net->proc_dir);
 	if (var->status_proc == NULL) {
 		kfree(var);
-		mutex_unlock(&proc_lock);
-		return -ENOMEM;
+		var = NULL;
+		goto out;
 	}
 
 	var->refcount = 1;
@@ -167,17 +150,14 @@ static int condition_mt_check(const struct xt_mtchk_param *par)
 	var->status_proc->uid        = condition_uid_perms;
 	var->status_proc->gid        = condition_gid_perms;
 	list_add(&var->list, &cond_net->list);
+out:
 	mutex_unlock(&proc_lock);
-	info->condvar = var;
-	return 0;
+	return var;
 }
 
-static void condition_mt_destroy(const struct xt_mtdtor_param *par)
+static void xt_condition_put(struct condition_variable *var,
+			     struct condition_net *cond_net)
 {
-	const struct xt_condition_mtinfo *info = par->matchinfo;
-	struct condition_variable *var = info->condvar;
-	struct condition_net *cond_net = condition_pernet(par->net);
-
 	mutex_lock(&proc_lock);
 	if (--var->refcount == 0) {
 		list_del(&var->list);
@@ -192,6 +172,106 @@ static void condition_mt_destroy(const struct xt_mtdtor_param *par)
 	mutex_unlock(&proc_lock);
 }
 
+static bool
+condition_mt(const struct sk_buff *skb, struct xt_action_param *par)
+{
+	const struct xt_condition_mtinfo *info = par->matchinfo;
+	const struct condition_variable *var   = info->condvar;
+
+	return (var->value == info->value) ^ info->invert;
+}
+
+static int condition_mt_check(const struct xt_mtchk_param *par)
+{
+	struct xt_condition_mtinfo *info = par->matchinfo;
+	struct condition_variable *var;
+	struct condition_net *cond_net = condition_pernet(par->net);
+
+	/* Forbid certain names */
+	if (*info->name == '\0' || *info->name == '.' ||
+	    info->name[sizeof(info->name)-1] != '\0' ||
+	    memchr(info->name, '/', sizeof(info->name)) != NULL) {
+		pr_info("name not allowed or too long: \"%.*s\"\n",
+			(unsigned int)sizeof(info->name), info->name);
+		return -EINVAL;
+	}
+
+	var = xt_condition_insert(info->name, cond_net);
+	if (var == NULL)
+		return -ENOMEM;
+
+	info->condvar = var;
+	return 0;
+}
+
+static void condition_mt_destroy(const struct xt_mtdtor_param *par)
+{
+	const struct xt_condition_mtinfo *info = par->matchinfo;
+	struct condition_net *cond_net = condition_pernet(par->net);
+
+	xt_condition_put(info->condvar, cond_net);
+}
+
+static unsigned int condition_tg_target(struct sk_buff *skb,
+					const struct xt_action_param *par)
+{
+	const struct condition_tginfo *info = par->targinfo;
+	struct condition_variable *var = info->condvar;
+
+	pr_debug("setting condition %s, value %d\n",
+		 info->name, info->value);
+
+	var->value = info->value;
+
+	return XT_CONTINUE;
+}
+
+static int condition_tg_checkentry(const struct xt_tgchk_param *par)
+{
+	struct condition_tginfo *info = par->targinfo;
+	struct condition_variable *var;
+	struct condition_net *cond_net = condition_pernet(par->net);
+
+	pr_debug("checkentry %s\n", info->name);
+
+	/* Forbid certain names */
+	if (*info->name == '\0' || *info->name == '.' ||
+	    info->name[sizeof(info->name)-1] != '\0' ||
+	    memchr(info->name, '/', sizeof(info->name)) != NULL) {
+		pr_info("name not allowed or too long: \"%.*s\"\n",
+			(unsigned int)sizeof(info->name), info->name);
+		return -EINVAL;
+	}
+
+	var = xt_condition_insert(info->name, cond_net);
+	if (var == NULL)
+		return -ENOMEM;
+
+	info->condvar = var;
+	return 0;
+}
+
+static void condition_tg_destroy(const struct xt_tgdtor_param *par)
+{
+	const struct condition_tginfo *info = par->targinfo;
+	struct condition_net *cond_net = condition_pernet(par->net);
+
+	pr_debug("destroy %s\n", info->name);
+
+	xt_condition_put(info->condvar, cond_net);
+}
+
+static struct xt_target condition_tg_reg __read_mostly = {
+	.name           = "CONDITION",
+	.revision       = 0,
+	.family         = NFPROTO_UNSPEC,
+	.target         = condition_tg_target,
+	.targetsize     = sizeof(struct condition_tginfo),
+	.checkentry     = condition_tg_checkentry,
+	.destroy        = condition_tg_destroy,
+	.me             = THIS_MODULE,
+};
+
 static struct xt_match condition_mt_reg __read_mostly = {
 	.name       = "condition",
 	.revision   = 2,
@@ -205,7 +285,7 @@ static struct xt_match condition_mt_reg __read_mostly = {
 
 static const char *const dir_name = "nf_condition";
 
-static int __net_init condnet_mt_init(struct net *net)
+static int __net_init condnet_init(struct net *net)
 {
 	struct condition_net *cond_net = condition_pernet(net);
 
@@ -216,7 +296,7 @@ static int __net_init condnet_mt_init(struct net *net)
 	return (cond_net->proc_dir == NULL) ? -EACCES : 0;
 }
 
-static void __net_exit condnet_mt_exit(struct net *net)
+static void __net_exit condnet_exit(struct net *net)
 {
 	struct condition_net *cond_net = condition_pernet(net);
 	struct condition_variable *var, *tmp;
@@ -234,14 +314,14 @@ static void __net_exit condnet_mt_exit(struct net *net)
 	remove_proc_entry(dir_name, net->proc_net);
 }
 
-static struct pernet_operations condition_mt_netops = {
-	.init = condnet_mt_init,
-	.exit = condnet_mt_exit,
+static struct pernet_operations condition_netops = {
+	.init = condnet_init,
+	.exit = condnet_exit,
 	.id   = &condition_net_id,
 	.size = sizeof(struct condition_net),
 };
 
-static int __init condition_mt_init(void)
+static int __init condition_init(void)
 {
 	int ret;
 
@@ -250,8 +330,15 @@ static int __init condition_mt_init(void)
 	if (ret < 0)
 		return ret;
 
-	ret = register_pernet_subsys(&condition_mt_netops);
+	ret =  xt_register_target(&condition_tg_reg);
+	if (ret < 0) {
+		xt_unregister_match(&condition_mt_reg);
+		return ret;
+	}
+
+	ret = register_pernet_subsys(&condition_netops);
 	if (ret < 0) {
+		xt_unregister_target(&condition_tg_reg);
 		xt_unregister_match(&condition_mt_reg);
 		return ret;
 	}
@@ -259,11 +346,12 @@ static int __init condition_mt_init(void)
 	return 0;
 }
 
-static void __exit condition_mt_exit(void)
+static void __exit condition_exit(void)
 {
-	unregister_pernet_subsys(&condition_mt_netops);
+	unregister_pernet_subsys(&condition_netops);
 	xt_unregister_match(&condition_mt_reg);
+	xt_unregister_target(&condition_tg_reg);
 }
 
-module_init(condition_mt_init);
-module_exit(condition_mt_exit);
+module_init(condition_init);
+module_exit(condition_exit);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 0/1] netfilter: xt_condition: add condition target
From: Luciano Coelho @ 2010-08-12  6:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: netdev, kaber, jengelh, sameo, janne.ylalehto

Hello,

So here's my patch to include the condition target in the existing condition
module.  This patch is supposed to be applied on top of the previous
xt_condition patches I submitted and is intended for 2.6.37 (I'll resend all
the 3 patches when the next tree starts accepting patches again).

One thing that came to my mind was whether it would make sense to rename this
match/target combo to "variable" instead of "condition".  To me it makes more
sense to call it variable than condition, since I have changed the value from
boolean to u32.  On the other hand, it could become very confusing because it
used to be called condition in its xtables-addons days...

Your comments are appreciated!

Cheers,
Luca.

Luciano Coelho (1):
  netfilter: xt_condition: add condition target support

 include/linux/netfilter/xt_condition.h |   13 ++-
 net/netfilter/Kconfig                  |   19 ++--
 net/netfilter/Makefile                 |    2 +-
 net/netfilter/xt_condition.c           |  194 +++++++++++++++++++++++---------
 4 files changed, 165 insertions(+), 63 deletions(-)


^ permalink raw reply

* RE: [MeeGo-Dev][PATCH] Topcliff: Update PCH_CAN driver to 2.6.35
From: Wang, Qi @ 2010-08-12  6:29 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: Greg KH, Daniel Baluta, Masayuki Ohtak, meego-dev@meego.com,
	Wolfgang Grandegger, socketcan-core@lists.berlios.de,
	netdev@vger.kernel.org, Khor, Andrew Chih Howe,
	arjan@linux.intel.com, Wang, Yong Y
In-Reply-To: <4C6393F0.5090005@hartkopp.net>

> -----Original Message-----
> From: Oliver Hartkopp [mailto:socketcan@hartkopp.net]
> Sent: Thursday, August 12, 2010 2:26 PM
> To: Wang, Qi
> Cc: Greg KH; Daniel Baluta; Masayuki Ohtak; meego-dev@meego.com;
> Wolfgang Grandegger; socketcan-core@lists.berlios.de;
> netdev@vger.kernel.org; Khor, Andrew Chih Howe; arjan@linux.intel.com;
> Wang, Yong Y
> Subject: Re: [MeeGo-Dev][PATCH] Topcliff: Update PCH_CAN driver to 2.6.35
> 
> On 12.08.2010 04:04, Greg KH wrote:
> > On Thu, Aug 12, 2010 at 09:42:27AM +0800, Wang, Qi wrote:
> 
> >>> 2. Why don't you use kernel existing kfifo infrastructure? ([2]).
> >> Just take a look at kfifo.h. This structure has been changed. I
> >> remembered there was a spin_lock from kfifo previously. Currently it's
> >> been removed, good.
> >> OKI-sans, would you please take a look at ./include/linux/kfifo.h, and try to
> use this structure and APIs?
> >>
> >> Daniel,
> >>
> >> We're anxious to integrate those codes now. Perhaps it'll take us
> >> quite a long time to use kfifo. How about implementing it with the
> >> next version?
> >
> > What do you mean by this?  Code isn't merged into the tree unless it is
> > correct.  Please fix this now, it's not that big of a deal.
> >
> 
> Hello Qi,
> 
> i generally wonder what this FIFO is used for??
> 
> For me it looks like a artifact from a former chardev implementation, as
> several other code sniplets do (see comments from Wolfgang and Marc).
> 
> The network driver model is used for CAN drivers and therefore all the
> infrastructure for queueing inbound and outbound network traffic should be
> used from the Kernel like all other CAN drivers and all other ethernet drivers
> do.
> 
> Additionally there is a powerful infrastructure to support the special
> functions of CAN netdevices (like setting of bittimings, listen-only modes, or
> to produce CAN driver states etc.), that's part of the CAN drivers in
> drivers/net/can/ since it has gone mainline.
> 
> CAN netdevices are intentionally dumb (like the original ethernet adapters).
> This allows a simple driver interface between the kernel and the hardware
> driver, e.g. for queueing CAN frames. CAN drivers don't use any hardware
> rx-filtering(!) due to multiuser requirements and it's a vital requirement
> that the frames are not re-ordered on sending (by the 'some magic' CAN
> controller dealing with CAN-ID priorities, e.g. see tx-path in the MSCAN driver).
> 
> From my perspective about 70% of your code is obsolete, as you implemented
> tricky details (like FIFOs, bittiming tables or magic filter handlings),
> that's not needed at all.
> 
> Please take a look at the SJA1000 driver (for a low complex CAN controller) or
> at the TI driver (for a higher complex CAN controller) how these drivers
> handle the specialties of each hardware. And read some documentation in
> Documentation/networking/can.txt to get an impression about the concepts of
> the CAN implementation in the Linux Kernel and the CAN netdevices.
> 
> I strongly assume that your driver would be about 30 kBytes of code fitting
> into a single c-file like the ti_hecc.c does. And that's definitely easier for
> us to review and easier for you to maintain in the future ...
> 
> Thanks & best regards,
> Oliver
Thank you for your commits.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox