From 83e331e2a492a134e491bcf50c984fd50c7fae03 Mon Sep 17 00:00:00 2001 From: Chuck Short Date: Mon, 25 Sep 2006 22:31:03 -0700 Subject: [IRDA] via-ircc: fix memory leak Fix memory leak. Coverity id# 653 patch location: http://www.kernel.org/git/?p=linux/kernel/git/bcollins/ubuntu-dapper.git;a=commitdiff;h=a1f34cb68b16807ed9d5ebb0f6a6ec5ff8a5fc78 Signed-off-by: Chuck Short Signed-off-by: Ben Collins Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/irda/via-ircc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 79b85f327500..d916e1257c47 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -1223,8 +1223,13 @@ static int upload_rxdata(struct via_ircc_cb *self, int iobase) IRDA_DEBUG(2, "%s(): len=%x\n", __FUNCTION__, len); + if ((len - 4) < 2) { + self->stats.rx_dropped++; + return FALSE; + } + skb = dev_alloc_skb(len + 1); - if ((skb == NULL) || ((len - 4) < 2)) { + if (skb == NULL) { self->stats.rx_dropped++; return FALSE; } -- cgit v1.2.3 From 1618cb0c9c2ac128beb94ff376e3367932ae6432 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 25 Sep 2006 23:11:21 -0700 Subject: [NETDEV] config: revert part of previous patch Net devices should depend on NETDEVICES, so revert part of Paolo's previous patch. See http://marc.theaimsgroup.com/?l=linux-kernel&m=115566326218740&w=2 for history. Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 63154774c257..ff8a8c0a26d5 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -24,6 +24,9 @@ config NETDEVICES If unsure, say Y. +# All the following symbols are dependent on NETDEVICES - do not repeat +# that for each of the symbols. +if NETDEVICES config IFB tristate "Intermediate Functional Block support" @@ -2852,6 +2855,8 @@ config NETCONSOLE If you want to log kernel messages over the network, enable this. See for details. +endif #NETDEVICES + config NETPOLL def_bool NETCONSOLE -- cgit v1.2.3 From 2a50f28c326d20ab4556be1b867ecddf6aefbb88 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Sep 2006 21:22:08 -0700 Subject: [ATALK]: endianness annotations Signed-off-by: Al Viro Signed-off-by: David S. Miller --- drivers/net/appletalk/ipddp.c | 5 +-- include/linux/atalk.h | 40 +--------------------- net/appletalk/ddp.c | 79 +++++++++++++++---------------------------- 3 files changed, 30 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index 7f7dd450226a..b98592a8bac8 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -145,9 +145,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) /* Create the Extended DDP header */ ddp = (struct ddpehdr *)skb->data; - ddp->deh_len = skb->len; - ddp->deh_hops = 1; - ddp->deh_pad = 0; + ddp->deh_len_hops = htons(skb->len + (1<<10)); ddp->deh_sum = 0; /* @@ -170,7 +168,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) ddp->deh_sport = 72; *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ - *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); /* fix up length field */ skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ diff --git a/include/linux/atalk.h b/include/linux/atalk.h index 6ba3aa8a81f4..75b8baca08f3 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h @@ -88,15 +88,7 @@ static inline struct atalk_sock *at_sk(struct sock *sk) #include struct ddpehdr { -#ifdef __LITTLE_ENDIAN_BITFIELD - __u16 deh_len:10, - deh_hops:4, - deh_pad:2; -#else - __u16 deh_pad:2, - deh_hops:4, - deh_len:10; -#endif + __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */ __be16 deh_sum; __be16 deh_dnet; __be16 deh_snet; @@ -112,36 +104,6 @@ static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) return (struct ddpehdr *)skb->h.raw; } -/* - * Don't drop the struct into the struct above. You'll get some - * surprise padding. - */ -struct ddpebits { -#ifdef __LITTLE_ENDIAN_BITFIELD - __u16 deh_len:10, - deh_hops:4, - deh_pad:2; -#else - __u16 deh_pad:2, - deh_hops:4, - deh_len:10; -#endif -}; - -/* Short form header */ -struct ddpshdr { -#ifdef __LITTLE_ENDIAN_BITFIELD - __u16 dsh_len:10, - dsh_pad:6; -#else - __u16 dsh_pad:6, - dsh_len:10; -#endif - __u8 dsh_dport; - __u8 dsh_sport; - /* And netatalk apps expect to stick the type in themselves */ -}; - /* AppleTalk AARP headers */ struct elapaarp { __be16 hw_type; diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 96dc6bb52d14..708e2e0371af 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1002,7 +1002,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, return sum; } -static unsigned short atalk_checksum(const struct sk_buff *skb, int len) +static __be16 atalk_checksum(const struct sk_buff *skb, int len) { unsigned long sum; @@ -1010,7 +1010,7 @@ static unsigned short atalk_checksum(const struct sk_buff *skb, int len) sum = atalk_sum_skb(skb, 4, len-4, 0); /* Use 0xFFFF for 0. 0 itself means none */ - return sum ? htons((unsigned short)sum) : 0xFFFF; + return sum ? htons((unsigned short)sum) : htons(0xFFFF); } static struct proto ddp_proto = { @@ -1289,7 +1289,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb) #endif static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, - struct ddpehdr *ddp, struct ddpebits *ddphv, + struct ddpehdr *ddp, __u16 len_hops, int origlen) { struct atalk_route *rt; @@ -1317,10 +1317,12 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, /* Route the packet */ rt = atrtr_find(&ta); - if (!rt || ddphv->deh_hops == DDP_MAXHOPS) + /* increment hops count */ + len_hops += 1 << 10; + if (!rt || !(len_hops & (15 << 10))) goto free_it; + /* FIXME: use skb->cb to be able to use shared skbs */ - ddphv->deh_hops++; /* * Route goes through another gateway, so set the target to the @@ -1335,11 +1337,10 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, /* Fix up skb->len field */ skb_trim(skb, min_t(unsigned int, origlen, (rt->dev->hard_header_len + - ddp_dl->header_length + ddphv->deh_len))); + ddp_dl->header_length + (len_hops & 1023)))); - /* Mend the byte order */ /* FIXME: use skb->cb to be able to use shared skbs */ - *((__u16 *)ddp) = ntohs(*((__u16 *)ddphv)); + ddp->deh_len_hops = htons(len_hops); /* * Send the buffer onwards @@ -1394,7 +1395,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct atalk_iface *atif; struct sockaddr_at tosat; int origlen; - struct ddpebits ddphv; + __u16 len_hops; /* Don't mangle buffer if shared */ if (!(skb = skb_share_check(skb, GFP_ATOMIC))) @@ -1406,16 +1407,11 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, ddp = ddp_hdr(skb); - /* - * Fix up the length field [Ok this is horrible but otherwise - * I end up with unions of bit fields and messy bit field order - * compiler/endian dependencies..] - */ - *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); + len_hops = ntohs(ddp->deh_len_hops); /* Trim buffer in case of stray trailing data */ origlen = skb->len; - skb_trim(skb, min_t(unsigned int, skb->len, ddphv.deh_len)); + skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023)); /* * Size check to see if ddp->deh_len was crap @@ -1430,7 +1426,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, * valid for net byte orders all over the networking code... */ if (ddp->deh_sum && - atalk_checksum(skb, ddphv.deh_len) != ddp->deh_sum) + atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum) /* Not a valid AppleTalk frame - dustbin time */ goto freeit; @@ -1444,7 +1440,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, /* Not ours, so we route the packet via the correct * AppleTalk iface */ - atalk_route_packet(skb, dev, ddp, &ddphv, origlen); + atalk_route_packet(skb, dev, ddp, len_hops, origlen); goto out; } @@ -1489,7 +1485,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, /* Find our address */ struct atalk_addr *ap = atalk_find_dev_addr(dev); - if (!ap || skb->len < sizeof(struct ddpshdr)) + if (!ap || skb->len < sizeof(__be16) || skb->len > 1023) goto freeit; /* Don't mangle buffer if shared */ @@ -1519,11 +1515,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, /* * Not sure about this bit... */ - ddp->deh_len = skb->len; - ddp->deh_hops = DDP_MAXHOPS; /* Non routable, so force a drop - if we slip up later */ - /* Mend the byte order */ - *((__u16 *)ddp) = htons(*((__u16 *)ddp)); + /* Non routable, so force a drop if we slip up later */ + ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10)); } skb->h.raw = skb->data; @@ -1622,16 +1615,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); - ddp->deh_pad = 0; - ddp->deh_hops = 0; - ddp->deh_len = len + sizeof(*ddp); - /* - * Fix up the length field [Ok this is horrible but otherwise - * I end up with unions of bit fields and messy bit field order - * compiler/endian dependencies.. - */ - *((__u16 *)ddp) = ntohs(*((__u16 *)ddp)); - + ddp->deh_len_hops = htons(len + sizeof(*ddp)); ddp->deh_dnet = usat->sat_addr.s_net; ddp->deh_snet = at->src_net; ddp->deh_dnode = usat->sat_addr.s_node; @@ -1712,8 +1696,8 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; struct ddpehdr *ddp; int copied = 0; + int offset = 0; int err = 0; - struct ddpebits ddphv; struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); if (!skb) @@ -1721,25 +1705,18 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr /* FIXME: use skb->cb to be able to use shared skbs */ ddp = ddp_hdr(skb); - *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); + copied = ntohs(ddp->deh_len_hops) & 1023; - if (sk->sk_type == SOCK_RAW) { - copied = ddphv.deh_len; - if (copied > size) { - copied = size; - msg->msg_flags |= MSG_TRUNC; - } + if (sk->sk_type != SOCK_RAW) { + offset = sizeof(*ddp); + copied -= offset; + } - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - } else { - copied = ddphv.deh_len - sizeof(*ddp); - if (copied > size) { - copied = size; - msg->msg_flags |= MSG_TRUNC; - } - err = skb_copy_datagram_iovec(skb, sizeof(*ddp), - msg->msg_iov, copied); + if (copied > size) { + copied = size; + msg->msg_flags |= MSG_TRUNC; } + err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); if (!err) { if (sat) { -- cgit v1.2.3 From a144ea4b7a13087081ab5402fa9ad0bcfd249e67 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 Sep 2006 18:00:55 -0700 Subject: [IPV4]: annotate struct in_ifaddr ifa_local, ifa_address, ifa_mask, ifa_broadcast and ifa_anycast are net-endian. Annotated them and variables that are inferred to be net-endian. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/ia64/hp/sim/simeth.c | 4 ++-- arch/um/drivers/net_kern.c | 2 +- arch/xtensa/platform-iss/network.c | 2 +- drivers/isdn/i4l/isdn_net.c | 4 ++-- drivers/net/bonding/bond_main.c | 2 +- drivers/net/wan/hdlc_cisco.c | 2 +- drivers/net/wan/syncppp.c | 2 +- drivers/net/wireless/strip.c | 4 ++-- include/linux/inetdevice.h | 10 +++++----- net/ipv4/devinet.c | 4 ++-- net/ipv4/fib_frontend.c | 12 ++++++------ net/ipv4/icmp.c | 2 +- net/ipv4/netfilter/ip_conntrack_netbios_ns.c | 2 +- net/ipv4/netfilter/ipt_REDIRECT.c | 2 +- 14 files changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index b5195be62818..e1a1b11473e2 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -320,7 +320,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) } printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n", - dev->name, htonl(ifa->ifa_local)); + dev->name, ntohl(ifa->ifa_local)); /* * XXX Fix me @@ -331,7 +331,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) local = dev->priv; /* now do it for real */ r = event == NETDEV_UP ? - netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)): + netdev_attach(local->simfd, dev->irq, ntohl(ifa->ifa_local)): netdev_detach(local->simfd); printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n", diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 664c2e2fb820..bd1178fa4e9a 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -825,7 +825,7 @@ int dev_netmask(void *d, void *m) struct net_device *dev = d; struct in_device *ip = dev->ip_ptr; struct in_ifaddr *in; - __u32 *mask_out = m; + __be32 *mask_out = m; if(ip == NULL) return(1); diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index d96164e602fe..15d64414bd60 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c @@ -201,7 +201,7 @@ static void dev_ip_addr(void *d, char *buf, char *bin_buf) struct net_device *dev = d; struct in_device *ip = dev->ip_ptr; struct in_ifaddr *in; - u32 addr; + __be32 addr; if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) { printk(KERN_WARNING "Device not assigned an IP address!\n"); diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 43da8ae1b2ad..1f8d6ae66b41 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -1614,8 +1614,8 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp) struct sk_buff *skb; unsigned char *p; struct in_device *in_dev = NULL; - u32 addr = 0; /* local ipv4 address */ - u32 mask = 0; /* local netmask */ + __be32 addr = 0; /* local ipv4 address */ + __be32 mask = 0; /* local netmask */ if ((in_dev = lp->netdev->dev.ip_ptr) != NULL) { /* take primary(first) address of interface */ diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0fb5f653d3ce..c0bbddae4ec4 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2252,7 +2252,7 @@ static u32 bond_glean_dev_ip(struct net_device *dev) { struct in_device *idev; struct in_ifaddr *ifa; - u32 addr = 0; + __be32 addr = 0; if (!dev) return 0; diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index 7ec2b2f9b7ee..b0bc5ddcf1b1 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -161,7 +161,7 @@ static int cisco_rx(struct sk_buff *skb) struct hdlc_header *data = (struct hdlc_header*)skb->data; struct cisco_packet *cisco_data; struct in_device *in_dev; - u32 addr, mask; + __be32 addr, mask; if (skb->len < sizeof(struct hdlc_header)) goto rx_error; diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index c13b459a0137..d1173089f334 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c @@ -763,7 +763,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb) { struct in_device *in_dev; struct in_ifaddr *ifa; - u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */ + __be32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */ #ifdef CONFIG_INET rcu_read_lock(); if ((in_dev = __in_dev_get_rcu(dev)) != NULL) diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index ccaf28e8db0a..337c692f6fd6 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -1342,7 +1342,7 @@ static unsigned char *strip_make_packet(unsigned char *buffer, * 'broadcast hub' radio (First byte of address being 0xFF means broadcast) */ if (haddr.c[0] == 0xFF) { - u32 brd = 0; + __be32 brd = 0; struct in_device *in_dev; rcu_read_lock(); @@ -1406,7 +1406,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb) int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0; int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0 && !doreset; - u32 addr, brd; + __be32 addr, brd; /* * 1. If we have a packet, encapsulate it and put it in the buffer diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 5ae09372c144..54b32e8b8f65 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -90,11 +90,11 @@ struct in_ifaddr struct in_ifaddr *ifa_next; struct in_device *ifa_dev; struct rcu_head rcu_head; - u32 ifa_local; - u32 ifa_address; - u32 ifa_mask; - u32 ifa_broadcast; - u32 ifa_anycast; + __be32 ifa_local; + __be32 ifa_address; + __be32 ifa_mask; + __be32 ifa_broadcast; + __be32 ifa_anycast; unsigned char ifa_scope; unsigned char ifa_flags; unsigned char ifa_prefixlen; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 5988584f6a6d..a0a7780e7515 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -805,7 +805,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) break; ret = 0; if (ifa->ifa_mask != sin->sin_addr.s_addr) { - u32 old_mask = ifa->ifa_mask; + __be32 old_mask = ifa->ifa_mask; inet_del_ifa(in_dev, ifap, 0); ifa->ifa_mask = sin->sin_addr.s_addr; ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask); @@ -931,7 +931,7 @@ static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst, u32 local, int scope) { int same = 0; - u32 addr = 0; + __be32 addr = 0; for_ifa(in_dev) { if (!addr && diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 7f5217907e5a..62ee71ee6bc9 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -667,9 +667,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) struct in_device *in_dev = ifa->ifa_dev; struct net_device *dev = in_dev->dev; struct in_ifaddr *prim = ifa; - u32 mask = ifa->ifa_mask; - u32 addr = ifa->ifa_local; - u32 prefix = ifa->ifa_address&mask; + __be32 mask = ifa->ifa_mask; + __be32 addr = ifa->ifa_local; + __be32 prefix = ifa->ifa_address&mask; if (ifa->ifa_flags&IFA_F_SECONDARY) { prim = inet_ifa_byprefix(in_dev, prefix, mask); @@ -685,7 +685,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) return; /* Add broadcast address, if it is explicitly assigned. */ - if (ifa->ifa_broadcast && ifa->ifa_broadcast != 0xFFFFFFFF) + if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); if (!ZERONET(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) && @@ -707,8 +707,8 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) struct net_device *dev = in_dev->dev; struct in_ifaddr *ifa1; struct in_ifaddr *prim = ifa; - u32 brd = ifa->ifa_address|~ifa->ifa_mask; - u32 any = ifa->ifa_address&ifa->ifa_mask; + __be32 brd = ifa->ifa_address|~ifa->ifa_mask; + __be32 any = ifa->ifa_address&ifa->ifa_mask; #define LOCAL_OK 1 #define BRD_OK 2 #define BRD0_OK 4 diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index fd39685241c1..428f1c91ec45 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -895,7 +895,7 @@ static void icmp_address_reply(struct sk_buff *skb) if (in_dev->ifa_list && IN_DEV_LOG_MARTIANS(in_dev) && IN_DEV_FORWARD(in_dev)) { - u32 _mask, *mp; + __be32 _mask, *mp; mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask); BUG_ON(mp == NULL); diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c index 3d0b438783db..4adec47aae32 100644 --- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c +++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c @@ -48,7 +48,7 @@ static int help(struct sk_buff **pskb, struct iphdr *iph = (*pskb)->nh.iph; struct rtable *rt = (struct rtable *)(*pskb)->dst; struct in_device *in_dev; - u_int32_t mask = 0; + __be32 mask = 0; /* we're only interested in locally generated packets */ if ((*pskb)->sk == NULL) diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index f03d43671c6d..c0dcfe9d610c 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c @@ -61,7 +61,7 @@ redirect_target(struct sk_buff **pskb, { struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; - u_int32_t newdst; + __be32 newdst; const struct ip_nat_multi_range_compat *mr = targinfo; struct ip_nat_range newrange; -- cgit v1.2.3 From 60cad5da5791ceb0beefe9a79b570cca45791f50 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Sep 2006 22:17:09 -0700 Subject: [IPV4]: annotate inetdev.h helpers inet_confirm_addr(), inet_ifa_byprefix(), ip_dev_find(), inet_make_mask() and inet_ifa_match() annotated, along with inferred net-endian variables Signed-off-by: Al Viro Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 4 ++-- include/linux/inetdevice.h | 10 +++++----- net/ipv4/devinet.c | 12 ++++++------ net/ipv4/fib_frontend.c | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 9cbf09e2052f..60d3fbdd216c 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -86,7 +86,7 @@ EXPORT_SYMBOL(rdma_copy_addr); int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) { struct net_device *dev; - u32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr; + __be32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr; int ret; dev = ip_dev_find(ip); @@ -239,7 +239,7 @@ static int addr_resolve_local(struct sockaddr_in *src_in, { struct net_device *dev; u32 src_ip = src_in->sin_addr.s_addr; - u32 dst_ip = dst_in->sin_addr.s_addr; + __be32 dst_ip = dst_in->sin_addr.s_addr; int ret; dev = ip_dev_find(dst_ip); diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 54b32e8b8f65..5a0ab04627bc 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -104,18 +104,18 @@ struct in_ifaddr extern int register_inetaddr_notifier(struct notifier_block *nb); extern int unregister_inetaddr_notifier(struct notifier_block *nb); -extern struct net_device *ip_dev_find(u32 addr); +extern struct net_device *ip_dev_find(__be32 addr); extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); extern int devinet_ioctl(unsigned int cmd, void __user *); extern void devinet_init(void); extern struct in_device *inetdev_init(struct net_device *dev); extern struct in_device *inetdev_by_index(int); extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); -extern u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope); -extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, u32 mask); +extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope); +extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask); extern void inet_forward_change(void); -static __inline__ int inet_ifa_match(u32 addr, struct in_ifaddr *ifa) +static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa) { return !((addr^ifa->ifa_address)&ifa->ifa_mask); } @@ -183,7 +183,7 @@ static inline void in_dev_put(struct in_device *idev) #endif /* __KERNEL__ */ -static __inline__ __u32 inet_make_mask(int logmask) +static __inline__ __be32 inet_make_mask(int logmask) { if (logmask) return htonl(~((1<<(32-logmask))-1)); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index afba56222fb5..7602c79a389b 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -429,8 +429,8 @@ struct in_device *inetdev_by_index(int ifindex) /* Called only from RTNL semaphored context. No locks. */ -struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, - u32 mask) +struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, + __be32 mask) { ASSERT_RTNL(); @@ -927,8 +927,8 @@ out: return addr; } -static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst, - u32 local, int scope) +static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst, + __be32 local, int scope) { int same = 0; __be32 addr = 0; @@ -971,9 +971,9 @@ static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst, * - local: address, 0=autoselect the local address * - scope: maximum allowed scope value for the local address */ -u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope) +__be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope) { - u32 addr = 0; + __be32 addr = 0; struct in_device *in_dev; if (dev) { diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 62ee71ee6bc9..c0bd2f122da2 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -122,7 +122,7 @@ static void fib_flush(void) * Find the first device with a given source address. */ -struct net_device * ip_dev_find(u32 addr) +struct net_device * ip_dev_find(__be32 addr) { struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; -- cgit v1.2.3 From fd6832220974809141b3981e380b78690bba8911 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Sep 2006 22:17:51 -0700 Subject: [IPV4]: inet_addr_type() annotations argument and inferred net-endian variables in callers annotated. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- drivers/s390/net/qeth_main.c | 2 +- include/net/route.h | 2 +- net/ipv4/arp.c | 4 ++-- net/ipv4/fib_frontend.c | 2 +- net/ipv4/ip_options.c | 4 ++-- net/ipv4/netfilter/ipt_addrtype.c | 2 +- net/ipv6/af_inet6.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 5613b4564fa2..8364d5475ac7 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -8067,7 +8067,7 @@ qeth_arp_constructor(struct neighbour *neigh) neigh->parms = neigh_parms_clone(parms); rcu_read_unlock(); - neigh->type = inet_addr_type(*(u32 *) neigh->primary_key); + neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key); neigh->nud_state = NUD_NOARP; neigh->ops = arp_direct_ops; neigh->output = neigh->ops->queue_xmit; diff --git a/include/net/route.h b/include/net/route.h index 63524843f6d9..58752722c968 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -120,7 +120,7 @@ extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, stru extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu); extern void ip_rt_send_redirect(struct sk_buff *skb); -extern unsigned inet_addr_type(u32 addr); +extern unsigned inet_addr_type(__be32 addr); extern void ip_rt_multicast_event(struct in_device *); extern int ip_rt_ioctl(unsigned int cmd, void __user *arg); extern void ip_rt_get_source(u8 *src, struct rtable *rt); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index db72339c21e1..2a29a5ebc978 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -234,7 +234,7 @@ static u32 arp_hash(const void *pkey, const struct net_device *dev) static int arp_constructor(struct neighbour *neigh) { - u32 addr = *(u32*)neigh->primary_key; + __be32 addr = *(__be32*)neigh->primary_key; struct net_device *dev = neigh->dev; struct in_device *in_dev; struct neigh_parms *parms; @@ -470,7 +470,7 @@ static int arp_set_predefined(int addr_hint, unsigned char * haddr, u32 paddr, s int arp_find(unsigned char *haddr, struct sk_buff *skb) { struct net_device *dev = skb->dev; - u32 paddr; + __be32 paddr; struct neighbour *n; if (!skb->dst) { diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index c0bd2f122da2..34dc640478a0 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -146,7 +146,7 @@ out: return dev; } -unsigned inet_addr_type(u32 addr) +unsigned inet_addr_type(__be32 addr) { struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 87f25486fd64..3245bec23f4d 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -148,7 +148,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) dopt->ts_needtime = 0; if (soffset + 8 <= optlen) { - __u32 addr; + __be32 addr; memcpy(&addr, sptr+soffset-1, 4); if (inet_addr_type(addr) != RTN_LOCAL) { @@ -396,7 +396,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) } opt->ts = optptr - iph; { - u32 addr; + __be32 addr; memcpy(&addr, &optptr[optptr[2]-1], 4); if (inet_addr_type(addr) == RTN_UNICAST) break; diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 893dae210b04..7b60eb74788b 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c @@ -22,7 +22,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy "); MODULE_DESCRIPTION("iptables addrtype match"); -static inline int match_type(u_int32_t addr, u_int16_t mask) +static inline int match_type(__be32 addr, u_int16_t mask) { return !!(mask & (1 << inet_addr_type(addr))); } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index bf6e8aff19d4..e94eccb99707 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -246,7 +246,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); - __u32 v4addr = 0; + __be32 v4addr = 0; unsigned short snum; int addr_type = 0; int err = 0; -- cgit v1.2.3 From 9c724357f432df5ddc83a62c8168414a604cd420 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 6 Jul 2006 15:45:23 +0200 Subject: [Bluetooth] Code cleanup of the drivers source code This patch is an attempt to cleanup the drivers source code to make all Bluetooth drivers look more unique. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bfusb.c | 316 ++++++++++++++++++++++--------------------- drivers/bluetooth/hci_vhci.c | 97 ++++++------- 2 files changed, 208 insertions(+), 205 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index 23f96213f4ac..efcc28ec9d9a 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c @@ -2,7 +2,7 @@ * * AVM BlueFRITZ! USB driver * - * Copyright (C) 2003 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -59,7 +59,6 @@ static struct usb_device_id bfusb_table[] = { MODULE_DEVICE_TABLE(usb, bfusb_table); - #define BFUSB_MAX_BLOCK_SIZE 256 #define BFUSB_BLOCK_TIMEOUT 3000 @@ -70,7 +69,7 @@ MODULE_DEVICE_TABLE(usb, bfusb_table); #define BFUSB_MAX_BULK_TX 2 #define BFUSB_MAX_BULK_RX 2 -struct bfusb { +struct bfusb_data { struct hci_dev *hdev; unsigned long state; @@ -92,137 +91,136 @@ struct bfusb { struct sk_buff_head completed_q; }; -struct bfusb_scb { +struct bfusb_data_scb { struct urb *urb; }; static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs); static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs); -static struct urb *bfusb_get_completed(struct bfusb *bfusb) +static struct urb *bfusb_get_completed(struct bfusb_data *data) { struct sk_buff *skb; struct urb *urb = NULL; - BT_DBG("bfusb %p", bfusb); + BT_DBG("bfusb %p", data); - skb = skb_dequeue(&bfusb->completed_q); + skb = skb_dequeue(&data->completed_q); if (skb) { - urb = ((struct bfusb_scb *) skb->cb)->urb; + urb = ((struct bfusb_data_scb *) skb->cb)->urb; kfree_skb(skb); } return urb; } -static void bfusb_unlink_urbs(struct bfusb *bfusb) +static void bfusb_unlink_urbs(struct bfusb_data *data) { struct sk_buff *skb; struct urb *urb; - BT_DBG("bfusb %p", bfusb); + BT_DBG("bfusb %p", data); - while ((skb = skb_dequeue(&bfusb->pending_q))) { - urb = ((struct bfusb_scb *) skb->cb)->urb; + while ((skb = skb_dequeue(&data->pending_q))) { + urb = ((struct bfusb_data_scb *) skb->cb)->urb; usb_kill_urb(urb); - skb_queue_tail(&bfusb->completed_q, skb); + skb_queue_tail(&data->completed_q, skb); } - while ((urb = bfusb_get_completed(bfusb))) + while ((urb = bfusb_get_completed(data))) usb_free_urb(urb); } - -static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb) +static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb) { - struct bfusb_scb *scb = (void *) skb->cb; - struct urb *urb = bfusb_get_completed(bfusb); + struct bfusb_data_scb *scb = (void *) skb->cb; + struct urb *urb = bfusb_get_completed(data); int err, pipe; - BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len); + BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len); if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) return -ENOMEM; - pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); + pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); - usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, skb->len, + usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, bfusb_tx_complete, skb); scb->urb = urb; - skb_queue_tail(&bfusb->pending_q, skb); + skb_queue_tail(&data->pending_q, skb); err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk tx submit failed urb %p err %d", - bfusb->hdev->name, urb, err); - skb_unlink(skb, &bfusb->pending_q); + data->hdev->name, urb, err); + skb_unlink(skb, &data->pending_q); usb_free_urb(urb); } else - atomic_inc(&bfusb->pending_tx); + atomic_inc(&data->pending_tx); return err; } -static void bfusb_tx_wakeup(struct bfusb *bfusb) +static void bfusb_tx_wakeup(struct bfusb_data *data) { struct sk_buff *skb; - BT_DBG("bfusb %p", bfusb); + BT_DBG("bfusb %p", data); - if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) { - set_bit(BFUSB_TX_WAKEUP, &bfusb->state); + if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) { + set_bit(BFUSB_TX_WAKEUP, &data->state); return; } do { - clear_bit(BFUSB_TX_WAKEUP, &bfusb->state); + clear_bit(BFUSB_TX_WAKEUP, &data->state); - while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) && - (skb = skb_dequeue(&bfusb->transmit_q))) { - if (bfusb_send_bulk(bfusb, skb) < 0) { - skb_queue_head(&bfusb->transmit_q, skb); + while ((atomic_read(&data->pending_tx) < BFUSB_MAX_BULK_TX) && + (skb = skb_dequeue(&data->transmit_q))) { + if (bfusb_send_bulk(data, skb) < 0) { + skb_queue_head(&data->transmit_q, skb); break; } } - } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state)); + } while (test_bit(BFUSB_TX_WAKEUP, &data->state)); - clear_bit(BFUSB_TX_PROCESS, &bfusb->state); + clear_bit(BFUSB_TX_PROCESS, &data->state); } static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; - struct bfusb *bfusb = (struct bfusb *) skb->dev; + struct bfusb_data *data = (struct bfusb_data *) skb->dev; - BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); + BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len); - atomic_dec(&bfusb->pending_tx); + atomic_dec(&data->pending_tx); - if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) + if (!test_bit(HCI_RUNNING, &data->hdev->flags)) return; if (!urb->status) - bfusb->hdev->stat.byte_tx += skb->len; + data->hdev->stat.byte_tx += skb->len; else - bfusb->hdev->stat.err_tx++; + data->hdev->stat.err_tx++; - read_lock(&bfusb->lock); + read_lock(&data->lock); - skb_unlink(skb, &bfusb->pending_q); - skb_queue_tail(&bfusb->completed_q, skb); + skb_unlink(skb, &data->pending_q); + skb_queue_tail(&data->completed_q, skb); - bfusb_tx_wakeup(bfusb); + bfusb_tx_wakeup(data); - read_unlock(&bfusb->lock); + read_unlock(&data->lock); } -static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) +static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb) { - struct bfusb_scb *scb; + struct bfusb_data_scb *scb; struct sk_buff *skb; int err, pipe, size = HCI_MAX_FRAME_SIZE + 32; @@ -231,28 +229,29 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) return -ENOMEM; - if (!(skb = bt_skb_alloc(size, GFP_ATOMIC))) { + skb = bt_skb_alloc(size, GFP_ATOMIC); + if (!skb) { usb_free_urb(urb); return -ENOMEM; } - skb->dev = (void *) bfusb; + skb->dev = (void *) data; - scb = (struct bfusb_scb *) skb->cb; + scb = (struct bfusb_data_scb *) skb->cb; scb->urb = urb; - pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep); + pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep); - usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, size, + usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size, bfusb_rx_complete, skb); - skb_queue_tail(&bfusb->pending_q, skb); + skb_queue_tail(&data->pending_q, skb); err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk rx submit failed urb %p err %d", - bfusb->hdev->name, urb, err); - skb_unlink(skb, &bfusb->pending_q); + data->hdev->name, urb, err); + skb_unlink(skb, &data->pending_q); kfree_skb(skb); usb_free_urb(urb); } @@ -260,15 +259,15 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) return err; } -static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len) +static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len) { - BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len); + BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len); if (hdr & 0x10) { - BT_ERR("%s error in block", bfusb->hdev->name); - if (bfusb->reassembly) - kfree_skb(bfusb->reassembly); - bfusb->reassembly = NULL; + BT_ERR("%s error in block", data->hdev->name); + if (data->reassembly) + kfree_skb(data->reassembly); + data->reassembly = NULL; return -EIO; } @@ -277,46 +276,46 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char * unsigned char pkt_type; int pkt_len = 0; - if (bfusb->reassembly) { - BT_ERR("%s unexpected start block", bfusb->hdev->name); - kfree_skb(bfusb->reassembly); - bfusb->reassembly = NULL; + if (data->reassembly) { + BT_ERR("%s unexpected start block", data->hdev->name); + kfree_skb(data->reassembly); + data->reassembly = NULL; } if (len < 1) { - BT_ERR("%s no packet type found", bfusb->hdev->name); + BT_ERR("%s no packet type found", data->hdev->name); return -EPROTO; } - pkt_type = *data++; len--; + pkt_type = *buf++; len--; switch (pkt_type) { case HCI_EVENT_PKT: if (len >= HCI_EVENT_HDR_SIZE) { - struct hci_event_hdr *hdr = (struct hci_event_hdr *) data; + struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf; pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen; } else { - BT_ERR("%s event block is too short", bfusb->hdev->name); + BT_ERR("%s event block is too short", data->hdev->name); return -EILSEQ; } break; case HCI_ACLDATA_PKT: if (len >= HCI_ACL_HDR_SIZE) { - struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) data; + struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf; pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen); } else { - BT_ERR("%s data block is too short", bfusb->hdev->name); + BT_ERR("%s data block is too short", data->hdev->name); return -EILSEQ; } break; case HCI_SCODATA_PKT: if (len >= HCI_SCO_HDR_SIZE) { - struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) data; + struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf; pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen; } else { - BT_ERR("%s audio block is too short", bfusb->hdev->name); + BT_ERR("%s audio block is too short", data->hdev->name); return -EILSEQ; } break; @@ -324,27 +323,27 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char * skb = bt_skb_alloc(pkt_len, GFP_ATOMIC); if (!skb) { - BT_ERR("%s no memory for the packet", bfusb->hdev->name); + BT_ERR("%s no memory for the packet", data->hdev->name); return -ENOMEM; } - skb->dev = (void *) bfusb->hdev; + skb->dev = (void *) data->hdev; bt_cb(skb)->pkt_type = pkt_type; - bfusb->reassembly = skb; + data->reassembly = skb; } else { - if (!bfusb->reassembly) { - BT_ERR("%s unexpected continuation block", bfusb->hdev->name); + if (!data->reassembly) { + BT_ERR("%s unexpected continuation block", data->hdev->name); return -EIO; } } if (len > 0) - memcpy(skb_put(bfusb->reassembly, len), data, len); + memcpy(skb_put(data->reassembly, len), buf, len); if (hdr & 0x08) { - hci_recv_frame(bfusb->reassembly); - bfusb->reassembly = NULL; + hci_recv_frame(data->reassembly); + data->reassembly = NULL; } return 0; @@ -353,22 +352,22 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char * static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; - struct bfusb *bfusb = (struct bfusb *) skb->dev; + struct bfusb_data *data = (struct bfusb_data *) skb->dev; unsigned char *buf = urb->transfer_buffer; int count = urb->actual_length; int err, hdr, len; BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); - read_lock(&bfusb->lock); + read_lock(&data->lock); - if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) + if (!test_bit(HCI_RUNNING, &data->hdev->flags)) goto unlock; if (urb->status || !count) goto resubmit; - bfusb->hdev->stat.byte_rx += count; + data->hdev->stat.byte_rx += count; skb_put(skb, count); @@ -387,90 +386,89 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs) if (count < len) { BT_ERR("%s block extends over URB buffer ranges", - bfusb->hdev->name); + data->hdev->name); } if ((hdr & 0xe1) == 0xc1) - bfusb_recv_block(bfusb, hdr, buf, len); + bfusb_recv_block(data, hdr, buf, len); count -= len; buf += len; } - skb_unlink(skb, &bfusb->pending_q); + skb_unlink(skb, &data->pending_q); kfree_skb(skb); - bfusb_rx_submit(bfusb, urb); + bfusb_rx_submit(data, urb); - read_unlock(&bfusb->lock); + read_unlock(&data->lock); return; resubmit: - urb->dev = bfusb->udev; + urb->dev = data->udev; err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk resubmit failed urb %p err %d", - bfusb->hdev->name, urb, err); + data->hdev->name, urb, err); } unlock: - read_unlock(&bfusb->lock); + read_unlock(&data->lock); } - static int bfusb_open(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; unsigned long flags; int i, err; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) return 0; - write_lock_irqsave(&bfusb->lock, flags); + write_lock_irqsave(&data->lock, flags); - err = bfusb_rx_submit(bfusb, NULL); + err = bfusb_rx_submit(data, NULL); if (!err) { for (i = 1; i < BFUSB_MAX_BULK_RX; i++) - bfusb_rx_submit(bfusb, NULL); + bfusb_rx_submit(data, NULL); } else { clear_bit(HCI_RUNNING, &hdev->flags); } - write_unlock_irqrestore(&bfusb->lock, flags); + write_unlock_irqrestore(&data->lock, flags); return err; } static int bfusb_flush(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); - skb_queue_purge(&bfusb->transmit_q); + skb_queue_purge(&data->transmit_q); return 0; } static int bfusb_close(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; unsigned long flags; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; - write_lock_irqsave(&bfusb->lock, flags); - write_unlock_irqrestore(&bfusb->lock, flags); + write_lock_irqsave(&data->lock, flags); + write_unlock_irqrestore(&data->lock, flags); - bfusb_unlink_urbs(bfusb); + bfusb_unlink_urbs(data); bfusb_flush(hdev); return 0; @@ -479,7 +477,7 @@ static int bfusb_close(struct hci_dev *hdev) static int bfusb_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; - struct bfusb *bfusb; + struct bfusb_data *data; struct sk_buff *nskb; unsigned char buf[3]; int sent = 0, size, count; @@ -494,7 +492,7 @@ static int bfusb_send_frame(struct sk_buff *skb) if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; - bfusb = (struct bfusb *) hdev->driver_data; + data = hdev->driver_data; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -514,12 +512,13 @@ static int bfusb_send_frame(struct sk_buff *skb) count = skb->len; /* Max HCI frame size seems to be 1511 + 1 */ - if (!(nskb = bt_skb_alloc(count + 32, GFP_ATOMIC))) { + nskb = bt_skb_alloc(count + 32, GFP_ATOMIC); + if (!nskb) { BT_ERR("Can't allocate memory for new packet"); return -ENOMEM; } - nskb->dev = (void *) bfusb; + nskb->dev = (void *) data; while (count) { size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE); @@ -536,18 +535,18 @@ static int bfusb_send_frame(struct sk_buff *skb) } /* Don't send frame with multiple size of bulk max packet */ - if ((nskb->len % bfusb->bulk_pkt_size) == 0) { + if ((nskb->len % data->bulk_pkt_size) == 0) { buf[0] = 0xdd; buf[1] = 0x00; memcpy(skb_put(nskb, 2), buf, 2); } - read_lock(&bfusb->lock); + read_lock(&data->lock); - skb_queue_tail(&bfusb->transmit_q, nskb); - bfusb_tx_wakeup(bfusb); + skb_queue_tail(&data->transmit_q, nskb); + bfusb_tx_wakeup(data); - read_unlock(&bfusb->lock); + read_unlock(&data->lock); kfree_skb(skb); @@ -556,11 +555,11 @@ static int bfusb_send_frame(struct sk_buff *skb) static void bfusb_destruct(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); - kfree(bfusb); + kfree(data); } static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) @@ -568,25 +567,24 @@ static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg return -ENOIOCTLCMD; } - -static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count) +static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, int count) { unsigned char *buf; int err, pipe, len, size, sent = 0; - BT_DBG("bfusb %p udev %p", bfusb, bfusb->udev); + BT_DBG("bfusb %p udev %p", data, data->udev); BT_INFO("BlueFRITZ! USB loading firmware"); - pipe = usb_sndctrlpipe(bfusb->udev, 0); + pipe = usb_sndctrlpipe(data->udev, 0); - if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, + if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) { BT_ERR("Can't change to loading configuration"); return -EBUSY; } - bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0; + data->udev->toggle[0] = data->udev->toggle[1] = 0; buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC); if (!buf) { @@ -594,14 +592,14 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int return -ENOMEM; } - pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); + pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); while (count) { size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3); memcpy(buf, firmware + sent, size); - err = usb_bulk_msg(bfusb->udev, pipe, buf, size, + err = usb_bulk_msg(data->udev, pipe, buf, size, &len, BFUSB_BLOCK_TIMEOUT); if (err || (len != size)) { @@ -613,21 +611,23 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count -= size; } - if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0, - &len, BFUSB_BLOCK_TIMEOUT)) < 0) { + err = usb_bulk_msg(data->udev, pipe, NULL, 0, + &len, BFUSB_BLOCK_TIMEOUT); + if (err < 0) { BT_ERR("Error in null packet request"); goto error; } - pipe = usb_sndctrlpipe(bfusb->udev, 0); + pipe = usb_sndctrlpipe(data->udev, 0); - if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, - 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) { + err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, + 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + if (err < 0) { BT_ERR("Can't change to running configuration"); goto error; } - bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0; + data->udev->toggle[0] = data->udev->toggle[1] = 0; BT_INFO("BlueFRITZ! USB device ready"); @@ -637,9 +637,9 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int error: kfree(buf); - pipe = usb_sndctrlpipe(bfusb->udev, 0); + pipe = usb_sndctrlpipe(data->udev, 0); - usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, + usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, 0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); return err; @@ -652,7 +652,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_host_endpoint *bulk_out_ep; struct usb_host_endpoint *bulk_in_ep; struct hci_dev *hdev; - struct bfusb *bfusb; + struct bfusb_data *data; BT_DBG("intf %p id %p", intf, id); @@ -672,23 +672,24 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i } /* Initialize control structure and load firmware */ - if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) { + data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL); + if (!data) { BT_ERR("Can't allocate memory for control structure"); goto done; } - bfusb->udev = udev; - bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress; - bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; - bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); + data->udev = udev; + data->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress; + data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; + data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); - rwlock_init(&bfusb->lock); + rwlock_init(&data->lock); - bfusb->reassembly = NULL; + data->reassembly = NULL; - skb_queue_head_init(&bfusb->transmit_q); - skb_queue_head_init(&bfusb->pending_q); - skb_queue_head_init(&bfusb->completed_q); + skb_queue_head_init(&data->transmit_q); + skb_queue_head_init(&data->pending_q); + skb_queue_head_init(&data->completed_q); if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) { BT_ERR("Firmware request failed"); @@ -697,7 +698,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i BT_DBG("firmware data %p size %d", firmware->data, firmware->size); - if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) { + if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) { BT_ERR("Firmware loading failed"); goto release; } @@ -711,10 +712,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i goto error; } - bfusb->hdev = hdev; + data->hdev = hdev; hdev->type = HCI_USB; - hdev->driver_data = bfusb; + hdev->driver_data = data; SET_HCIDEV_DEV(hdev, &intf->dev); hdev->open = bfusb_open; @@ -732,7 +733,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i goto error; } - usb_set_intfdata(intf, bfusb); + usb_set_intfdata(intf, data); return 0; @@ -740,7 +741,7 @@ release: release_firmware(firmware); error: - kfree(bfusb); + kfree(data); done: return -EIO; @@ -748,8 +749,8 @@ done: static void bfusb_disconnect(struct usb_interface *intf) { - struct bfusb *bfusb = usb_get_intfdata(intf); - struct hci_dev *hdev = bfusb->hdev; + struct bfusb_data *data = usb_get_intfdata(intf); + struct hci_dev *hdev = data->hdev; BT_DBG("intf %p", intf); @@ -779,7 +780,8 @@ static int __init bfusb_init(void) BT_INFO("BlueFRITZ! USB driver ver %s", VERSION); - if ((err = usb_register(&bfusb_driver)) < 0) + err = usb_register(&bfusb_driver); + if (err < 0) BT_ERR("Failed to register BlueFRITZ! USB driver"); return err; diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index aac67a3a6019..fc2130f1776a 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -2,9 +2,9 @@ * * Bluetooth virtual HCI driver * - * Copyright (C) 2000-2001 Qualcomm Incorporated - * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -72,21 +72,21 @@ static int vhci_open_dev(struct hci_dev *hdev) static int vhci_close_dev(struct hci_dev *hdev) { - struct vhci_data *vhci = hdev->driver_data; + struct vhci_data *data = hdev->driver_data; if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; - skb_queue_purge(&vhci->readq); + skb_queue_purge(&data->readq); return 0; } static int vhci_flush(struct hci_dev *hdev) { - struct vhci_data *vhci = hdev->driver_data; + struct vhci_data *data = hdev->driver_data; - skb_queue_purge(&vhci->readq); + skb_queue_purge(&data->readq); return 0; } @@ -94,7 +94,7 @@ static int vhci_flush(struct hci_dev *hdev) static int vhci_send_frame(struct sk_buff *skb) { struct hci_dev* hdev = (struct hci_dev *) skb->dev; - struct vhci_data *vhci; + struct vhci_data *data; if (!hdev) { BT_ERR("Frame for unknown HCI device (hdev=NULL)"); @@ -104,15 +104,15 @@ static int vhci_send_frame(struct sk_buff *skb) if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; - vhci = hdev->driver_data; + data = hdev->driver_data; memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); - skb_queue_tail(&vhci->readq, skb); + skb_queue_tail(&data->readq, skb); - if (vhci->flags & VHCI_FASYNC) - kill_fasync(&vhci->fasync, SIGIO, POLL_IN); + if (data->flags & VHCI_FASYNC) + kill_fasync(&data->fasync, SIGIO, POLL_IN); - wake_up_interruptible(&vhci->read_wait); + wake_up_interruptible(&data->read_wait); return 0; } @@ -122,7 +122,7 @@ static void vhci_destruct(struct hci_dev *hdev) kfree(hdev->driver_data); } -static inline ssize_t vhci_get_user(struct vhci_data *vhci, +static inline ssize_t vhci_get_user(struct vhci_data *data, const char __user *buf, size_t count) { struct sk_buff *skb; @@ -139,7 +139,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci, return -EFAULT; } - skb->dev = (void *) vhci->hdev; + skb->dev = (void *) data->hdev; bt_cb(skb)->pkt_type = *((__u8 *) skb->data); skb_pull(skb, 1); @@ -148,7 +148,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci, return count; } -static inline ssize_t vhci_put_user(struct vhci_data *vhci, +static inline ssize_t vhci_put_user(struct vhci_data *data, struct sk_buff *skb, char __user *buf, int count) { char __user *ptr = buf; @@ -161,42 +161,43 @@ static inline ssize_t vhci_put_user(struct vhci_data *vhci, total += len; - vhci->hdev->stat.byte_tx += len; + data->hdev->stat.byte_tx += len; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: - vhci->hdev->stat.cmd_tx++; + data->hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: - vhci->hdev->stat.acl_tx++; + data->hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: - vhci->hdev->stat.cmd_tx++; + data->hdev->stat.cmd_tx++; break; }; return total; } -static loff_t vhci_llseek(struct file * file, loff_t offset, int origin) +static loff_t vhci_llseek(struct file *file, loff_t offset, int origin) { return -ESPIPE; } -static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos) +static ssize_t vhci_read(struct file *file, + char __user *buf, size_t count, loff_t *pos) { DECLARE_WAITQUEUE(wait, current); - struct vhci_data *vhci = file->private_data; + struct vhci_data *data = file->private_data; struct sk_buff *skb; ssize_t ret = 0; - add_wait_queue(&vhci->read_wait, &wait); + add_wait_queue(&data->read_wait, &wait); while (count) { set_current_state(TASK_INTERRUPTIBLE); - skb = skb_dequeue(&vhci->readq); + skb = skb_dequeue(&data->readq); if (!skb) { if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; @@ -213,7 +214,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo } if (access_ok(VERIFY_WRITE, buf, count)) - ret = vhci_put_user(vhci, skb, buf, count); + ret = vhci_put_user(data, skb, buf, count); else ret = -EFAULT; @@ -221,7 +222,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo break; } set_current_state(TASK_RUNNING); - remove_wait_queue(&vhci->read_wait, &wait); + remove_wait_queue(&data->read_wait, &wait); return ret; } @@ -229,21 +230,21 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo static ssize_t vhci_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct vhci_data *vhci = file->private_data; + struct vhci_data *data = file->private_data; if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; - return vhci_get_user(vhci, buf, count); + return vhci_get_user(data, buf, count); } static unsigned int vhci_poll(struct file *file, poll_table *wait) { - struct vhci_data *vhci = file->private_data; + struct vhci_data *data = file->private_data; - poll_wait(file, &vhci->read_wait, wait); + poll_wait(file, &data->read_wait, wait); - if (!skb_queue_empty(&vhci->readq)) + if (!skb_queue_empty(&data->readq)) return POLLIN | POLLRDNORM; return POLLOUT | POLLWRNORM; @@ -257,26 +258,26 @@ static int vhci_ioctl(struct inode *inode, struct file *file, static int vhci_open(struct inode *inode, struct file *file) { - struct vhci_data *vhci; + struct vhci_data *data; struct hci_dev *hdev; - vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); - if (!vhci) + data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); + if (!data) return -ENOMEM; - skb_queue_head_init(&vhci->readq); - init_waitqueue_head(&vhci->read_wait); + skb_queue_head_init(&data->readq); + init_waitqueue_head(&data->read_wait); hdev = hci_alloc_dev(); if (!hdev) { - kfree(vhci); + kfree(data); return -ENOMEM; } - vhci->hdev = hdev; + data->hdev = hdev; hdev->type = HCI_VHCI; - hdev->driver_data = vhci; + hdev->driver_data = data; hdev->open = vhci_open_dev; hdev->close = vhci_close_dev; @@ -288,20 +289,20 @@ static int vhci_open(struct inode *inode, struct file *file) if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); - kfree(vhci); + kfree(data); hci_free_dev(hdev); return -EBUSY; } - file->private_data = vhci; + file->private_data = data; return nonseekable_open(inode, file); } static int vhci_release(struct inode *inode, struct file *file) { - struct vhci_data *vhci = file->private_data; - struct hci_dev *hdev = vhci->hdev; + struct vhci_data *data = file->private_data; + struct hci_dev *hdev = data->hdev; if (hci_unregister_dev(hdev) < 0) { BT_ERR("Can't unregister HCI device %s", hdev->name); @@ -316,17 +317,17 @@ static int vhci_release(struct inode *inode, struct file *file) static int vhci_fasync(int fd, struct file *file, int on) { - struct vhci_data *vhci = file->private_data; + struct vhci_data *data = file->private_data; int err; - err = fasync_helper(fd, file, on, &vhci->fasync); + err = fasync_helper(fd, file, on, &data->fasync); if (err < 0) return err; if (on) - vhci->flags |= VHCI_FASYNC; + data->flags |= VHCI_FASYNC; else - vhci->flags &= ~VHCI_FASYNC; + data->flags &= ~VHCI_FASYNC; return 0; } -- cgit v1.2.3 From 0ac53939a06c610b394aeb0211b985804f2d2da3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 Jul 2006 13:57:15 +0200 Subject: [Bluetooth] Add HCI device identifier for SDIO cards This patch assigns the next free HCI device identifier to Bluetooth devices based on the SDIO interface. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_vhci.c | 2 +- include/net/bluetooth/hci.h | 3 ++- net/bluetooth/hci_sysfs.c | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index fc2130f1776a..a278d98a9151 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -276,7 +276,7 @@ static int vhci_open(struct inode *inode, struct file *file) data->hdev = hdev; - hdev->type = HCI_VHCI; + hdev->type = HCI_VIRTUAL; hdev->driver_data = data; hdev->open = vhci_open_dev; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index b2bdb1aa0429..fde08f452b59 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -44,12 +44,13 @@ #define HCI_NOTIFY_VOICE_SETTING 3 /* HCI device types */ -#define HCI_VHCI 0 +#define HCI_VIRTUAL 0 #define HCI_USB 1 #define HCI_PCCARD 2 #define HCI_UART 3 #define HCI_RS232 4 #define HCI_PCI 5 +#define HCI_SDIO 6 /* HCI device quirks */ enum { diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 58df4360d242..09c61615e961 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -16,7 +16,7 @@ static inline char *typetostr(int type) { switch (type) { - case HCI_VHCI: + case HCI_VIRTUAL: return "VIRTUAL"; case HCI_USB: return "USB"; @@ -28,6 +28,8 @@ static inline char *typetostr(int type) return "RS232"; case HCI_PCI: return "PCI"; + case HCI_SDIO: + return "SDIO"; default: return "UNKNOWN"; } -- cgit v1.2.3 From 62ae15919b6db6644049338296624fbd724c0054 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Sep 2006 16:19:55 +0200 Subject: [Bluetooth] Add support for Canyon CN-BTU1 dongle This patch adds the vendor and product id of the Canycon CN-BTU1 dongle and sets a flag to send HCI_Reset as the first command. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_usb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index e2d4beac7420..0801af4ad2b9 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -96,6 +96,9 @@ static struct usb_device_id bluetooth_ids[] = { /* Ericsson with non-standard id */ { USB_DEVICE(0x0bdb, 0x1002) }, + /* Canyon CN-BTU1 with HID interfaces */ + { USB_DEVICE(0x0c10, 0x0000), .driver_info = HCI_RESET }, + { } /* Terminating entry */ }; -- cgit v1.2.3 From 7785162cf2baf7c6c1e4ad8ae5888f85fcc5febc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Sep 2006 16:23:19 +0200 Subject: [Bluetooth] Code cleanup for the HCI UART driver This patch cleans up the Bluetooth HCI UART driver a bit. Signed-off-by: Pavel Machek Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ldisc.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 93ba25b7ea32..420b645c4c9f 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -241,15 +241,11 @@ static int hci_uart_send_frame(struct sk_buff *skb) static void hci_uart_destruct(struct hci_dev *hdev) { - struct hci_uart *hu; - if (!hdev) return; BT_DBG("%s", hdev->name); - - hu = (struct hci_uart *) hdev->driver_data; - kfree(hu); + kfree(hdev->driver_data); } /* ------ LDISC part ------ */ @@ -272,7 +268,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) return -EEXIST; if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { - BT_ERR("Can't allocate controll structure"); + BT_ERR("Can't allocate control structure"); return -ENFILE; } @@ -360,7 +356,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * * Return Value: None */ -static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count) +static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) { struct hci_uart *hu = (void *)tty->disc_data; @@ -375,7 +371,8 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char hu->hdev->stat.byte_rx += count; spin_unlock(&hu->rx_lock); - if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver->unthrottle) + if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && + tty->driver->unthrottle) tty->driver->unthrottle(tty); } -- cgit v1.2.3 From 3d3ebe741b2c06fe3df67739d09f6ef0e25ee41a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 15:59:15 -0700 Subject: [TG3]: Improve 5704S autoneg. Improve 5704S autoneg logic by using a serdes_counter field to keep track of the transient states. This eliminates a 200 msec busy loop in the code. Autoneg will take its course without the driver busy waiting for it to finish. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 66 ++++++++++++++++++++++++++++++++++--------------------- drivers/net/tg3.h | 7 +++++- 2 files changed, 47 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index aaf45b907a78..4eef798fbb7b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2406,24 +2406,27 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) expected_sg_dig_ctrl |= (1 << 12); if (sg_dig_ctrl != expected_sg_dig_ctrl) { + if ((tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) && + tp->serdes_counter && + ((mac_status & (MAC_STATUS_PCS_SYNCED | + MAC_STATUS_RCVD_CFG)) == + MAC_STATUS_PCS_SYNCED)) { + tp->serdes_counter--; + current_link_up = 1; + goto out; + } +restart_autoneg: if (workaround) tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000); tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30)); udelay(5); tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl); - tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } else if (mac_status & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DET)) { - int i; - - /* Giver time to negotiate (~200ms) */ - for (i = 0; i < 40000; i++) { - sg_dig_status = tr32(SG_DIG_STATUS); - if (sg_dig_status & (0x3)) - break; - udelay(5); - } + sg_dig_status = tr32(SG_DIG_STATUS); mac_status = tr32(MAC_STATUS); if ((sg_dig_status & (1 << 1)) && @@ -2439,10 +2442,11 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) tg3_setup_flow_control(tp, local_adv, remote_adv); current_link_up = 1; - tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter = 0; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } else if (!(sg_dig_status & (1 << 1))) { - if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) - tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + if (tp->serdes_counter) + tp->serdes_counter--; else { if (workaround) { u32 val = serdes_cfg; @@ -2466,9 +2470,17 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) !(mac_status & MAC_STATUS_RCVD_CFG)) { tg3_setup_flow_control(tp, 0, 0); current_link_up = 1; - } + tp->tg3_flags2 |= + TG3_FLG2_PARALLEL_DETECT; + tp->serdes_counter = + SERDES_PARALLEL_DET_TIMEOUT; + } else + goto restart_autoneg; } } + } else { + tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } out: @@ -2599,14 +2611,16 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) MAC_STATUS_CFG_CHANGED)); udelay(5); if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED | - MAC_STATUS_CFG_CHANGED)) == 0) + MAC_STATUS_CFG_CHANGED | + MAC_STATUS_LNKSTATE_CHANGED)) == 0) break; } mac_status = tr32(MAC_STATUS); if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) { current_link_up = 0; - if (tp->link_config.autoneg == AUTONEG_ENABLE) { + if (tp->link_config.autoneg == AUTONEG_ENABLE && + tp->serdes_counter == 0) { tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS)); udelay(1); @@ -2711,7 +2725,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) tg3_writephy(tp, MII_BMCR, bmcr); tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); - tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter = SERDES_AN_TIMEOUT_5714S; tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; return err; @@ -2816,9 +2830,9 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) static void tg3_serdes_parallel_detect(struct tg3 *tp) { - if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) { + if (tp->serdes_counter) { /* Give autoneg time to complete. */ - tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + tp->serdes_counter--; return; } if (!netif_carrier_ok(tp->dev) && @@ -6660,12 +6674,14 @@ static void tg3_timer(unsigned long __opaque) need_setup = 1; } if (need_setup) { - tw32_f(MAC_MODE, - (tp->mac_mode & - ~MAC_MODE_PORT_MODE_MASK)); - udelay(40); - tw32_f(MAC_MODE, tp->mac_mode); - udelay(40); + if (!tp->serdes_counter) { + tw32_f(MAC_MODE, + (tp->mac_mode & + ~MAC_MODE_PORT_MODE_MASK)); + udelay(40); + tw32_f(MAC_MODE, tp->mac_mode); + udelay(40); + } tg3_setup_phy(tp, 0); } } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 3ecf356cfb08..f9c81baca8d8 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2203,7 +2203,6 @@ struct tg3 { #define TG3_FLG2_PCI_EXPRESS 0x00000200 #define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400 #define TG3_FLG2_HW_AUTONEG 0x00000800 -#define TG3_FLG2_PHY_JUST_INITTED 0x00001000 #define TG3_FLG2_PHY_SERDES 0x00002000 #define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 #define TG3_FLG2_FLASH 0x00008000 @@ -2236,6 +2235,12 @@ struct tg3 { u16 asf_counter; u16 asf_multiplier; + /* 1 second counter for transient serdes link events */ + u32 serdes_counter; +#define SERDES_AN_TIMEOUT_5704S 2 +#define SERDES_PARALLEL_DET_TIMEOUT 1 +#define SERDES_AN_TIMEOUT_5714S 1 + struct tg3_link_config link_config; struct tg3_bufmgr_config bufmgr_config; -- cgit v1.2.3 From 130b8e4d0e4edadcecee9fdff2c32f33d77c4fe9 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:00:40 -0700 Subject: [TG3]: Improve ASF heartbeat. Change to a different ASF heartbeat message code to improve reliability. There were some reports of unintended resets on real time kernels where the timer may be slow and cause the heartbeat to be late. Netpoll will also have the same problem because the timer irq will be unavailable. Using the new heartbeat code, the ASF firmware will also check the ring condition before resetting the chip when the heartbeat is expiring. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 20 ++++++++++++++++++-- drivers/net/tg3.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4eef798fbb7b..6af8ebcf35f0 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6690,13 +6690,29 @@ static void tg3_timer(unsigned long __opaque) tp->timer_counter = tp->timer_multiplier; } - /* Heartbeat is only sent once every 2 seconds. */ + /* Heartbeat is only sent once every 2 seconds. + * + * The heartbeat is to tell the ASF firmware that the host + * driver is still alive. In the event that the OS crashes, + * ASF needs to reset the hardware to free up the FIFO space + * that may be filled with rx packets destined for the host. + * If the FIFO is full, ASF will no longer function properly. + * + * Unintended resets have been reported on real time kernels + * where the timer doesn't run on time. Netpoll will also have + * same problem. + * + * The new FWCMD_NICDRV_ALIVE3 command tells the ASF firmware + * to check the ring condition when the heartbeat is expiring + * before doing the reset. This will prevent most unintended + * resets. + */ if (!--tp->asf_counter) { if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { u32 val; tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, - FWCMD_NICDRV_ALIVE2); + FWCMD_NICDRV_ALIVE3); tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); /* 5 seconds timeout */ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index f9c81baca8d8..f7462c2ccc0a 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1537,6 +1537,7 @@ #define FWCMD_NICDRV_FIX_DMAR 0x00000005 #define FWCMD_NICDRV_FIX_DMAW 0x00000006 #define FWCMD_NICDRV_ALIVE2 0x0000000d +#define FWCMD_NICDRV_ALIVE3 0x0000000e #define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c #define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80 #define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00 -- cgit v1.2.3 From 3f7045c1f28bedd44389b9392b54c6fdb83ee5c6 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:02:29 -0700 Subject: [TG3]: PHY fixes. Some PHY related fixes: 1. Fix Serdes WoL. 2. Fix loopback test on 10/100 only devices. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6af8ebcf35f0..14e964524969 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1117,6 +1117,12 @@ static void tg3_nvram_unlock(struct tg3 *); static void tg3_power_down_phy(struct tg3 *tp) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) + return; + + tg3_writephy(tp, MII_TG3_EXT_CTRL, MII_TG3_EXT_CTRL_FORCE_LED_OFF); + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); + /* The PHY should not be powered down on some chips because * of bugs. */ @@ -1223,7 +1229,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); udelay(40); - mac_mode = MAC_MODE_PORT_MODE_MII; + if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) + mac_mode = MAC_MODE_PORT_MODE_GMII; + else + mac_mode = MAC_MODE_PORT_MODE_MII; if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 || !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)) @@ -1301,15 +1310,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) } if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) && - !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { - /* Turn off the PHY */ - if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { - tg3_writephy(tp, MII_TG3_EXT_CTRL, - MII_TG3_EXT_CTRL_FORCE_LED_OFF); - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); - tg3_power_down_phy(tp); - } - } + !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) + tg3_power_down_phy(tp); tg3_frob_aux_power(tp); @@ -7889,7 +7891,7 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; if ((wol->wolopts & WAKE_MAGIC) && - tp->tg3_flags2 & TG3_FLG2_PHY_SERDES && + tp->tg3_flags2 & TG3_FLG2_ANY_SERDES && !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) return -EINVAL; @@ -8573,12 +8575,22 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) return 0; mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | - MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | - MAC_MODE_PORT_MODE_GMII; + MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY; + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) + mac_mode |= MAC_MODE_PORT_MODE_MII; + else + mac_mode |= MAC_MODE_PORT_MODE_GMII; tw32(MAC_MODE, mac_mode); } else if (loopback_mode == TG3_PHY_LOOPBACK) { - tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | - BMCR_SPEED1000); + u32 val; + + val = BMCR_LOOPBACK | BMCR_FULLDPLX; + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) + val |= BMCR_SPEED100; + else + val |= BMCR_SPEED1000; + + tg3_writephy(tp, MII_BMCR, val); udelay(40); /* reset to prevent losing 1st rx packet intermittently */ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { @@ -8587,7 +8599,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) tw32_f(MAC_RX_MODE, tp->rx_mode); } mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | - MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; + MAC_MODE_LINK_POLARITY; + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) + mac_mode |= MAC_MODE_PORT_MODE_MII; + else + mac_mode |= MAC_MODE_PORT_MODE_GMII; if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { mac_mode &= ~MAC_MODE_LINK_POLARITY; tg3_writephy(tp, MII_TG3_EXT_CTRL, @@ -8636,7 +8652,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) udelay(10); - for (i = 0; i < 10; i++) { + /* 250 usec to allow enough time on some 10/100 Mbps devices. */ + for (i = 0; i < 25; i++) { tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW); -- cgit v1.2.3 From 126a336822a6594662f5898f1ddf33e6d048fcc7 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:03:07 -0700 Subject: [TG3]: Add 5722 and 5756 support. Add IDs to support 5722 and 5756. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +++ drivers/net/tg3.h | 4 +++- include/linux/pci_ids.h | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 14e964524969..d443b7372325 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -173,6 +173,7 @@ static struct pci_device_id tg3_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5720)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M)}, @@ -187,6 +188,7 @@ static struct pci_device_id tg3_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5756)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)}, @@ -11273,6 +11275,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case PHY_ID_BCM5780: return "5780"; case PHY_ID_BCM5755: return "5755"; case PHY_ID_BCM5787: return "5787"; + case PHY_ID_BCM5756: return "5722/5756"; case PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; default: return "unknown"; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index f7462c2ccc0a..feed13dc8719 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2282,6 +2282,7 @@ struct tg3 { #define PHY_ID_BCM5780 0x60008350 #define PHY_ID_BCM5755 0xbc050cc0 #define PHY_ID_BCM5787 0xbc050ce0 +#define PHY_ID_BCM5756 0xbc050ed0 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_INVALID 0xffffffff #define PHY_ID_REV_MASK 0x0000000f @@ -2308,7 +2309,8 @@ struct tg3 { (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \ - (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM8002) + (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \ + (X) == PHY_ID_BCM8002) struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 61db1907f06f..ea3140d226e6 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1904,6 +1904,7 @@ #define PCI_DEVICE_ID_TIGON3_5705_2 0x1654 #define PCI_DEVICE_ID_TIGON3_5720 0x1658 #define PCI_DEVICE_ID_TIGON3_5721 0x1659 +#define PCI_DEVICE_ID_TIGON3_5722 0x165a #define PCI_DEVICE_ID_TIGON3_5705M 0x165d #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e #define PCI_DEVICE_ID_TIGON3_5714 0x1668 @@ -1913,6 +1914,7 @@ #define PCI_DEVICE_ID_TIGON3_5705F 0x166e #define PCI_DEVICE_ID_TIGON3_5754M 0x1672 #define PCI_DEVICE_ID_TIGON3_5755M 0x1673 +#define PCI_DEVICE_ID_TIGON3_5756 0x1674 #define PCI_DEVICE_ID_TIGON3_5750 0x1676 #define PCI_DEVICE_ID_TIGON3_5751 0x1677 #define PCI_DEVICE_ID_TIGON3_5715 0x1678 -- cgit v1.2.3 From 7a6f4369449a471a6e5718a87c53ac75a46960ba Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:03:31 -0700 Subject: [TG3]: Add tg3_poll_fw(). Put the firmware polling logic into a separate function. This makes the code cleaner. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 54 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d443b7372325..eafca2a0dd00 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4662,6 +4662,35 @@ static void tg3_write_sig_legacy(struct tg3 *tp, int kind) } } +static int tg3_poll_fw(struct tg3 *tp) +{ + int i; + u32 val; + + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + + /* Chip might not be fitted with firmware. Some Sun onboard + * parts are configured like that. So don't signal the timeout + * of the above loop as an error, but do report the lack of + * running firmware once. + */ + if (i >= 100000 && + !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { + tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; + + printk(KERN_INFO PFX "%s: No firmware running.\n", + tp->dev->name); + } + + return 0; +} + static void tg3_stop_fw(struct tg3 *); /* tp->lock is held. */ @@ -4669,7 +4698,7 @@ static int tg3_chip_reset(struct tg3 *tp) { u32 val; void (*write_op)(struct tg3 *, u32, u32); - int i; + int err; tg3_nvram_lock(tp); @@ -4829,26 +4858,9 @@ static int tg3_chip_reset(struct tg3 *tp) tw32_f(MAC_MODE, 0); udelay(40); - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - - /* Chip might not be fitted with firmare. Some Sun onboard - * parts are configured like that. So don't signal the timeout - * of the above loop as an error, but do report the lack of - * running firmware once. - */ - if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { - tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; - - printk(KERN_INFO PFX "%s: No firmware running.\n", - tp->dev->name); - } + err = tg3_poll_fw(tp); + if (err) + return err; if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) { -- cgit v1.2.3 From b5d3772ccbe0bc5ac8ffbb5356b74ca698aee28c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:06:21 -0700 Subject: [TG3]: Add basic 5906 support. Add support for the new 5709 device. This is a new 10/100 Mbps chip. The mailbox access and firmware interface are quite different from all other tg3 chips. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 126 +++++++++++++++++++++++++++++++++++++++++++----- drivers/net/tg3.h | 28 +++++++++-- include/linux/pci_ids.h | 2 + 3 files changed, 141 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index eafca2a0dd00..2b062d776511 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -199,6 +199,8 @@ static struct pci_device_id tg3_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, @@ -426,6 +428,16 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) readl(mbox); } +static u32 tg3_read32_mbox_5906(struct tg3 *tp, u32 off) +{ + return (readl(tp->regs + off + GRCMBOX_BASE)); +} + +static void tg3_write32_mbox_5906(struct tg3 *tp, u32 off, u32 val) +{ + writel(val, tp->regs + off + GRCMBOX_BASE); +} + #define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) #define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) #define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) @@ -441,6 +453,10 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) { unsigned long flags; + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) && + (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) + return; + spin_lock_irqsave(&tp->indirect_lock, flags); if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); @@ -462,6 +478,12 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) { unsigned long flags; + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) && + (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) { + *val = 0; + return; + } + spin_lock_irqsave(&tp->indirect_lock, flags); if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) { pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); @@ -491,6 +513,9 @@ static inline void tg3_cond_int(struct tg3 *tp) if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) && (tp->hw_status->status & SD_STATUS_UPDATED)) tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); + else + tw32(HOSTCC_MODE, tp->coalesce_mode | + (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); } static void tg3_enable_ints(struct tg3 *tp) @@ -656,6 +681,10 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val) unsigned int loops; int ret; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 && + (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL)) + return 0; + if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) { tw32_f(MAC_MI_MODE, (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL)); @@ -1207,7 +1236,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) tg3_setup_phy(tp, 0); } - if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val; + + val = tr32(GRC_VCPU_EXT_CTRL); + tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL); + } else if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { int i; u32 val; @@ -4667,6 +4701,15 @@ static int tg3_poll_fw(struct tg3 *tp) int i; u32 val; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + for (i = 0; i < 400; i++) { + if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) + return 0; + udelay(10); + } + return -ENODEV; + } + /* Wait for firmware initialization to complete. */ for (i = 0; i < 100000; i++) { tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); @@ -4735,6 +4778,12 @@ static int tg3_chip_reset(struct tg3 *tp) } } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + tw32(VCPU_STATUS, tr32(VCPU_STATUS) | VCPU_STATUS_DRV_RESET); + tw32(GRC_VCPU_EXT_CTRL, + tr32(GRC_VCPU_EXT_CTRL) & ~GRC_VCPU_EXT_CTRL_HALT_CPU); + } + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) val |= GRC_MISC_CFG_KEEP_GPHY_POWER; tw32(GRC_MISC_CFG, val); @@ -5066,6 +5115,12 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) BUG_ON(offset == TX_CPU_BASE && (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val = tr32(GRC_VCPU_EXT_CTRL); + + tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU); + return 0; + } if (offset == RX_CPU_BASE) { for (i = 0; i < 10000; i++) { tw32(offset + CPU_STATE, 0xffffffff); @@ -6070,6 +6125,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) val = 1; else if (val > tp->rx_std_max_post) val = tp->rx_std_max_post; + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1) + tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2); + + if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2)) + val = TG3_RX_INTERNAL_RING_SZ_5906 / 2; + } tw32(RCVBDI_STD_THRESH, val); @@ -6984,9 +7046,10 @@ static int tg3_open(struct net_device *dev) if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) { - u32 val = tr32(0x7c04); + u32 val = tr32(PCIE_TRANSACTION_CFG); - tw32(0x7c04, val | (1 << 29)); + tw32(PCIE_TRANSACTION_CFG, + val | PCIE_TRANS_CFG_1SHOT_MSI); } } } @@ -7941,7 +8004,8 @@ static int tg3_set_tso(struct net_device *dev, u32 value) return -EINVAL; return 0; } - if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) { + if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) { if (value) dev->features |= NETIF_F_TSO6; else @@ -9257,6 +9321,13 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp) } } +static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp) +{ + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; +} + /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { @@ -9293,6 +9364,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) tg3_get_5755_nvram_info(tp); else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) tg3_get_5787_nvram_info(tp); + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + tg3_get_5906_nvram_info(tp); else tg3_get_nvram_info(tp); @@ -9766,6 +9839,12 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) /* Assume an onboard device by default. */ tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) + tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; + return; + } + tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { u32 nic_cfg, led_cfg; @@ -10097,7 +10176,10 @@ static void __devinit tg3_read_partno(struct tg3 *tp) } out_not_found: - strcpy(tp->board_part_number, "none"); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + strcpy(tp->board_part_number, "BCM95906"); + else + strcpy(tp->board_part_number, "none"); } static void __devinit tg3_read_fw_ver(struct tg3 *tp) @@ -10299,6 +10381,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) tp->tg3_flags2 |= TG3_FLG2_5750_PLUS; @@ -10308,7 +10391,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) { + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2; tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; } else { @@ -10325,7 +10409,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) @@ -10455,6 +10540,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) pci_cmd &= ~PCI_COMMAND_MEMORY; pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + tp->read32_mbox = tg3_read32_mbox_5906; + tp->write32_mbox = tg3_write32_mbox_5906; + tp->write32_tx_mbox = tg3_write32_mbox_5906; + tp->write32_rx_mbox = tg3_write32_mbox_5906; + } if (tp->write32 == tg3_write_indirect_reg32 || ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && @@ -10526,6 +10617,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) && (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) || (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED; @@ -10539,7 +10631,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; - else + else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; } @@ -10629,7 +10721,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) || (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F || - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F))) + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); @@ -10680,7 +10773,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) * straddle the 4GB address boundary in some cases. */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->dev->hard_start_xmit = tg3_start_xmit; else tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug; @@ -10761,6 +10855,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) else tg3_nvram_unlock(tp); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + mac_offset = 0x10; /* First try to get it from MAC address mailbox. */ tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi); @@ -11244,6 +11340,12 @@ static void __devinit tg3_init_bufmgr_config(struct tg3 *tp) DEFAULT_MB_MACRX_LOW_WATER_5705; tp->bufmgr_config.mbuf_high_water = DEFAULT_MB_HIGH_WATER_5705; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + tp->bufmgr_config.mbuf_mac_rx_low_water = + DEFAULT_MB_MACRX_LOW_WATER_5906; + tp->bufmgr_config.mbuf_high_water = + DEFAULT_MB_HIGH_WATER_5906; + } tp->bufmgr_config.mbuf_read_dma_low_water_jumbo = DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780; @@ -11288,6 +11390,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case PHY_ID_BCM5755: return "5755"; case PHY_ID_BCM5787: return "5787"; case PHY_ID_BCM5756: return "5722/5756"; + case PHY_ID_BCM5906: return "5906"; case PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; default: return "unknown"; @@ -11590,7 +11693,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, */ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { dev->features |= NETIF_F_TSO; - if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) + if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) dev->features |= NETIF_F_TSO6; } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index feed13dc8719..2f5e00c96016 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -24,6 +24,8 @@ #define RX_COPY_THRESHOLD 256 +#define TG3_RX_INTERNAL_RING_SZ_5906 32 + #define RX_STD_MAX_SIZE 1536 #define RX_STD_MAX_SIZE_5705 512 #define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ @@ -129,6 +131,7 @@ #define CHIPREV_ID_5752_A0_HW 0x5000 #define CHIPREV_ID_5752_A0 0x6000 #define CHIPREV_ID_5752_A1 0x6001 +#define CHIPREV_ID_5906_A1 0xc001 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 @@ -141,6 +144,7 @@ #define ASIC_REV_5714 0x09 #define ASIC_REV_5755 0x0a #define ASIC_REV_5787 0x0b +#define ASIC_REV_5906 0x0c #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 @@ -646,7 +650,8 @@ #define SNDDATAI_SCTRL_FORCE_ZERO 0x00000010 #define SNDDATAI_STATSENAB 0x00000c0c #define SNDDATAI_STATSINCMASK 0x00000c10 -/* 0xc14 --> 0xc80 unused */ +#define ISO_PKT_TX 0x00000c20 +/* 0xc24 --> 0xc80 unused */ #define SNDDATAI_COS_CNT_0 0x00000c80 #define SNDDATAI_COS_CNT_1 0x00000c84 #define SNDDATAI_COS_CNT_2 0x00000c88 @@ -997,11 +1002,13 @@ #define BUFMGR_MB_MACRX_LOW_WATER 0x00004414 #define DEFAULT_MB_MACRX_LOW_WATER 0x00000020 #define DEFAULT_MB_MACRX_LOW_WATER_5705 0x00000010 +#define DEFAULT_MB_MACRX_LOW_WATER_5906 0x00000004 #define DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098 #define DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780 0x0000004b #define BUFMGR_MB_HIGH_WATER 0x00004418 #define DEFAULT_MB_HIGH_WATER 0x00000060 #define DEFAULT_MB_HIGH_WATER_5705 0x00000060 +#define DEFAULT_MB_HIGH_WATER_5906 0x00000010 #define DEFAULT_MB_HIGH_WATER_JUMBO 0x0000017c #define DEFAULT_MB_HIGH_WATER_JUMBO_5780 0x00000096 #define BUFMGR_RX_MB_ALLOC_REQ 0x0000441c @@ -1138,7 +1145,12 @@ #define TX_CPU_STATE 0x00005404 #define TX_CPU_PGMCTR 0x0000541c +#define VCPU_STATUS 0x00005100 +#define VCPU_STATUS_INIT_DONE 0x04000000 +#define VCPU_STATUS_DRV_RESET 0x08000000 + /* Mailboxes */ +#define GRCMBOX_BASE 0x00005600 #define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */ #define GRCMBOX_INTERRUPT_1 0x00005808 /* 64-bit */ #define GRCMBOX_INTERRUPT_2 0x00005810 /* 64-bit */ @@ -1398,7 +1410,10 @@ #define GRC_EEPROM_CTRL 0x00006840 #define GRC_MDI_CTRL 0x00006844 #define GRC_SEEPROM_DELAY 0x00006848 -/* 0x684c --> 0x6c00 unused */ +/* 0x684c --> 0x6890 unused */ +#define GRC_VCPU_EXT_CTRL 0x00006890 +#define GRC_VCPU_EXT_CTRL_HALT_CPU 0x00400000 +#define GRC_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000 #define GRC_FASTBOOT_PC 0x00006894 /* 5752, 5755, 5787 */ /* 0x6c00 --> 0x7000 unused */ @@ -1485,7 +1500,11 @@ #define NVRAM_WRITE1 0x00007028 /* 0x702c --> 0x7400 unused */ -/* 0x7400 --> 0x8000 unused */ +/* 0x7400 --> 0x7c00 unused */ +#define PCIE_TRANSACTION_CFG 0x00007c04 +#define PCIE_TRANS_CFG_1SHOT_MSI 0x20000000 +#define PCIE_TRANS_CFG_LOM 0x00000020 + #define TG3_EEPROM_MAGIC 0x669955aa @@ -2283,6 +2302,7 @@ struct tg3 { #define PHY_ID_BCM5755 0xbc050cc0 #define PHY_ID_BCM5787 0xbc050ce0 #define PHY_ID_BCM5756 0xbc050ed0 +#define PHY_ID_BCM5906 0xdc00ac40 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_INVALID 0xffffffff #define PHY_ID_REV_MASK 0x0000000f @@ -2310,7 +2330,7 @@ struct tg3 { (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \ (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \ - (X) == PHY_ID_BCM8002) + (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM8002) struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ea3140d226e6..b7e85ff045ea 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1944,6 +1944,8 @@ #define PCI_DEVICE_ID_TIGON3_5901 0x170d #define PCI_DEVICE_ID_BCM4401B1 0x170c #define PCI_DEVICE_ID_TIGON3_5901_2 0x170e +#define PCI_DEVICE_ID_TIGON3_5906 0x1712 +#define PCI_DEVICE_ID_TIGON3_5906M 0x1713 #define PCI_DEVICE_ID_BCM4401 0x4401 #define PCI_DEVICE_ID_BCM4401B0 0x4402 -- cgit v1.2.3 From 715116a12610b67c1d301a9b845ce95f7247dad3 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:09:25 -0700 Subject: [TG3]: Add 5709 PHY support. Add support for the 5709 10/100 PHY. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 37 +++++++++++++++++++++++++++++++++---- drivers/net/tg3.h | 6 ++++++ 2 files changed, 39 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 2b062d776511..23f5744bdffa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1035,6 +1035,24 @@ out: phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 phy_reg; + + /* adjust output voltage */ + tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12); + + if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phy_reg)) { + u32 phy_reg2; + + tg3_writephy(tp, MII_TG3_EPHY_TEST, + phy_reg | MII_TG3_EPHY_SHADOW_EN); + /* Enable auto-MDIX */ + if (!tg3_readphy(tp, 0x10, &phy_reg2)) + tg3_writephy(tp, 0x10, phy_reg2 | 0x4000); + tg3_writephy(tp, MII_TG3_EPHY_TEST, phy_reg); + } + } + tg3_phy_set_wirespeed(tp); return 0; } @@ -1151,8 +1169,11 @@ static void tg3_power_down_phy(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) return; - tg3_writephy(tp, MII_TG3_EXT_CTRL, MII_TG3_EXT_CTRL_FORCE_LED_OFF); - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) { + tg3_writephy(tp, MII_TG3_EXT_CTRL, + MII_TG3_EXT_CTRL_FORCE_LED_OFF); + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); + } /* The PHY should not be powered down on some chips because * of bugs. @@ -1505,6 +1526,13 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 break; default: + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 : + SPEED_10; + *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL : + DUPLEX_HALF; + break; + } *speed = SPEED_INVALID; *duplex = DUPLEX_INVALID; break; @@ -1787,7 +1815,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG); - else + else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tg3_writephy(tp, MII_TG3_IMASK, ~0); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || @@ -6552,7 +6580,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (err) return err; - if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) { u32 tmp; /* Clear CRC stats. */ diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 2f5e00c96016..9259d12fabd9 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1624,6 +1624,7 @@ #define MII_TG3_DSP_RW_PORT 0x15 /* DSP coefficient read/write port */ #define MII_TG3_DSP_ADDRESS 0x17 /* DSP address register */ +#define MII_TG3_EPHY_PTEST 0x17 /* 5906 PHY register */ #define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */ @@ -1637,6 +1638,8 @@ #define MII_TG3_AUX_STAT_100FULL 0x0500 #define MII_TG3_AUX_STAT_1000HALF 0x0600 #define MII_TG3_AUX_STAT_1000FULL 0x0700 +#define MII_TG3_AUX_STAT_100 0x0008 +#define MII_TG3_AUX_STAT_FULL 0x0001 #define MII_TG3_ISTAT 0x1a /* IRQ status register */ #define MII_TG3_IMASK 0x1b /* IRQ mask register */ @@ -1647,6 +1650,9 @@ #define MII_TG3_INT_DUPLEXCHG 0x0008 #define MII_TG3_INT_ANEG_PAGE_RX 0x0400 +#define MII_TG3_EPHY_TEST 0x1f /* 5906 PHY register */ +#define MII_TG3_EPHY_SHADOW_EN 0x80 + /* There are two ways to manage the TX descriptors on the tigon3. * Either the descriptors are in host DMA'able memory, or they * exist only in the cards on-chip SRAM. All 16 send bds are under -- cgit v1.2.3 From b16250e3d1c55820f08f0296624a423122ea9805 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:10:14 -0700 Subject: [TG3]: Add 5709 self-test support. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++------- drivers/net/tg3.h | 4 ++ 2 files changed, 111 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 23f5744bdffa..21843de4a88a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3615,8 +3615,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, if ((sblk->status & SD_STATUS_UPDATED) || !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000001); + tg3_disable_ints(tp); return IRQ_RETVAL(1); } return IRQ_RETVAL(0); @@ -6860,8 +6859,7 @@ static int tg3_request_irq(struct tg3 *tp) static int tg3_test_interrupt(struct tg3 *tp) { struct net_device *dev = tp->dev; - int err, i; - u32 int_mbox = 0; + int err, i, intr_ok = 0; if (!netif_running(dev)) return -ENODEV; @@ -6882,10 +6880,18 @@ static int tg3_test_interrupt(struct tg3 *tp) HOSTCC_MODE_NOW); for (i = 0; i < 5; i++) { + u32 int_mbox, misc_host_ctrl; + int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); - if (int_mbox != 0) + misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); + + if ((int_mbox != 0) || + (misc_host_ctrl & MISC_HOST_CTRL_MASK_PCI_INT)) { + intr_ok = 1; break; + } + msleep(10); } @@ -6898,7 +6904,7 @@ static int tg3_test_interrupt(struct tg3 *tp) if (err) return err; - if (int_mbox != 0) + if (intr_ok) return 0; return -EIO; @@ -8288,6 +8294,8 @@ static void tg3_get_ethtool_stats (struct net_device *dev, #define NVRAM_TEST_SIZE 0x100 #define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14 +#define NVRAM_SELFBOOT_HW_SIZE 0x20 +#define NVRAM_SELFBOOT_DATA_SIZE 0x1c static int tg3_test_nvram(struct tg3 *tp) { @@ -8299,12 +8307,14 @@ static int tg3_test_nvram(struct tg3 *tp) if (magic == TG3_EEPROM_MAGIC) size = NVRAM_TEST_SIZE; - else if ((magic & 0xff000000) == 0xa5000000) { + else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) { if ((magic & 0xe00000) == 0x200000) size = NVRAM_SELFBOOT_FORMAT1_SIZE; else return 0; - } else + } else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW) + size = NVRAM_SELFBOOT_HW_SIZE; + else return -EIO; buf = kmalloc(size, GFP_KERNEL); @@ -8323,7 +8333,8 @@ static int tg3_test_nvram(struct tg3 *tp) goto out; /* Selfboot format */ - if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) { + if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_FW_MSK) == + TG3_EEPROM_MAGIC_FW) { u8 *buf8 = (u8 *) buf, csum8 = 0; for (i = 0; i < size; i++) @@ -8338,6 +8349,51 @@ static int tg3_test_nvram(struct tg3 *tp) goto out; } + if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_HW_MSK) == + TG3_EEPROM_MAGIC_HW) { + u8 data[NVRAM_SELFBOOT_DATA_SIZE]; + u8 parity[NVRAM_SELFBOOT_DATA_SIZE]; + u8 *buf8 = (u8 *) buf; + int j, k; + + /* Separate the parity bits and the data bytes. */ + for (i = 0, j = 0, k = 0; i < NVRAM_SELFBOOT_HW_SIZE; i++) { + if ((i == 0) || (i == 8)) { + int l; + u8 msk; + + for (l = 0, msk = 0x80; l < 7; l++, msk >>= 1) + parity[k++] = buf8[i] & msk; + i++; + } + else if (i == 16) { + int l; + u8 msk; + + for (l = 0, msk = 0x20; l < 6; l++, msk >>= 1) + parity[k++] = buf8[i] & msk; + i++; + + for (l = 0, msk = 0x80; l < 8; l++, msk >>= 1) + parity[k++] = buf8[i] & msk; + i++; + } + data[j++] = buf8[i]; + } + + err = -EIO; + for (i = 0; i < NVRAM_SELFBOOT_DATA_SIZE; i++) { + u8 hw8 = hweight8(data[i]); + + if ((hw8 & 0x1) && parity[i]) + goto out; + else if (!(hw8 & 0x1) && !parity[i]) + goto out; + } + err = 0; + goto out; + } + /* Bootstrap checksum at offset 0x10 */ csum = calc_crc((unsigned char *) buf, 0x10); if(csum != cpu_to_le32(buf[0x10/4])) @@ -8384,7 +8440,7 @@ static int tg3_test_link(struct tg3 *tp) /* Only test the commonly used registers */ static int tg3_test_registers(struct tg3 *tp) { - int i, is_5705; + int i, is_5705, is_5750; u32 offset, read_mask, write_mask, val, save_val, read_val; static struct { u16 offset; @@ -8392,6 +8448,7 @@ static int tg3_test_registers(struct tg3 *tp) #define TG3_FL_5705 0x1 #define TG3_FL_NOT_5705 0x2 #define TG3_FL_NOT_5788 0x4 +#define TG3_FL_NOT_5750 0x8 u32 read_mask; u32 write_mask; } reg_tbl[] = { @@ -8502,9 +8559,9 @@ static int tg3_test_registers(struct tg3 *tp) 0xffffffff, 0x00000000 }, /* Buffer Manager Control Registers. */ - { BUFMGR_MB_POOL_ADDR, 0x0000, + { BUFMGR_MB_POOL_ADDR, TG3_FL_NOT_5750, 0x00000000, 0x007fff80 }, - { BUFMGR_MB_POOL_SIZE, 0x0000, + { BUFMGR_MB_POOL_SIZE, TG3_FL_NOT_5750, 0x00000000, 0x007fffff }, { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, 0x00000000, 0x0000003f }, @@ -8530,10 +8587,12 @@ static int tg3_test_registers(struct tg3 *tp) { 0xffff, 0x0000, 0x00000000, 0x00000000 }, }; - if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) + is_5705 = is_5750 = 0; + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { is_5705 = 1; - else - is_5705 = 0; + if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) + is_5750 = 1; + } for (i = 0; reg_tbl[i].offset != 0xffff; i++) { if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) @@ -8546,6 +8605,9 @@ static int tg3_test_registers(struct tg3 *tp) (reg_tbl[i].flags & TG3_FL_NOT_5788)) continue; + if (is_5750 && (reg_tbl[i].flags & TG3_FL_NOT_5750)) + continue; + offset = (u32) reg_tbl[i].offset; read_mask = reg_tbl[i].read_mask; write_mask = reg_tbl[i].write_mask; @@ -8637,6 +8699,13 @@ static int tg3_test_memory(struct tg3 *tp) { 0x00008000, 0x02000}, { 0x00010000, 0x0c000}, { 0xffffffff, 0x00000} + }, mem_tbl_5906[] = { + { 0x00000200, 0x00008}, + { 0x00004000, 0x00400}, + { 0x00006000, 0x00400}, + { 0x00008000, 0x01000}, + { 0x00010000, 0x01000}, + { 0xffffffff, 0x00000} }; struct mem_entry *mem_tbl; int err = 0; @@ -8646,6 +8715,8 @@ static int tg3_test_memory(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) mem_tbl = mem_tbl_5755; + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + mem_tbl = mem_tbl_5906; else mem_tbl = mem_tbl_5705; } else @@ -8691,6 +8762,21 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) } else if (loopback_mode == TG3_PHY_LOOPBACK) { u32 val; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 phytest; + + if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phytest)) { + u32 phy; + + tg3_writephy(tp, MII_TG3_EPHY_TEST, + phytest | MII_TG3_EPHY_SHADOW_EN); + if (!tg3_readphy(tp, 0x1b, &phy)) + tg3_writephy(tp, 0x1b, phy & ~0x20); + if (!tg3_readphy(tp, 0x10, &phy)) + tg3_writephy(tp, 0x10, phy & ~0x4000); + tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest); + } + } val = BMCR_LOOPBACK | BMCR_FULLDPLX; if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) val |= BMCR_SPEED100; @@ -8699,6 +8785,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) tg3_writephy(tp, MII_BMCR, val); udelay(40); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800); + /* reset to prevent losing 1st rx packet intermittently */ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { tw32_f(MAC_RX_MODE, RX_MODE_RESET); @@ -9112,7 +9201,9 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp) if (tg3_nvram_read_swab(tp, 0, &magic) != 0) return; - if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000)) + if ((magic != TG3_EEPROM_MAGIC) && + ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) && + ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW)) return; /* diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 9259d12fabd9..92f53000bce6 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1507,6 +1507,10 @@ #define TG3_EEPROM_MAGIC 0x669955aa +#define TG3_EEPROM_MAGIC_FW 0xa5000000 +#define TG3_EEPROM_MAGIC_FW_MSK 0xff000000 +#define TG3_EEPROM_MAGIC_HW 0xabcd +#define TG3_EEPROM_MAGIC_HW_MSK 0xffff /* 32K Window into NIC internal memory */ #define NIC_SRAM_WIN_BASE 0x00008000 -- cgit v1.2.3 From 1533d382155ee888d9621391c108ffb7a68bb25d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 27 Sep 2006 16:10:35 -0700 Subject: [TG3]: Update version and reldate. Update version to 3.66. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 21843de4a88a..c25ba273b745 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.65" -#define DRV_MODULE_RELDATE "August 07, 2006" +#define DRV_MODULE_VERSION "3.66" +#define DRV_MODULE_RELDATE "September 23, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.3 From c9aa6895371b2a257401f59d3393c9f7ac5a8698 Mon Sep 17 00:00:00 2001 From: Michal Ostrowski Date: Wed, 27 Sep 2006 16:11:25 -0700 Subject: [PPPOE]: Advertise PPPoE MTU PPPoE must advertise the underlying device's MTU via the ppp channel descriptor structure, as multilink functionality depends on it. Signed-off-by: Michal Ostrowski Acked-by: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 5666ed998142..0adee733b761 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -600,6 +600,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.hdrlen = (sizeof(struct pppoe_hdr) + dev->hard_header_len); + po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr); po->chan.private = sk; po->chan.ops = &pppoe_chan_ops; -- cgit v1.2.3 From 778e6398d32590eaf2333706318cbcd04dbe50b7 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 27 Sep 2006 20:06:16 -0700 Subject: [IrDA]: irda-usb needs firmware loader With the inclusion of the stir421x code, we now need to select FW_LOADER whenever we try to build the irda-usb code. Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index e9e6d99a9add..7c8ccc09b601 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -287,6 +287,7 @@ comment "FIR device drivers" config USB_IRDA tristate "IrDA USB dongles" depends on IRDA && USB + select FW_LOADER ---help--- Say Y here if you want to build support for the USB IrDA FIR Dongle device driver. To compile it as a module, choose M here: the module -- cgit v1.2.3 From 7fa6b06689085a3e2237cf810f5e0c114e00a2da Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 27 Sep 2006 20:33:34 -0700 Subject: [NET] loopback: minor statistics optimization The loopback device status structure is a singleton and doesn't need to be allocated. Add ethtool_ops hooks to show checksum always on, and make ethtool_ops const. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/loopback.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index f429b19bf620..4178b4b1d2df 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -161,15 +161,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) return(0); } +static struct net_device_stats loopback_stats; + static struct net_device_stats *get_stats(struct net_device *dev) { - struct net_device_stats *stats = dev->priv; + struct net_device_stats *stats = &loopback_stats; int i; - if (!stats) { - return NULL; - } - memset(stats, 0, sizeof(struct net_device_stats)); for_each_possible_cpu(i) { @@ -185,19 +183,28 @@ static struct net_device_stats *get_stats(struct net_device *dev) return stats; } -static u32 loopback_get_link(struct net_device *dev) +static u32 always_on(struct net_device *dev) { return 1; } static const struct ethtool_ops loopback_ethtool_ops = { - .get_link = loopback_get_link, + .get_link = always_on, .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, + .get_tx_csum = always_on, + .get_sg = always_on, + .get_rx_csum = always_on, }; +/* + * The loopback device is special. There is only one instance and + * it is statically allocated. Don't do this for other devices. + */ struct net_device loopback_dev = { .name = "lo", + .get_stats = &get_stats, + .priv = &loopback_stats, .mtu = (16 * 1024) + 20 + 20 + 12, .hard_start_xmit = loopback_xmit, .hard_header = eth_header, @@ -221,16 +228,6 @@ struct net_device loopback_dev = { /* Setup and register the loopback device. */ int __init loopback_init(void) { - struct net_device_stats *stats; - - /* Can survive without statistics */ - stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); - if (stats) { - memset(stats, 0, sizeof(struct net_device_stats)); - loopback_dev.priv = stats; - loopback_dev.get_stats = &get_stats; - } - return register_netdev(&loopback_dev); }; -- cgit v1.2.3 From 2fd19a687c256fa4c4750465b9856e2c80660ec8 Mon Sep 17 00:00:00 2001 From: Lamarque Vieira Souza Date: Wed, 27 Sep 2006 22:48:36 -0700 Subject: [IrDA] nsc-ircc: Configuration base address for PC87383 According to NatSemi datasheet, the configuration base address for the PC8738x family is 0x2e or 0x164. 0x0 doesn't appear in any datasheet. Patch from Lamarque Vieira Souza Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/nsc-ircc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index cb62f2a9676a..7185a4ee3c1e 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -110,7 +110,7 @@ static nsc_chip_t chips[] = { { "PC87338", { 0x398, 0x15c, 0x2e }, 0x08, 0xb0, 0xf8, nsc_ircc_probe_338, nsc_ircc_init_338 }, /* Contributed by Steffen Pingel - IBM X40 */ - { "PC8738x", { 0x164e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff, + { "PC8738x", { 0x164e, 0x4e, 0x2e }, 0x20, 0xf4, 0xff, nsc_ircc_probe_39x, nsc_ircc_init_39x }, /* Contributed by Jan Frey - IBM A30/A31 */ { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, -- cgit v1.2.3 From 895de090d4302a02a77cdf366fc6e54fc2001857 Mon Sep 17 00:00:00 2001 From: "Linus Walleij (LD/EAB" Date: Wed, 27 Sep 2006 22:49:23 -0700 Subject: [IrDA] smsc-ircc: More laptops detected This patch detects the smsc-ircc chipset on the nx1000 (including nx7000 and nx7010) and the nx5000 HP/Compaq laptop series. Patch from "Linus Walleij (LD/EAB)" Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/smsc-ircc2.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 2eff45bedc7c..22358ff68c4c 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -2354,6 +2354,26 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) #define PCIID_VENDOR_INTEL 0x8086 #define PCIID_VENDOR_ALI 0x10b9 static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = { + /* + * Subsystems needing entries: + * 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family + * 0x10b9:0x1533 0x0e11:0x005a Compaq nc4000 family + * 0x8086:0x24cc 0x0e11:0x002a HP nx9000 family + */ + { + /* Guessed entry */ + .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ + .device = 0x24cc, + .subvendor = 0x103c, + .subdevice = 0x08bc, + .sir_io = 0x02f8, + .fir_io = 0x0130, + .fir_irq = 0x05, + .fir_dma = 0x03, + .cfg_base = 0x004e, + .preconfigure = preconfigure_through_82801, + .name = "HP nx5000 family", + }, { .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, @@ -2366,7 +2386,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .fir_dma = 0x03, .cfg_base = 0x004e, .preconfigure = preconfigure_through_82801, - .name = "HP nc8000", + .name = "HP nc8000 family", }, { .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ @@ -2379,7 +2399,21 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .fir_dma = 0x03, .cfg_base = 0x004e, .preconfigure = preconfigure_through_82801, - .name = "HP nc6000", + .name = "HP nc6000 family", + }, + { + .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ + .device = 0x24cc, + .subvendor = 0x0e11, + .subdevice = 0x0860, + /* I assume these are the same for x1000 as for the others */ + .sir_io = 0x02e8, + .fir_io = 0x02f8, + .fir_irq = 0x07, + .fir_dma = 0x03, + .cfg_base = 0x002e, + .preconfigure = preconfigure_through_82801, + .name = "Compaq x1000 family", }, { /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ -- cgit v1.2.3 From febac9b93724f3ee293e7e5450043ae28e61531a Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 27 Sep 2006 22:50:06 -0700 Subject: [IrDA] stir4200: removing undocumented bits handling FIFOCTL_RXERR and FIFOCTL_TXERR are undocumented bits, according to the Sigmatel datasheet. We should thus not take any assumption on their values and semantics. Problem spotted by andrzej zaborowski Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/stir4200.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index d61b208b52a2..12103c93f7ef 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -149,8 +149,6 @@ enum StirFifoCtlMask { FIFOCTL_DIR = 0x10, FIFOCTL_CLR = 0x08, FIFOCTL_EMPTY = 0x04, - FIFOCTL_RXERR = 0x02, - FIFOCTL_TXERR = 0x01, }; enum StirDiagMask { @@ -615,19 +613,6 @@ static int fifo_txwait(struct stir_cb *stir, int space) pr_debug("fifo status 0x%lx count %lu\n", status, count); - /* error when receive/transmit fifo gets confused */ - if (status & FIFOCTL_RXERR) { - stir->stats.rx_fifo_errors++; - stir->stats.rx_errors++; - break; - } - - if (status & FIFOCTL_TXERR) { - stir->stats.tx_fifo_errors++; - stir->stats.tx_errors++; - break; - } - /* is fifo receiving already, or empty */ if (!(status & FIFOCTL_DIR) || (status & FIFOCTL_EMPTY)) -- cgit v1.2.3