* Re: [PATCH] phylib: Add autoload support for the LXT973 phy.
From: David Miller @ 2010-06-27 5:16 UTC (permalink / raw)
To: dwmw2; +Cc: richardcochran, netdev
In-Reply-To: <1277210293.21798.11.camel@localhost>
From: David Woodhouse <dwmw2@infradead.org>
Date: Tue, 22 Jun 2010 13:38:13 +0100
> Commit e13647c1 (phylib: Add support for the LXT973 phy.) added a new ID
> but neglected to also add it to the MODULE_DEVICE_TABLE.
>
> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Applied, thanks.
> When I did this stuff, I did wonder if we should make this happen
> automatically somehow. I pondered some dirty macro hack in
> phy_driver_register() which would do it somehow, but couldn't come up
> with anything that'd work.
>
> Removing the phy_id and phy_id_mask from struct phy_driver and having a
> pointer to a match table would suck, since each driver only really
> matches one device/mask. (Even where a single C file has multiple
> drivers, they often differ in some methods or flags.)
>
> The best option I can come up with right now, is probably to remove
> phy_id and phy_id_mask from phy_driver and put a pointer to the driver
> into the ID table, and take the ID table as the argument to
> phy_driver_register(). I'm not sure I like that very much though -- I'd
> prefer that we just remember to update the table and don't need to be
> forced :)
>
> (Another cheap option is to pass the ID table as an extra argument to
> the existing phy_device_register(), I suppose, and it can just print a
> warning if it doesn't find the same phy_id and phy_id_mask in the table)
As our experience shows, people aren't remembering to do it so we have
to do something hard handed to make sure this doesn't break.
A compile time error out is the best, but if that is too hard or ugly
and we do it at run time then we should fail the register (not just
print a warning) if the table is incomplete.
Otherwise we run into cases where a developer adds several new IDs,
forgets some of the table entries, but only tries testing the ones he
did remember to add and doesn't notice the warning message.
^ permalink raw reply
* Re: [PATCH] ISDN: hysdn, fix potential NULL dereference
From: David Miller @ 2010-06-27 5:12 UTC (permalink / raw)
To: jslaby; +Cc: isdn, linux-kernel, jirislaby, shemminger, kaber, netdev
In-Reply-To: <1277206896-27197-1-git-send-email-jslaby@suse.cz>
From: Jiri Slaby <jslaby@suse.cz>
Date: Tue, 22 Jun 2010 13:41:36 +0200
> Stanse found that lp is dereferenced earlier than checked for being
> NULL in hysdn_rx_netpkt. Move the initialization below the test.
>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Applied.
^ permalink raw reply
* Re: [PATCH] vxge: fix memory leak in vxge_alloc_msix() error path {nodisc}
From: David Miller @ 2010-06-27 5:12 UTC (permalink / raw)
To: Ramkrishna.Vepa; +Cc: mschmidt, netdev
In-Reply-To: <FCA91A92EE52B041906A0358FC28FCC38EF1837D08@FRE1EXCH02.hq.exar.com>
From: Ramkrishna Vepa <Ramkrishna.Vepa@exar.com>
Date: Fri, 25 Jun 2010 00:21:48 -0700
>> When pci_enable_msix() returned ret<0, entries and vxge_entries were
>> leaked.
>> While at it, use the centralized exit idiom in the function.
>>
>> Not tested. It compiles OK.
>>
>> Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
>
> Reviewed and tested the patch. Thanks!
>
> Acked-by: Ram Vepa <ram.vepa@exar.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] syncookies: add support for ECN
From: David Miller @ 2010-06-27 5:00 UTC (permalink / raw)
To: fw; +Cc: netdev
In-Reply-To: <1277156925-7295-2-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Mon, 21 Jun 2010 23:48:45 +0200
> Allows use of ECN when syncookies are in effect by encoding ecn_ok
> into the syn-ack tcp timestamp.
>
> While at it, remove a uneeded #ifdef CONFIG_SYN_COOKIES.
> With CONFIG_SYN_COOKIES=nm want_cookie is ifdef'd to 0 and gcc
> removes the "if (0)".
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
Also applied, nice work Florian.
^ permalink raw reply
* Re: [PATCH 1/2] syncookies: do not store rcv_wscale in tcp timestamp
From: David Miller @ 2010-06-27 5:00 UTC (permalink / raw)
To: fw; +Cc: netdev
In-Reply-To: <1277156925-7295-1-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Mon, 21 Jun 2010 23:48:44 +0200
> As pointed out by Fernando Gont there is no need to encode rcv_wscale
> into the cookie.
>
> We did not use the restored rcv_wscale anyway; it is recomputed
> via tcp_select_initial_window().
>
> Thus we can save 4 bits in the ts option space by removing rcv_wscale.
> In case window scaling was not supported, we set the (invalid) wscale
> value 0xf.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
Applied.
^ permalink raw reply
* Re: [PATCH 1/2] syncookies: do not store rcv_wscale in tcp timestamp
From: David Miller @ 2010-06-27 4:27 UTC (permalink / raw)
To: hagen; +Cc: fw, netdev, ilpo.jarvinen
In-Reply-To: <20100624221416.GA31116@nuttenaction>
From: Hagen Paul Pfeifer <hagen@jauu.net>
Date: Fri, 25 Jun 2010 00:14:16 +0200
> why not limit the window to 2^16 bytes which is sufficient for
> 99.9999% of the use case?
This may have been true 8 years ago, but it is not any longer.
You will underutilize your link with anything smaller than
~512k on the modern internet.
^ permalink raw reply
* Re: [PATCH] net, ucc_geth: ethtool -d shows phy register values
From: David Miller @ 2010-06-27 4:20 UTC (permalink / raw)
To: holger.brunck; +Cc: netdev, christopher.varlese, leoli, avorontsov, tj
In-Reply-To: <1276610603-11589-1-git-send-email-holger.brunck@keymile.com>
From: Holger Brunck <holger.brunck@keymile.com>
Date: Tue, 15 Jun 2010 16:03:23 +0200
> From: Chris Varlese <christopher.varlese@keymile.com>
>
> Fixes MPC83xx UCC Ethernet driver so ethtool -d dumps values of
> the PHY registers (like other devices do) instead of the UCC registers
> of the MPC83xx.
>
> Signed-off-by: Chris Varlese <christopher.varlese@keymile.com>
> Signed-off-by: Holger Brunck <holger.brunck@keymile.com>
This doesn't look right at all.
ethtool -d dumps "chip registers", not the PHY registers. So the
current code looks correct, not what you're changing it to.
^ permalink raw reply
* Re: dhclient, checksum and tap
From: David Miller @ 2010-06-27 3:03 UTC (permalink / raw)
To: mst; +Cc: herbert.xu, netdev
In-Reply-To: <20100626211419.GA3646@redhat.com>
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Sun, 27 Jun 2010 00:14:19 +0300
> On Fri, Jun 25, 2010 at 11:21:52AM -0700, David Miller wrote:
>> We added the af_packet status as the migration path to deal with
>> this issue in the cleanest manner possible. Putting a new hack
>> into the TAP driver works contrary to that goal.
>
> Hmm, problem is, using the af_packets status requires
> userspace changes, and so does not help old clients.
> And for virt, clients might be running old kernels without this support.
> qemu has a hack to make old guests running within qemu work.
> I guess I can copy that hack into vhost - a bit ugly as I don't have
> access to the original skb there, so I will have to duplcate some logic,
> but doable. Is this what you suggest? OTOH if we had the workaround in
> tap, this could replace hacks in both vhost and qemu.
If you add the TAP thing you can _never_ remove it. Exactly for the
same reason that the qemu thing can never be removed. It'll always be
needed for the sake of old guests running old stuff.
This is why I truly believe that keeping the af_packet status thing as
the only kernel side assist is likely best in the long run.
^ permalink raw reply
* Re: [PATCH] usb: pegasus: fixed coding style issues
From: Petko Manolov @ 2010-06-27 2:47 UTC (permalink / raw)
To: Nicolas Kaiser; +Cc: Petko Manolov, linux-usb, netdev
In-Reply-To: <20100626185854.4a3eff43@absol.kitzblitz>
I think the old code is what "Lindent" script outputs. To me it doesn't
matter either way. :-)
Petko
On Sat, 26 Jun 2010, Nicolas Kaiser wrote:
> Fixed brace, static initialization, comment, whitespace and spacing
> coding style issues.
>
> Signed-off-by: Nicolas Kaiser <nikai@nikai.net>
> ---
> drivers/net/usb/pegasus.c | 125 +++++++++----------
> drivers/net/usb/pegasus.h | 296 ++++++++++++++++++++++----------------------
> 2 files changed, 209 insertions(+), 212 deletions(-)
>
> diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
> index 974d17f..6710f09 100644
> --- a/drivers/net/usb/pegasus.c
> +++ b/drivers/net/usb/pegasus.c
> @@ -21,11 +21,11 @@
> * behaves. Pegasus II support added since this version.
> * TODO: suppressing HCD warnings spewage on disconnect.
> * v0.4.13 Ethernet address is now set at probe(), not at open()
> - * time as this seems to break dhcpd.
> + * time as this seems to break dhcpd.
> * v0.5.0 branch to 2.5.x kernels
> * v0.5.1 ethtool support added
> * v0.5.5 rx socket buffers are in a pool and the their allocation
> - * is out of the interrupt routine.
> + * is out of the interrupt routine.
> */
>
> #include <linux/sched.h>
> @@ -55,9 +55,9 @@ static const char driver_name[] = "pegasus";
> #define BMSR_MEDIA (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \
> BMSR_100FULL | BMSR_ANEGCAPABLE)
>
> -static int loopback = 0;
> -static int mii_mode = 0;
> -static char *devid=NULL;
> +static int loopback;
> +static int mii_mode;
> +static char *devid;
>
> static struct usb_eth_dev usb_dev_id[] = {
> #define PEGASUS_DEV(pn, vid, pid, flags) \
> @@ -102,8 +102,8 @@ MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'");
>
> /* use ethtool to change the level for any given device */
> static int msg_level = -1;
> -module_param (msg_level, int, 0);
> -MODULE_PARM_DESC (msg_level, "Override default message level");
> +module_param(msg_level, int, 0);
> +MODULE_PARM_DESC(msg_level, "Override default message level");
>
> MODULE_DEVICE_TABLE(usb, pegasus_ids);
> static const struct net_device_ops pegasus_netdev_ops;
> @@ -141,7 +141,7 @@ static void ctrl_callback(struct urb *urb)
> wake_up(&pegasus->ctrl_wait);
> }
>
> -static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
> +static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
> void *data)
> {
> int ret;
> @@ -196,7 +196,7 @@ out:
> return ret;
> }
>
> -static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
> +static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
> void *data)
> {
> int ret;
> @@ -248,7 +248,7 @@ out:
> return ret;
> }
>
> -static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
> +static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
> {
> int ret;
> char *tmp;
> @@ -299,7 +299,7 @@ out:
> return ret;
> }
>
> -static int update_eth_regs_async(pegasus_t * pegasus)
> +static int update_eth_regs_async(pegasus_t *pegasus)
> {
> int ret;
>
> @@ -326,7 +326,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)
> }
>
> /* Returns 0 on success, error on failure */
> -static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
> +static int read_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd)
> {
> int i;
> __u8 data[4] = { phy, 0, 0, indx };
> @@ -334,7 +334,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
> int ret;
>
> set_register(pegasus, PhyCtrl, 0);
> - set_registers(pegasus, PhyAddr, sizeof (data), data);
> + set_registers(pegasus, PhyAddr, sizeof(data), data);
> set_register(pegasus, PhyCtrl, (indx | PHY_READ));
> for (i = 0; i < REG_TIMEOUT; i++) {
> ret = get_registers(pegasus, PhyCtrl, 1, data);
> @@ -366,7 +366,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int loc)
> return (int)res;
> }
>
> -static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
> +static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 regd)
> {
> int i;
> __u8 data[4] = { phy, 0, 0, indx };
> @@ -402,7 +402,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
> write_mii_word(pegasus, phy_id, loc, val);
> }
>
> -static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
> +static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata)
> {
> int i;
> __u8 tmp;
> @@ -433,7 +433,7 @@ fail:
> }
>
> #ifdef PEGASUS_WRITE_EEPROM
> -static inline void enable_eprom_write(pegasus_t * pegasus)
> +static inline void enable_eprom_write(pegasus_t *pegasus)
> {
> __u8 tmp;
> int ret;
> @@ -442,7 +442,7 @@ static inline void enable_eprom_write(pegasus_t * pegasus)
> set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
> }
>
> -static inline void disable_eprom_write(pegasus_t * pegasus)
> +static inline void disable_eprom_write(pegasus_t *pegasus)
> {
> __u8 tmp;
> int ret;
> @@ -452,7 +452,7 @@ static inline void disable_eprom_write(pegasus_t * pegasus)
> set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
> }
>
> -static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
> +static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data)
> {
> int i;
> __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
> @@ -484,7 +484,7 @@ fail:
> }
> #endif /* PEGASUS_WRITE_EEPROM */
>
> -static inline void get_node_id(pegasus_t * pegasus, __u8 * id)
> +static inline void get_node_id(pegasus_t *pegasus, __u8 *id)
> {
> int i;
> __u16 w16;
> @@ -495,7 +495,7 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id)
> }
> }
>
> -static void set_ethernet_addr(pegasus_t * pegasus)
> +static void set_ethernet_addr(pegasus_t *pegasus)
> {
> __u8 node_id[6];
>
> @@ -503,12 +503,12 @@ static void set_ethernet_addr(pegasus_t * pegasus)
> get_registers(pegasus, 0x10, sizeof(node_id), node_id);
> } else {
> get_node_id(pegasus, node_id);
> - set_registers(pegasus, EthID, sizeof (node_id), node_id);
> + set_registers(pegasus, EthID, sizeof(node_id), node_id);
> }
> - memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id));
> + memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id));
> }
>
> -static inline int reset_mac(pegasus_t * pegasus)
> +static inline int reset_mac(pegasus_t *pegasus)
> {
> __u8 data = 0x8;
> int i;
> @@ -563,7 +563,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
> data[1] = 0;
> data[2] = (loopback & 1) ? 0x09 : 0x01;
>
> - memcpy(pegasus->eth_regs, data, sizeof (data));
> + memcpy(pegasus->eth_regs, data, sizeof(data));
> ret = set_registers(pegasus, EthCtrl0, 3, data);
>
> if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
> @@ -577,7 +577,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
> return ret;
> }
>
> -static void fill_skb_pool(pegasus_t * pegasus)
> +static void fill_skb_pool(pegasus_t *pegasus)
> {
> int i;
>
> @@ -595,7 +595,7 @@ static void fill_skb_pool(pegasus_t * pegasus)
> }
> }
>
> -static void free_skb_pool(pegasus_t * pegasus)
> +static void free_skb_pool(pegasus_t *pegasus)
> {
> int i;
>
> @@ -667,11 +667,11 @@ static void read_bulk_callback(struct urb *urb)
> netif_dbg(pegasus, rx_err, net,
> "RX packet error %x\n", rx_status);
> pegasus->stats.rx_errors++;
> - if (rx_status & 0x06) // long or runt
> + if (rx_status & 0x06) /* long or runt */
> pegasus->stats.rx_length_errors++;
> if (rx_status & 0x08)
> pegasus->stats.rx_crc_errors++;
> - if (rx_status & 0x10) // extra bits
> + if (rx_status & 0x10) /* extra bits */
> pegasus->stats.rx_frame_errors++;
> goto goon;
> }
> @@ -748,9 +748,8 @@ static void rx_fixup(unsigned long data)
> if (pegasus->flags & PEGASUS_RX_URB_FAIL)
> if (pegasus->rx_skb)
> goto try_again;
> - if (pegasus->rx_skb == NULL) {
> + if (pegasus->rx_skb == NULL)
> pegasus->rx_skb = pull_skb(pegasus);
> - }
> if (pegasus->rx_skb == NULL) {
> netif_warn(pegasus, rx_err, pegasus->net, "low on memory\n");
> tasklet_schedule(&pegasus->rx_tl);
> @@ -835,7 +834,7 @@ static void intr_callback(struct urb *urb)
> }
>
> if (urb->actual_length >= 6) {
> - u8 * d = urb->transfer_buffer;
> + u8 *d = urb->transfer_buffer;
>
> /* byte 0 == tx_status1, reg 2B */
> if (d[0] & (TX_UNDERRUN|EXCESSIVE_COL
> @@ -918,14 +917,14 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
> return &((pegasus_t *) netdev_priv(dev))->stats;
> }
>
> -static inline void disable_net_traffic(pegasus_t * pegasus)
> +static inline void disable_net_traffic(pegasus_t *pegasus)
> {
> __le16 tmp = cpu_to_le16(0);
>
> set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp);
> }
>
> -static inline void get_interrupt_interval(pegasus_t * pegasus)
> +static inline void get_interrupt_interval(pegasus_t *pegasus)
> {
> u16 data;
> u8 interval;
> @@ -961,7 +960,7 @@ static void set_carrier(struct net_device *net)
> netif_carrier_off(net);
> }
>
> -static void free_all_urbs(pegasus_t * pegasus)
> +static void free_all_urbs(pegasus_t *pegasus)
> {
> usb_free_urb(pegasus->intr_urb);
> usb_free_urb(pegasus->tx_urb);
> @@ -969,7 +968,7 @@ static void free_all_urbs(pegasus_t * pegasus)
> usb_free_urb(pegasus->ctrl_urb);
> }
>
> -static void unlink_all_urbs(pegasus_t * pegasus)
> +static void unlink_all_urbs(pegasus_t *pegasus)
> {
> usb_kill_urb(pegasus->intr_urb);
> usb_kill_urb(pegasus->tx_urb);
> @@ -977,12 +976,11 @@ static void unlink_all_urbs(pegasus_t * pegasus)
> usb_kill_urb(pegasus->ctrl_urb);
> }
>
> -static int alloc_urbs(pegasus_t * pegasus)
> +static int alloc_urbs(pegasus_t *pegasus)
> {
> pegasus->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
> - if (!pegasus->ctrl_urb) {
> + if (!pegasus->ctrl_urb)
> return 0;
> - }
> pegasus->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
> if (!pegasus->rx_urb) {
> usb_free_urb(pegasus->ctrl_urb);
> @@ -1019,7 +1017,7 @@ static int pegasus_open(struct net_device *net)
> return -ENOMEM;
>
> res = set_registers(pegasus, EthID, 6, net->dev_addr);
> -
> +
> usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
> usb_rcvbulkpipe(pegasus->usb, 1),
> pegasus->rx_skb->data, PEGASUS_MTU + 8,
> @@ -1033,7 +1031,7 @@ static int pegasus_open(struct net_device *net)
>
> usb_fill_int_urb(pegasus->intr_urb, pegasus->usb,
> usb_rcvintpipe(pegasus->usb, 3),
> - pegasus->intr_buff, sizeof (pegasus->intr_buff),
> + pegasus->intr_buff, sizeof(pegasus->intr_buff),
> intr_callback, pegasus, pegasus->intr_interval);
> if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) {
> if (res == -ENODEV)
> @@ -1076,9 +1074,9 @@ static void pegasus_get_drvinfo(struct net_device *dev,
> struct ethtool_drvinfo *info)
> {
> pegasus_t *pegasus = netdev_priv(dev);
> - strncpy(info->driver, driver_name, sizeof (info->driver) - 1);
> - strncpy(info->version, DRIVER_VERSION, sizeof (info->version) - 1);
> - usb_make_path(pegasus->usb, info->bus_info, sizeof (info->bus_info));
> + strncpy(info->driver, driver_name, sizeof(info->driver) - 1);
> + strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
> + usb_make_path(pegasus->usb, info->bus_info, sizeof(info->bus_info));
> }
>
> /* also handles three patterns of some kind in hardware */
> @@ -1098,7 +1096,7 @@ pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
> {
> pegasus_t *pegasus = netdev_priv(dev);
> u8 reg78 = 0x04;
> -
> +
> if (wol->wolopts & ~WOL_SUPPORTED)
> return -EINVAL;
>
> @@ -1118,7 +1116,7 @@ pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
> static inline void pegasus_reset_wol(struct net_device *dev)
> {
> struct ethtool_wolinfo wol;
> -
> +
> memset(&wol, 0, sizeof wol);
> (void) pegasus_set_wol(dev, &wol);
> }
> @@ -1178,7 +1176,7 @@ static const struct ethtool_ops ops = {
>
> static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
> {
> - __u16 *data = (__u16 *) & rq->ifr_ifru;
> + __u16 *data = (__u16 *) &rq->ifr_ifru;
> pegasus_t *pegasus = netdev_priv(net);
> int res;
>
> @@ -1223,7 +1221,7 @@ static void pegasus_set_multicast(struct net_device *net)
> ctrl_callback(pegasus->ctrl_urb);
> }
>
> -static __u8 mii_phy_probe(pegasus_t * pegasus)
> +static __u8 mii_phy_probe(pegasus_t *pegasus)
> {
> int i;
> __u16 tmp;
> @@ -1239,10 +1237,10 @@ static __u8 mii_phy_probe(pegasus_t * pegasus)
> return 0xff;
> }
>
> -static inline void setup_pegasus_II(pegasus_t * pegasus)
> +static inline void setup_pegasus_II(pegasus_t *pegasus)
> {
> __u8 data = 0xa5;
> -
> +
> set_register(pegasus, Reg1d, 0);
> set_register(pegasus, Reg7b, 1);
> mdelay(100);
> @@ -1254,16 +1252,15 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
> set_register(pegasus, 0x83, data);
> get_registers(pegasus, 0x83, 1, &data);
>
> - if (data == 0xa5) {
> + if (data == 0xa5)
> pegasus->chip = 0x8513;
> - } else {
> + else
> pegasus->chip = 0;
> - }
>
> set_register(pegasus, 0x80, 0xc0);
> set_register(pegasus, 0x83, 0xff);
> set_register(pegasus, 0x84, 0x01);
> -
> +
> if (pegasus->features & HAS_HOME_PNA && mii_mode)
> set_register(pegasus, Reg81, 6);
> else
> @@ -1272,7 +1269,7 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
>
>
> static int pegasus_count;
> -static struct workqueue_struct *pegasus_workqueue = NULL;
> +static struct workqueue_struct *pegasus_workqueue;
> #define CARRIER_CHECK_DELAY (2 * HZ)
>
> static void check_carrier(struct work_struct *work)
> @@ -1367,7 +1364,7 @@ static int pegasus_probe(struct usb_interface *intf,
> pegasus->mii.phy_id_mask = 0x1f;
> pegasus->mii.reg_num_mask = 0x1f;
> spin_lock_init(&pegasus->rx_pool_lock);
> - pegasus->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
> + pegasus->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV
> | NETIF_MSG_PROBE | NETIF_MSG_LINK);
>
> pegasus->features = usb_dev_id[dev_index].private;
> @@ -1442,11 +1439,11 @@ static void pegasus_disconnect(struct usb_interface *intf)
> pegasus_dec_workqueue();
> }
>
> -static int pegasus_suspend (struct usb_interface *intf, pm_message_t message)
> +static int pegasus_suspend(struct usb_interface *intf, pm_message_t message)
> {
> struct pegasus *pegasus = usb_get_intfdata(intf);
> -
> - netif_device_detach (pegasus->net);
> +
> + netif_device_detach(pegasus->net);
> cancel_delayed_work(&pegasus->carrier_check);
> if (netif_running(pegasus->net)) {
> usb_kill_urb(pegasus->rx_urb);
> @@ -1455,11 +1452,11 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message)
> return 0;
> }
>
> -static int pegasus_resume (struct usb_interface *intf)
> +static int pegasus_resume(struct usb_interface *intf)
> {
> struct pegasus *pegasus = usb_get_intfdata(intf);
>
> - netif_device_attach (pegasus->net);
> + netif_device_attach(pegasus->net);
> if (netif_running(pegasus->net)) {
> pegasus->rx_urb->status = 0;
> pegasus->rx_urb->actual_length = 0;
> @@ -1498,8 +1495,8 @@ static struct usb_driver pegasus_driver = {
>
> static void __init parse_id(char *id)
> {
> - unsigned int vendor_id=0, device_id=0, flags=0, i=0;
> - char *token, *name=NULL;
> + unsigned int vendor_id = 0, device_id = 0, flags = 0, i = 0;
> + char *token, *name = NULL;
>
> if ((token = strsep(&id, ":")) != NULL)
> name = token;
> @@ -1510,14 +1507,14 @@ static void __init parse_id(char *id)
> device_id = simple_strtoul(token, NULL, 16);
> flags = simple_strtoul(id, NULL, 16);
> pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n",
> - driver_name, name, vendor_id, device_id, flags);
> + driver_name, name, vendor_id, device_id, flags);
>
> if (vendor_id > 0x10000 || vendor_id == 0)
> return;
> if (device_id > 0x10000 || device_id == 0)
> return;
>
> - for (i=0; usb_dev_id[i].name; i++);
> + for (i = 0; usb_dev_id[i].name; i++);
> usb_dev_id[i].name = name;
> usb_dev_id[i].vendor = vendor_id;
> usb_dev_id[i].device = device_id;
> diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
> index 29f5211..65b78b3 100644
> --- a/drivers/net/usb/pegasus.h
> +++ b/drivers/net/usb/pegasus.h
> @@ -68,7 +68,7 @@ enum pegasus_registers {
> EpromData = 0x21, /* 0x21 low, 0x22 high byte */
> EpromCtrl = 0x23,
> PhyAddr = 0x25,
> - PhyData = 0x26, /* 0x26 low, 0x27 high byte */
> + PhyData = 0x26, /* 0x26 low, 0x27 high byte */
> PhyCtrl = 0x28,
> UsbStst = 0x2a,
> EthTxStat0 = 0x2b,
> @@ -154,162 +154,162 @@ struct usb_eth_dev {
>
> #else /* PEGASUS_DEV */
>
> -PEGASUS_DEV( "3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
> - DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
> -PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
> - DEFAULT_GPIO_RESET | HAS_HOME_PNA )
> -PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4004,
> - DEFAULT_GPIO_RESET | HAS_HOME_PNA )
> -PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4007,
> - DEFAULT_GPIO_RESET | HAS_HOME_PNA )
> -PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4102,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4002,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400b,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
> +PEGASUS_DEV("3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
> + DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
> +PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
> + DEFAULT_GPIO_RESET | HAS_HOME_PNA)
> +PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4004,
> + DEFAULT_GPIO_RESET | HAS_HOME_PNA)
> +PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4007,
> + DEFAULT_GPIO_RESET | HAS_HOME_PNA)
> +PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4102,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4002,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400b,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
> VENDOR_ADMTEK, 0x8511,
> - DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
> -PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
> + DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
> +PEGASUS_DEV("ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
> VENDOR_ADMTEK, 0x8513,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "ADMtek ADM8515 \"Pegasus II\" USB-2.0 Ethernet",
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("ADMtek ADM8515 \"Pegasus II\" USB-2.0 Ethernet",
> VENDOR_ADMTEK, 0x8515,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)",
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)",
> VENDOR_ADMTEK, 0x0986,
> - DEFAULT_GPIO_RESET | HAS_HOME_PNA )
> -PEGASUS_DEV( "AN986A USB MAC", VENDOR_ADMTEK, 1986,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> + DEFAULT_GPIO_RESET | HAS_HOME_PNA)
> +PEGASUS_DEV("AN986A USB MAC", VENDOR_ADMTEK, 1986,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> /*
> * Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors
> * with the same product IDs by checking the device class too.
> */
> -PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
> - DEFAULT_GPIO_RESET | HAS_HOME_PNA )
> -PEGASUS_DEV( "iPAQ Networking 10/100 USB", VENDOR_COMPAQ, 0x8511,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Corega FEther USB-TX", VENDOR_COREGA, 0x0004,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Corega FEther USB-TXS", VENDOR_COREGA, 0x000d,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4102,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x400b,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x200c,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
> - DEFAULT_GPIO_RESET | HAS_HOME_PNA )
> -PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
> - DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
> -PEGASUS_DEV( "ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "EasiDock Ethernet", VENDOR_MOBILITY, 0x0304,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "IO DATA USB ETX-US2", VENDOR_IODATA, 0x093a,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
> +PEGASUS_DEV_CLASS("Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
> + DEFAULT_GPIO_RESET | HAS_HOME_PNA)
> +PEGASUS_DEV("iPAQ Networking 10/100 USB", VENDOR_COMPAQ, 0x8511,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Corega FEther USB-TX", VENDOR_COREGA, 0x0004,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Corega FEther USB-TXS", VENDOR_COREGA, 0x000d,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4102,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x400b,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x200c,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
> + DEFAULT_GPIO_RESET | HAS_HOME_PNA)
> +PEGASUS_DEV("D-Link DSB-650", VENDOR_DLINK, 0xabc1,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
> + DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
> +PEGASUS_DEV("ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("EasiDock Ethernet", VENDOR_MOBILITY, 0x0304,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
> DEFAULT_GPIO_RESET)
> -PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005,
> - DEFAULT_GPIO_RESET | PEGASUS_II)
> -PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
> - DEFAULT_GPIO_RESET | HAS_HOME_PNA )
> -PEGASUS_DEV( "Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
> - DEFAULT_GPIO_RESET | PEGASUS_II)
> -PEGASUS_DEV( "Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "Microsoft MN-110", VENDOR_MICROSOFT, 0x007a,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "OCT Inc.", VENDOR_OCT, 0x0109,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "OCT USB TO Ethernet", VENDOR_OCT, 0x0901,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
> - DEFAULT_GPIO_RESET | PEGASUS_II)
> -PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
> - DEFAULT_GPIO_RESET )
> -PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> -PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
> - DEFAULT_GPIO_RESET | PEGASUS_II )
> +PEGASUS_DEV("GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("IO DATA USB ETX-US2", VENDOR_IODATA, 0x093a,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
> + DEFAULT_GPIO_RESET | HAS_HOME_PNA)
> +PEGASUS_DEV("Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("Microsoft MN-110", VENDOR_MICROSOFT, 0x007a,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("OCT Inc.", VENDOR_OCT, 0x0109,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("OCT USB TO Ethernet", VENDOR_OCT, 0x0901,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
> + DEFAULT_GPIO_RESET)
> +PEGASUS_DEV("SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
> +PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
> + DEFAULT_GPIO_RESET | PEGASUS_II)
>
>
> #endif /* PEGASUS_DEV */
> --
> 1.7.1
>
^ permalink raw reply
* Re: [PATCH] ip: correctly report 802.15.4 link type
From: Stephen Hemminger @ 2010-06-26 23:51 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: netdev
OK but long-term fix is to get rid of hardcoded table
Jan Engelhardt <jengelh@medozas.de> wrote:
>Up until now, the "hardwpan" devices were displayed as link/[804].
>
>Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
>---
> lib/ll_types.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
>diff --git a/lib/ll_types.c b/lib/ll_types.c
>index 846cdb0..1cc46b6 100644
>--- a/lib/ll_types.c
>+++ b/lib/ll_types.c
>@@ -125,6 +125,9 @@ __PF(IEEE80211_PRISM,ieee802.11/prism)
> #ifdef ARPHRD_IEEE80211_RADIOTAP
> __PF(IEEE80211_RADIOTAP,ieee802.11/radiotap)
> #endif
>+#ifdef ARPHRD_IEEE802154
>+__PF(IEEE802154, ieee802.15.4)
>+#endif
> #ifdef ARPHRD_NONE
> __PF(NONE, none)
> #endif
>--
>1.7.1
>
^ permalink raw reply
* [PATCH 2/2] ipv6: Use interface max_desync_factor instead of static default
From: Ben Hutchings @ 2010-06-26 21:42 UTC (permalink / raw)
To: David Miller
Cc: Hideaki YOSHIFUJI, Patrick McHardy, 514646, Piotr Lewandowski,
netdev
In-Reply-To: <1277588267.26161.300.camel@localhost>
max_desync_factor can be configured per-interface, but nothing is
using the value.
Reported-by: Piotr Lewandowski <piotr.lewandowski@gmail.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
Also compile-tested only.
Note that there is nothing to stop temp_prefered_lft being set smaller
than max_desync_factor, which can result in underflow in calculation of
tmp_prefered_lft in ipv6_create_tempaddr(). However, the same applies
to the current static variable desync_factor.
Ben.
net/ipv6/addrconf.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 1459eed..ec8c92f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -121,8 +121,6 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
static int __ipv6_regen_rndid(struct inet6_dev *idev);
static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
static void ipv6_regen_rndid(unsigned long data);
-
-static int desync_factor = MAX_DESYNC_FACTOR * HZ;
#endif
static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
@@ -890,7 +888,8 @@ retry:
idev->cnf.temp_valid_lft);
tmp_prefered_lft = min_t(__u32,
ifp->prefered_lft,
- idev->cnf.temp_prefered_lft - desync_factor / HZ);
+ idev->cnf.temp_prefered_lft -
+ idev->cnf.max_desync_factor);
tmp_plen = ifp->prefix_len;
max_addresses = idev->cnf.max_addresses;
tmp_cstamp = ifp->cstamp;
@@ -1650,7 +1649,8 @@ static void ipv6_regen_rndid(unsigned long data)
expires = jiffies +
idev->cnf.temp_prefered_lft * HZ -
- idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor;
+ idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time -
+ idev->cnf.max_desync_factor * HZ;
if (time_before(expires, jiffies)) {
printk(KERN_WARNING
"ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n",
--
1.7.1
^ permalink raw reply related
* [PATCH 1/2] ipv6: Clamp reported valid_lft to a minimum of 0
From: Ben Hutchings @ 2010-06-26 21:37 UTC (permalink / raw)
To: David Miller
Cc: Hideaki YOSHIFUJI, Patrick McHardy, 514644, Piotr Lewandowski,
netdev
Since addresses are only revalidated every 2 minutes, the reported
valid_lft can underflow shortly before the address is deleted.
Clamp it to a minimum of 0, as for prefered_lft.
Reported-by: Piotr Lewandowski <piotr.lewandowski@gmail.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
This is compile-tested only. I don't claim any familiarity with this
code.
Ben.
net/ipv6/addrconf.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b97bb1f..1459eed 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3492,8 +3492,12 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
preferred -= tval;
else
preferred = 0;
- if (valid != INFINITY_LIFE_TIME)
- valid -= tval;
+ if (valid != INFINITY_LIFE_TIME) {
+ if (valid > tval)
+ valid -= tval;
+ else
+ valid = 0;
+ }
}
} else {
preferred = INFINITY_LIFE_TIME;
--
1.7.1
^ permalink raw reply related
* [PATCH v4 2/2] caif-driver: Add CAIF-SPI Protocol driver.
From: sjur.brandeland @ 2010-06-26 21:31 UTC (permalink / raw)
To: davem
Cc: sjurbr, netdev, marcel, daniel.martensson, linus.walleij,
Sjur Braendeland
In-Reply-To: <1277587889-17314-1-git-send-email-sjur.brandeland@stericsson.com>
From: Sjur Braendeland <sjur.brandeland@stericsson.com>
This patch introduces the CAIF SPI Protocol Driver for
CAIF Link Layer.
This driver implements a platform driver to accommodate for a
platform specific SPI device. A general platform driver is not
possible as there are no SPI Slave side Kernel API defined.
A sample CAIF SPI Platform device can be found in
.../Documentation/networking/caif/spi_porting.txt
Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
== CHANGES since v1 of CAIF-SPI Protocol driver:
o Using "depends on" instead of "if" in Kconfig files.
o Changed uint8_t to u8 et. al.
o Using netif_rx_ni instead of netif_rx from workqueue.
o Removed CONFIG_* defines from Makefile.
Documentation/networking/caif/spi_porting.txt | 208 ++++++
drivers/net/caif/Kconfig | 20 +
drivers/net/caif/Makefile | 4 +
drivers/net/caif/caif_spi.c | 847 +++++++++++++++++++++++++
drivers/net/caif/caif_spi_slave.c | 252 ++++++++
include/net/caif/caif_spi.h | 153 +++++
6 files changed, 1484 insertions(+), 0 deletions(-)
create mode 100644 Documentation/networking/caif/spi_porting.txt
create mode 100644 drivers/net/caif/caif_spi.c
create mode 100644 drivers/net/caif/caif_spi_slave.c
create mode 100644 include/net/caif/caif_spi.h
diff --git a/Documentation/networking/caif/spi_porting.txt b/Documentation/networking/caif/spi_porting.txt
new file mode 100644
index 0000000..61d7c92
--- /dev/null
+++ b/Documentation/networking/caif/spi_porting.txt
@@ -0,0 +1,208 @@
+- CAIF SPI porting -
+
+- CAIF SPI basics:
+
+Running CAIF over SPI needs some extra setup, owing to the nature of SPI.
+Two extra GPIOs have been added in order to negotiate the transfers
+ between the master and the slave. The minimum requirement for running
+CAIF over SPI is a SPI slave chip and two GPIOs (more details below).
+Please note that running as a slave implies that you need to keep up
+with the master clock. An overrun or underrun event is fatal.
+
+- CAIF SPI framework:
+
+To make porting as easy as possible, the CAIF SPI has been divided in
+two parts. The first part (called the interface part) deals with all
+generic functionality such as length framing, SPI frame negotiation
+and SPI frame delivery and transmission. The other part is the CAIF
+SPI slave device part, which is the module that you have to write if
+you want to run SPI CAIF on a new hardware. This part takes care of
+the physical hardware, both with regard to SPI and to GPIOs.
+
+- Implementing a CAIF SPI device:
+
+ - Functionality provided by the CAIF SPI slave device:
+
+ In order to implement a SPI device you will, as a minimum,
+ need to implement the following
+ functions:
+
+ int (*init_xfer) (struct cfspi_xfer * xfer, struct cfspi_dev *dev):
+
+ This function is called by the CAIF SPI interface to give
+ you a chance to set up your hardware to be ready to receive
+ a stream of data from the master. The xfer structure contains
+ both physical and logical adresses, as well as the total length
+ of the transfer in both directions.The dev parameter can be used
+ to map to different CAIF SPI slave devices.
+
+ void (*sig_xfer) (bool xfer, struct cfspi_dev *dev):
+
+ This function is called by the CAIF SPI interface when the output
+ (SPI_INT) GPIO needs to change state. The boolean value of the xfer
+ variable indicates whether the GPIO should be asserted (HIGH) or
+ deasserted (LOW). The dev parameter can be used to map to different CAIF
+ SPI slave devices.
+
+ - Functionality provided by the CAIF SPI interface:
+
+ void (*ss_cb) (bool assert, struct cfspi_ifc *ifc);
+
+ This function is called by the CAIF SPI slave device in order to
+ signal a change of state of the input GPIO (SS) to the interface.
+ Only active edges are mandatory to be reported.
+ This function can be called from IRQ context (recommended in order
+ not to introduce latency). The ifc parameter should be the pointer
+ returned from the platform probe function in the SPI device structure.
+
+ void (*xfer_done_cb) (struct cfspi_ifc *ifc);
+
+ This function is called by the CAIF SPI slave device in order to
+ report that a transfer is completed. This function should only be
+ called once both the transmission and the reception are completed.
+ This function can be called from IRQ context (recommended in order
+ not to introduce latency). The ifc parameter should be the pointer
+ returned from the platform probe function in the SPI device structure.
+
+ - Connecting the bits and pieces:
+
+ - Filling in the SPI slave device structure:
+
+ Connect the necessary callback functions.
+ Indicate clock speed (used to calculate toggle delays).
+ Chose a suitable name (helps debugging if you use several CAIF
+ SPI slave devices).
+ Assign your private data (can be used to map to your structure).
+
+ - Filling in the SPI slave platform device structure:
+ Add name of driver to connect to ("cfspi_sspi").
+ Assign the SPI slave device structure as platform data.
+
+- Padding:
+
+In order to optimize throughput, a number of SPI padding options are provided.
+Padding can be enabled independently for uplink and downlink transfers.
+Padding can be enabled for the head, the tail and for the total frame size.
+The padding needs to be correctly configured on both sides of the link.
+The padding can be changed via module parameters in cfspi_sspi.c or via
+the sysfs directory of the cfspi_sspi driver (before device registration).
+
+- CAIF SPI device template:
+
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+ * License terms: GNU General Public License (GPL), version 2.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <net/caif/caif_spi.h>
+
+MODULE_LICENSE("GPL");
+
+struct sspi_struct {
+ struct cfspi_dev sdev;
+ struct cfspi_xfer *xfer;
+};
+
+static struct sspi_struct slave;
+static struct platform_device slave_device;
+
+static irqreturn_t sspi_irq(int irq, void *arg)
+{
+ /* You only need to trigger on an edge to the active state of the
+ * SS signal. Once a edge is detected, the ss_cb() function should be
+ * called with the parameter assert set to true. It is OK
+ * (and even advised) to call the ss_cb() function in IRQ context in
+ * order not to add any delay. */
+
+ return IRQ_HANDLED;
+}
+
+static void sspi_complete(void *context)
+{
+ /* Normally the DMA or the SPI framework will call you back
+ * in something similar to this. The only thing you need to
+ * do is to call the xfer_done_cb() function, providing the pointer
+ * to the CAIF SPI interface. It is OK to call this function
+ * from IRQ context. */
+}
+
+static int sspi_init_xfer(struct cfspi_xfer *xfer, struct cfspi_dev *dev)
+{
+ /* Store transfer info. For a normal implementation you should
+ * set up your DMA here and make sure that you are ready to
+ * receive the data from the master SPI. */
+
+ struct sspi_struct *sspi = (struct sspi_struct *)dev->priv;
+
+ sspi->xfer = xfer;
+
+ return 0;
+}
+
+void sspi_sig_xfer(bool xfer, struct cfspi_dev *dev)
+{
+ /* If xfer is true then you should assert the SPI_INT to indicate to
+ * the master that you are ready to recieve the data from the master
+ * SPI. If xfer is false then you should de-assert SPI_INT to indicate
+ * that the transfer is done.
+ */
+
+ struct sspi_struct *sspi = (struct sspi_struct *)dev->priv;
+}
+
+static void sspi_release(struct device *dev)
+{
+ /*
+ * Here you should release your SPI device resources.
+ */
+}
+
+static int __init sspi_init(void)
+{
+ /* Here you should initialize your SPI device by providing the
+ * necessary functions, clock speed, name and private data. Once
+ * done, you can register your device with the
+ * platform_device_register() function. This function will return
+ * with the CAIF SPI interface initialized. This is probably also
+ * the place where you should set up your GPIOs, interrupts and SPI
+ * resources. */
+
+ int res = 0;
+
+ /* Initialize slave device. */
+ slave.sdev.init_xfer = sspi_init_xfer;
+ slave.sdev.sig_xfer = sspi_sig_xfer;
+ slave.sdev.clk_mhz = 13;
+ slave.sdev.priv = &slave;
+ slave.sdev.name = "spi_sspi";
+ slave_device.dev.release = sspi_release;
+
+ /* Initialize platform device. */
+ slave_device.name = "cfspi_sspi";
+ slave_device.dev.platform_data = &slave.sdev;
+
+ /* Register platform device. */
+ res = platform_device_register(&slave_device);
+ if (res) {
+ printk(KERN_WARNING "sspi_init: failed to register dev.\n");
+ return -ENODEV;
+ }
+
+ return res;
+}
+
+static void __exit sspi_exit(void)
+{
+ platform_device_del(&slave_device);
+}
+
+module_init(sspi_init);
+module_exit(sspi_exit);
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
index 6f33ee4..cfbe675 100644
--- a/drivers/net/caif/Kconfig
+++ b/drivers/net/caif/Kconfig
@@ -12,3 +12,23 @@ config CAIF_TTY
The CAIF TTY transport driver is a Line Discipline (ldisc)
identified as N_CAIF. When this ldisc is opened from user space
it will redirect the TTY's traffic into the CAIF stack.
+
+config CAIF_SPI_SLAVE
+ tristate "CAIF SPI transport driver for slave interface"
+ depends on CAIF
+ default n
+ ---help---
+ The CAIF Link layer SPI Protocol driver for Slave SPI interface.
+ This driver implements a platform driver to accommodate for a
+ platform specific SPI device. A sample CAIF SPI Platform device is
+ provided in Documentation/networking/caif/spi_porting.txt
+
+config CAIF_SPI_SYNC
+ bool "Next command and length in start of frame"
+ depends on CAIF_SPI_SLAVE
+ default n
+ ---help---
+ Putting the next command and length in the start of the frame can
+ help to synchronize to the next transfer in case of over or under-runs.
+ This option also needs to be enabled on the modem.
+
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
index e6d3ca0..3a11d61 100644
--- a/drivers/net/caif/Makefile
+++ b/drivers/net/caif/Makefile
@@ -4,3 +4,7 @@ endif
# Serial interface
obj-$(CONFIG_CAIF_TTY) += caif_serial.o
+
+# SPI slave physical interfaces module
+cfspi_slave-objs := caif_spi.o caif_spi_slave.o
+obj-$(CONFIG_CAIF_SPI_SLAVE) += cfspi_slave.o
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
new file mode 100644
index 0000000..03049e8
--- /dev/null
+++ b/drivers/net/caif/caif_spi.c
@@ -0,0 +1,847 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com
+ * Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2.
+ */
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/debugfs.h>
+#include <linux/if_arp.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/caif_spi.h>
+
+#ifndef CONFIG_CAIF_SPI_SYNC
+#define FLAVOR "Flavour: Vanilla.\n"
+#else
+#define FLAVOR "Flavour: Master CMD&LEN at start.\n"
+#endif /* CONFIG_CAIF_SPI_SYNC */
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel Martensson<daniel.martensson@stericsson.com>");
+MODULE_DESCRIPTION("CAIF SPI driver");
+
+static int spi_loop;
+module_param(spi_loop, bool, S_IRUGO);
+MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode.");
+
+/* SPI frame alignment. */
+module_param(spi_frm_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment.");
+
+/* SPI padding options. */
+module_param(spi_up_head_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment.");
+
+module_param(spi_up_tail_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_up_tail_align, "SPI uplink tail alignment.");
+
+module_param(spi_down_head_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_down_head_align, "SPI downlink head alignment.");
+
+module_param(spi_down_tail_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_down_tail_align, "SPI downlink tail alignment.");
+
+#ifdef CONFIG_ARM
+#define BYTE_HEX_FMT "%02X"
+#else
+#define BYTE_HEX_FMT "%02hhX"
+#endif
+
+#define SPI_MAX_PAYLOAD_SIZE 4096
+/*
+ * Threshold values for the SPI packet queue. Flowcontrol will be asserted
+ * when the number of packets exceeds HIGH_WATER_MARK. It will not be
+ * deasserted before the number of packets drops below LOW_WATER_MARK.
+ */
+#define LOW_WATER_MARK 100
+#define HIGH_WATER_MARK (LOW_WATER_MARK*5)
+
+#ifdef CONFIG_UML
+
+/*
+ * We sometimes use UML for debugging, but it cannot handle
+ * dma_alloc_coherent so we have to wrap it.
+ */
+static inline void *dma_alloc(dma_addr_t *daddr)
+{
+ return kmalloc(SPI_DMA_BUF_LEN, GFP_KERNEL);
+}
+
+static inline void dma_free(void *cpu_addr, dma_addr_t handle)
+{
+ kfree(cpu_addr);
+}
+
+#else
+
+static inline void *dma_alloc(dma_addr_t *daddr)
+{
+ return dma_alloc_coherent(NULL, SPI_DMA_BUF_LEN, daddr,
+ GFP_KERNEL);
+}
+
+static inline void dma_free(void *cpu_addr, dma_addr_t handle)
+{
+ dma_free_coherent(NULL, SPI_DMA_BUF_LEN, cpu_addr, handle);
+}
+#endif /* CONFIG_UML */
+
+#ifdef CONFIG_DEBUG_FS
+
+#define DEBUGFS_BUF_SIZE 4096
+
+static struct dentry *dbgfs_root;
+
+static inline void driver_debugfs_create(void)
+{
+ dbgfs_root = debugfs_create_dir(cfspi_spi_driver.driver.name, NULL);
+}
+
+static inline void driver_debugfs_remove(void)
+{
+ debugfs_remove(dbgfs_root);
+}
+
+static inline void dev_debugfs_rem(struct cfspi *cfspi)
+{
+ debugfs_remove(cfspi->dbgfs_frame);
+ debugfs_remove(cfspi->dbgfs_state);
+ debugfs_remove(cfspi->dbgfs_dir);
+}
+
+static int dbgfs_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t dbgfs_state(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int len = 0;
+ ssize_t size;
+ struct cfspi *cfspi = (struct cfspi *)file->private_data;
+
+ buf = kzalloc(DEBUGFS_BUF_SIZE, GFP_KERNEL);
+ if (!buf)
+ return 0;
+
+ /* Print out debug information. */
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "CAIF SPI debug information:\n");
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR);
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "STATE: %d\n", cfspi->dbg_state);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Previous CMD: 0x%x\n", cfspi->pcmd);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current CMD: 0x%x\n", cfspi->cmd);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Previous TX len: %d\n", cfspi->tx_ppck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Previous RX len: %d\n", cfspi->rx_ppck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current TX len: %d\n", cfspi->tx_cpck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current RX len: %d\n", cfspi->rx_cpck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Next TX len: %d\n", cfspi->tx_npck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Next RX len: %d\n", cfspi->rx_npck_len);
+
+ size = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return size;
+}
+
+static ssize_t print_frame(char *buf, size_t size, char *frm,
+ size_t count, size_t cut)
+{
+ int len = 0;
+ int i;
+ for (i = 0; i < count; i++) {
+ len += snprintf((buf + len), (size - len),
+ "[0x" BYTE_HEX_FMT "]",
+ frm[i]);
+ if ((i == cut) && (count > (cut * 2))) {
+ /* Fast forward. */
+ i = count - cut;
+ len += snprintf((buf + len), (size - len),
+ "--- %u bytes skipped ---\n",
+ (int)(count - (cut * 2)));
+ }
+
+ if ((!(i % 10)) && i) {
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "\n");
+ }
+ }
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), "\n");
+ return len;
+}
+
+static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int len = 0;
+ ssize_t size;
+ struct cfspi *cfspi;
+
+ cfspi = (struct cfspi *)file->private_data;
+ buf = kzalloc(DEBUGFS_BUF_SIZE, GFP_KERNEL);
+ if (!buf)
+ return 0;
+
+ /* Print out debug information. */
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current frame:\n");
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Tx data (Len: %d):\n", cfspi->tx_cpck_len);
+
+ len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
+ cfspi->xfer.va_tx,
+ (cfspi->tx_cpck_len + SPI_CMD_SZ), 100);
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Rx data (Len: %d):\n", cfspi->rx_cpck_len);
+
+ len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
+ cfspi->xfer.va_rx,
+ (cfspi->rx_cpck_len + SPI_CMD_SZ), 100);
+
+ size = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return size;
+}
+
+static const struct file_operations dbgfs_state_fops = {
+ .open = dbgfs_open,
+ .read = dbgfs_state,
+ .owner = THIS_MODULE
+};
+
+static const struct file_operations dbgfs_frame_fops = {
+ .open = dbgfs_open,
+ .read = dbgfs_frame,
+ .owner = THIS_MODULE
+};
+
+static inline void dev_debugfs_add(struct cfspi *cfspi)
+{
+ cfspi->dbgfs_dir = debugfs_create_dir(cfspi->pdev->name, dbgfs_root);
+ cfspi->dbgfs_state = debugfs_create_file("state", S_IRUGO,
+ cfspi->dbgfs_dir, cfspi,
+ &dbgfs_state_fops);
+ cfspi->dbgfs_frame = debugfs_create_file("frame", S_IRUGO,
+ cfspi->dbgfs_dir, cfspi,
+ &dbgfs_frame_fops);
+}
+
+inline void cfspi_dbg_state(struct cfspi *cfspi, int state)
+{
+ cfspi->dbg_state = state;
+};
+#else
+
+static inline void driver_debugfs_create(void)
+{
+}
+
+static inline void driver_debugfs_remove(void)
+{
+}
+
+static inline void dev_debugfs_add(struct cfspi *cfspi)
+{
+}
+
+static inline void dev_debugfs_rem(struct cfspi *cfspi)
+{
+}
+
+inline void cfspi_dbg_state(struct cfspi *cfspi, int state)
+{
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static LIST_HEAD(cfspi_list);
+static spinlock_t cfspi_list_lock;
+
+/* SPI uplink head alignment. */
+static ssize_t show_up_head_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_up_head_align);
+}
+
+static DRIVER_ATTR(up_head_align, S_IRUSR, show_up_head_align, NULL);
+
+/* SPI uplink tail alignment. */
+static ssize_t show_up_tail_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_up_tail_align);
+}
+
+static DRIVER_ATTR(up_tail_align, S_IRUSR, show_up_tail_align, NULL);
+
+/* SPI downlink head alignment. */
+static ssize_t show_down_head_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_down_head_align);
+}
+
+static DRIVER_ATTR(down_head_align, S_IRUSR, show_down_head_align, NULL);
+
+/* SPI downlink tail alignment. */
+static ssize_t show_down_tail_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_down_tail_align);
+}
+
+static DRIVER_ATTR(down_tail_align, S_IRUSR, show_down_tail_align, NULL);
+
+/* SPI frame alignment. */
+static ssize_t show_frame_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_frm_align);
+}
+
+static DRIVER_ATTR(frame_align, S_IRUSR, show_frame_align, NULL);
+
+int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len)
+{
+ u8 *dst = buf;
+ caif_assert(buf);
+
+ do {
+ struct sk_buff *skb;
+ struct caif_payload_info *info;
+ int spad = 0;
+ int epad;
+
+ skb = skb_dequeue(&cfspi->chead);
+ if (!skb)
+ break;
+
+ /*
+ * Calculate length of frame including SPI padding.
+ * The payload position is found in the control buffer.
+ */
+ info = (struct caif_payload_info *)&skb->cb;
+
+ /*
+ * Compute head offset i.e. number of bytes to add to
+ * get the start of the payload aligned.
+ */
+ if (spi_up_head_align) {
+ spad = 1 + ((info->hdr_len + 1) & spi_up_head_align);
+ *dst = (u8)(spad - 1);
+ dst += spad;
+ }
+
+ /* Copy in CAIF frame. */
+ skb_copy_bits(skb, 0, dst, skb->len);
+ dst += skb->len;
+ cfspi->ndev->stats.tx_packets++;
+ cfspi->ndev->stats.tx_bytes += skb->len;
+
+ /*
+ * Compute tail offset i.e. number of bytes to add to
+ * get the complete CAIF frame aligned.
+ */
+ epad = (skb->len + spad) & spi_up_tail_align;
+ dst += epad;
+
+ dev_kfree_skb(skb);
+
+ } while ((dst - buf) < len);
+
+ return dst - buf;
+}
+
+int cfspi_xmitlen(struct cfspi *cfspi)
+{
+ struct sk_buff *skb = NULL;
+ int frm_len = 0;
+ int pkts = 0;
+
+ /*
+ * Decommit previously commited frames.
+ * skb_queue_splice_tail(&cfspi->chead,&cfspi->qhead)
+ */
+ while (skb_peek(&cfspi->chead)) {
+ skb = skb_dequeue_tail(&cfspi->chead);
+ skb_queue_head(&cfspi->qhead, skb);
+ }
+
+ do {
+ struct caif_payload_info *info = NULL;
+ int spad = 0;
+ int epad = 0;
+
+ skb = skb_dequeue(&cfspi->qhead);
+ if (!skb)
+ break;
+
+ /*
+ * Calculate length of frame including SPI padding.
+ * The payload position is found in the control buffer.
+ */
+ info = (struct caif_payload_info *)&skb->cb;
+
+ /*
+ * Compute head offset i.e. number of bytes to add to
+ * get the start of the payload aligned.
+ */
+ if (spi_up_head_align)
+ spad = 1 + ((info->hdr_len + 1) & spi_up_head_align);
+
+ /*
+ * Compute tail offset i.e. number of bytes to add to
+ * get the complete CAIF frame aligned.
+ */
+ epad = (skb->len + spad) & spi_up_tail_align;
+
+ if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) {
+ skb_queue_tail(&cfspi->chead, skb);
+ pkts++;
+ frm_len += skb->len + spad + epad;
+ } else {
+ /* Put back packet. */
+ skb_queue_head(&cfspi->qhead, skb);
+ }
+ } while (pkts <= CAIF_MAX_SPI_PKTS);
+
+ /*
+ * Send flow on if previously sent flow off
+ * and now go below the low water mark
+ */
+ if (cfspi->flow_off_sent && cfspi->qhead.qlen < cfspi->qd_low_mark &&
+ cfspi->cfdev.flowctrl) {
+ cfspi->flow_off_sent = 0;
+ cfspi->cfdev.flowctrl(cfspi->ndev, 1);
+ }
+
+ return frm_len;
+}
+
+static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc)
+{
+ struct cfspi *cfspi = (struct cfspi *)ifc->priv;
+
+ if (!in_interrupt())
+ spin_lock(&cfspi->lock);
+ if (assert) {
+ set_bit(SPI_SS_ON, &cfspi->state);
+ set_bit(SPI_XFER, &cfspi->state);
+ } else {
+ set_bit(SPI_SS_OFF, &cfspi->state);
+ }
+ if (!in_interrupt())
+ spin_unlock(&cfspi->lock);
+
+ /* Wake up the xfer thread. */
+ wake_up_interruptible(&cfspi->wait);
+}
+
+static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc)
+{
+ struct cfspi *cfspi = (struct cfspi *)ifc->priv;
+
+ /* Transfer done, complete work queue */
+ complete(&cfspi->comp);
+}
+
+static int cfspi_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct cfspi *cfspi = NULL;
+ unsigned long flags;
+ if (!dev)
+ return -EINVAL;
+
+ cfspi = netdev_priv(dev);
+
+ skb_queue_tail(&cfspi->qhead, skb);
+
+ spin_lock_irqsave(&cfspi->lock, flags);
+ if (!test_and_set_bit(SPI_XFER, &cfspi->state)) {
+ /* Wake up xfer thread. */
+ wake_up_interruptible(&cfspi->wait);
+ }
+ spin_unlock_irqrestore(&cfspi->lock, flags);
+
+ /* Send flow off if number of bytes is above high water mark */
+ if (!cfspi->flow_off_sent &&
+ cfspi->qhead.qlen > cfspi->qd_high_mark &&
+ cfspi->cfdev.flowctrl) {
+ cfspi->flow_off_sent = 1;
+ cfspi->cfdev.flowctrl(cfspi->ndev, 0);
+ }
+
+ return 0;
+}
+
+int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len)
+{
+ u8 *src = buf;
+
+ caif_assert(buf != NULL);
+
+ do {
+ int res;
+ struct sk_buff *skb = NULL;
+ int spad = 0;
+ int epad = 0;
+ u8 *dst = NULL;
+ int pkt_len = 0;
+
+ /*
+ * Compute head offset i.e. number of bytes added to
+ * get the start of the payload aligned.
+ */
+ if (spi_down_head_align) {
+ spad = 1 + *src;
+ src += spad;
+ }
+
+ /* Read length of CAIF frame (little endian). */
+ pkt_len = *src;
+ pkt_len |= ((*(src+1)) << 8) & 0xFF00;
+ pkt_len += 2; /* Add FCS fields. */
+
+ /* Get a suitable caif packet and copy in data. */
+
+ skb = netdev_alloc_skb(cfspi->ndev, pkt_len + 1);
+ caif_assert(skb != NULL);
+
+ dst = skb_put(skb, pkt_len);
+ memcpy(dst, src, pkt_len);
+ src += pkt_len;
+
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+ skb->dev = cfspi->ndev;
+
+ /*
+ * Push received packet up the stack.
+ */
+ if (!spi_loop)
+ res = netif_rx_ni(skb);
+ else
+ res = cfspi_xmit(skb, cfspi->ndev);
+
+ if (!res) {
+ cfspi->ndev->stats.rx_packets++;
+ cfspi->ndev->stats.rx_bytes += pkt_len;
+ } else
+ cfspi->ndev->stats.rx_dropped++;
+
+ /*
+ * Compute tail offset i.e. number of bytes added to
+ * get the complete CAIF frame aligned.
+ */
+ epad = (pkt_len + spad) & spi_down_tail_align;
+ src += epad;
+ } while ((src - buf) < len);
+
+ return src - buf;
+}
+
+static int cfspi_open(struct net_device *dev)
+{
+ netif_wake_queue(dev);
+ return 0;
+}
+
+static int cfspi_close(struct net_device *dev)
+{
+ netif_stop_queue(dev);
+ return 0;
+}
+static const struct net_device_ops cfspi_ops = {
+ .ndo_open = cfspi_open,
+ .ndo_stop = cfspi_close,
+ .ndo_start_xmit = cfspi_xmit
+};
+
+static void cfspi_setup(struct net_device *dev)
+{
+ struct cfspi *cfspi = netdev_priv(dev);
+ dev->features = 0;
+ dev->netdev_ops = &cfspi_ops;
+ dev->type = ARPHRD_CAIF;
+ dev->flags = IFF_NOARP | IFF_POINTOPOINT;
+ dev->tx_queue_len = 0;
+ dev->mtu = SPI_MAX_PAYLOAD_SIZE;
+ dev->destructor = free_netdev;
+ skb_queue_head_init(&cfspi->qhead);
+ skb_queue_head_init(&cfspi->chead);
+ cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
+ cfspi->cfdev.use_frag = false;
+ cfspi->cfdev.use_stx = false;
+ cfspi->cfdev.use_fcs = false;
+ cfspi->ndev = dev;
+}
+
+int cfspi_spi_probe(struct platform_device *pdev)
+{
+ struct cfspi *cfspi = NULL;
+ struct net_device *ndev;
+ struct cfspi_dev *dev;
+ int res;
+ dev = (struct cfspi_dev *)pdev->dev.platform_data;
+
+ ndev = alloc_netdev(sizeof(struct cfspi),
+ "cfspi%d", cfspi_setup);
+ if (!dev)
+ return -ENODEV;
+
+ cfspi = netdev_priv(ndev);
+ netif_stop_queue(ndev);
+ cfspi->ndev = ndev;
+ cfspi->pdev = pdev;
+
+ /* Set flow info */
+ cfspi->flow_off_sent = 0;
+ cfspi->qd_low_mark = LOW_WATER_MARK;
+ cfspi->qd_high_mark = HIGH_WATER_MARK;
+
+ /* Assign the SPI device. */
+ cfspi->dev = dev;
+ /* Assign the device ifc to this SPI interface. */
+ dev->ifc = &cfspi->ifc;
+
+ /* Allocate DMA buffers. */
+ cfspi->xfer.va_tx = dma_alloc(&cfspi->xfer.pa_tx);
+ if (!cfspi->xfer.va_tx) {
+ printk(KERN_WARNING
+ "CFSPI: failed to allocate dma TX buffer.\n");
+ res = -ENODEV;
+ goto err_dma_alloc_tx;
+ }
+
+ cfspi->xfer.va_rx = dma_alloc(&cfspi->xfer.pa_rx);
+
+ if (!cfspi->xfer.va_rx) {
+ printk(KERN_WARNING
+ "CFSPI: failed to allocate dma TX buffer.\n");
+ res = -ENODEV;
+ goto err_dma_alloc_rx;
+ }
+
+ /* Initialize the work queue. */
+ INIT_WORK(&cfspi->work, cfspi_xfer);
+
+ /* Initialize spin locks. */
+ spin_lock_init(&cfspi->lock);
+
+ /* Initialize flow control state. */
+ cfspi->flow_stop = false;
+
+ /* Initialize wait queue. */
+ init_waitqueue_head(&cfspi->wait);
+
+ /* Create work thread. */
+ cfspi->wq = create_singlethread_workqueue(dev->name);
+ if (!cfspi->wq) {
+ printk(KERN_WARNING "CFSPI: failed to create work queue.\n");
+ res = -ENODEV;
+ goto err_create_wq;
+ }
+
+ /* Initialize work queue. */
+ init_completion(&cfspi->comp);
+
+ /* Create debugfs entries. */
+ dev_debugfs_add(cfspi);
+
+ /* Set up the ifc. */
+ cfspi->ifc.ss_cb = cfspi_ss_cb;
+ cfspi->ifc.xfer_done_cb = cfspi_xfer_done_cb;
+ cfspi->ifc.priv = cfspi;
+
+ /* Add CAIF SPI device to list. */
+ spin_lock(&cfspi_list_lock);
+ list_add_tail(&cfspi->list, &cfspi_list);
+ spin_unlock(&cfspi_list_lock);
+
+ /* Schedule the work queue. */
+ queue_work(cfspi->wq, &cfspi->work);
+
+ /* Register network device. */
+ res = register_netdev(ndev);
+ if (res) {
+ printk(KERN_ERR "CFSPI: Reg. error: %d.\n", res);
+ goto err_net_reg;
+ }
+ return res;
+
+ err_net_reg:
+ dev_debugfs_rem(cfspi);
+ set_bit(SPI_TERMINATE, &cfspi->state);
+ wake_up_interruptible(&cfspi->wait);
+ destroy_workqueue(cfspi->wq);
+ err_create_wq:
+ dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
+ err_dma_alloc_rx:
+ dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx);
+ err_dma_alloc_tx:
+ free_netdev(ndev);
+
+ return res;
+}
+
+int cfspi_spi_remove(struct platform_device *pdev)
+{
+ struct list_head *list_node;
+ struct list_head *n;
+ struct cfspi *cfspi = NULL;
+ struct cfspi_dev *dev;
+
+ dev = (struct cfspi_dev *)pdev->dev.platform_data;
+ spin_lock(&cfspi_list_lock);
+ list_for_each_safe(list_node, n, &cfspi_list) {
+ cfspi = list_entry(list_node, struct cfspi, list);
+ /* Find the corresponding device. */
+ if (cfspi->dev == dev) {
+ /* Remove from list. */
+ list_del(list_node);
+ /* Free DMA buffers. */
+ dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
+ dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx);
+ set_bit(SPI_TERMINATE, &cfspi->state);
+ wake_up_interruptible(&cfspi->wait);
+ destroy_workqueue(cfspi->wq);
+ /* Destroy debugfs directory and files. */
+ dev_debugfs_rem(cfspi);
+ unregister_netdev(cfspi->ndev);
+ spin_unlock(&cfspi_list_lock);
+ return 0;
+ }
+ }
+ spin_unlock(&cfspi_list_lock);
+ return -ENODEV;
+}
+
+static void __exit cfspi_exit_module(void)
+{
+ struct list_head *list_node;
+ struct list_head *n;
+ struct cfspi *cfspi = NULL;
+
+ list_for_each_safe(list_node, n, &cfspi_list) {
+ cfspi = list_entry(list_node, struct cfspi, list);
+ platform_device_unregister(cfspi->pdev);
+ }
+
+ /* Destroy sysfs files. */
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_head_align);
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_tail_align);
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_head_align);
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_tail_align);
+ driver_remove_file(&cfspi_spi_driver.driver, &driver_attr_frame_align);
+ /* Unregister platform driver. */
+ platform_driver_unregister(&cfspi_spi_driver);
+ /* Destroy debugfs root directory. */
+ driver_debugfs_remove();
+}
+
+static int __init cfspi_init_module(void)
+{
+ int result;
+
+ /* Initialize spin lock. */
+ spin_lock_init(&cfspi_list_lock);
+
+ /* Register platform driver. */
+ result = platform_driver_register(&cfspi_spi_driver);
+ if (result) {
+ printk(KERN_ERR "Could not register platform SPI driver.\n");
+ goto err_dev_register;
+ }
+
+ /* Create sysfs files. */
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_head_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 1.\n");
+ goto err_create_up_head_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_tail_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 2.\n");
+ goto err_create_up_tail_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_head_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 3.\n");
+ goto err_create_down_head_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_tail_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 4.\n");
+ goto err_create_down_tail_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_frame_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 5.\n");
+ goto err_create_frame_align;
+ }
+ driver_debugfs_create();
+ return result;
+
+ err_create_frame_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_tail_align);
+ err_create_down_tail_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_head_align);
+ err_create_down_head_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_tail_align);
+ err_create_up_tail_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_head_align);
+ err_create_up_head_align:
+ err_dev_register:
+ return result;
+}
+
+module_init(cfspi_init_module);
+module_exit(cfspi_exit_module);
diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c
new file mode 100644
index 0000000..077ccf8
--- /dev/null
+++ b/drivers/net/caif/caif_spi_slave.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com
+ * Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2.
+ */
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/debugfs.h>
+#include <net/caif/caif_spi.h>
+
+#ifndef CONFIG_CAIF_SPI_SYNC
+#define SPI_DATA_POS SPI_CMD_SZ
+static inline int forward_to_spi_cmd(struct cfspi *cfspi)
+{
+ return cfspi->rx_cpck_len;
+}
+#else
+#define SPI_DATA_POS 0
+static inline int forward_to_spi_cmd(struct cfspi *cfspi)
+{
+ return 0;
+}
+#endif
+
+int spi_frm_align = 2;
+int spi_up_head_align = 1;
+int spi_up_tail_align;
+int spi_down_head_align = 3;
+int spi_down_tail_align = 1;
+
+#ifdef CONFIG_DEBUG_FS
+static inline void debugfs_store_prev(struct cfspi *cfspi)
+{
+ /* Store previous command for debugging reasons.*/
+ cfspi->pcmd = cfspi->cmd;
+ /* Store previous transfer. */
+ cfspi->tx_ppck_len = cfspi->tx_cpck_len;
+ cfspi->rx_ppck_len = cfspi->rx_cpck_len;
+}
+#else
+static inline void debugfs_store_prev(struct cfspi *cfspi)
+{
+}
+#endif
+
+void cfspi_xfer(struct work_struct *work)
+{
+ struct cfspi *cfspi;
+ u8 *ptr = NULL;
+ unsigned long flags;
+ int ret;
+ cfspi = container_of(work, struct cfspi, work);
+
+ /* Initialize state. */
+ cfspi->cmd = SPI_CMD_EOT;
+
+ for (;;) {
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAITING);
+
+ /* Wait for master talk or transmit event. */
+ wait_event_interruptible(cfspi->wait,
+ test_bit(SPI_XFER, &cfspi->state) ||
+ test_bit(SPI_TERMINATE, &cfspi->state));
+
+ if (test_bit(SPI_TERMINATE, &cfspi->state))
+ return;
+
+#if CFSPI_DBG_PREFILL
+ /* Prefill buffers for easier debugging. */
+ memset(cfspi->xfer.va_tx, 0xFF, SPI_DMA_BUF_LEN);
+ memset(cfspi->xfer.va_rx, 0xFF, SPI_DMA_BUF_LEN);
+#endif /* CFSPI_DBG_PREFILL */
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_AWAKE);
+
+ /* Check whether we have a committed frame. */
+ if (cfspi->tx_cpck_len) {
+ int len;
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_FETCH_PKT);
+
+ /* Copy commited SPI frames after the SPI indication. */
+ ptr = (u8 *) cfspi->xfer.va_tx;
+ ptr += SPI_IND_SZ;
+ len = cfspi_xmitfrm(cfspi, ptr, cfspi->tx_cpck_len);
+ WARN_ON(len != cfspi->tx_cpck_len);
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_GET_NEXT);
+
+ /* Get length of next frame to commit. */
+ cfspi->tx_npck_len = cfspi_xmitlen(cfspi);
+
+ WARN_ON(cfspi->tx_npck_len > SPI_DMA_BUF_LEN);
+
+ /*
+ * Add indication and length at the beginning of the frame,
+ * using little endian.
+ */
+ ptr = (u8 *) cfspi->xfer.va_tx;
+ *ptr++ = SPI_CMD_IND;
+ *ptr++ = (SPI_CMD_IND & 0xFF00) >> 8;
+ *ptr++ = cfspi->tx_npck_len & 0x00FF;
+ *ptr++ = (cfspi->tx_npck_len & 0xFF00) >> 8;
+
+ /* Calculate length of DMAs. */
+ cfspi->xfer.tx_dma_len = cfspi->tx_cpck_len + SPI_IND_SZ;
+ cfspi->xfer.rx_dma_len = cfspi->rx_cpck_len + SPI_CMD_SZ;
+
+ /* Add SPI TX frame alignment padding, if necessary. */
+ if (cfspi->tx_cpck_len &&
+ (cfspi->xfer.tx_dma_len % spi_frm_align)) {
+
+ cfspi->xfer.tx_dma_len += spi_frm_align -
+ (cfspi->xfer.tx_dma_len % spi_frm_align);
+ }
+
+ /* Add SPI RX frame alignment padding, if necessary. */
+ if (cfspi->rx_cpck_len &&
+ (cfspi->xfer.rx_dma_len % spi_frm_align)) {
+
+ cfspi->xfer.rx_dma_len += spi_frm_align -
+ (cfspi->xfer.rx_dma_len % spi_frm_align);
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_INIT_XFER);
+
+ /* Start transfer. */
+ ret = cfspi->dev->init_xfer(&cfspi->xfer, cfspi->dev);
+ WARN_ON(ret);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_ACTIVE);
+
+ /*
+ * TODO: We might be able to make an assumption if this is the
+ * first loop. Make sure that minimum toggle time is respected.
+ */
+ udelay(MIN_TRANSITION_TIME_USEC);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_SIG_ACTIVE);
+
+ /* Signal that we are ready to recieve data. */
+ cfspi->dev->sig_xfer(true, cfspi->dev);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_XFER_DONE);
+
+ /* Wait for transfer completion. */
+ wait_for_completion(&cfspi->comp);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_XFER_DONE);
+
+ if (cfspi->cmd == SPI_CMD_EOT) {
+ /*
+ * Clear the master talk bit. A xfer is always at
+ * least two bursts.
+ */
+ clear_bit(SPI_SS_ON, &cfspi->state);
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_INACTIVE);
+
+ /* Make sure that the minimum toggle time is respected. */
+ if (SPI_XFER_TIME_USEC(cfspi->xfer.tx_dma_len,
+ cfspi->dev->clk_mhz) <
+ MIN_TRANSITION_TIME_USEC) {
+
+ udelay(MIN_TRANSITION_TIME_USEC -
+ SPI_XFER_TIME_USEC
+ (cfspi->xfer.tx_dma_len, cfspi->dev->clk_mhz));
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_SIG_INACTIVE);
+
+ /* De-assert transfer signal. */
+ cfspi->dev->sig_xfer(false, cfspi->dev);
+
+ /* Check whether we received a CAIF packet. */
+ if (cfspi->rx_cpck_len) {
+ int len;
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_DELIVER_PKT);
+
+ /* Parse SPI frame. */
+ ptr = ((u8 *)(cfspi->xfer.va_rx + SPI_DATA_POS));
+
+ len = cfspi_rxfrm(cfspi, ptr, cfspi->rx_cpck_len);
+ WARN_ON(len != cfspi->rx_cpck_len);
+ }
+
+ /* Check the next SPI command and length. */
+ ptr = (u8 *) cfspi->xfer.va_rx;
+
+ ptr += forward_to_spi_cmd(cfspi);
+
+ cfspi->cmd = *ptr++;
+ cfspi->cmd |= ((*ptr++) << 8) & 0xFF00;
+ cfspi->rx_npck_len = *ptr++;
+ cfspi->rx_npck_len |= ((*ptr++) << 8) & 0xFF00;
+
+ WARN_ON(cfspi->rx_npck_len > SPI_DMA_BUF_LEN);
+ WARN_ON(cfspi->cmd > SPI_CMD_EOT);
+
+ debugfs_store_prev(cfspi);
+
+ /* Check whether the master issued an EOT command. */
+ if (cfspi->cmd == SPI_CMD_EOT) {
+ /* Reset state. */
+ cfspi->tx_cpck_len = 0;
+ cfspi->rx_cpck_len = 0;
+ } else {
+ /* Update state. */
+ cfspi->tx_cpck_len = cfspi->tx_npck_len;
+ cfspi->rx_cpck_len = cfspi->rx_npck_len;
+ }
+
+ /*
+ * Check whether we need to clear the xfer bit.
+ * Spin lock needed for packet insertion.
+ * Test and clear of different bits
+ * are not supported.
+ */
+ spin_lock_irqsave(&cfspi->lock, flags);
+ if (cfspi->cmd == SPI_CMD_EOT && !cfspi_xmitlen(cfspi)
+ && !test_bit(SPI_SS_ON, &cfspi->state))
+ clear_bit(SPI_XFER, &cfspi->state);
+
+ spin_unlock_irqrestore(&cfspi->lock, flags);
+ }
+}
+
+struct platform_driver cfspi_spi_driver = {
+ .probe = cfspi_spi_probe,
+ .remove = cfspi_spi_remove,
+ .driver = {
+ .name = "cfspi_sspi",
+ .owner = THIS_MODULE,
+ },
+};
diff --git a/include/net/caif/caif_spi.h b/include/net/caif/caif_spi.h
new file mode 100644
index 0000000..ce4570d
--- /dev/null
+++ b/include/net/caif/caif_spi.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CAIF_SPI_H_
+#define CAIF_SPI_H_
+
+#include <net/caif/caif_device.h>
+
+#define SPI_CMD_WR 0x00
+#define SPI_CMD_RD 0x01
+#define SPI_CMD_EOT 0x02
+#define SPI_CMD_IND 0x04
+
+#define SPI_DMA_BUF_LEN 8192
+
+#define WL_SZ 2 /* 16 bits. */
+#define SPI_CMD_SZ 4 /* 32 bits. */
+#define SPI_IND_SZ 4 /* 32 bits. */
+
+#define SPI_XFER 0
+#define SPI_SS_ON 1
+#define SPI_SS_OFF 2
+#define SPI_TERMINATE 3
+
+/* Minimum time between different levels is 50 microseconds. */
+#define MIN_TRANSITION_TIME_USEC 50
+
+/* Defines for calculating duration of SPI transfers for a particular
+ * number of bytes.
+ */
+#define SPI_MASTER_CLK_MHZ 13
+#define SPI_XFER_TIME_USEC(bytes, clk) (((bytes) * 8) / clk)
+
+/* Normally this should be aligned on the modem in order to benefit from full
+ * duplex transfers. However a size of 8188 provokes errors when running with
+ * the modem. These errors occur when packet sizes approaches 4 kB of data.
+ */
+#define CAIF_MAX_SPI_FRAME 4092
+
+/* Maximum number of uplink CAIF frames that can reside in the same SPI frame.
+ * This number should correspond with the modem setting. The application side
+ * CAIF accepts any number of embedded downlink CAIF frames.
+ */
+#define CAIF_MAX_SPI_PKTS 9
+
+/* Decides if SPI buffers should be prefilled with 0xFF pattern for easier
+ * debugging. Both TX and RX buffers will be filled before the transfer.
+ */
+#define CFSPI_DBG_PREFILL 0
+
+/* Structure describing a SPI transfer. */
+struct cfspi_xfer {
+ u16 tx_dma_len;
+ u16 rx_dma_len;
+ void *va_tx;
+ dma_addr_t pa_tx;
+ void *va_rx;
+ dma_addr_t pa_rx;
+};
+
+/* Structure implemented by the SPI interface. */
+struct cfspi_ifc {
+ void (*ss_cb) (bool assert, struct cfspi_ifc *ifc);
+ void (*xfer_done_cb) (struct cfspi_ifc *ifc);
+ void *priv;
+};
+
+/* Structure implemented by SPI clients. */
+struct cfspi_dev {
+ int (*init_xfer) (struct cfspi_xfer *xfer, struct cfspi_dev *dev);
+ void (*sig_xfer) (bool xfer, struct cfspi_dev *dev);
+ struct cfspi_ifc *ifc;
+ char *name;
+ u32 clk_mhz;
+ void *priv;
+};
+
+/* Enumeration describing the CAIF SPI state. */
+enum cfspi_state {
+ CFSPI_STATE_WAITING = 0,
+ CFSPI_STATE_AWAKE,
+ CFSPI_STATE_FETCH_PKT,
+ CFSPI_STATE_GET_NEXT,
+ CFSPI_STATE_INIT_XFER,
+ CFSPI_STATE_WAIT_ACTIVE,
+ CFSPI_STATE_SIG_ACTIVE,
+ CFSPI_STATE_WAIT_XFER_DONE,
+ CFSPI_STATE_XFER_DONE,
+ CFSPI_STATE_WAIT_INACTIVE,
+ CFSPI_STATE_SIG_INACTIVE,
+ CFSPI_STATE_DELIVER_PKT,
+ CFSPI_STATE_MAX,
+};
+
+/* Structure implemented by SPI physical interfaces. */
+struct cfspi {
+ struct caif_dev_common cfdev;
+ struct net_device *ndev;
+ struct platform_device *pdev;
+ struct sk_buff_head qhead;
+ struct sk_buff_head chead;
+ u16 cmd;
+ u16 tx_cpck_len;
+ u16 tx_npck_len;
+ u16 rx_cpck_len;
+ u16 rx_npck_len;
+ struct cfspi_ifc ifc;
+ struct cfspi_xfer xfer;
+ struct cfspi_dev *dev;
+ unsigned long state;
+ struct work_struct work;
+ struct workqueue_struct *wq;
+ struct list_head list;
+ int flow_off_sent;
+ u32 qd_low_mark;
+ u32 qd_high_mark;
+ struct completion comp;
+ wait_queue_head_t wait;
+ spinlock_t lock;
+ bool flow_stop;
+#ifdef CONFIG_DEBUG_FS
+ enum cfspi_state dbg_state;
+ u16 pcmd;
+ u16 tx_ppck_len;
+ u16 rx_ppck_len;
+ struct dentry *dbgfs_dir;
+ struct dentry *dbgfs_state;
+ struct dentry *dbgfs_frame;
+#endif /* CONFIG_DEBUG_FS */
+};
+
+extern int spi_frm_align;
+extern int spi_up_head_align;
+extern int spi_up_tail_align;
+extern int spi_down_head_align;
+extern int spi_down_tail_align;
+extern struct platform_driver cfspi_spi_driver;
+
+void cfspi_dbg_state(struct cfspi *cfspi, int state);
+int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len);
+int cfspi_xmitlen(struct cfspi *cfspi);
+int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len);
+int cfspi_spi_remove(struct platform_device *pdev);
+int cfspi_spi_probe(struct platform_device *pdev);
+int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len);
+int cfspi_xmitlen(struct cfspi *cfspi);
+int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len);
+void cfspi_xfer(struct work_struct *work);
+
+#endif /* CAIF_SPI_H_ */
--
1.6.3.3
^ permalink raw reply related
* [PATCH 1/2] caif: Kconfig and Makefile fixes
From: sjur.brandeland @ 2010-06-26 21:31 UTC (permalink / raw)
To: davem
Cc: sjurbr, netdev, marcel, daniel.martensson, linus.walleij,
Sjur Braendeland
In-Reply-To: <20100625.211223.232914661.davem@davemloft.net>
From: Sjur Braendeland <sjur.brandeland@stericsson.com>
Use "depends on" instead of "if" in Kconfig files.
Fixed CAIF debug flag, and removed unnecessary clean-* options.
Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
David Miller wrote:
>Surrounding a config options with "if XXX" protection is not the
>proper way to protect config options. Simply add a proper "Depends"
>specification to it.
Thanks Dave,
I've updated the existing Kconfig files with "depends on" instead of "if".
drivers/net/caif/Kconfig | 5 +----
drivers/net/caif/Makefile | 10 ++--------
net/caif/Kconfig | 7 ++-----
net/caif/Makefile | 14 ++------------
4 files changed, 7 insertions(+), 29 deletions(-)
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
index 0b28e01..6f33ee4 100644
--- a/drivers/net/caif/Kconfig
+++ b/drivers/net/caif/Kconfig
@@ -2,16 +2,13 @@
# CAIF physical drivers
#
-if CAIF
-
comment "CAIF transport drivers"
config CAIF_TTY
tristate "CAIF TTY transport driver"
+ depends on CAIF
default n
---help---
The CAIF TTY transport driver is a Line Discipline (ldisc)
identified as N_CAIF. When this ldisc is opened from user space
it will redirect the TTY's traffic into the CAIF stack.
-
-endif # CAIF
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
index 52b6d1f..e6d3ca0 100644
--- a/drivers/net/caif/Makefile
+++ b/drivers/net/caif/Makefile
@@ -1,12 +1,6 @@
-ifeq ($(CONFIG_CAIF_DEBUG),1)
-CAIF_DBG_FLAGS := -DDEBUG
+ifeq ($(CONFIG_CAIF_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
endif
-KBUILD_EXTRA_SYMBOLS=net/caif/Module.symvers
-
-ccflags-y := $(CAIF_FLAGS) $(CAIF_DBG_FLAGS)
-clean-dirs:= .tmp_versions
-clean-files:= Module.symvers modules.order *.cmd *~ \
-
# Serial interface
obj-$(CONFIG_CAIF_TTY) += caif_serial.o
diff --git a/net/caif/Kconfig b/net/caif/Kconfig
index ed65178..529750d 100644
--- a/net/caif/Kconfig
+++ b/net/caif/Kconfig
@@ -21,19 +21,18 @@ menuconfig CAIF
See Documentation/networking/caif for a further explanation on how to
use and configure CAIF.
-if CAIF
-
config CAIF_DEBUG
bool "Enable Debug"
+ depends on CAIF
default n
--- help ---
Enable the inclusion of debug code in the CAIF stack.
Be aware that doing this will impact performance.
If unsure say N.
-
config CAIF_NETDEV
tristate "CAIF GPRS Network device"
+ depends on CAIF
default CAIF
---help---
Say Y if you will be using a CAIF based GPRS network device.
@@ -41,5 +40,3 @@ config CAIF_NETDEV
If you select to build it as a built-in then the main CAIF device must
also be a built-in.
If unsure say Y.
-
-endif
diff --git a/net/caif/Makefile b/net/caif/Makefile
index 34852af..f87481f 100644
--- a/net/caif/Makefile
+++ b/net/caif/Makefile
@@ -1,23 +1,13 @@
-ifeq ($(CONFIG_CAIF_DEBUG),1)
-CAIF_DBG_FLAGS := -DDEBUG
+ifeq ($(CONFIG_CAIF_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
endif
-ccflags-y := $(CAIF_FLAGS) $(CAIF_DBG_FLAGS)
-
caif-objs := caif_dev.o \
cfcnfg.o cfmuxl.o cfctrl.o \
cffrml.o cfveil.o cfdbgl.o\
cfserl.o cfdgml.o \
cfrfml.o cfvidl.o cfutill.o \
cfsrvl.o cfpkt_skbuff.o caif_config_util.o
-clean-dirs:= .tmp_versions
-
-clean-files:= \
- Module.symvers \
- modules.order \
- *.cmd \
- *.o \
- *~
obj-$(CONFIG_CAIF) += caif.o
obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o
--
1.6.3.3
^ permalink raw reply related
* Re: dhclient, checksum and tap
From: Michael S. Tsirkin @ 2010-06-26 21:14 UTC (permalink / raw)
To: David Miller; +Cc: herbert.xu, netdev
In-Reply-To: <20100625.112152.241921019.davem@davemloft.net>
On Fri, Jun 25, 2010 at 11:21:52AM -0700, David Miller wrote:
> From: "Michael S. Tsirkin" <mst@redhat.com>
> Date: Fri, 25 Jun 2010 18:10:08 +0300
>
> > I've been looking at the issue of checksum on
> > dhcp packets: to recap, 8dc4194474159660d7f37c495e3fc3f10d0db8cc
> > added a way for af_packet sockets to get the packet status.
> > Unfortunately not all dhcp clients caught up with
> > this development, so they are still broken
> > when both server and client run on the same host,
> > e.g. with bridge+tap.
> >
> > And of course virtualization adds another way to run
> > old dhcp clients, so userspace virtio net in qemu has
> > a hack to detect DHCP and fill in the checksum.
> > I guess we could add this in vhost, as well.
> >
> > However, one wonders whether the tap driver is a better place
> > for this work-around, that would help all users.
> > Any objections against putting such code in tap?
>
> We added the af_packet status as the migration path to deal with
> this issue in the cleanest manner possible. Putting a new hack
> into the TAP driver works contrary to that goal.
Hmm, problem is, using the af_packets status requires
userspace changes, and so does not help old clients.
And for virt, clients might be running old kernels without this support.
qemu has a hack to make old guests running within qemu work.
I guess I can copy that hack into vhost - a bit ugly as I don't have
access to the original skb there, so I will have to duplcate some logic,
but doable. Is this what you suggest? OTOH if we had the workaround in
tap, this could replace hacks in both vhost and qemu.
--
MST
^ permalink raw reply
* Re: nonlocal_bind & IPv6
From: Michal Humpula @ 2010-06-26 20:42 UTC (permalink / raw)
To: Simon Horman; +Cc: netdev
In-Reply-To: <20100626132540.GA30133@verge.net.au>
On Saturday 26 of June 2010 15:25:40 Simon Horman wrote:
> On Fri, Jun 25, 2010 at 09:10:08PM +0200, Michal Humpula wrote:
> > Ok, more detail example.
> >
> > Let on each node be an apache (just for an example), and you configure
> > VirtualHost for specific IP. So when node A fails, keepalived move IP to
> > the node B and everything is still running. No need for restart of apache
> > or anything else. There is a probably a better solution, but I can't find
> > anything more simple than the posted patch:)
>
> Not an answer to your original question, but that sounds like a problem
> that can be resolved using IP_TRANSPARENT. Although I have only tested
> that feature in conjunction with IPv4, it seems to support IPv6 too.
>
> See Documentation/networking/tproxy.txt
Thanks for redirection. I don't think that IP_TRANSPARENT is suited well for my problem,
but I did find the IP_FREEBIND in the process. Unfortunately it seems that both are
enabled only for IPv4 and IPv6 mapped addresses.
So, is there any reason why IP_FREEBIND or nonlocal_bind sysctl is not in current IPv6
kernel implementation?
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/2 v2] man - IP_NODEFRAG option for IPv4 socket
From: Jiri Olsa @ 2010-06-26 19:13 UTC (permalink / raw)
To: David Miller
Cc: mtk.manpages, eric.dumazet, jengelh, kaber, netdev,
netfilter-devel, linux-man
In-Reply-To: <20100626.095857.137828263.davem@davemloft.net>
On Sat, Jun 26, 2010 at 09:58:57AM -0700, David Miller wrote:
> From: Michael Kerrisk <mtk.manpages@gmail.com>
> Date: Sat, 26 Jun 2010 15:01:03 +0200
>
> >> sent from this socket.
> >> +.TP
> >> +.BR IP_NODEFRAG " (since Linux 2.6)"
> >
> > here, we'd write the exact version in which the flag is added. It
> > looks like that might be 2.36, right?
>
> It'll show up in 2.6.36
>
> I doubt I'll be alive when we make it to 2.36 :-)
:) ok, attaching changed patch
thanks,
jirka
---
hi,
this patch adds description for IP_NODEFRAG option for IPv4 socket.
wbr,
jirka
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
man7/ip.7 | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/man7/ip.7 b/man7/ip.7
index 34f7e80..12c0d5b 100644
--- a/man7/ip.7
+++ b/man7/ip.7
@@ -705,6 +705,12 @@ socket option (see
.BR IP_TTL " (since Linux 1.0)"
Set or retrieve the current time-to-live field that is used in every packet
sent from this socket.
+.TP
+.BR IP_NODEFRAG " (since Linux 2.6.36)"
+If enabled, the reassembly of outgoing packets is disabled in the netfilter layer.
+Only valid for
+.B SOCK_RAW
+sockets.
.\" FIXME Document IP_XFRM_POLICY
.\" Since Linux 2.5.48
.\" Needs CAP_NET_ADMIN
^ permalink raw reply related
* Re: [PATCH 2/2] man - IP_NODEFRAG option for IPv4 socket
From: David Miller @ 2010-06-26 16:58 UTC (permalink / raw)
To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
Cc: jolsa-H+wXaHxf7aLQT0dZR+AlfA, eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
jengelh-nopoi9nDyk+ELgA04lAiVw, kaber-dcUjhNyLwpNeoWH0uzbU5w,
netdev-u79uwXL29TY76Z2rM5mHXA,
netfilter-devel-u79uwXL29TY76Z2rM5mHXA,
linux-man-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <AANLkTim4N5rc8Sn_uo5bXsb9vjvKd3GTQD3p-1uApbB8-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
From: Michael Kerrisk <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Sat, 26 Jun 2010 15:01:03 +0200
>> sent from this socket.
>> +.TP
>> +.BR IP_NODEFRAG " (since Linux 2.6)"
>
> here, we'd write the exact version in which the flag is added. It
> looks like that might be 2.36, right?
It'll show up in 2.6.36
I doubt I'll be alive when we make it to 2.36 :-)
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] usb: pegasus: fixed coding style issues
From: Nicolas Kaiser @ 2010-06-26 16:58 UTC (permalink / raw)
To: Petko Manolov
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
Fixed brace, static initialization, comment, whitespace and spacing
coding style issues.
Signed-off-by: Nicolas Kaiser <nikai-bVCNqDZ4lKNeoWH0uzbU5w@public.gmane.org>
---
drivers/net/usb/pegasus.c | 125 +++++++++----------
drivers/net/usb/pegasus.h | 296 ++++++++++++++++++++++----------------------
2 files changed, 209 insertions(+), 212 deletions(-)
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 974d17f..6710f09 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -21,11 +21,11 @@
* behaves. Pegasus II support added since this version.
* TODO: suppressing HCD warnings spewage on disconnect.
* v0.4.13 Ethernet address is now set at probe(), not at open()
- * time as this seems to break dhcpd.
+ * time as this seems to break dhcpd.
* v0.5.0 branch to 2.5.x kernels
* v0.5.1 ethtool support added
* v0.5.5 rx socket buffers are in a pool and the their allocation
- * is out of the interrupt routine.
+ * is out of the interrupt routine.
*/
#include <linux/sched.h>
@@ -55,9 +55,9 @@ static const char driver_name[] = "pegasus";
#define BMSR_MEDIA (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \
BMSR_100FULL | BMSR_ANEGCAPABLE)
-static int loopback = 0;
-static int mii_mode = 0;
-static char *devid=NULL;
+static int loopback;
+static int mii_mode;
+static char *devid;
static struct usb_eth_dev usb_dev_id[] = {
#define PEGASUS_DEV(pn, vid, pid, flags) \
@@ -102,8 +102,8 @@ MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'");
/* use ethtool to change the level for any given device */
static int msg_level = -1;
-module_param (msg_level, int, 0);
-MODULE_PARM_DESC (msg_level, "Override default message level");
+module_param(msg_level, int, 0);
+MODULE_PARM_DESC(msg_level, "Override default message level");
MODULE_DEVICE_TABLE(usb, pegasus_ids);
static const struct net_device_ops pegasus_netdev_ops;
@@ -141,7 +141,7 @@ static void ctrl_callback(struct urb *urb)
wake_up(&pegasus->ctrl_wait);
}
-static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
+static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
void *data)
{
int ret;
@@ -196,7 +196,7 @@ out:
return ret;
}
-static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
+static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
void *data)
{
int ret;
@@ -248,7 +248,7 @@ out:
return ret;
}
-static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
+static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
{
int ret;
char *tmp;
@@ -299,7 +299,7 @@ out:
return ret;
}
-static int update_eth_regs_async(pegasus_t * pegasus)
+static int update_eth_regs_async(pegasus_t *pegasus)
{
int ret;
@@ -326,7 +326,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)
}
/* Returns 0 on success, error on failure */
-static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
+static int read_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd)
{
int i;
__u8 data[4] = { phy, 0, 0, indx };
@@ -334,7 +334,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
int ret;
set_register(pegasus, PhyCtrl, 0);
- set_registers(pegasus, PhyAddr, sizeof (data), data);
+ set_registers(pegasus, PhyAddr, sizeof(data), data);
set_register(pegasus, PhyCtrl, (indx | PHY_READ));
for (i = 0; i < REG_TIMEOUT; i++) {
ret = get_registers(pegasus, PhyCtrl, 1, data);
@@ -366,7 +366,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int loc)
return (int)res;
}
-static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
+static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 regd)
{
int i;
__u8 data[4] = { phy, 0, 0, indx };
@@ -402,7 +402,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
write_mii_word(pegasus, phy_id, loc, val);
}
-static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
+static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata)
{
int i;
__u8 tmp;
@@ -433,7 +433,7 @@ fail:
}
#ifdef PEGASUS_WRITE_EEPROM
-static inline void enable_eprom_write(pegasus_t * pegasus)
+static inline void enable_eprom_write(pegasus_t *pegasus)
{
__u8 tmp;
int ret;
@@ -442,7 +442,7 @@ static inline void enable_eprom_write(pegasus_t * pegasus)
set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
}
-static inline void disable_eprom_write(pegasus_t * pegasus)
+static inline void disable_eprom_write(pegasus_t *pegasus)
{
__u8 tmp;
int ret;
@@ -452,7 +452,7 @@ static inline void disable_eprom_write(pegasus_t * pegasus)
set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
}
-static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
+static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data)
{
int i;
__u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
@@ -484,7 +484,7 @@ fail:
}
#endif /* PEGASUS_WRITE_EEPROM */
-static inline void get_node_id(pegasus_t * pegasus, __u8 * id)
+static inline void get_node_id(pegasus_t *pegasus, __u8 *id)
{
int i;
__u16 w16;
@@ -495,7 +495,7 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id)
}
}
-static void set_ethernet_addr(pegasus_t * pegasus)
+static void set_ethernet_addr(pegasus_t *pegasus)
{
__u8 node_id[6];
@@ -503,12 +503,12 @@ static void set_ethernet_addr(pegasus_t * pegasus)
get_registers(pegasus, 0x10, sizeof(node_id), node_id);
} else {
get_node_id(pegasus, node_id);
- set_registers(pegasus, EthID, sizeof (node_id), node_id);
+ set_registers(pegasus, EthID, sizeof(node_id), node_id);
}
- memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id));
+ memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id));
}
-static inline int reset_mac(pegasus_t * pegasus)
+static inline int reset_mac(pegasus_t *pegasus)
{
__u8 data = 0x8;
int i;
@@ -563,7 +563,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
data[1] = 0;
data[2] = (loopback & 1) ? 0x09 : 0x01;
- memcpy(pegasus->eth_regs, data, sizeof (data));
+ memcpy(pegasus->eth_regs, data, sizeof(data));
ret = set_registers(pegasus, EthCtrl0, 3, data);
if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
@@ -577,7 +577,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
return ret;
}
-static void fill_skb_pool(pegasus_t * pegasus)
+static void fill_skb_pool(pegasus_t *pegasus)
{
int i;
@@ -595,7 +595,7 @@ static void fill_skb_pool(pegasus_t * pegasus)
}
}
-static void free_skb_pool(pegasus_t * pegasus)
+static void free_skb_pool(pegasus_t *pegasus)
{
int i;
@@ -667,11 +667,11 @@ static void read_bulk_callback(struct urb *urb)
netif_dbg(pegasus, rx_err, net,
"RX packet error %x\n", rx_status);
pegasus->stats.rx_errors++;
- if (rx_status & 0x06) // long or runt
+ if (rx_status & 0x06) /* long or runt */
pegasus->stats.rx_length_errors++;
if (rx_status & 0x08)
pegasus->stats.rx_crc_errors++;
- if (rx_status & 0x10) // extra bits
+ if (rx_status & 0x10) /* extra bits */
pegasus->stats.rx_frame_errors++;
goto goon;
}
@@ -748,9 +748,8 @@ static void rx_fixup(unsigned long data)
if (pegasus->flags & PEGASUS_RX_URB_FAIL)
if (pegasus->rx_skb)
goto try_again;
- if (pegasus->rx_skb == NULL) {
+ if (pegasus->rx_skb == NULL)
pegasus->rx_skb = pull_skb(pegasus);
- }
if (pegasus->rx_skb == NULL) {
netif_warn(pegasus, rx_err, pegasus->net, "low on memory\n");
tasklet_schedule(&pegasus->rx_tl);
@@ -835,7 +834,7 @@ static void intr_callback(struct urb *urb)
}
if (urb->actual_length >= 6) {
- u8 * d = urb->transfer_buffer;
+ u8 *d = urb->transfer_buffer;
/* byte 0 == tx_status1, reg 2B */
if (d[0] & (TX_UNDERRUN|EXCESSIVE_COL
@@ -918,14 +917,14 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
return &((pegasus_t *) netdev_priv(dev))->stats;
}
-static inline void disable_net_traffic(pegasus_t * pegasus)
+static inline void disable_net_traffic(pegasus_t *pegasus)
{
__le16 tmp = cpu_to_le16(0);
set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp);
}
-static inline void get_interrupt_interval(pegasus_t * pegasus)
+static inline void get_interrupt_interval(pegasus_t *pegasus)
{
u16 data;
u8 interval;
@@ -961,7 +960,7 @@ static void set_carrier(struct net_device *net)
netif_carrier_off(net);
}
-static void free_all_urbs(pegasus_t * pegasus)
+static void free_all_urbs(pegasus_t *pegasus)
{
usb_free_urb(pegasus->intr_urb);
usb_free_urb(pegasus->tx_urb);
@@ -969,7 +968,7 @@ static void free_all_urbs(pegasus_t * pegasus)
usb_free_urb(pegasus->ctrl_urb);
}
-static void unlink_all_urbs(pegasus_t * pegasus)
+static void unlink_all_urbs(pegasus_t *pegasus)
{
usb_kill_urb(pegasus->intr_urb);
usb_kill_urb(pegasus->tx_urb);
@@ -977,12 +976,11 @@ static void unlink_all_urbs(pegasus_t * pegasus)
usb_kill_urb(pegasus->ctrl_urb);
}
-static int alloc_urbs(pegasus_t * pegasus)
+static int alloc_urbs(pegasus_t *pegasus)
{
pegasus->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!pegasus->ctrl_urb) {
+ if (!pegasus->ctrl_urb)
return 0;
- }
pegasus->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pegasus->rx_urb) {
usb_free_urb(pegasus->ctrl_urb);
@@ -1019,7 +1017,7 @@ static int pegasus_open(struct net_device *net)
return -ENOMEM;
res = set_registers(pegasus, EthID, 6, net->dev_addr);
-
+
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
usb_rcvbulkpipe(pegasus->usb, 1),
pegasus->rx_skb->data, PEGASUS_MTU + 8,
@@ -1033,7 +1031,7 @@ static int pegasus_open(struct net_device *net)
usb_fill_int_urb(pegasus->intr_urb, pegasus->usb,
usb_rcvintpipe(pegasus->usb, 3),
- pegasus->intr_buff, sizeof (pegasus->intr_buff),
+ pegasus->intr_buff, sizeof(pegasus->intr_buff),
intr_callback, pegasus, pegasus->intr_interval);
if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) {
if (res == -ENODEV)
@@ -1076,9 +1074,9 @@ static void pegasus_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
pegasus_t *pegasus = netdev_priv(dev);
- strncpy(info->driver, driver_name, sizeof (info->driver) - 1);
- strncpy(info->version, DRIVER_VERSION, sizeof (info->version) - 1);
- usb_make_path(pegasus->usb, info->bus_info, sizeof (info->bus_info));
+ strncpy(info->driver, driver_name, sizeof(info->driver) - 1);
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
+ usb_make_path(pegasus->usb, info->bus_info, sizeof(info->bus_info));
}
/* also handles three patterns of some kind in hardware */
@@ -1098,7 +1096,7 @@ pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
pegasus_t *pegasus = netdev_priv(dev);
u8 reg78 = 0x04;
-
+
if (wol->wolopts & ~WOL_SUPPORTED)
return -EINVAL;
@@ -1118,7 +1116,7 @@ pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
static inline void pegasus_reset_wol(struct net_device *dev)
{
struct ethtool_wolinfo wol;
-
+
memset(&wol, 0, sizeof wol);
(void) pegasus_set_wol(dev, &wol);
}
@@ -1178,7 +1176,7 @@ static const struct ethtool_ops ops = {
static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
{
- __u16 *data = (__u16 *) & rq->ifr_ifru;
+ __u16 *data = (__u16 *) &rq->ifr_ifru;
pegasus_t *pegasus = netdev_priv(net);
int res;
@@ -1223,7 +1221,7 @@ static void pegasus_set_multicast(struct net_device *net)
ctrl_callback(pegasus->ctrl_urb);
}
-static __u8 mii_phy_probe(pegasus_t * pegasus)
+static __u8 mii_phy_probe(pegasus_t *pegasus)
{
int i;
__u16 tmp;
@@ -1239,10 +1237,10 @@ static __u8 mii_phy_probe(pegasus_t * pegasus)
return 0xff;
}
-static inline void setup_pegasus_II(pegasus_t * pegasus)
+static inline void setup_pegasus_II(pegasus_t *pegasus)
{
__u8 data = 0xa5;
-
+
set_register(pegasus, Reg1d, 0);
set_register(pegasus, Reg7b, 1);
mdelay(100);
@@ -1254,16 +1252,15 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
set_register(pegasus, 0x83, data);
get_registers(pegasus, 0x83, 1, &data);
- if (data == 0xa5) {
+ if (data == 0xa5)
pegasus->chip = 0x8513;
- } else {
+ else
pegasus->chip = 0;
- }
set_register(pegasus, 0x80, 0xc0);
set_register(pegasus, 0x83, 0xff);
set_register(pegasus, 0x84, 0x01);
-
+
if (pegasus->features & HAS_HOME_PNA && mii_mode)
set_register(pegasus, Reg81, 6);
else
@@ -1272,7 +1269,7 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
static int pegasus_count;
-static struct workqueue_struct *pegasus_workqueue = NULL;
+static struct workqueue_struct *pegasus_workqueue;
#define CARRIER_CHECK_DELAY (2 * HZ)
static void check_carrier(struct work_struct *work)
@@ -1367,7 +1364,7 @@ static int pegasus_probe(struct usb_interface *intf,
pegasus->mii.phy_id_mask = 0x1f;
pegasus->mii.reg_num_mask = 0x1f;
spin_lock_init(&pegasus->rx_pool_lock);
- pegasus->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
+ pegasus->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV
| NETIF_MSG_PROBE | NETIF_MSG_LINK);
pegasus->features = usb_dev_id[dev_index].private;
@@ -1442,11 +1439,11 @@ static void pegasus_disconnect(struct usb_interface *intf)
pegasus_dec_workqueue();
}
-static int pegasus_suspend (struct usb_interface *intf, pm_message_t message)
+static int pegasus_suspend(struct usb_interface *intf, pm_message_t message)
{
struct pegasus *pegasus = usb_get_intfdata(intf);
-
- netif_device_detach (pegasus->net);
+
+ netif_device_detach(pegasus->net);
cancel_delayed_work(&pegasus->carrier_check);
if (netif_running(pegasus->net)) {
usb_kill_urb(pegasus->rx_urb);
@@ -1455,11 +1452,11 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message)
return 0;
}
-static int pegasus_resume (struct usb_interface *intf)
+static int pegasus_resume(struct usb_interface *intf)
{
struct pegasus *pegasus = usb_get_intfdata(intf);
- netif_device_attach (pegasus->net);
+ netif_device_attach(pegasus->net);
if (netif_running(pegasus->net)) {
pegasus->rx_urb->status = 0;
pegasus->rx_urb->actual_length = 0;
@@ -1498,8 +1495,8 @@ static struct usb_driver pegasus_driver = {
static void __init parse_id(char *id)
{
- unsigned int vendor_id=0, device_id=0, flags=0, i=0;
- char *token, *name=NULL;
+ unsigned int vendor_id = 0, device_id = 0, flags = 0, i = 0;
+ char *token, *name = NULL;
if ((token = strsep(&id, ":")) != NULL)
name = token;
@@ -1510,14 +1507,14 @@ static void __init parse_id(char *id)
device_id = simple_strtoul(token, NULL, 16);
flags = simple_strtoul(id, NULL, 16);
pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n",
- driver_name, name, vendor_id, device_id, flags);
+ driver_name, name, vendor_id, device_id, flags);
if (vendor_id > 0x10000 || vendor_id == 0)
return;
if (device_id > 0x10000 || device_id == 0)
return;
- for (i=0; usb_dev_id[i].name; i++);
+ for (i = 0; usb_dev_id[i].name; i++);
usb_dev_id[i].name = name;
usb_dev_id[i].vendor = vendor_id;
usb_dev_id[i].device = device_id;
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index 29f5211..65b78b3 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -68,7 +68,7 @@ enum pegasus_registers {
EpromData = 0x21, /* 0x21 low, 0x22 high byte */
EpromCtrl = 0x23,
PhyAddr = 0x25,
- PhyData = 0x26, /* 0x26 low, 0x27 high byte */
+ PhyData = 0x26, /* 0x26 low, 0x27 high byte */
PhyCtrl = 0x28,
UsbStst = 0x2a,
EthTxStat0 = 0x2b,
@@ -154,162 +154,162 @@ struct usb_eth_dev {
#else /* PEGASUS_DEV */
-PEGASUS_DEV( "3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
- DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
-PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4004,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4007,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4102,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4002,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
+PEGASUS_DEV("3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
+ DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
+PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
+ DEFAULT_GPIO_RESET | HAS_HOME_PNA)
+PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4004,
+ DEFAULT_GPIO_RESET | HAS_HOME_PNA)
+PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4007,
+ DEFAULT_GPIO_RESET | HAS_HOME_PNA)
+PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4102,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4002,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400b,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
VENDOR_ADMTEK, 0x8511,
- DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
-PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
+ DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
+PEGASUS_DEV("ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
VENDOR_ADMTEK, 0x8513,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "ADMtek ADM8515 \"Pegasus II\" USB-2.0 Ethernet",
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("ADMtek ADM8515 \"Pegasus II\" USB-2.0 Ethernet",
VENDOR_ADMTEK, 0x8515,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)",
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)",
VENDOR_ADMTEK, 0x0986,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "AN986A USB MAC", VENDOR_ADMTEK, 1986,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
- DEFAULT_GPIO_RESET | PEGASUS_II )
+ DEFAULT_GPIO_RESET | HAS_HOME_PNA)
+PEGASUS_DEV("AN986A USB MAC", VENDOR_ADMTEK, 1986,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
/*
* Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors
* with the same product IDs by checking the device class too.
*/
-PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "iPAQ Networking 10/100 USB", VENDOR_COMPAQ, 0x8511,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Corega FEther USB-TX", VENDOR_COREGA, 0x0004,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Corega FEther USB-TXS", VENDOR_COREGA, 0x000d,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4102,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
- DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
-PEGASUS_DEV( "ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "EasiDock Ethernet", VENDOR_MOBILITY, 0x0304,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "IO DATA USB ETX-US2", VENDOR_IODATA, 0x093a,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
+PEGASUS_DEV_CLASS("Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
+ DEFAULT_GPIO_RESET | HAS_HOME_PNA)
+PEGASUS_DEV("iPAQ Networking 10/100 USB", VENDOR_COMPAQ, 0x8511,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Billionton USBE-100", VENDOR_BILLIONTON, 0x8511,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Corega FEther USB-TX", VENDOR_COREGA, 0x0004,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Corega FEther USB-TXS", VENDOR_COREGA, 0x000d,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4001,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4002,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4102,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x400b,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x200c,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003,
+ DEFAULT_GPIO_RESET | HAS_HOME_PNA)
+PEGASUS_DEV("D-Link DSB-650", VENDOR_DLINK, 0xabc1,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
+ DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA)
+PEGASUS_DEV("ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("EasiDock Ethernet", VENDOR_MOBILITY, 0x0304,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
DEFAULT_GPIO_RESET)
-PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
- DEFAULT_GPIO_RESET | HAS_HOME_PNA )
-PEGASUS_DEV( "Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV( "Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "Microsoft MN-110", VENDOR_MICROSOFT, 0x007a,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "OCT Inc.", VENDOR_OCT, 0x0109,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "OCT USB TO Ethernet", VENDOR_OCT, 0x0901,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
- DEFAULT_GPIO_RESET | PEGASUS_II)
-PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
- DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
- DEFAULT_GPIO_RESET | PEGASUS_II )
-PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
- DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV("GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("IO DATA USB ETX-US2", VENDOR_IODATA, 0x093a,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x2202,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2203,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2204,
+ DEFAULT_GPIO_RESET | HAS_HOME_PNA)
+PEGASUS_DEV("Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x200c,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("Microsoft MN-110", VENDOR_MICROSOFT, 0x007a,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("OCT Inc.", VENDOR_OCT, 0x0109,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("OCT USB TO Ethernet", VENDOR_OCT, 0x0901,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
+ DEFAULT_GPIO_RESET)
+PEGASUS_DEV("SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
+PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001,
+ DEFAULT_GPIO_RESET | PEGASUS_II)
#endif /* PEGASUS_DEV */
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: nonlocal_bind & IPv6
From: Simon Horman @ 2010-06-26 13:25 UTC (permalink / raw)
To: Michal Humpula; +Cc: Rémi Denis-Courmont, netdev
In-Reply-To: <201006252110.08508.michal.humpula@hudrydum.cz>
On Fri, Jun 25, 2010 at 09:10:08PM +0200, Michal Humpula wrote:
> Ok, more detail example.
>
> Let on each node be an apache (just for an example), and you configure
> VirtualHost for specific IP. So when node A fails, keepalived move IP to
> the node B and everything is still running. No need for restart of apache
> or anything else. There is a probably a better solution, but I can't find
> anything more simple than the posted patch:)
Not an answer to your original question, but that sounds like a problem
that can be resolved using IP_TRANSPARENT. Although I have only tested
that feature in conjunction with IPv4, it seems to support IPv6 too.
See Documentation/networking/tproxy.txt
^ permalink raw reply
* Re: [PATCH 4/9] cxgb4vf: Add code to provision T4 PCI-E SR-IOV Virtual Functions with hardware resources
From: Simon Horman @ 2010-06-26 13:37 UTC (permalink / raw)
To: Casey Leedom; +Cc: netdev
In-Reply-To: <201006251511.46660.leedom@chelsio.com>
On Fri, Jun 25, 2010 at 03:11:46PM -0700, Casey Leedom wrote:
> Add code to provision T4 PCI-E SR-IOV Virtual Functions with hardware
> resources.
>
> Signed-off-by: Casey Leedom
> ---
> drivers/net/cxgb4/cxgb4_main.c | 106
> ++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 106 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
> index 27f65b5..6528167 100644
> --- a/drivers/net/cxgb4/cxgb4_main.c
> +++ b/drivers/net/cxgb4/cxgb4_main.c
> @@ -77,6 +77,76 @@
> */
> #define MAX_SGE_TIMERVAL 200U
>
> +#ifdef CONFIG_PCI_IOV
> +/*
> + * Virtual Function provisioning constants. We need two extra Ingress Queues
> + * with Interrupt capability to serve as the VF's Firmware Event Queue and
> + * Forwarded Interrupt Queue (when using MSI mode) -- neither will have Free
> + * Lists associated with them). For each Ethernet/Control Egress Queue and
> + * for each Free List, we need an Egress Context.
> + */
> +enum {
> + VFRES_NPORTS = 1, /* # of "ports" per VF */
> + VFRES_NQSETS = 2, /* # of "Queue Sets" per VF */
> +
> + VFRES_NVI = VFRES_NPORTS, /* # of Virtual Interfaces */
> + VFRES_NETHCTRL = VFRES_NQSETS, /* # of EQs used for ETH or CTRL Qs */
> + VFRES_NIQFLINT = VFRES_NQSETS+2,/* # of ingress Qs/w Free List(s)/intr */
> + VFRES_NIQ = 0, /* # of non-fl/int ingress queues */
> + VFRES_NEQ = VFRES_NQSETS*2, /* # of egress queues */
> + VFRES_TC = 0, /* PCI-E traffic class */
> + VFRES_NEXACTF = 16, /* # of exact MPS filters */
> +
> + VFRES_R_CAPS = FW_CMD_CAP_DMAQ|FW_CMD_CAP_VF|FW_CMD_CAP_PORT,
> + VFRES_WX_CAPS = FW_CMD_CAP_DMAQ|FW_CMD_CAP_VF,
> +};
> +
> +/*
> + * Provide a Port Access Rights Mask for the specified PF/VF. This is very
> + * static and likely not to be useful in the long run. We really need to
> + * implement some form of persistent configuration which the firmware
> + * controls.
> + */
> +static unsigned int pfvfres_pmask(struct adapter *adapter,
> + unsigned int pf, unsigned int vf)
> +{
> + unsigned int portn, portvec;
> +
> + /*
> + * Give PF's access to all of the ports.
> + */
> + if (vf == 0)
> + return FW_PFVF_CMD_PMASK_MASK;
> +
> + /*
> + * For VFs, we'll assign them access to the ports based purely on the
> + * PF. We assign active ports in order, wrapping around if there are
> + * fewer active ports than PFs: e.g. active port[pf % nports].
> + * Unfortunately the adapter's port_info structs haven't been
> + * initialized yet so we have to compute this.
> + */
> + if (adapter->params.nports == 0)
> + return 0;
> +
> + portn = pf % adapter->params.nports;
> + portvec = adapter->params.portvec;
> + for (;;) {
> + /*
> + * Isolate the lowest set bit in the port vector. If we're at
> + * the port number that we want, return that as the pmask.
> + * otherwise mask that bit out of the port vector and
> + * decrement our port number ...
> + */
> + unsigned int pmask = portvec ^ (portvec & (portvec-1));
> + if (portn == 0)
> + return pmask;
> + portn--;
> + portvec &= ~pmask;
> + }
> + /*NOTREACHED*/
> +}
> +#endif
> +
> enum {
> MEMWIN0_APERTURE = 65536,
> MEMWIN0_BASE = 0x30000,
> @@ -2925,6 +2995,42 @@ static int adap_init0(struct adapter *adap)
> t4_read_mtu_tbl(adap, adap->params.mtus, NULL);
> t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd,
> adap->params.b_wnd);
> +
> +#ifdef CONFIG_PCI_IOV
> + /*
> + * Provision resource limits for Virtual Functions. We currently
> + * grant them all the same static resource limits except for the Port
> + * Access Rights Mask which we're assigning based on the PF. All of
> + * the static provisioning stuff for both the PF and VF really needs
> + * to be managed in a persistent manner for each device which the
> + * firmware controls.
> + */
> + {
> + int pf, vf;
> +
> + for (pf = 0; pf < ARRAY_SIZE(num_vf); pf++) {
> + if (num_vf[pf] <= 0)
> + continue;
> +
> + /* VF numbering starts at 1! */
> + for (vf = 1; vf <= num_vf[pf]; vf++) {
> + ret = t4_cfg_pfvf(adap, 0, pf, vf,
> + VFRES_NEQ, VFRES_NETHCTRL,
> + VFRES_NIQFLINT, VFRES_NIQ,
> + VFRES_TC, VFRES_NVI,
> + FW_PFVF_CMD_CMASK_MASK,
> + pfvfres_pmask(adap, pf, vf),
> + VFRES_NEXACTF,
> + VFRES_R_CAPS, VFRES_WX_CAPS);
> + if (ret < 0)
> + dev_warn(adap->pdev_dev, "failed to "
> + "provision pf/vf=%d/%d; "
> + "err=%d\n", pf, vf, ret);
> + }
> + }
> + }
> +#endif
> +
> return 0;
I wonder if it would be cleaner to move the guts of the last hunk
into a function (e.g. adap_init_sriov()) and have that be a dummy
function in the case that CONFIG_PCI_IOV in the first hunk is not set.
^ permalink raw reply
* Re: [PATCH 2/2] man - IP_NODEFRAG option for IPv4 socket
From: Michael Kerrisk @ 2010-06-26 13:01 UTC (permalink / raw)
To: Jiri Olsa
Cc: eric.dumazet, jengelh, kaber, netdev, netfilter-devel, linux-man
In-Reply-To: <1276600052-16499-3-git-send-email-jolsa@redhat.com>
Hi Jiri,
Thanks for this patch. See below.
On Tue, Jun 15, 2010 at 1:07 PM, Jiri Olsa <jolsa@redhat.com> wrote:
> hi,
>
> this patch adds description for IP_NODEFRAG option for IPv4 socket.
>
> wbr,
> jirka
>
>
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> ---
> man7/ip.7 | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/man7/ip.7 b/man7/ip.7
> index 34f7e80..12c0d5b 100644
> --- a/man7/ip.7
> +++ b/man7/ip.7
> @@ -705,6 +705,12 @@ socket option (see
> .BR IP_TTL " (since Linux 1.0)"
> Set or retrieve the current time-to-live field that is used in every packet
> sent from this socket.
> +.TP
> +.BR IP_NODEFRAG " (since Linux 2.6)"
here, we'd write the exact version in which the flag is added. It
looks like that might be 2.36, right?
Otherwise, this patch looks fine.
Cheers,
Michael
> +If enabled, the reassembly of outgoing packets is disabled in the netfilter layer.
> +Only valid for
> +.B SOCK_RAW
> +sockets.
> .\" FIXME Document IP_XFRM_POLICY
> .\" Since Linux 2.5.48
> .\" Needs CAP_NET_ADMIN
> --
> To unsubscribe from this list: send the line "unsubscribe linux-man" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface" http://blog.man7.org/
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: PATCH: uninitialized memory access in tcp_parse_options
From: Eric Dumazet @ 2010-06-26 5:58 UTC (permalink / raw)
To: Mathieu Lacage; +Cc: netdev
In-Reply-To: <1277127249.9469.53.camel@localhost.localdomain>
Le lundi 21 juin 2010 à 15:34 +0200, Mathieu Lacage a écrit :
> valgrind reports the following error:
>
> ==15996== Conditional jump or move depends on uninitialised value(s)
> ==15996== at 0x6E63E4C: tcp_parse_options (tcp_input.c:3776)
> ==15996== by 0x6E856A3: tcp_check_req (tcp_minisocks.c:532)
> ==15996== by 0x6E7F0C6: tcp_v4_hnd_req (tcp_ipv4.c:1492)
> ==15996== by 0x6E7F55A: tcp_v4_do_rcv (tcp_ipv4.c:1571)
> ==15996== by 0x6E808C5: tcp_v4_rcv (tcp_ipv4.c:1690)
> ==15996== by 0x6E2DA7B: ip_local_deliver_finish (ip_input.c:231)
> ==15996== by 0x6E2DE0C: ip_local_deliver (netfilter.h:206)
> ==15996== by 0x6E2E940: ip_rcv_finish (dst.h:255)
> ==15996== by 0x6E2F17C: ip_rcv (netfilter.h:206)
> ==15996== by 0x6D53D0E: __netif_receive_skb (dev.c:2873)
> ==15996== by 0x6D5521F: process_backlog (dev.c:3305)
> ==15996== by 0x6D55A20: net_rx_action (dev.c:3435)
>
> The attached patch (generated against net-next-2.6) fixes that error by
> making sure that user_mss is correctly initialized at the start of
> tcp_parse_options, just like saw_tstamp is initialized at the start of
> this function. To try to be coherent, this patch also removes the
> redundant initialization of saw_tstamp from the caller, tcp_check_req.
>
> hope this helps,
> Mathieu
Mathieu, this valgrind splat is a false positive, and your fix is not
necessary or at the right place.
In tcp_check_req(), we call tcp_parse_options() only to get the
saw_tstamp indication. So only initialize this field to 0 before calling
tcp_parse_options()
If you want to avoid valgrind false positive at this point, without
introducing bug for other tcp_parse_options() callers, a better fix
would be following patch.
Thanks
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 794c2e1..4e758ac 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -520,14 +520,13 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct request_sock **prev)
{
- struct tcp_options_received tmp_opt;
+ struct tcp_options_received tmp_opt = {0};
u8 *hash_location;
struct sock *child;
const struct tcphdr *th = tcp_hdr(skb);
__be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
int paws_reject = 0;
- tmp_opt.saw_tstamp = 0;
if (th->doff > (sizeof(struct tcphdr)>>2)) {
tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
^ permalink raw reply related
* Re: [RFC][BUG-FIX] the problem of checksum checking in UDP protocol
From: Eric Dumazet @ 2010-06-26 5:28 UTC (permalink / raw)
To: Shan Wei; +Cc: David Miller, Ronciak, John, netdev
In-Reply-To: <4C19E634.3030703@cn.fujitsu.com>
Le jeudi 17 juin 2010 à 17:09 +0800, Shan Wei a écrit :
> *Description of Problem*
> When received an UDP packet, if the length parameter in UDP header is less than
> the actual length of payload(including 8 bytes UDP header), and checksum parameter
> is calculated including all payload, some NIC devices that supports hardware checksum
> success to check checksum, and set ip_summed with CHECKSUM_UNNECESSARY flag.
> But If we turn off rx-checksumming offload, UDP protocol failed to check the checksum.
>
> *Step to Reproduce*
> We need to download netwib&netwox tools and then install them only on M1 node.
> On M1 node, execute the below steps.
>
> M1 M2
> +---------------------------+ +---------------------------+
> | eth1 |<---------------> |eth0 |
> |fe80::225:86ff:fe9d:3efa | |fe80::215:17ff:fe71:51f4 |
> +---------------------------+ +---------------------------+
>
> 1. netwox 149 -i fe80::215:17ff:fe71:51f4 -d eth1 -E 0:0:0:0:1:0 -e 0:15:17:71:51:f4 -I fe80::200:ff:fe00:100 -c 1
> This step is to create neighbor cache for spurious source address of fe80::200:ff:fe00:100.
>
> 2. netwox 141 -d eth1 -a 0:0:0:0:1:0 -b 0:15:17:71:51:f4 -f 17 -g 64 -h fe80::200:ff:fe00:100 -i fe80::215:17ff:fe71:51f4 \
> -o 3333 -p 7 -q 000000000000000000000000000000000000000000000000 -r 34525 -e 32 -s 16 -t 35126
> This step is to construct an UDPv6 packet that length field(16 bytes) less than total payload length(32 bytes).
>
> The readable format of this packet that netwox shows.
> Ethernet________________________________________________________.
> | 00:00:00:00:01:00->00:15:17:71:51:F4 type:0x86DD |
> |_______________________________________________________________|
> IP______________________________________________________________.
> |version| traffic class | flow label |
> |___6___|_______0_______|___________________0___________________|
> | payload length | next header | hop limit |
> |___________0x0020=32___________|____0x11=17____|______64_______|
> | source |
> |_____________________fe80::200:ff:fe00:100_____________________|
> | destination |
> |___________________fe80::215:17ff:fe71:51f4____________________|
> UDP_____________________________________________________________.
> | source port | destination port |
> |__________0x0D05=3333__________|___________0x0007=7____________|
> | length | checksum |
> |___________0x0010=16___________|_________0x8936=35126__________|
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # ................
> 00 00 00 00 00 00 00 00 # ........
>
>
> *Actual Results*
> On M2 note, using ethtool to see the counter about rx_csum_offload.
> #ethtool -S eth0 | grep csum
> rx_csum_offload_good: 1
> rx_csum_offload_errors: 0
>
> #cat /proc/net/snmp6 | grep Udp6
> Udp6InDatagrams 1
> Udp6InErrors 0
>
> *Expected Results*
> #ethtool -S eth0 | grep csum
> rx_csum_offload_good: 0
> rx_csum_offload_errors: 1
>
> #cat /proc/net/snmp6 | grep Udp6
> Udp6InDatagrams 0
> Udp6InErrors 1
>
> *The Reason*
> UDPv6 handles a received packet like this:
> 1. Confirm length of data
> If length parameter in UDPv6 header is greater than skb->len(actual data length added UDP header),
> the packet will be dropped. If length parameter in UDPv6 header is lower than skb->len, the data
> will be trimmed to be equal to length parameter.
>
> 2. Then UDPv6 calculates checksum with 40 bytes IPv6 pseudo-header,8 bytes UDPv6 header, 8 bytes
> Payload Data. Note that checksum(35126) in UDPv6 header includes 16 bytes redundant data.
>
> NIC checks checksum with total data includes redundant data, So the checksum that hardware calculated
> is different from that UDP did.
>
>
> *The Solution*
> We have reported the problem to Intel E1000e developer, the reply from Ronciak John is that
> the driver code of e1000e is ok.
> About the discuss, see http://comments.gmane.org/gmane.linux.drivers.e1000.devel/7077
>
> For this case, UDP protocol should not trust the CHECKSUM_UNNECESSARY flag set by driver.
> When UDP protocol received this kind of packet, if NIC hardware checked successfully,
> we reset ip_summed with CHECKSUM_NONE, and UDP protocol checked checksum again.
>
> (This patch is not complete, it's just for my idea.)
> diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
> index 1dd1aff..47f7e86 100644
> --- a/net/ipv6/udp.c
> +++ b/net/ipv6/udp.c
> @@ -723,6 +723,10 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
> if (ulen < skb->len) {
> if (pskb_trim_rcsum(skb, ulen))
> goto short_packet;
> +
> + if (skb_csum_unnecessary(skb))
> + skb->ip_summed = CHECKSUM_NONE;
> +
> saddr = &ipv6_hdr(skb)->saddr;
> daddr = &ipv6_hdr(skb)->daddr;
> uh = udp_hdr(skb);
>
I really dont know if this fix is the right one.
pskb_trim_rcsum() already contains a check. Should this check be changed
to include yours ?
static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
{
if (likely(len >= skb->len))
return 0;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->ip_summed = CHECKSUM_NONE;
return __pskb_trim(skb, len);
}
^ permalink raw reply
* Re: [PATCH 0/2] dccp: fix slow slow-start by symmetric Syn-RTT
From: David Miller @ 2010-06-26 4:36 UTC (permalink / raw)
To: gerrit; +Cc: dccp, netdev
In-Reply-To: <1277205275-5862-1-git-send-email-gerrit@erg.abdn.ac.uk>
From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Tue, 22 Jun 2010 13:14:33 +0200
> This changeset fixes slow startup behaviour for DCCP streaming via
> CCID-3/4 when a listening server needs to start streaming.
>
> Patch #1: removes an unused 'sk' argument from several functions,
> it is used by patch #2;
>
> Patch #2: fixes the sluggish slow-start problem by taking an RTT
> sample from the initial handshake also for listeing servers.
Both applied to net-next-2.6, thanks!
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox