diff options
| author | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-02-14 20:11:24 +0000 | 
|---|---|---|
| committer | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-02-14 20:11:24 +0000 | 
| commit | ca06b03a8ef726f5efb891eeaf4aefd71670acb1 (patch) | |
| tree | bddaf99e86c03d13c6df8e48e4fda579b336e26e | |
| parent | 12ee6100a29f4010af2e5797826abc95a4732f43 (diff) | |
linux-atm: update solos-pci driver to upstream
Fixes for the solos-pci driver.
- Corrects calculation of headroom for padding.
- Removes pointless debug messages.
- Expose Bis A and Bis M annex capabilities.
- Expose hardware revision.
Signed-off-by: Philip Prindeville <philipp_subx@redfish-solutions.com>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30541 3c298f89-4303-0410-b956-a3cf2f4a3e73
3 files changed, 1044 insertions, 0 deletions
| diff --git a/target/linux/generic/patches-2.6.39/050-linux-atm_nathan.patch b/target/linux/generic/patches-2.6.39/050-linux-atm_nathan.patch new file mode 100644 index 000000000..19e22d566 --- /dev/null +++ b/target/linux/generic/patches-2.6.39/050-linux-atm_nathan.patch @@ -0,0 +1,348 @@ +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:43:30 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 1/4] atm: solos-pci: Add AnnexA/M +	capability attributes + +BisACapability and BisMCapability allow users to +force either Annex A or Annex M. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-attrlist.c |    2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c +index 9a676ee..8092533 100644 +--- a/drivers/atm/solos-attrlist.c ++++ b/drivers/atm/solos-attrlist.c +@@ -71,6 +71,8 @@ SOLOS_ATTR_RW(BisAForceSNRMarginDn) + SOLOS_ATTR_RW(BisMForceSNRMarginDn) + SOLOS_ATTR_RW(BisAMaxMargin) + SOLOS_ATTR_RW(BisMMaxMargin) ++SOLOS_ATTR_RW(BisACapability) ++SOLOS_ATTR_RW(BisMCapability) + SOLOS_ATTR_RW(AnnexAForceSNRMarginDn) + SOLOS_ATTR_RW(AnnexAMaxMargin) + SOLOS_ATTR_RW(AnnexMMaxMargin) + +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:44:17 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 2/4] atm: solos-pci: Remove annoying +	line of debugging + +"len: %d" isn't particularly useful for anyone and confuses users. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |    1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 5d1d076..bd01aa3 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -452,7 +452,6 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, +  + 	len = skb->len; + 	memcpy(buf, skb->data, len); +-	dev_dbg(&card->dev->dev, "len: %d\n", len); +  + 	kfree_skb(skb); + 	return len; +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:45:15 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 3/4] atm: solos-pci: Add support for +	Geos GPIO pins + +Geos ADSL2+ routers have on-board Solos chipsets with some +extra I/O pins and a push button connected to the FPGA. + +PCB version and variant numbers are also made available +through the HardwareVersion and HardwareVariant attributes. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 98 insertions(+), 0 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index bd01aa3..33c0c2b 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -56,6 +56,7 @@ + #define FLASH_BUSY	0x60 + #define FPGA_MODE	0x5C + #define FLASH_MODE	0x58 ++#define GPIO_STATUS	0x54 + #define TX_DMA_ADDR(port)	(0x40 + (4 * (port))) + #define RX_DMA_ADDR(port)	(0x30 + (4 * (port))) +  +@@ -498,6 +499,87 @@ static ssize_t console_store(struct device *dev, struct device_attribute *attr, + 	return err?:count; + } +  ++struct geos_gpio { ++	char *name; ++	int offset; ++}; ++ ++static struct geos_gpio geos_gpio_pins[] = { ++	{"GPIO1", 9}, ++	{"GPIO2", 10}, ++	{"GPIO3", 11}, ++	{"GPIO4", 12}, ++	{"GPIO5", 13}, ++	{"PushButton", 14}, ++	{NULL, 0} ++}; ++ ++static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr, ++			       const char *buf, size_t count) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	struct geos_gpio *p = geos_gpio_pins; ++	while(p->name){ ++		if(!strcmp(attr->attr.name, p->name)){ ++			break; ++		} ++		p++; ++	} ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	if(buf[0] == '1'){ ++		data32 |= 1 << p->offset; ++		iowrite32(data32, card->config_regs + GPIO_STATUS); ++	} else if(buf[0] == '0') { ++		data32 &= ~(1 << p->offset); ++		iowrite32(data32, card->config_regs + GPIO_STATUS); ++	} ++	return count; ++} ++ ++static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr, ++			      char *buf) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	struct geos_gpio *p = geos_gpio_pins; ++	while(p->name){ ++		if(!strcmp(attr->attr.name, p->name)){ ++			break; ++		} ++		p++; ++	} ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	data32 = (data32 >> p->offset) & 1; ++ ++	return sprintf(buf, "%d\n", data32); ++} ++ ++static ssize_t hardware_show(struct device *dev, struct device_attribute *attr, ++			     char *buf) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	if(!strcmp(attr->attr.name, "HardwareVersion")){ ++		data32 = data32 & 0x1F; ++		return sprintf(buf, "%d\n", data32); ++	} else if(!strcmp(attr->attr.name, "HardwareVariant")){ ++		data32 = (data32 >> 5) & 0x0F; ++		return sprintf(buf, "%d\n", data32); ++	} ++ ++	return sprintf(buf, "Error\n"); ++} ++ + static DEVICE_ATTR(console, 0644, console_show, console_store); +  +  +@@ -506,6 +588,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store); +  + #include "solos-attrlist.c" +  ++static DEVICE_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(PushButton, 0444, geos_gpio_show, NULL); ++static DEVICE_ATTR(HardwareVersion, 0444, hardware_show, NULL); ++static DEVICE_ATTR(HardwareVariant, 0444, hardware_show, NULL); + #undef SOLOS_ATTR_RO + #undef SOLOS_ATTR_RW +  +@@ -514,6 +604,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store); +  + static struct attribute *solos_attrs[] = { + #include "solos-attrlist.c" ++	&dev_attr_GPIO1.attr, ++	&dev_attr_GPIO2.attr, ++	&dev_attr_GPIO3.attr, ++	&dev_attr_GPIO4.attr, ++	&dev_attr_GPIO5.attr, ++	&dev_attr_PushButton.attr, ++	&dev_attr_HardwareVersion.attr, ++	&dev_attr_HardwareVariant.attr, + 	NULL + }; +  +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:46:08 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 4/4] atm: solos-pci: M25P/M25PE SPI +	flash support + +Newer Geos ADSL2+ routers have different SPI flash. +The FPGA on these boards require driver version = 1 to enable +flash upgrades so old drivers can't corrupt new boards. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |   51 ++++++++++++++++++++++++++++++++++++---------- + 1 files changed, 40 insertions(+), 11 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 33c0c2b..2a75bf7 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -42,7 +42,8 @@ + #include <linux/swab.h> + #include <linux/slab.h> +  +-#define VERSION "0.07" ++#define VERSION "1.0" ++#define DRIVER_VERSION 0x01 + #define PTAG "solos-pci" +  + #define CONFIG_RAM_SIZE	128 +@@ -57,16 +58,20 @@ + #define FPGA_MODE	0x5C + #define FLASH_MODE	0x58 + #define GPIO_STATUS	0x54 ++#define DRIVER_VER	0x50 + #define TX_DMA_ADDR(port)	(0x40 + (4 * (port))) + #define RX_DMA_ADDR(port)	(0x30 + (4 * (port))) +  + #define DATA_RAM_SIZE	32768 + #define BUF_SIZE	2048 + #define OLD_BUF_SIZE	4096 /* For FPGA versions <= 2*/ +-#define FPGA_PAGE	528 /* FPGA flash page size*/ +-#define SOLOS_PAGE	512 /* Solos flash page size*/ +-#define FPGA_BLOCK	(FPGA_PAGE * 8) /* FPGA flash block size*/ +-#define SOLOS_BLOCK	(SOLOS_PAGE * 8) /* Solos flash block size*/ ++/* Old boards use ATMEL AD45DB161D flash */ ++#define ATMEL_FPGA_PAGE	528 /* FPGA flash page size*/ ++#define ATMEL_SOLOS_PAGE	512 /* Solos flash page size*/ ++#define ATMEL_FPGA_BLOCK	(ATMEL_FPGA_PAGE * 8) /* FPGA block size*/ ++#define ATMEL_SOLOS_BLOCK	(ATMEL_SOLOS_PAGE * 8) /* Solos block size*/ ++/* Current boards use M25P/M25PE SPI flash */ ++#define SPI_FLASH_BLOCK	(256 * 64) +  + #define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2) + #define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size)) +@@ -128,6 +133,7 @@ struct solos_card { + 	int using_dma; + 	int fpga_version; + 	int buffer_size; ++	int atmel_flash; + }; +  +  +@@ -631,16 +637,25 @@ static int flash_upgrade(struct solos_card *card, int chip) + 	switch (chip) { + 	case 0: + 		fw_name = "solos-FPGA.bin"; +-		blocksize = FPGA_BLOCK; ++		if (card->atmel_flash) ++			blocksize = ATMEL_FPGA_BLOCK; ++		else ++			blocksize = SPI_FLASH_BLOCK; + 		break; + 	case 1: + 		fw_name = "solos-Firmware.bin"; +-		blocksize = SOLOS_BLOCK; ++		if (card->atmel_flash) ++			blocksize = ATMEL_SOLOS_BLOCK; ++		else ++			blocksize = SPI_FLASH_BLOCK; + 		break; + 	case 2: + 		if (card->fpga_version > LEGACY_BUFFERS){ + 			fw_name = "solos-db-FPGA.bin"; +-			blocksize = FPGA_BLOCK; ++			if (card->atmel_flash) ++				blocksize = ATMEL_FPGA_BLOCK; ++			else ++				blocksize = SPI_FLASH_BLOCK; + 		} else { + 			dev_info(&card->dev->dev, "FPGA version doesn't support" + 					" daughter board upgrades\n"); +@@ -650,7 +665,10 @@ static int flash_upgrade(struct solos_card *card, int chip) + 	case 3: + 		if (card->fpga_version > LEGACY_BUFFERS){ + 			fw_name = "solos-Firmware.bin"; +-			blocksize = SOLOS_BLOCK; ++			if (card->atmel_flash) ++				blocksize = ATMEL_SOLOS_BLOCK; ++			else ++				blocksize = SPI_FLASH_BLOCK; + 		} else { + 			dev_info(&card->dev->dev, "FPGA version doesn't support" + 					" daughter board upgrades\n"); +@@ -695,9 +713,13 @@ static int flash_upgrade(struct solos_card *card, int chip) + 		/* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */ + 		iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE); +  +-		/* Copy block to buffer, swapping each 16 bits */ ++		/* Copy block to buffer, swapping each 16 bits for Atmel flash */ + 		for(i = 0; i < blocksize; i += 4) { +-			uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i)); ++			uint32_t word; ++			if (card->atmel_flash) ++				word = swahb32p((uint32_t *)(fw->data + offset + i)); ++			else ++				word = *(uint32_t *)(fw->data + offset + i); + 			if(card->fpga_version > LEGACY_BUFFERS) + 				iowrite32(word, FLASH_BUF + i); + 			else +@@ -1249,6 +1271,11 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + 		db_fpga_upgrade = db_firmware_upgrade = 0; + 	} +  ++	/* Stopped using Atmel flash after 0.03-38 */ ++	if (fpga_ver < 39) ++		card->atmel_flash = 1; ++	else ++		card->atmel_flash = 0; + 	if (card->fpga_version >= DMA_SUPPORTED){ + 		card->using_dma = 1; + 	} else { +@@ -1256,6 +1283,8 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + 		/* Set RX empty flag for all ports */ + 		iowrite32(0xF0, card->config_regs + FLAGS_ADDR); + 	} ++	/* New FPGAs require driver version before permitting flash upgrades */ ++	iowrite32(DRIVER_VERSION, card->config_regs + DRIVER_VER); +  + 	data32 = ioread32(card->config_regs + PORTS); + 	card->nr_ports = (data32 & 0x000000FF); diff --git a/target/linux/generic/patches-3.0/050-linux-atm_nathan.patch b/target/linux/generic/patches-3.0/050-linux-atm_nathan.patch new file mode 100644 index 000000000..19e22d566 --- /dev/null +++ b/target/linux/generic/patches-3.0/050-linux-atm_nathan.patch @@ -0,0 +1,348 @@ +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:43:30 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 1/4] atm: solos-pci: Add AnnexA/M +	capability attributes + +BisACapability and BisMCapability allow users to +force either Annex A or Annex M. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-attrlist.c |    2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c +index 9a676ee..8092533 100644 +--- a/drivers/atm/solos-attrlist.c ++++ b/drivers/atm/solos-attrlist.c +@@ -71,6 +71,8 @@ SOLOS_ATTR_RW(BisAForceSNRMarginDn) + SOLOS_ATTR_RW(BisMForceSNRMarginDn) + SOLOS_ATTR_RW(BisAMaxMargin) + SOLOS_ATTR_RW(BisMMaxMargin) ++SOLOS_ATTR_RW(BisACapability) ++SOLOS_ATTR_RW(BisMCapability) + SOLOS_ATTR_RW(AnnexAForceSNRMarginDn) + SOLOS_ATTR_RW(AnnexAMaxMargin) + SOLOS_ATTR_RW(AnnexMMaxMargin) + +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:44:17 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 2/4] atm: solos-pci: Remove annoying +	line of debugging + +"len: %d" isn't particularly useful for anyone and confuses users. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |    1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 5d1d076..bd01aa3 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -452,7 +452,6 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, +  + 	len = skb->len; + 	memcpy(buf, skb->data, len); +-	dev_dbg(&card->dev->dev, "len: %d\n", len); +  + 	kfree_skb(skb); + 	return len; +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:45:15 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 3/4] atm: solos-pci: Add support for +	Geos GPIO pins + +Geos ADSL2+ routers have on-board Solos chipsets with some +extra I/O pins and a push button connected to the FPGA. + +PCB version and variant numbers are also made available +through the HardwareVersion and HardwareVariant attributes. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 98 insertions(+), 0 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index bd01aa3..33c0c2b 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -56,6 +56,7 @@ + #define FLASH_BUSY	0x60 + #define FPGA_MODE	0x5C + #define FLASH_MODE	0x58 ++#define GPIO_STATUS	0x54 + #define TX_DMA_ADDR(port)	(0x40 + (4 * (port))) + #define RX_DMA_ADDR(port)	(0x30 + (4 * (port))) +  +@@ -498,6 +499,87 @@ static ssize_t console_store(struct device *dev, struct device_attribute *attr, + 	return err?:count; + } +  ++struct geos_gpio { ++	char *name; ++	int offset; ++}; ++ ++static struct geos_gpio geos_gpio_pins[] = { ++	{"GPIO1", 9}, ++	{"GPIO2", 10}, ++	{"GPIO3", 11}, ++	{"GPIO4", 12}, ++	{"GPIO5", 13}, ++	{"PushButton", 14}, ++	{NULL, 0} ++}; ++ ++static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr, ++			       const char *buf, size_t count) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	struct geos_gpio *p = geos_gpio_pins; ++	while(p->name){ ++		if(!strcmp(attr->attr.name, p->name)){ ++			break; ++		} ++		p++; ++	} ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	if(buf[0] == '1'){ ++		data32 |= 1 << p->offset; ++		iowrite32(data32, card->config_regs + GPIO_STATUS); ++	} else if(buf[0] == '0') { ++		data32 &= ~(1 << p->offset); ++		iowrite32(data32, card->config_regs + GPIO_STATUS); ++	} ++	return count; ++} ++ ++static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr, ++			      char *buf) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	struct geos_gpio *p = geos_gpio_pins; ++	while(p->name){ ++		if(!strcmp(attr->attr.name, p->name)){ ++			break; ++		} ++		p++; ++	} ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	data32 = (data32 >> p->offset) & 1; ++ ++	return sprintf(buf, "%d\n", data32); ++} ++ ++static ssize_t hardware_show(struct device *dev, struct device_attribute *attr, ++			     char *buf) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	if(!strcmp(attr->attr.name, "HardwareVersion")){ ++		data32 = data32 & 0x1F; ++		return sprintf(buf, "%d\n", data32); ++	} else if(!strcmp(attr->attr.name, "HardwareVariant")){ ++		data32 = (data32 >> 5) & 0x0F; ++		return sprintf(buf, "%d\n", data32); ++	} ++ ++	return sprintf(buf, "Error\n"); ++} ++ + static DEVICE_ATTR(console, 0644, console_show, console_store); +  +  +@@ -506,6 +588,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store); +  + #include "solos-attrlist.c" +  ++static DEVICE_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(PushButton, 0444, geos_gpio_show, NULL); ++static DEVICE_ATTR(HardwareVersion, 0444, hardware_show, NULL); ++static DEVICE_ATTR(HardwareVariant, 0444, hardware_show, NULL); + #undef SOLOS_ATTR_RO + #undef SOLOS_ATTR_RW +  +@@ -514,6 +604,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store); +  + static struct attribute *solos_attrs[] = { + #include "solos-attrlist.c" ++	&dev_attr_GPIO1.attr, ++	&dev_attr_GPIO2.attr, ++	&dev_attr_GPIO3.attr, ++	&dev_attr_GPIO4.attr, ++	&dev_attr_GPIO5.attr, ++	&dev_attr_PushButton.attr, ++	&dev_attr_HardwareVersion.attr, ++	&dev_attr_HardwareVariant.attr, + 	NULL + }; +  +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:46:08 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 4/4] atm: solos-pci: M25P/M25PE SPI +	flash support + +Newer Geos ADSL2+ routers have different SPI flash. +The FPGA on these boards require driver version = 1 to enable +flash upgrades so old drivers can't corrupt new boards. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |   51 ++++++++++++++++++++++++++++++++++++---------- + 1 files changed, 40 insertions(+), 11 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 33c0c2b..2a75bf7 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -42,7 +42,8 @@ + #include <linux/swab.h> + #include <linux/slab.h> +  +-#define VERSION "0.07" ++#define VERSION "1.0" ++#define DRIVER_VERSION 0x01 + #define PTAG "solos-pci" +  + #define CONFIG_RAM_SIZE	128 +@@ -57,16 +58,20 @@ + #define FPGA_MODE	0x5C + #define FLASH_MODE	0x58 + #define GPIO_STATUS	0x54 ++#define DRIVER_VER	0x50 + #define TX_DMA_ADDR(port)	(0x40 + (4 * (port))) + #define RX_DMA_ADDR(port)	(0x30 + (4 * (port))) +  + #define DATA_RAM_SIZE	32768 + #define BUF_SIZE	2048 + #define OLD_BUF_SIZE	4096 /* For FPGA versions <= 2*/ +-#define FPGA_PAGE	528 /* FPGA flash page size*/ +-#define SOLOS_PAGE	512 /* Solos flash page size*/ +-#define FPGA_BLOCK	(FPGA_PAGE * 8) /* FPGA flash block size*/ +-#define SOLOS_BLOCK	(SOLOS_PAGE * 8) /* Solos flash block size*/ ++/* Old boards use ATMEL AD45DB161D flash */ ++#define ATMEL_FPGA_PAGE	528 /* FPGA flash page size*/ ++#define ATMEL_SOLOS_PAGE	512 /* Solos flash page size*/ ++#define ATMEL_FPGA_BLOCK	(ATMEL_FPGA_PAGE * 8) /* FPGA block size*/ ++#define ATMEL_SOLOS_BLOCK	(ATMEL_SOLOS_PAGE * 8) /* Solos block size*/ ++/* Current boards use M25P/M25PE SPI flash */ ++#define SPI_FLASH_BLOCK	(256 * 64) +  + #define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2) + #define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size)) +@@ -128,6 +133,7 @@ struct solos_card { + 	int using_dma; + 	int fpga_version; + 	int buffer_size; ++	int atmel_flash; + }; +  +  +@@ -631,16 +637,25 @@ static int flash_upgrade(struct solos_card *card, int chip) + 	switch (chip) { + 	case 0: + 		fw_name = "solos-FPGA.bin"; +-		blocksize = FPGA_BLOCK; ++		if (card->atmel_flash) ++			blocksize = ATMEL_FPGA_BLOCK; ++		else ++			blocksize = SPI_FLASH_BLOCK; + 		break; + 	case 1: + 		fw_name = "solos-Firmware.bin"; +-		blocksize = SOLOS_BLOCK; ++		if (card->atmel_flash) ++			blocksize = ATMEL_SOLOS_BLOCK; ++		else ++			blocksize = SPI_FLASH_BLOCK; + 		break; + 	case 2: + 		if (card->fpga_version > LEGACY_BUFFERS){ + 			fw_name = "solos-db-FPGA.bin"; +-			blocksize = FPGA_BLOCK; ++			if (card->atmel_flash) ++				blocksize = ATMEL_FPGA_BLOCK; ++			else ++				blocksize = SPI_FLASH_BLOCK; + 		} else { + 			dev_info(&card->dev->dev, "FPGA version doesn't support" + 					" daughter board upgrades\n"); +@@ -650,7 +665,10 @@ static int flash_upgrade(struct solos_card *card, int chip) + 	case 3: + 		if (card->fpga_version > LEGACY_BUFFERS){ + 			fw_name = "solos-Firmware.bin"; +-			blocksize = SOLOS_BLOCK; ++			if (card->atmel_flash) ++				blocksize = ATMEL_SOLOS_BLOCK; ++			else ++				blocksize = SPI_FLASH_BLOCK; + 		} else { + 			dev_info(&card->dev->dev, "FPGA version doesn't support" + 					" daughter board upgrades\n"); +@@ -695,9 +713,13 @@ static int flash_upgrade(struct solos_card *card, int chip) + 		/* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */ + 		iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE); +  +-		/* Copy block to buffer, swapping each 16 bits */ ++		/* Copy block to buffer, swapping each 16 bits for Atmel flash */ + 		for(i = 0; i < blocksize; i += 4) { +-			uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i)); ++			uint32_t word; ++			if (card->atmel_flash) ++				word = swahb32p((uint32_t *)(fw->data + offset + i)); ++			else ++				word = *(uint32_t *)(fw->data + offset + i); + 			if(card->fpga_version > LEGACY_BUFFERS) + 				iowrite32(word, FLASH_BUF + i); + 			else +@@ -1249,6 +1271,11 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + 		db_fpga_upgrade = db_firmware_upgrade = 0; + 	} +  ++	/* Stopped using Atmel flash after 0.03-38 */ ++	if (fpga_ver < 39) ++		card->atmel_flash = 1; ++	else ++		card->atmel_flash = 0; + 	if (card->fpga_version >= DMA_SUPPORTED){ + 		card->using_dma = 1; + 	} else { +@@ -1256,6 +1283,8 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + 		/* Set RX empty flag for all ports */ + 		iowrite32(0xF0, card->config_regs + FLAGS_ADDR); + 	} ++	/* New FPGAs require driver version before permitting flash upgrades */ ++	iowrite32(DRIVER_VERSION, card->config_regs + DRIVER_VER); +  + 	data32 = ioread32(card->config_regs + PORTS); + 	card->nr_ports = (data32 & 0x000000FF); diff --git a/target/linux/generic/patches-3.1/050-linux-atm_nathan.patch b/target/linux/generic/patches-3.1/050-linux-atm_nathan.patch new file mode 100644 index 000000000..19e22d566 --- /dev/null +++ b/target/linux/generic/patches-3.1/050-linux-atm_nathan.patch @@ -0,0 +1,348 @@ +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:43:30 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 1/4] atm: solos-pci: Add AnnexA/M +	capability attributes + +BisACapability and BisMCapability allow users to +force either Annex A or Annex M. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-attrlist.c |    2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c +index 9a676ee..8092533 100644 +--- a/drivers/atm/solos-attrlist.c ++++ b/drivers/atm/solos-attrlist.c +@@ -71,6 +71,8 @@ SOLOS_ATTR_RW(BisAForceSNRMarginDn) + SOLOS_ATTR_RW(BisMForceSNRMarginDn) + SOLOS_ATTR_RW(BisAMaxMargin) + SOLOS_ATTR_RW(BisMMaxMargin) ++SOLOS_ATTR_RW(BisACapability) ++SOLOS_ATTR_RW(BisMCapability) + SOLOS_ATTR_RW(AnnexAForceSNRMarginDn) + SOLOS_ATTR_RW(AnnexAMaxMargin) + SOLOS_ATTR_RW(AnnexMMaxMargin) + +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:44:17 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 2/4] atm: solos-pci: Remove annoying +	line of debugging + +"len: %d" isn't particularly useful for anyone and confuses users. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |    1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 5d1d076..bd01aa3 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -452,7 +452,6 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, +  + 	len = skb->len; + 	memcpy(buf, skb->data, len); +-	dev_dbg(&card->dev->dev, "len: %d\n", len); +  + 	kfree_skb(skb); + 	return len; +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:45:15 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 3/4] atm: solos-pci: Add support for +	Geos GPIO pins + +Geos ADSL2+ routers have on-board Solos chipsets with some +extra I/O pins and a push button connected to the FPGA. + +PCB version and variant numbers are also made available +through the HardwareVersion and HardwareVariant attributes. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 98 insertions(+), 0 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index bd01aa3..33c0c2b 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -56,6 +56,7 @@ + #define FLASH_BUSY	0x60 + #define FPGA_MODE	0x5C + #define FLASH_MODE	0x58 ++#define GPIO_STATUS	0x54 + #define TX_DMA_ADDR(port)	(0x40 + (4 * (port))) + #define RX_DMA_ADDR(port)	(0x30 + (4 * (port))) +  +@@ -498,6 +499,87 @@ static ssize_t console_store(struct device *dev, struct device_attribute *attr, + 	return err?:count; + } +  ++struct geos_gpio { ++	char *name; ++	int offset; ++}; ++ ++static struct geos_gpio geos_gpio_pins[] = { ++	{"GPIO1", 9}, ++	{"GPIO2", 10}, ++	{"GPIO3", 11}, ++	{"GPIO4", 12}, ++	{"GPIO5", 13}, ++	{"PushButton", 14}, ++	{NULL, 0} ++}; ++ ++static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr, ++			       const char *buf, size_t count) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	struct geos_gpio *p = geos_gpio_pins; ++	while(p->name){ ++		if(!strcmp(attr->attr.name, p->name)){ ++			break; ++		} ++		p++; ++	} ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	if(buf[0] == '1'){ ++		data32 |= 1 << p->offset; ++		iowrite32(data32, card->config_regs + GPIO_STATUS); ++	} else if(buf[0] == '0') { ++		data32 &= ~(1 << p->offset); ++		iowrite32(data32, card->config_regs + GPIO_STATUS); ++	} ++	return count; ++} ++ ++static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr, ++			      char *buf) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	struct geos_gpio *p = geos_gpio_pins; ++	while(p->name){ ++		if(!strcmp(attr->attr.name, p->name)){ ++			break; ++		} ++		p++; ++	} ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	data32 = (data32 >> p->offset) & 1; ++ ++	return sprintf(buf, "%d\n", data32); ++} ++ ++static ssize_t hardware_show(struct device *dev, struct device_attribute *attr, ++			     char *buf) ++{ ++	struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); ++	struct solos_card *card = atmdev->dev_data; ++	uint32_t data32; ++ ++	data32 = ioread32(card->config_regs + GPIO_STATUS); ++	if(!strcmp(attr->attr.name, "HardwareVersion")){ ++		data32 = data32 & 0x1F; ++		return sprintf(buf, "%d\n", data32); ++	} else if(!strcmp(attr->attr.name, "HardwareVariant")){ ++		data32 = (data32 >> 5) & 0x0F; ++		return sprintf(buf, "%d\n", data32); ++	} ++ ++	return sprintf(buf, "Error\n"); ++} ++ + static DEVICE_ATTR(console, 0644, console_show, console_store); +  +  +@@ -506,6 +588,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store); +  + #include "solos-attrlist.c" +  ++static DEVICE_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store); ++static DEVICE_ATTR(PushButton, 0444, geos_gpio_show, NULL); ++static DEVICE_ATTR(HardwareVersion, 0444, hardware_show, NULL); ++static DEVICE_ATTR(HardwareVariant, 0444, hardware_show, NULL); + #undef SOLOS_ATTR_RO + #undef SOLOS_ATTR_RW +  +@@ -514,6 +604,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store); +  + static struct attribute *solos_attrs[] = { + #include "solos-attrlist.c" ++	&dev_attr_GPIO1.attr, ++	&dev_attr_GPIO2.attr, ++	&dev_attr_GPIO3.attr, ++	&dev_attr_GPIO4.attr, ++	&dev_attr_GPIO5.attr, ++	&dev_attr_PushButton.attr, ++	&dev_attr_HardwareVersion.attr, ++	&dev_attr_HardwareVariant.attr, + 	NULL + }; +  +From: Nathan Williams <nathan@traverse.com.au> +To: netdev@vger.kernel.org +Date: Wed, 05 Oct 2011 15:46:08 +1100 +Cc: linux-atm-general@lists.sourceforge.net, +        David Woodhouse <dwmw2@infradead.org>, linux-kernel@vger.kernel.org +Subject: [Linux-ATM-General] [PATCH 4/4] atm: solos-pci: M25P/M25PE SPI +	flash support + +Newer Geos ADSL2+ routers have different SPI flash. +The FPGA on these boards require driver version = 1 to enable +flash upgrades so old drivers can't corrupt new boards. + +Signed-off-by: Nathan Williams <nathan@traverse.com.au> +--- + drivers/atm/solos-pci.c |   51 ++++++++++++++++++++++++++++++++++++---------- + 1 files changed, 40 insertions(+), 11 deletions(-) + +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 33c0c2b..2a75bf7 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -42,7 +42,8 @@ + #include <linux/swab.h> + #include <linux/slab.h> +  +-#define VERSION "0.07" ++#define VERSION "1.0" ++#define DRIVER_VERSION 0x01 + #define PTAG "solos-pci" +  + #define CONFIG_RAM_SIZE	128 +@@ -57,16 +58,20 @@ + #define FPGA_MODE	0x5C + #define FLASH_MODE	0x58 + #define GPIO_STATUS	0x54 ++#define DRIVER_VER	0x50 + #define TX_DMA_ADDR(port)	(0x40 + (4 * (port))) + #define RX_DMA_ADDR(port)	(0x30 + (4 * (port))) +  + #define DATA_RAM_SIZE	32768 + #define BUF_SIZE	2048 + #define OLD_BUF_SIZE	4096 /* For FPGA versions <= 2*/ +-#define FPGA_PAGE	528 /* FPGA flash page size*/ +-#define SOLOS_PAGE	512 /* Solos flash page size*/ +-#define FPGA_BLOCK	(FPGA_PAGE * 8) /* FPGA flash block size*/ +-#define SOLOS_BLOCK	(SOLOS_PAGE * 8) /* Solos flash block size*/ ++/* Old boards use ATMEL AD45DB161D flash */ ++#define ATMEL_FPGA_PAGE	528 /* FPGA flash page size*/ ++#define ATMEL_SOLOS_PAGE	512 /* Solos flash page size*/ ++#define ATMEL_FPGA_BLOCK	(ATMEL_FPGA_PAGE * 8) /* FPGA block size*/ ++#define ATMEL_SOLOS_BLOCK	(ATMEL_SOLOS_PAGE * 8) /* Solos block size*/ ++/* Current boards use M25P/M25PE SPI flash */ ++#define SPI_FLASH_BLOCK	(256 * 64) +  + #define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2) + #define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size)) +@@ -128,6 +133,7 @@ struct solos_card { + 	int using_dma; + 	int fpga_version; + 	int buffer_size; ++	int atmel_flash; + }; +  +  +@@ -631,16 +637,25 @@ static int flash_upgrade(struct solos_card *card, int chip) + 	switch (chip) { + 	case 0: + 		fw_name = "solos-FPGA.bin"; +-		blocksize = FPGA_BLOCK; ++		if (card->atmel_flash) ++			blocksize = ATMEL_FPGA_BLOCK; ++		else ++			blocksize = SPI_FLASH_BLOCK; + 		break; + 	case 1: + 		fw_name = "solos-Firmware.bin"; +-		blocksize = SOLOS_BLOCK; ++		if (card->atmel_flash) ++			blocksize = ATMEL_SOLOS_BLOCK; ++		else ++			blocksize = SPI_FLASH_BLOCK; + 		break; + 	case 2: + 		if (card->fpga_version > LEGACY_BUFFERS){ + 			fw_name = "solos-db-FPGA.bin"; +-			blocksize = FPGA_BLOCK; ++			if (card->atmel_flash) ++				blocksize = ATMEL_FPGA_BLOCK; ++			else ++				blocksize = SPI_FLASH_BLOCK; + 		} else { + 			dev_info(&card->dev->dev, "FPGA version doesn't support" + 					" daughter board upgrades\n"); +@@ -650,7 +665,10 @@ static int flash_upgrade(struct solos_card *card, int chip) + 	case 3: + 		if (card->fpga_version > LEGACY_BUFFERS){ + 			fw_name = "solos-Firmware.bin"; +-			blocksize = SOLOS_BLOCK; ++			if (card->atmel_flash) ++				blocksize = ATMEL_SOLOS_BLOCK; ++			else ++				blocksize = SPI_FLASH_BLOCK; + 		} else { + 			dev_info(&card->dev->dev, "FPGA version doesn't support" + 					" daughter board upgrades\n"); +@@ -695,9 +713,13 @@ static int flash_upgrade(struct solos_card *card, int chip) + 		/* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */ + 		iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE); +  +-		/* Copy block to buffer, swapping each 16 bits */ ++		/* Copy block to buffer, swapping each 16 bits for Atmel flash */ + 		for(i = 0; i < blocksize; i += 4) { +-			uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i)); ++			uint32_t word; ++			if (card->atmel_flash) ++				word = swahb32p((uint32_t *)(fw->data + offset + i)); ++			else ++				word = *(uint32_t *)(fw->data + offset + i); + 			if(card->fpga_version > LEGACY_BUFFERS) + 				iowrite32(word, FLASH_BUF + i); + 			else +@@ -1249,6 +1271,11 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + 		db_fpga_upgrade = db_firmware_upgrade = 0; + 	} +  ++	/* Stopped using Atmel flash after 0.03-38 */ ++	if (fpga_ver < 39) ++		card->atmel_flash = 1; ++	else ++		card->atmel_flash = 0; + 	if (card->fpga_version >= DMA_SUPPORTED){ + 		card->using_dma = 1; + 	} else { +@@ -1256,6 +1283,8 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + 		/* Set RX empty flag for all ports */ + 		iowrite32(0xF0, card->config_regs + FLAGS_ADDR); + 	} ++	/* New FPGAs require driver version before permitting flash upgrades */ ++	iowrite32(DRIVER_VERSION, card->config_regs + DRIVER_VER); +  + 	data32 = ioread32(card->config_regs + PORTS); + 	card->nr_ports = (data32 & 0x000000FF); | 
