diff options
Diffstat (limited to 'drivers/net')
27 files changed, 321 insertions, 84 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 6e4c80d41b08..6ddc911e7d15 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
| @@ -2023,6 +2023,7 @@ rrd_ok: | |||
| 2023 | /* Good Receive */ | 2023 | /* Good Receive */ |
| 2024 | pci_unmap_page(adapter->pdev, buffer_info->dma, | 2024 | pci_unmap_page(adapter->pdev, buffer_info->dma, |
| 2025 | buffer_info->length, PCI_DMA_FROMDEVICE); | 2025 | buffer_info->length, PCI_DMA_FROMDEVICE); |
| 2026 | buffer_info->dma = 0; | ||
| 2026 | skb = buffer_info->skb; | 2027 | skb = buffer_info->skb; |
| 2027 | length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); | 2028 | length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); |
| 2028 | 2029 | ||
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 348371fda597..fba87abe78ee 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
| @@ -1394,7 +1394,11 @@ net_open(struct net_device *dev) | |||
| 1394 | #endif | 1394 | #endif |
| 1395 | if (!result) { | 1395 | if (!result) { |
| 1396 | printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); | 1396 | printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); |
| 1397 | release_irq: | 1397 | release_dma: |
| 1398 | #if ALLOW_DMA | ||
| 1399 | free_dma(dev->dma); | ||
| 1400 | #endif | ||
| 1401 | release_irq: | ||
| 1398 | #if ALLOW_DMA | 1402 | #if ALLOW_DMA |
| 1399 | release_dma_buff(lp); | 1403 | release_dma_buff(lp); |
| 1400 | #endif | 1404 | #endif |
| @@ -1442,12 +1446,12 @@ net_open(struct net_device *dev) | |||
| 1442 | if ((result = detect_bnc(dev)) != DETECTED_NONE) | 1446 | if ((result = detect_bnc(dev)) != DETECTED_NONE) |
| 1443 | break; | 1447 | break; |
| 1444 | printk(KERN_ERR "%s: no media detected\n", dev->name); | 1448 | printk(KERN_ERR "%s: no media detected\n", dev->name); |
| 1445 | goto release_irq; | 1449 | goto release_dma; |
| 1446 | } | 1450 | } |
| 1447 | switch(result) { | 1451 | switch(result) { |
| 1448 | case DETECTED_NONE: | 1452 | case DETECTED_NONE: |
| 1449 | printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); | 1453 | printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); |
| 1450 | goto release_irq; | 1454 | goto release_dma; |
| 1451 | case DETECTED_RJ45H: | 1455 | case DETECTED_RJ45H: |
| 1452 | printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); | 1456 | printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); |
| 1453 | break; | 1457 | break; |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 36be6efc6398..e0d76c75aea0 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
| @@ -75,7 +75,7 @@ | |||
| 75 | #include "myri10ge_mcp.h" | 75 | #include "myri10ge_mcp.h" |
| 76 | #include "myri10ge_mcp_gen_header.h" | 76 | #include "myri10ge_mcp_gen_header.h" |
| 77 | 77 | ||
| 78 | #define MYRI10GE_VERSION_STR "1.3.2-1.287" | 78 | #define MYRI10GE_VERSION_STR "1.3.99-1.347" |
| 79 | 79 | ||
| 80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); | 80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); |
| 81 | MODULE_AUTHOR("Maintainer: help@myri.com"); | 81 | MODULE_AUTHOR("Maintainer: help@myri.com"); |
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 8db342f2fdc9..70cfdb46aa27 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c | |||
| @@ -240,12 +240,15 @@ static inline struct pppol2tp_session *pppol2tp_sock_to_session(struct sock *sk) | |||
| 240 | if (sk == NULL) | 240 | if (sk == NULL) |
| 241 | return NULL; | 241 | return NULL; |
| 242 | 242 | ||
| 243 | sock_hold(sk); | ||
| 243 | session = (struct pppol2tp_session *)(sk->sk_user_data); | 244 | session = (struct pppol2tp_session *)(sk->sk_user_data); |
| 244 | if (session == NULL) | 245 | if (session == NULL) { |
| 245 | return NULL; | 246 | sock_put(sk); |
| 247 | goto out; | ||
| 248 | } | ||
| 246 | 249 | ||
| 247 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); | 250 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); |
| 248 | 251 | out: | |
| 249 | return session; | 252 | return session; |
| 250 | } | 253 | } |
| 251 | 254 | ||
| @@ -256,12 +259,15 @@ static inline struct pppol2tp_tunnel *pppol2tp_sock_to_tunnel(struct sock *sk) | |||
| 256 | if (sk == NULL) | 259 | if (sk == NULL) |
| 257 | return NULL; | 260 | return NULL; |
| 258 | 261 | ||
| 262 | sock_hold(sk); | ||
| 259 | tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data); | 263 | tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data); |
| 260 | if (tunnel == NULL) | 264 | if (tunnel == NULL) { |
| 261 | return NULL; | 265 | sock_put(sk); |
| 266 | goto out; | ||
| 267 | } | ||
| 262 | 268 | ||
| 263 | BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); | 269 | BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); |
| 264 | 270 | out: | |
| 265 | return tunnel; | 271 | return tunnel; |
| 266 | } | 272 | } |
| 267 | 273 | ||
| @@ -716,12 +722,14 @@ discard: | |||
| 716 | session->stats.rx_errors++; | 722 | session->stats.rx_errors++; |
| 717 | kfree_skb(skb); | 723 | kfree_skb(skb); |
| 718 | sock_put(session->sock); | 724 | sock_put(session->sock); |
| 725 | sock_put(sock); | ||
| 719 | 726 | ||
| 720 | return 0; | 727 | return 0; |
| 721 | 728 | ||
| 722 | error: | 729 | error: |
| 723 | /* Put UDP header back */ | 730 | /* Put UDP header back */ |
| 724 | __skb_push(skb, sizeof(struct udphdr)); | 731 | __skb_push(skb, sizeof(struct udphdr)); |
| 732 | sock_put(sock); | ||
| 725 | 733 | ||
| 726 | no_tunnel: | 734 | no_tunnel: |
| 727 | return 1; | 735 | return 1; |
| @@ -745,10 +753,13 @@ static int pppol2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
| 745 | "%s: received %d bytes\n", tunnel->name, skb->len); | 753 | "%s: received %d bytes\n", tunnel->name, skb->len); |
| 746 | 754 | ||
| 747 | if (pppol2tp_recv_core(sk, skb)) | 755 | if (pppol2tp_recv_core(sk, skb)) |
| 748 | goto pass_up; | 756 | goto pass_up_put; |
| 749 | 757 | ||
| 758 | sock_put(sk); | ||
| 750 | return 0; | 759 | return 0; |
| 751 | 760 | ||
| 761 | pass_up_put: | ||
| 762 | sock_put(sk); | ||
| 752 | pass_up: | 763 | pass_up: |
| 753 | return 1; | 764 | return 1; |
| 754 | } | 765 | } |
| @@ -858,7 +869,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
| 858 | 869 | ||
| 859 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 870 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
| 860 | if (tunnel == NULL) | 871 | if (tunnel == NULL) |
| 861 | goto error; | 872 | goto error_put_sess; |
| 862 | 873 | ||
| 863 | /* What header length is configured for this session? */ | 874 | /* What header length is configured for this session? */ |
| 864 | hdr_len = pppol2tp_l2tp_header_len(session); | 875 | hdr_len = pppol2tp_l2tp_header_len(session); |
| @@ -870,7 +881,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
| 870 | sizeof(ppph) + total_len, | 881 | sizeof(ppph) + total_len, |
| 871 | 0, GFP_KERNEL); | 882 | 0, GFP_KERNEL); |
| 872 | if (!skb) | 883 | if (!skb) |
| 873 | goto error; | 884 | goto error_put_sess_tun; |
| 874 | 885 | ||
| 875 | /* Reserve space for headers. */ | 886 | /* Reserve space for headers. */ |
| 876 | skb_reserve(skb, NET_SKB_PAD); | 887 | skb_reserve(skb, NET_SKB_PAD); |
| @@ -900,7 +911,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
| 900 | error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); | 911 | error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); |
| 901 | if (error < 0) { | 912 | if (error < 0) { |
| 902 | kfree_skb(skb); | 913 | kfree_skb(skb); |
| 903 | goto error; | 914 | goto error_put_sess_tun; |
| 904 | } | 915 | } |
| 905 | skb_put(skb, total_len); | 916 | skb_put(skb, total_len); |
| 906 | 917 | ||
| @@ -947,10 +958,33 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
| 947 | session->stats.tx_errors++; | 958 | session->stats.tx_errors++; |
| 948 | } | 959 | } |
| 949 | 960 | ||
| 961 | return error; | ||
| 962 | |||
| 963 | error_put_sess_tun: | ||
| 964 | sock_put(session->tunnel_sock); | ||
| 965 | error_put_sess: | ||
| 966 | sock_put(sk); | ||
| 950 | error: | 967 | error: |
| 951 | return error; | 968 | return error; |
| 952 | } | 969 | } |
| 953 | 970 | ||
| 971 | /* Automatically called when the skb is freed. | ||
| 972 | */ | ||
| 973 | static void pppol2tp_sock_wfree(struct sk_buff *skb) | ||
| 974 | { | ||
| 975 | sock_put(skb->sk); | ||
| 976 | } | ||
| 977 | |||
| 978 | /* For data skbs that we transmit, we associate with the tunnel socket | ||
| 979 | * but don't do accounting. | ||
| 980 | */ | ||
| 981 | static inline void pppol2tp_skb_set_owner_w(struct sk_buff *skb, struct sock *sk) | ||
| 982 | { | ||
| 983 | sock_hold(sk); | ||
| 984 | skb->sk = sk; | ||
| 985 | skb->destructor = pppol2tp_sock_wfree; | ||
| 986 | } | ||
| 987 | |||
| 954 | /* Transmit function called by generic PPP driver. Sends PPP frame | 988 | /* Transmit function called by generic PPP driver. Sends PPP frame |
| 955 | * over PPPoL2TP socket. | 989 | * over PPPoL2TP socket. |
| 956 | * | 990 | * |
| @@ -993,10 +1027,10 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 993 | 1027 | ||
| 994 | sk_tun = session->tunnel_sock; | 1028 | sk_tun = session->tunnel_sock; |
| 995 | if (sk_tun == NULL) | 1029 | if (sk_tun == NULL) |
| 996 | goto abort; | 1030 | goto abort_put_sess; |
| 997 | tunnel = pppol2tp_sock_to_tunnel(sk_tun); | 1031 | tunnel = pppol2tp_sock_to_tunnel(sk_tun); |
| 998 | if (tunnel == NULL) | 1032 | if (tunnel == NULL) |
| 999 | goto abort; | 1033 | goto abort_put_sess; |
| 1000 | 1034 | ||
| 1001 | /* What header length is configured for this session? */ | 1035 | /* What header length is configured for this session? */ |
| 1002 | hdr_len = pppol2tp_l2tp_header_len(session); | 1036 | hdr_len = pppol2tp_l2tp_header_len(session); |
| @@ -1009,7 +1043,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 1009 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); | 1043 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); |
| 1010 | old_headroom = skb_headroom(skb); | 1044 | old_headroom = skb_headroom(skb); |
| 1011 | if (skb_cow_head(skb, headroom)) | 1045 | if (skb_cow_head(skb, headroom)) |
| 1012 | goto abort; | 1046 | goto abort_put_sess_tun; |
| 1013 | 1047 | ||
| 1014 | new_headroom = skb_headroom(skb); | 1048 | new_headroom = skb_headroom(skb); |
| 1015 | skb_orphan(skb); | 1049 | skb_orphan(skb); |
| @@ -1069,7 +1103,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 1069 | /* Get routing info from the tunnel socket */ | 1103 | /* Get routing info from the tunnel socket */ |
| 1070 | dst_release(skb->dst); | 1104 | dst_release(skb->dst); |
| 1071 | skb->dst = dst_clone(__sk_dst_get(sk_tun)); | 1105 | skb->dst = dst_clone(__sk_dst_get(sk_tun)); |
| 1072 | skb->sk = sk_tun; | 1106 | pppol2tp_skb_set_owner_w(skb, sk_tun); |
| 1073 | 1107 | ||
| 1074 | /* Queue the packet to IP for output */ | 1108 | /* Queue the packet to IP for output */ |
| 1075 | len = skb->len; | 1109 | len = skb->len; |
| @@ -1086,8 +1120,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 1086 | session->stats.tx_errors++; | 1120 | session->stats.tx_errors++; |
| 1087 | } | 1121 | } |
| 1088 | 1122 | ||
| 1123 | sock_put(sk_tun); | ||
| 1124 | sock_put(sk); | ||
| 1089 | return 1; | 1125 | return 1; |
| 1090 | 1126 | ||
| 1127 | abort_put_sess_tun: | ||
| 1128 | sock_put(sk_tun); | ||
| 1129 | abort_put_sess: | ||
| 1130 | sock_put(sk); | ||
| 1091 | abort: | 1131 | abort: |
| 1092 | /* Free the original skb */ | 1132 | /* Free the original skb */ |
| 1093 | kfree_skb(skb); | 1133 | kfree_skb(skb); |
| @@ -1191,7 +1231,7 @@ static void pppol2tp_tunnel_destruct(struct sock *sk) | |||
| 1191 | { | 1231 | { |
| 1192 | struct pppol2tp_tunnel *tunnel; | 1232 | struct pppol2tp_tunnel *tunnel; |
| 1193 | 1233 | ||
| 1194 | tunnel = pppol2tp_sock_to_tunnel(sk); | 1234 | tunnel = sk->sk_user_data; |
| 1195 | if (tunnel == NULL) | 1235 | if (tunnel == NULL) |
| 1196 | goto end; | 1236 | goto end; |
| 1197 | 1237 | ||
| @@ -1230,10 +1270,12 @@ static void pppol2tp_session_destruct(struct sock *sk) | |||
| 1230 | if (sk->sk_user_data != NULL) { | 1270 | if (sk->sk_user_data != NULL) { |
| 1231 | struct pppol2tp_tunnel *tunnel; | 1271 | struct pppol2tp_tunnel *tunnel; |
| 1232 | 1272 | ||
| 1233 | session = pppol2tp_sock_to_session(sk); | 1273 | session = sk->sk_user_data; |
| 1234 | if (session == NULL) | 1274 | if (session == NULL) |
| 1235 | goto out; | 1275 | goto out; |
| 1236 | 1276 | ||
| 1277 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); | ||
| 1278 | |||
| 1237 | /* Don't use pppol2tp_sock_to_tunnel() here to | 1279 | /* Don't use pppol2tp_sock_to_tunnel() here to |
| 1238 | * get the tunnel context because the tunnel | 1280 | * get the tunnel context because the tunnel |
| 1239 | * socket might have already been closed (its | 1281 | * socket might have already been closed (its |
| @@ -1279,6 +1321,7 @@ out: | |||
| 1279 | static int pppol2tp_release(struct socket *sock) | 1321 | static int pppol2tp_release(struct socket *sock) |
| 1280 | { | 1322 | { |
| 1281 | struct sock *sk = sock->sk; | 1323 | struct sock *sk = sock->sk; |
| 1324 | struct pppol2tp_session *session; | ||
| 1282 | int error; | 1325 | int error; |
| 1283 | 1326 | ||
| 1284 | if (!sk) | 1327 | if (!sk) |
| @@ -1296,9 +1339,18 @@ static int pppol2tp_release(struct socket *sock) | |||
| 1296 | sock_orphan(sk); | 1339 | sock_orphan(sk); |
| 1297 | sock->sk = NULL; | 1340 | sock->sk = NULL; |
| 1298 | 1341 | ||
| 1342 | session = pppol2tp_sock_to_session(sk); | ||
| 1343 | |||
| 1299 | /* Purge any queued data */ | 1344 | /* Purge any queued data */ |
| 1300 | skb_queue_purge(&sk->sk_receive_queue); | 1345 | skb_queue_purge(&sk->sk_receive_queue); |
| 1301 | skb_queue_purge(&sk->sk_write_queue); | 1346 | skb_queue_purge(&sk->sk_write_queue); |
| 1347 | if (session != NULL) { | ||
| 1348 | struct sk_buff *skb; | ||
| 1349 | while ((skb = skb_dequeue(&session->reorder_q))) { | ||
| 1350 | kfree_skb(skb); | ||
| 1351 | sock_put(sk); | ||
| 1352 | } | ||
| 1353 | } | ||
| 1302 | 1354 | ||
| 1303 | release_sock(sk); | 1355 | release_sock(sk); |
| 1304 | 1356 | ||
| @@ -1601,7 +1653,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
| 1601 | 1653 | ||
| 1602 | error = ppp_register_channel(&po->chan); | 1654 | error = ppp_register_channel(&po->chan); |
| 1603 | if (error) | 1655 | if (error) |
| 1604 | goto end; | 1656 | goto end_put_tun; |
| 1605 | 1657 | ||
| 1606 | /* This is how we get the session context from the socket. */ | 1658 | /* This is how we get the session context from the socket. */ |
| 1607 | sk->sk_user_data = session; | 1659 | sk->sk_user_data = session; |
| @@ -1621,6 +1673,8 @@ out_no_ppp: | |||
| 1621 | PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, | 1673 | PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, |
| 1622 | "%s: created\n", session->name); | 1674 | "%s: created\n", session->name); |
| 1623 | 1675 | ||
| 1676 | end_put_tun: | ||
| 1677 | sock_put(tunnel_sock); | ||
| 1624 | end: | 1678 | end: |
| 1625 | release_sock(sk); | 1679 | release_sock(sk); |
| 1626 | 1680 | ||
| @@ -1668,6 +1722,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, | |||
| 1668 | *usockaddr_len = len; | 1722 | *usockaddr_len = len; |
| 1669 | 1723 | ||
| 1670 | error = 0; | 1724 | error = 0; |
| 1725 | sock_put(sock->sk); | ||
| 1671 | 1726 | ||
| 1672 | end: | 1727 | end: |
| 1673 | return error; | 1728 | return error; |
| @@ -1906,14 +1961,17 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd, | |||
| 1906 | err = -EBADF; | 1961 | err = -EBADF; |
| 1907 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 1962 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
| 1908 | if (tunnel == NULL) | 1963 | if (tunnel == NULL) |
| 1909 | goto end; | 1964 | goto end_put_sess; |
| 1910 | 1965 | ||
| 1911 | err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); | 1966 | err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); |
| 1912 | goto end; | 1967 | sock_put(session->tunnel_sock); |
| 1968 | goto end_put_sess; | ||
| 1913 | } | 1969 | } |
| 1914 | 1970 | ||
| 1915 | err = pppol2tp_session_ioctl(session, cmd, arg); | 1971 | err = pppol2tp_session_ioctl(session, cmd, arg); |
| 1916 | 1972 | ||
| 1973 | end_put_sess: | ||
| 1974 | sock_put(sk); | ||
| 1917 | end: | 1975 | end: |
| 1918 | return err; | 1976 | return err; |
| 1919 | } | 1977 | } |
| @@ -2059,14 +2117,17 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, | |||
| 2059 | err = -EBADF; | 2117 | err = -EBADF; |
| 2060 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 2118 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
| 2061 | if (tunnel == NULL) | 2119 | if (tunnel == NULL) |
| 2062 | goto end; | 2120 | goto end_put_sess; |
| 2063 | 2121 | ||
| 2064 | err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); | 2122 | err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); |
| 2123 | sock_put(session->tunnel_sock); | ||
| 2065 | } else | 2124 | } else |
| 2066 | err = pppol2tp_session_setsockopt(sk, session, optname, val); | 2125 | err = pppol2tp_session_setsockopt(sk, session, optname, val); |
| 2067 | 2126 | ||
| 2068 | err = 0; | 2127 | err = 0; |
| 2069 | 2128 | ||
| 2129 | end_put_sess: | ||
| 2130 | sock_put(sk); | ||
| 2070 | end: | 2131 | end: |
| 2071 | return err; | 2132 | return err; |
| 2072 | } | 2133 | } |
| @@ -2181,20 +2242,24 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, | |||
| 2181 | err = -EBADF; | 2242 | err = -EBADF; |
| 2182 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 2243 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
| 2183 | if (tunnel == NULL) | 2244 | if (tunnel == NULL) |
| 2184 | goto end; | 2245 | goto end_put_sess; |
| 2185 | 2246 | ||
| 2186 | err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); | 2247 | err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); |
| 2248 | sock_put(session->tunnel_sock); | ||
| 2187 | } else | 2249 | } else |
| 2188 | err = pppol2tp_session_getsockopt(sk, session, optname, &val); | 2250 | err = pppol2tp_session_getsockopt(sk, session, optname, &val); |
| 2189 | 2251 | ||
| 2190 | err = -EFAULT; | 2252 | err = -EFAULT; |
| 2191 | if (put_user(len, (int __user *) optlen)) | 2253 | if (put_user(len, (int __user *) optlen)) |
| 2192 | goto end; | 2254 | goto end_put_sess; |
| 2193 | 2255 | ||
| 2194 | if (copy_to_user((void __user *) optval, &val, len)) | 2256 | if (copy_to_user((void __user *) optval, &val, len)) |
| 2195 | goto end; | 2257 | goto end_put_sess; |
| 2196 | 2258 | ||
| 2197 | err = 0; | 2259 | err = 0; |
| 2260 | |||
| 2261 | end_put_sess: | ||
| 2262 | sock_put(sk); | ||
| 2198 | end: | 2263 | end: |
| 2199 | return err; | 2264 | return err; |
| 2200 | } | 2265 | } |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index a20693e09ae8..b5c1e663417d 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
| @@ -2861,7 +2861,8 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) | |||
| 2861 | struct config_param *config; | 2861 | struct config_param *config; |
| 2862 | struct mac_info *mac_control; | 2862 | struct mac_info *mac_control; |
| 2863 | int pkts_processed = 0; | 2863 | int pkts_processed = 0; |
| 2864 | u8 *addr = NULL, val8 = 0; | 2864 | u8 __iomem *addr = NULL; |
| 2865 | u8 val8 = 0; | ||
| 2865 | struct s2io_nic *nic = dev->priv; | 2866 | struct s2io_nic *nic = dev->priv; |
| 2866 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 2867 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
| 2867 | int budget_org = budget; | 2868 | int budget_org = budget; |
| @@ -2878,7 +2879,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) | |||
| 2878 | if (pkts_processed < budget_org) { | 2879 | if (pkts_processed < budget_org) { |
| 2879 | netif_rx_complete(dev, napi); | 2880 | netif_rx_complete(dev, napi); |
| 2880 | /*Re Enable MSI-Rx Vector*/ | 2881 | /*Re Enable MSI-Rx Vector*/ |
| 2881 | addr = (u8 *)&bar0->xmsi_mask_reg; | 2882 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; |
| 2882 | addr += 7 - ring->ring_no; | 2883 | addr += 7 - ring->ring_no; |
| 2883 | val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; | 2884 | val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; |
| 2884 | writeb(val8, addr); | 2885 | writeb(val8, addr); |
| @@ -4364,9 +4365,10 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | |||
| 4364 | return IRQ_HANDLED; | 4365 | return IRQ_HANDLED; |
| 4365 | 4366 | ||
| 4366 | if (sp->config.napi) { | 4367 | if (sp->config.napi) { |
| 4367 | u8 *addr = NULL, val8 = 0; | 4368 | u8 __iomem *addr = NULL; |
| 4369 | u8 val8 = 0; | ||
| 4368 | 4370 | ||
| 4369 | addr = (u8 *)&bar0->xmsi_mask_reg; | 4371 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; |
| 4370 | addr += (7 - ring->ring_no); | 4372 | addr += (7 - ring->ring_no); |
| 4371 | val8 = (ring->ring_no == 0) ? 0x7f : 0xff; | 4373 | val8 = (ring->ring_no == 0) ? 0x7f : 0xff; |
| 4372 | writeb(val8, addr); | 4374 | writeb(val8, addr); |
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index b4b63805ee8f..61955f8d8011 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c | |||
| @@ -972,7 +972,7 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 972 | skb_copy_and_csum_dev(skb, priv->tx_bufs + entry * TX_BUF_SIZE); | 972 | skb_copy_and_csum_dev(skb, priv->tx_bufs + entry * TX_BUF_SIZE); |
| 973 | 973 | ||
| 974 | len = skb->len; | 974 | len = skb->len; |
| 975 | if (unlikely(len < ETH_ZLEN)) { | 975 | if (len < ETH_ZLEN) { |
| 976 | memset(priv->tx_bufs + entry * TX_BUF_SIZE + len, | 976 | memset(priv->tx_bufs + entry * TX_BUF_SIZE + len, |
| 977 | 0, ETH_ZLEN - len); | 977 | 0, ETH_ZLEN - len); |
| 978 | len = ETH_ZLEN; | 978 | len = ETH_ZLEN; |
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index dbdcee4b0f8d..55c0d9760be8 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c | |||
| @@ -459,7 +459,7 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx) | |||
| 459 | tries--; | 459 | tries--; |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | EFX_ERR(efx, "Failed to bring XAUI link back up in %d tries!\n", | 462 | EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", |
| 463 | max_tries); | 463 | max_tries); |
| 464 | return 0; | 464 | return 0; |
| 465 | } | 465 | } |
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index b4e7f30ea4e8..1aa425be3067 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c | |||
| @@ -111,7 +111,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne | |||
| 111 | struct hme_tx_logent *tlp; | 111 | struct hme_tx_logent *tlp; |
| 112 | unsigned long flags; | 112 | unsigned long flags; |
| 113 | 113 | ||
| 114 | save_and_cli(flags); | 114 | local_irq_save(flags); |
| 115 | tlp = &tx_log[txlog_cur_entry]; | 115 | tlp = &tx_log[txlog_cur_entry]; |
| 116 | tlp->tstamp = (unsigned int)jiffies; | 116 | tlp->tstamp = (unsigned int)jiffies; |
| 117 | tlp->tx_new = hp->tx_new; | 117 | tlp->tx_new = hp->tx_new; |
| @@ -119,7 +119,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne | |||
| 119 | tlp->action = a; | 119 | tlp->action = a; |
| 120 | tlp->status = s; | 120 | tlp->status = s; |
| 121 | txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1); | 121 | txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1); |
| 122 | restore_flags(flags); | 122 | local_irq_restore(flags); |
| 123 | } | 123 | } |
| 124 | static __inline__ void tx_dump_log(void) | 124 | static __inline__ void tx_dump_log(void) |
| 125 | { | 125 | { |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index f9d13fa05d64..55670b5eb611 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
| @@ -1729,12 +1729,15 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state) | |||
| 1729 | if (!dev) | 1729 | if (!dev) |
| 1730 | return -EINVAL; | 1730 | return -EINVAL; |
| 1731 | 1731 | ||
| 1732 | if (netif_running(dev)) | 1732 | if (!netif_running(dev)) |
| 1733 | tulip_down(dev); | 1733 | goto save_state; |
| 1734 | |||
| 1735 | tulip_down(dev); | ||
| 1734 | 1736 | ||
| 1735 | netif_device_detach(dev); | 1737 | netif_device_detach(dev); |
| 1736 | free_irq(dev->irq, dev); | 1738 | free_irq(dev->irq, dev); |
| 1737 | 1739 | ||
| 1740 | save_state: | ||
| 1738 | pci_save_state(pdev); | 1741 | pci_save_state(pdev); |
| 1739 | pci_disable_device(pdev); | 1742 | pci_disable_device(pdev); |
| 1740 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 1743 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
| @@ -1754,6 +1757,9 @@ static int tulip_resume(struct pci_dev *pdev) | |||
| 1754 | pci_set_power_state(pdev, PCI_D0); | 1757 | pci_set_power_state(pdev, PCI_D0); |
| 1755 | pci_restore_state(pdev); | 1758 | pci_restore_state(pdev); |
| 1756 | 1759 | ||
| 1760 | if (!netif_running(dev)) | ||
| 1761 | return 0; | ||
| 1762 | |||
| 1757 | if ((retval = pci_enable_device(pdev))) { | 1763 | if ((retval = pci_enable_device(pdev))) { |
| 1758 | printk (KERN_ERR "tulip: pci_enable_device failed in resume\n"); | 1764 | printk (KERN_ERR "tulip: pci_enable_device failed in resume\n"); |
| 1759 | return retval; | 1765 | return retval; |
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 299b7f176950..f5839c4a5cbd 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c | |||
| @@ -73,6 +73,7 @@ static char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { | |||
| 73 | "tx-frames-ok", | 73 | "tx-frames-ok", |
| 74 | "tx-excessive-differ-frames", | 74 | "tx-excessive-differ-frames", |
| 75 | "tx-256-511-frames", | 75 | "tx-256-511-frames", |
| 76 | "tx-512-1023-frames", | ||
| 76 | "tx-1024-1518-frames", | 77 | "tx-1024-1518-frames", |
| 77 | "tx-jumbo-frames", | 78 | "tx-jumbo-frames", |
| 78 | }; | 79 | }; |
| @@ -308,7 +309,7 @@ static void uec_get_strings(struct net_device *netdev, u32 stringset, u8 *buf) | |||
| 308 | buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN; | 309 | buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN; |
| 309 | } | 310 | } |
| 310 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) | 311 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) |
| 311 | memcpy(buf, tx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN * | 312 | memcpy(buf, rx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN * |
| 312 | ETH_GSTRING_LEN); | 313 | ETH_GSTRING_LEN); |
| 313 | } | 314 | } |
| 314 | 315 | ||
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index fe7cdf2a2a23..5450eac9e263 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -47,6 +47,9 @@ struct virtnet_info | |||
| 47 | /* Number of input buffers, and max we've ever had. */ | 47 | /* Number of input buffers, and max we've ever had. */ |
| 48 | unsigned int num, max; | 48 | unsigned int num, max; |
| 49 | 49 | ||
| 50 | /* For cleaning up after transmission. */ | ||
| 51 | struct tasklet_struct tasklet; | ||
| 52 | |||
| 50 | /* Receive & send queues. */ | 53 | /* Receive & send queues. */ |
| 51 | struct sk_buff_head recv; | 54 | struct sk_buff_head recv; |
| 52 | struct sk_buff_head send; | 55 | struct sk_buff_head send; |
| @@ -68,8 +71,13 @@ static void skb_xmit_done(struct virtqueue *svq) | |||
| 68 | 71 | ||
| 69 | /* Suppress further interrupts. */ | 72 | /* Suppress further interrupts. */ |
| 70 | svq->vq_ops->disable_cb(svq); | 73 | svq->vq_ops->disable_cb(svq); |
| 74 | |||
| 71 | /* We were waiting for more output buffers. */ | 75 | /* We were waiting for more output buffers. */ |
| 72 | netif_wake_queue(vi->dev); | 76 | netif_wake_queue(vi->dev); |
| 77 | |||
| 78 | /* Make sure we re-xmit last_xmit_skb: if there are no more packets | ||
| 79 | * queued, start_xmit won't be called. */ | ||
| 80 | tasklet_schedule(&vi->tasklet); | ||
| 73 | } | 81 | } |
| 74 | 82 | ||
| 75 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, | 83 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, |
| @@ -278,6 +286,18 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | |||
| 278 | return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | 286 | return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); |
| 279 | } | 287 | } |
| 280 | 288 | ||
| 289 | static void xmit_tasklet(unsigned long data) | ||
| 290 | { | ||
| 291 | struct virtnet_info *vi = (void *)data; | ||
| 292 | |||
| 293 | netif_tx_lock_bh(vi->dev); | ||
| 294 | if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) == 0) { | ||
| 295 | vi->svq->vq_ops->kick(vi->svq); | ||
| 296 | vi->last_xmit_skb = NULL; | ||
| 297 | } | ||
| 298 | netif_tx_unlock_bh(vi->dev); | ||
| 299 | } | ||
| 300 | |||
| 281 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) | 301 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) |
| 282 | { | 302 | { |
| 283 | struct virtnet_info *vi = netdev_priv(dev); | 303 | struct virtnet_info *vi = netdev_priv(dev); |
| @@ -287,21 +307,25 @@ again: | |||
| 287 | free_old_xmit_skbs(vi); | 307 | free_old_xmit_skbs(vi); |
| 288 | 308 | ||
| 289 | /* If we has a buffer left over from last time, send it now. */ | 309 | /* If we has a buffer left over from last time, send it now. */ |
| 290 | if (vi->last_xmit_skb) { | 310 | if (unlikely(vi->last_xmit_skb)) { |
| 291 | if (xmit_skb(vi, vi->last_xmit_skb) != 0) { | 311 | if (xmit_skb(vi, vi->last_xmit_skb) != 0) { |
| 292 | /* Drop this skb: we only queue one. */ | 312 | /* Drop this skb: we only queue one. */ |
| 293 | vi->dev->stats.tx_dropped++; | 313 | vi->dev->stats.tx_dropped++; |
| 294 | kfree_skb(skb); | 314 | kfree_skb(skb); |
| 315 | skb = NULL; | ||
| 295 | goto stop_queue; | 316 | goto stop_queue; |
| 296 | } | 317 | } |
| 297 | vi->last_xmit_skb = NULL; | 318 | vi->last_xmit_skb = NULL; |
| 298 | } | 319 | } |
| 299 | 320 | ||
| 300 | /* Put new one in send queue and do transmit */ | 321 | /* Put new one in send queue and do transmit */ |
| 301 | __skb_queue_head(&vi->send, skb); | 322 | if (likely(skb)) { |
| 302 | if (xmit_skb(vi, skb) != 0) { | 323 | __skb_queue_head(&vi->send, skb); |
| 303 | vi->last_xmit_skb = skb; | 324 | if (xmit_skb(vi, skb) != 0) { |
| 304 | goto stop_queue; | 325 | vi->last_xmit_skb = skb; |
| 326 | skb = NULL; | ||
| 327 | goto stop_queue; | ||
| 328 | } | ||
| 305 | } | 329 | } |
| 306 | done: | 330 | done: |
| 307 | vi->svq->vq_ops->kick(vi->svq); | 331 | vi->svq->vq_ops->kick(vi->svq); |
| @@ -428,6 +452,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
| 428 | skb_queue_head_init(&vi->recv); | 452 | skb_queue_head_init(&vi->recv); |
| 429 | skb_queue_head_init(&vi->send); | 453 | skb_queue_head_init(&vi->send); |
| 430 | 454 | ||
| 455 | tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi); | ||
| 456 | |||
| 431 | err = register_netdev(dev); | 457 | err = register_netdev(dev); |
| 432 | if (err) { | 458 | if (err) { |
| 433 | pr_debug("virtio_net: registering device failed\n"); | 459 | pr_debug("virtio_net: registering device failed\n"); |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 4e1c690ff45f..32019fb878d8 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
| @@ -2905,7 +2905,7 @@ EXPORT_SYMBOL(init_airo_card); | |||
| 2905 | 2905 | ||
| 2906 | static int waitbusy (struct airo_info *ai) { | 2906 | static int waitbusy (struct airo_info *ai) { |
| 2907 | int delay = 0; | 2907 | int delay = 0; |
| 2908 | while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) { | 2908 | while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) { |
| 2909 | udelay (10); | 2909 | udelay (10); |
| 2910 | if ((++delay % 20) == 0) | 2910 | if ((++delay % 20) == 0) |
| 2911 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); | 2911 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 37783cdd301a..dfa4bdd5597c 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
| @@ -737,6 +737,7 @@ struct b43_wl { | |||
| 737 | struct ieee80211_tx_control beacon_txctl; | 737 | struct ieee80211_tx_control beacon_txctl; |
| 738 | bool beacon0_uploaded; | 738 | bool beacon0_uploaded; |
| 739 | bool beacon1_uploaded; | 739 | bool beacon1_uploaded; |
| 740 | bool beacon_templates_virgin; /* Never wrote the templates? */ | ||
| 740 | struct work_struct beacon_update_trigger; | 741 | struct work_struct beacon_update_trigger; |
| 741 | 742 | ||
| 742 | /* The current QOS parameters for the 4 queues. | 743 | /* The current QOS parameters for the 4 queues. |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 8fdba9415c04..6c3d9ea0a9f8 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
| @@ -1544,6 +1544,30 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, | |||
| 1544 | kfree(probe_resp_data); | 1544 | kfree(probe_resp_data); |
| 1545 | } | 1545 | } |
| 1546 | 1546 | ||
| 1547 | static void b43_upload_beacon0(struct b43_wldev *dev) | ||
| 1548 | { | ||
| 1549 | struct b43_wl *wl = dev->wl; | ||
| 1550 | |||
| 1551 | if (wl->beacon0_uploaded) | ||
| 1552 | return; | ||
| 1553 | b43_write_beacon_template(dev, 0x68, 0x18); | ||
| 1554 | /* FIXME: Probe resp upload doesn't really belong here, | ||
| 1555 | * but we don't use that feature anyway. */ | ||
| 1556 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | ||
| 1557 | &__b43_ratetable[3]); | ||
| 1558 | wl->beacon0_uploaded = 1; | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | static void b43_upload_beacon1(struct b43_wldev *dev) | ||
| 1562 | { | ||
| 1563 | struct b43_wl *wl = dev->wl; | ||
| 1564 | |||
| 1565 | if (wl->beacon1_uploaded) | ||
| 1566 | return; | ||
| 1567 | b43_write_beacon_template(dev, 0x468, 0x1A); | ||
| 1568 | wl->beacon1_uploaded = 1; | ||
| 1569 | } | ||
| 1570 | |||
| 1547 | static void handle_irq_beacon(struct b43_wldev *dev) | 1571 | static void handle_irq_beacon(struct b43_wldev *dev) |
| 1548 | { | 1572 | { |
| 1549 | struct b43_wl *wl = dev->wl; | 1573 | struct b43_wl *wl = dev->wl; |
| @@ -1568,24 +1592,27 @@ static void handle_irq_beacon(struct b43_wldev *dev) | |||
| 1568 | return; | 1592 | return; |
| 1569 | } | 1593 | } |
| 1570 | 1594 | ||
| 1571 | if (!beacon0_valid) { | 1595 | if (unlikely(wl->beacon_templates_virgin)) { |
| 1572 | if (!wl->beacon0_uploaded) { | 1596 | /* We never uploaded a beacon before. |
| 1573 | b43_write_beacon_template(dev, 0x68, 0x18); | 1597 | * Upload both templates now, but only mark one valid. */ |
| 1574 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | 1598 | wl->beacon_templates_virgin = 0; |
| 1575 | &__b43_ratetable[3]); | 1599 | b43_upload_beacon0(dev); |
| 1576 | wl->beacon0_uploaded = 1; | 1600 | b43_upload_beacon1(dev); |
| 1577 | } | ||
| 1578 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | 1601 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
| 1579 | cmd |= B43_MACCMD_BEACON0_VALID; | 1602 | cmd |= B43_MACCMD_BEACON0_VALID; |
| 1580 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | 1603 | b43_write32(dev, B43_MMIO_MACCMD, cmd); |
| 1581 | } else if (!beacon1_valid) { | 1604 | } else { |
| 1582 | if (!wl->beacon1_uploaded) { | 1605 | if (!beacon0_valid) { |
| 1583 | b43_write_beacon_template(dev, 0x468, 0x1A); | 1606 | b43_upload_beacon0(dev); |
| 1584 | wl->beacon1_uploaded = 1; | 1607 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
| 1608 | cmd |= B43_MACCMD_BEACON0_VALID; | ||
| 1609 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
| 1610 | } else if (!beacon1_valid) { | ||
| 1611 | b43_upload_beacon1(dev); | ||
| 1612 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
| 1613 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
| 1614 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
| 1585 | } | 1615 | } |
| 1586 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
| 1587 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
| 1588 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
| 1589 | } | 1616 | } |
| 1590 | } | 1617 | } |
| 1591 | 1618 | ||
| @@ -4073,6 +4100,9 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
| 4073 | wl->filter_flags = 0; | 4100 | wl->filter_flags = 0; |
| 4074 | wl->radiotap_enabled = 0; | 4101 | wl->radiotap_enabled = 0; |
| 4075 | b43_qos_clear(wl); | 4102 | b43_qos_clear(wl); |
| 4103 | wl->beacon0_uploaded = 0; | ||
| 4104 | wl->beacon1_uploaded = 0; | ||
| 4105 | wl->beacon_templates_virgin = 1; | ||
| 4076 | 4106 | ||
| 4077 | /* First register RFkill. | 4107 | /* First register RFkill. |
| 4078 | * LEDs that are registered later depend on it. */ | 4108 | * LEDs that are registered later depend on it. */ |
| @@ -4241,7 +4271,9 @@ static void b43_chip_reset(struct work_struct *work) | |||
| 4241 | goto out; | 4271 | goto out; |
| 4242 | } | 4272 | } |
| 4243 | } | 4273 | } |
| 4244 | out: | 4274 | out: |
| 4275 | if (err) | ||
| 4276 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
| 4245 | mutex_unlock(&wl->mutex); | 4277 | mutex_unlock(&wl->mutex); |
| 4246 | if (err) | 4278 | if (err) |
| 4247 | b43err(wl, "Controller restart FAILED\n"); | 4279 | b43err(wl, "Controller restart FAILED\n"); |
| @@ -4382,9 +4414,11 @@ static void b43_one_core_detach(struct ssb_device *dev) | |||
| 4382 | struct b43_wldev *wldev; | 4414 | struct b43_wldev *wldev; |
| 4383 | struct b43_wl *wl; | 4415 | struct b43_wl *wl; |
| 4384 | 4416 | ||
| 4417 | /* Do not cancel ieee80211-workqueue based work here. | ||
| 4418 | * See comment in b43_remove(). */ | ||
| 4419 | |||
| 4385 | wldev = ssb_get_drvdata(dev); | 4420 | wldev = ssb_get_drvdata(dev); |
| 4386 | wl = wldev->wl; | 4421 | wl = wldev->wl; |
| 4387 | cancel_work_sync(&wldev->restart_work); | ||
| 4388 | b43_debugfs_remove_device(wldev); | 4422 | b43_debugfs_remove_device(wldev); |
| 4389 | b43_wireless_core_detach(wldev); | 4423 | b43_wireless_core_detach(wldev); |
| 4390 | list_del(&wldev->list); | 4424 | list_del(&wldev->list); |
| @@ -4569,6 +4603,10 @@ static void b43_remove(struct ssb_device *dev) | |||
| 4569 | struct b43_wl *wl = ssb_get_devtypedata(dev); | 4603 | struct b43_wl *wl = ssb_get_devtypedata(dev); |
| 4570 | struct b43_wldev *wldev = ssb_get_drvdata(dev); | 4604 | struct b43_wldev *wldev = ssb_get_drvdata(dev); |
| 4571 | 4605 | ||
| 4606 | /* We must cancel any work here before unregistering from ieee80211, | ||
| 4607 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
| 4608 | cancel_work_sync(&wldev->restart_work); | ||
| 4609 | |||
| 4572 | B43_WARN_ON(!wl); | 4610 | B43_WARN_ON(!wl); |
| 4573 | if (wl->current_dev == wldev) | 4611 | if (wl->current_dev == wldev) |
| 4574 | ieee80211_unregister_hw(wl->hw); | 4612 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 14a5eea2573e..204077c13870 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
| @@ -3039,7 +3039,6 @@ static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev) | |||
| 3039 | /* Locking: wl->mutex */ | 3039 | /* Locking: wl->mutex */ |
| 3040 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | 3040 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) |
| 3041 | { | 3041 | { |
| 3042 | struct b43legacy_wl *wl = dev->wl; | ||
| 3043 | struct b43legacy_phy *phy = &dev->phy; | 3042 | struct b43legacy_phy *phy = &dev->phy; |
| 3044 | u32 macctl; | 3043 | u32 macctl; |
| 3045 | 3044 | ||
| @@ -3054,12 +3053,6 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
| 3054 | macctl |= B43legacy_MACCTL_PSM_JMP0; | 3053 | macctl |= B43legacy_MACCTL_PSM_JMP0; |
| 3055 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); | 3054 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); |
| 3056 | 3055 | ||
| 3057 | mutex_unlock(&wl->mutex); | ||
| 3058 | /* Must unlock as it would otherwise deadlock. No races here. | ||
| 3059 | * Cancel possibly pending workqueues. */ | ||
| 3060 | cancel_work_sync(&dev->restart_work); | ||
| 3061 | mutex_lock(&wl->mutex); | ||
| 3062 | |||
| 3063 | b43legacy_leds_exit(dev); | 3056 | b43legacy_leds_exit(dev); |
| 3064 | b43legacy_rng_exit(dev->wl); | 3057 | b43legacy_rng_exit(dev->wl); |
| 3065 | b43legacy_pio_free(dev); | 3058 | b43legacy_pio_free(dev); |
| @@ -3486,6 +3479,8 @@ static void b43legacy_chip_reset(struct work_struct *work) | |||
| 3486 | } | 3479 | } |
| 3487 | } | 3480 | } |
| 3488 | out: | 3481 | out: |
| 3482 | if (err) | ||
| 3483 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
| 3489 | mutex_unlock(&wl->mutex); | 3484 | mutex_unlock(&wl->mutex); |
| 3490 | if (err) | 3485 | if (err) |
| 3491 | b43legacyerr(wl, "Controller restart FAILED\n"); | 3486 | b43legacyerr(wl, "Controller restart FAILED\n"); |
| @@ -3618,9 +3613,11 @@ static void b43legacy_one_core_detach(struct ssb_device *dev) | |||
| 3618 | struct b43legacy_wldev *wldev; | 3613 | struct b43legacy_wldev *wldev; |
| 3619 | struct b43legacy_wl *wl; | 3614 | struct b43legacy_wl *wl; |
| 3620 | 3615 | ||
| 3616 | /* Do not cancel ieee80211-workqueue based work here. | ||
| 3617 | * See comment in b43legacy_remove(). */ | ||
| 3618 | |||
| 3621 | wldev = ssb_get_drvdata(dev); | 3619 | wldev = ssb_get_drvdata(dev); |
| 3622 | wl = wldev->wl; | 3620 | wl = wldev->wl; |
| 3623 | cancel_work_sync(&wldev->restart_work); | ||
| 3624 | b43legacy_debugfs_remove_device(wldev); | 3621 | b43legacy_debugfs_remove_device(wldev); |
| 3625 | b43legacy_wireless_core_detach(wldev); | 3622 | b43legacy_wireless_core_detach(wldev); |
| 3626 | list_del(&wldev->list); | 3623 | list_del(&wldev->list); |
| @@ -3789,6 +3786,10 @@ static void b43legacy_remove(struct ssb_device *dev) | |||
| 3789 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); | 3786 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); |
| 3790 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); | 3787 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); |
| 3791 | 3788 | ||
| 3789 | /* We must cancel any work here before unregistering from ieee80211, | ||
| 3790 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
| 3791 | cancel_work_sync(&wldev->restart_work); | ||
| 3792 | |||
| 3792 | B43legacy_WARN_ON(!wl); | 3793 | B43legacy_WARN_ON(!wl); |
| 3793 | if (wl->current_dev == wldev) | 3794 | if (wl->current_dev == wldev) |
| 3794 | ieee80211_unregister_hw(wl->hw); | 3795 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index d74c061994ae..729336774828 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
| @@ -7558,8 +7558,31 @@ static int ipw_associate(void *data) | |||
| 7558 | priv->ieee->iw_mode == IW_MODE_ADHOC && | 7558 | priv->ieee->iw_mode == IW_MODE_ADHOC && |
| 7559 | priv->config & CFG_ADHOC_CREATE && | 7559 | priv->config & CFG_ADHOC_CREATE && |
| 7560 | priv->config & CFG_STATIC_ESSID && | 7560 | priv->config & CFG_STATIC_ESSID && |
| 7561 | priv->config & CFG_STATIC_CHANNEL && | 7561 | priv->config & CFG_STATIC_CHANNEL) { |
| 7562 | !list_empty(&priv->ieee->network_free_list)) { | 7562 | /* Use oldest network if the free list is empty */ |
| 7563 | if (list_empty(&priv->ieee->network_free_list)) { | ||
| 7564 | struct ieee80211_network *oldest = NULL; | ||
| 7565 | struct ieee80211_network *target; | ||
| 7566 | DECLARE_MAC_BUF(mac); | ||
| 7567 | |||
| 7568 | list_for_each_entry(target, &priv->ieee->network_list, list) { | ||
| 7569 | if ((oldest == NULL) || | ||
| 7570 | (target->last_scanned < oldest->last_scanned)) | ||
| 7571 | oldest = target; | ||
| 7572 | } | ||
| 7573 | |||
| 7574 | /* If there are no more slots, expire the oldest */ | ||
| 7575 | list_del(&oldest->list); | ||
| 7576 | target = oldest; | ||
| 7577 | IPW_DEBUG_ASSOC("Expired '%s' (%s) from " | ||
| 7578 | "network list.\n", | ||
| 7579 | escape_essid(target->ssid, | ||
| 7580 | target->ssid_len), | ||
| 7581 | print_mac(mac, target->bssid)); | ||
| 7582 | list_add_tail(&target->list, | ||
| 7583 | &priv->ieee->network_free_list); | ||
| 7584 | } | ||
| 7585 | |||
| 7563 | element = priv->ieee->network_free_list.next; | 7586 | element = priv->ieee->network_free_list.next; |
| 7564 | network = list_entry(element, struct ieee80211_network, list); | 7587 | network = list_entry(element, struct ieee80211_network, list); |
| 7565 | ipw_adhoc_create(priv, network); | 7588 | ipw_adhoc_create(priv, network); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index c9847b1a67f7..3a7f0cb710ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
| @@ -1162,7 +1162,6 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
| 1162 | 1162 | ||
| 1163 | /* Higher rate not available, use the original */ | 1163 | /* Higher rate not available, use the original */ |
| 1164 | } else { | 1164 | } else { |
| 1165 | new_rate = rate; | ||
| 1166 | break; | 1165 | break; |
| 1167 | } | 1166 | } |
| 1168 | } | 1167 | } |
| @@ -2009,7 +2008,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
| 2009 | * 2) Not just finishing up a search | 2008 | * 2) Not just finishing up a search |
| 2010 | * 3) Allowing a new search | 2009 | * 3) Allowing a new search |
| 2011 | */ | 2010 | */ |
| 2012 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl) { | 2011 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl && window->counter) { |
| 2013 | /* Save current throughput to compare with "search" throughput*/ | 2012 | /* Save current throughput to compare with "search" throughput*/ |
| 2014 | lq_sta->last_tpt = current_tpt; | 2013 | lq_sta->last_tpt = current_tpt; |
| 2015 | 2014 | ||
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index ad2fabca9116..0aa0ce3b2c42 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
| @@ -312,8 +312,8 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, | |||
| 312 | if (tlv_type != TLV_TYPE_BCNMISS) | 312 | if (tlv_type != TLV_TYPE_BCNMISS) |
| 313 | tlv->freq = freq; | 313 | tlv->freq = freq; |
| 314 | 314 | ||
| 315 | /* The command header, the event mask, and the one TLV */ | 315 | /* The command header, the action, the event mask, and one TLV */ |
| 316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 2 + sizeof(*tlv)); | 316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 4 + sizeof(*tlv)); |
| 317 | 317 | ||
| 318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); | 318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); |
| 319 | 319 | ||
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 98ddbb3b3273..1610a7308c1d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
| @@ -49,6 +49,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
| 49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ | 49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ |
| 50 | 50 | ||
| 51 | /* Version 2 devices (3887) */ | 51 | /* Version 2 devices (3887) */ |
| 52 | {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */ | ||
| 52 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ | 53 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ |
| 53 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ | 54 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ |
| 54 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ | 55 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d0b1fb15c709..18c9931e3267 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
| @@ -116,6 +116,7 @@ MODULE_PARM_DESC(workaround_interval, | |||
| 116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) | 116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) |
| 117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) | 117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) |
| 118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) | 118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) |
| 119 | #define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f) | ||
| 119 | #define OID_802_11_PMKID ccpu2(0x0d010123) | 120 | #define OID_802_11_PMKID ccpu2(0x0d010123) |
| 120 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) | 121 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) |
| 121 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) | 122 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) |
| @@ -271,6 +272,26 @@ struct ndis_config_param { | |||
| 271 | __le32 value_length; | 272 | __le32 value_length; |
| 272 | } __attribute__((packed)); | 273 | } __attribute__((packed)); |
| 273 | 274 | ||
| 275 | struct ndis_80211_assoc_info { | ||
| 276 | __le32 length; | ||
| 277 | __le16 req_ies; | ||
| 278 | struct req_ie { | ||
| 279 | __le16 capa; | ||
| 280 | __le16 listen_interval; | ||
| 281 | u8 cur_ap_address[6]; | ||
| 282 | } req_ie; | ||
| 283 | __le32 req_ie_length; | ||
| 284 | __le32 offset_req_ies; | ||
| 285 | __le16 resp_ies; | ||
| 286 | struct resp_ie { | ||
| 287 | __le16 capa; | ||
| 288 | __le16 status_code; | ||
| 289 | __le16 assoc_id; | ||
| 290 | } resp_ie; | ||
| 291 | __le32 resp_ie_length; | ||
| 292 | __le32 offset_resp_ies; | ||
| 293 | } __attribute__((packed)); | ||
| 294 | |||
| 274 | /* these have to match what is in wpa_supplicant */ | 295 | /* these have to match what is in wpa_supplicant */ |
| 275 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; | 296 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; |
| 276 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, | 297 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, |
| @@ -674,6 +695,12 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) | |||
| 674 | return ret; | 695 | return ret; |
| 675 | } | 696 | } |
| 676 | 697 | ||
| 698 | static int get_association_info(struct usbnet *usbdev, | ||
| 699 | struct ndis_80211_assoc_info *info, int len) | ||
| 700 | { | ||
| 701 | return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, | ||
| 702 | info, &len); | ||
| 703 | } | ||
| 677 | 704 | ||
| 678 | static int is_associated(struct usbnet *usbdev) | 705 | static int is_associated(struct usbnet *usbdev) |
| 679 | { | 706 | { |
| @@ -2182,11 +2209,40 @@ static void rndis_wext_worker(struct work_struct *work) | |||
| 2182 | struct usbnet *usbdev = priv->usbdev; | 2209 | struct usbnet *usbdev = priv->usbdev; |
| 2183 | union iwreq_data evt; | 2210 | union iwreq_data evt; |
| 2184 | unsigned char bssid[ETH_ALEN]; | 2211 | unsigned char bssid[ETH_ALEN]; |
| 2185 | int ret; | 2212 | struct ndis_80211_assoc_info *info; |
| 2213 | int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; | ||
| 2214 | int ret, offset; | ||
| 2186 | 2215 | ||
| 2187 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { | 2216 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { |
| 2188 | ret = get_bssid(usbdev, bssid); | 2217 | info = kzalloc(assoc_size, GFP_KERNEL); |
| 2218 | if (!info) | ||
| 2219 | goto get_bssid; | ||
| 2220 | |||
| 2221 | /* Get association info IEs from device and send them back to | ||
| 2222 | * userspace. */ | ||
| 2223 | ret = get_association_info(usbdev, info, assoc_size); | ||
| 2224 | if (!ret) { | ||
| 2225 | evt.data.length = le32_to_cpu(info->req_ie_length); | ||
| 2226 | if (evt.data.length > 0) { | ||
| 2227 | offset = le32_to_cpu(info->offset_req_ies); | ||
| 2228 | wireless_send_event(usbdev->net, | ||
| 2229 | IWEVASSOCREQIE, &evt, | ||
| 2230 | (char *)info + offset); | ||
| 2231 | } | ||
| 2232 | |||
| 2233 | evt.data.length = le32_to_cpu(info->resp_ie_length); | ||
| 2234 | if (evt.data.length > 0) { | ||
| 2235 | offset = le32_to_cpu(info->offset_resp_ies); | ||
| 2236 | wireless_send_event(usbdev->net, | ||
| 2237 | IWEVASSOCRESPIE, &evt, | ||
| 2238 | (char *)info + offset); | ||
| 2239 | } | ||
| 2240 | } | ||
| 2241 | |||
| 2242 | kfree(info); | ||
| 2189 | 2243 | ||
| 2244 | get_bssid: | ||
| 2245 | ret = get_bssid(usbdev, bssid); | ||
| 2190 | if (!ret) { | 2246 | if (!ret) { |
| 2191 | evt.data.flags = 0; | 2247 | evt.data.flags = 0; |
| 2192 | evt.data.length = 0; | 2248 | evt.data.length = 0; |
| @@ -2414,6 +2470,11 @@ static int bcm4320_early_init(struct usbnet *dev) | |||
| 2414 | else if (priv->param_power_save > 2) | 2470 | else if (priv->param_power_save > 2) |
| 2415 | priv->param_power_save = 2; | 2471 | priv->param_power_save = 2; |
| 2416 | 2472 | ||
| 2473 | if (priv->param_power_output < 0) | ||
| 2474 | priv->param_power_output = 0; | ||
| 2475 | else if (priv->param_power_output > 3) | ||
| 2476 | priv->param_power_output = 3; | ||
| 2477 | |||
| 2417 | if (priv->param_roamtrigger < -80) | 2478 | if (priv->param_roamtrigger < -80) |
| 2418 | priv->param_roamtrigger = -80; | 2479 | priv->param_roamtrigger = -80; |
| 2419 | else if (priv->param_roamtrigger > -60) | 2480 | else if (priv->param_roamtrigger > -60) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 57bdc153952f..611d98320593 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
| @@ -328,6 +328,11 @@ static inline int rt2x00_get_link_ant_rssi(struct link *link) | |||
| 328 | return DEFAULT_RSSI; | 328 | return DEFAULT_RSSI; |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | static inline void rt2x00_reset_link_ant_rssi(struct link *link) | ||
| 332 | { | ||
| 333 | link->ant.rssi_ant = 0; | ||
| 334 | } | ||
| 335 | |||
| 331 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, | 336 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, |
| 332 | enum antenna ant) | 337 | enum antenna ant) |
| 333 | { | 338 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index a9930a03f450..48608e8cc8b4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
| @@ -129,6 +129,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
| 129 | */ | 129 | */ |
| 130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); | 130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
| 131 | rt2x00lib_reset_link_tuner(rt2x00dev); | 131 | rt2x00lib_reset_link_tuner(rt2x00dev); |
| 132 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); | ||
| 132 | 133 | ||
| 133 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 134 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
| 134 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; | 135 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b22c02737185..2673d568bcac 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
| @@ -483,9 +483,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
| 483 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 483 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
| 484 | return; | 484 | return; |
| 485 | 485 | ||
| 486 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 486 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, |
| 487 | rt2x00lib_beacondone_iter, | 487 | rt2x00lib_beacondone_iter, |
| 488 | rt2x00dev); | 488 | rt2x00dev); |
| 489 | 489 | ||
| 490 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 490 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); |
| 491 | } | 491 | } |
| @@ -507,7 +507,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
| 507 | * Update TX statistics. | 507 | * Update TX statistics. |
| 508 | */ | 508 | */ |
| 509 | rt2x00dev->link.qual.tx_success += success; | 509 | rt2x00dev->link.qual.tx_success += success; |
| 510 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; | 510 | rt2x00dev->link.qual.tx_failed += fail; |
| 511 | 511 | ||
| 512 | /* | 512 | /* |
| 513 | * Initialize TX status | 513 | * Initialize TX status |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c206b5092070..87e280a21971 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
| @@ -93,6 +93,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 93 | */ | 93 | */ |
| 94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { | 94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { |
| 95 | ieee80211_stop_queues(hw); | 95 | ieee80211_stop_queues(hw); |
| 96 | dev_kfree_skb_any(skb); | ||
| 96 | return NETDEV_TX_OK; | 97 | return NETDEV_TX_OK; |
| 97 | } | 98 | } |
| 98 | 99 | ||
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c index 5d47935dbac3..947ee55f18b2 100644 --- a/drivers/net/wireless/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl8180_grf5101.c | |||
| @@ -88,7 +88,7 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | |||
| 88 | write_grf5101(dev, 0x0B, chan); | 88 | write_grf5101(dev, 0x0B, chan); |
| 89 | write_grf5101(dev, 0x07, 0x1000); | 89 | write_grf5101(dev, 0x07, 0x1000); |
| 90 | 90 | ||
| 91 | grf5101_write_phy_antenna(dev, chan); | 91 | grf5101_write_phy_antenna(dev, channel); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) | 94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) |
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c index a34dfd382b6d..6c825fd7f3b6 100644 --- a/drivers/net/wireless/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl8180_max2820.c | |||
| @@ -78,7 +78,8 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
| 78 | struct ieee80211_conf *conf) | 78 | struct ieee80211_conf *conf) |
| 79 | { | 79 | { |
| 80 | struct rtl8180_priv *priv = dev->priv; | 80 | struct rtl8180_priv *priv = dev->priv; |
| 81 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 81 | int channel = conf ? |
| 82 | ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; | ||
| 82 | unsigned int chan_idx = channel - 1; | 83 | unsigned int chan_idx = channel - 1; |
| 83 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; | 84 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; |
| 84 | u32 chan = max2820_chan[chan_idx]; | 85 | u32 chan = max2820_chan[chan_idx]; |
| @@ -87,7 +88,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
| 87 | * sa2400, for MAXIM we do this directly from BB */ | 88 | * sa2400, for MAXIM we do this directly from BB */ |
| 88 | rtl8180_write_phy(dev, 3, txpw); | 89 | rtl8180_write_phy(dev, 3, txpw); |
| 89 | 90 | ||
| 90 | max2820_write_phy_antenna(dev, chan); | 91 | max2820_write_phy_antenna(dev, channel); |
| 91 | write_max2820(dev, 3, chan); | 92 | write_max2820(dev, 3, chan); |
| 92 | } | 93 | } |
| 93 | 94 | ||
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c index 0311b4ea124c..cea4e0ccb92d 100644 --- a/drivers/net/wireless/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl8180_sa2400.c | |||
| @@ -86,7 +86,7 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | |||
| 86 | 86 | ||
| 87 | write_sa2400(dev, 7, txpw); | 87 | write_sa2400(dev, 7, txpw); |
| 88 | 88 | ||
| 89 | sa2400_write_phy_antenna(dev, chan); | 89 | sa2400_write_phy_antenna(dev, channel); |
| 90 | 90 | ||
| 91 | write_sa2400(dev, 0, chan); | 91 | write_sa2400(dev, 0, chan); |
| 92 | write_sa2400(dev, 1, 0xbb50); | 92 | write_sa2400(dev, 1, 0xbb50); |
