diff options
Diffstat (limited to 'drivers/net')
32 files changed, 5495 insertions, 2492 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 07746b95fd83..455ba915ede7 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
| @@ -973,6 +973,11 @@ static int vortex_suspend (struct pci_dev *pdev, pm_message_t state) | |||
| 973 | netif_device_detach(dev); | 973 | netif_device_detach(dev); |
| 974 | vortex_down(dev, 1); | 974 | vortex_down(dev, 1); |
| 975 | } | 975 | } |
| 976 | pci_save_state(pdev); | ||
| 977 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
| 978 | free_irq(dev->irq, dev); | ||
| 979 | pci_disable_device(pdev); | ||
| 980 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 976 | } | 981 | } |
| 977 | return 0; | 982 | return 0; |
| 978 | } | 983 | } |
| @@ -980,8 +985,19 @@ static int vortex_suspend (struct pci_dev *pdev, pm_message_t state) | |||
| 980 | static int vortex_resume (struct pci_dev *pdev) | 985 | static int vortex_resume (struct pci_dev *pdev) |
| 981 | { | 986 | { |
| 982 | struct net_device *dev = pci_get_drvdata(pdev); | 987 | struct net_device *dev = pci_get_drvdata(pdev); |
| 988 | struct vortex_private *vp = netdev_priv(dev); | ||
| 983 | 989 | ||
| 984 | if (dev && dev->priv) { | 990 | if (dev && vp) { |
| 991 | pci_set_power_state(pdev, PCI_D0); | ||
| 992 | pci_restore_state(pdev); | ||
| 993 | pci_enable_device(pdev); | ||
| 994 | pci_set_master(pdev); | ||
| 995 | if (request_irq(dev->irq, vp->full_bus_master_rx ? | ||
| 996 | &boomerang_interrupt : &vortex_interrupt, SA_SHIRQ, dev->name, dev)) { | ||
| 997 | printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq); | ||
| 998 | pci_disable_device(pdev); | ||
| 999 | return -EBUSY; | ||
| 1000 | } | ||
| 985 | if (netif_running(dev)) { | 1001 | if (netif_running(dev)) { |
| 986 | vortex_up(dev); | 1002 | vortex_up(dev); |
| 987 | netif_device_attach(dev); | 1003 | netif_device_attach(dev); |
| @@ -1873,6 +1889,7 @@ vortex_timer(unsigned long data) | |||
| 1873 | { | 1889 | { |
| 1874 | spin_lock_bh(&vp->lock); | 1890 | spin_lock_bh(&vp->lock); |
| 1875 | mii_status = mdio_read(dev, vp->phys[0], 1); | 1891 | mii_status = mdio_read(dev, vp->phys[0], 1); |
| 1892 | mii_status = mdio_read(dev, vp->phys[0], 1); | ||
| 1876 | ok = 1; | 1893 | ok = 1; |
| 1877 | if (vortex_debug > 2) | 1894 | if (vortex_debug > 2) |
| 1878 | printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n", | 1895 | printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n", |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ae9e7a579b94..6bb9232514b4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -2058,6 +2058,13 @@ config BNX2 | |||
| 2058 | To compile this driver as a module, choose M here: the module | 2058 | To compile this driver as a module, choose M here: the module |
| 2059 | will be called bnx2. This is recommended. | 2059 | will be called bnx2. This is recommended. |
| 2060 | 2060 | ||
| 2061 | config SPIDER_NET | ||
| 2062 | tristate "Spider Gigabit Ethernet driver" | ||
| 2063 | depends on PCI && PPC_BPA | ||
| 2064 | help | ||
| 2065 | This driver supports the Gigabit Ethernet chips present on the | ||
| 2066 | Cell Processor-Based Blades from IBM. | ||
| 2067 | |||
| 2061 | config GIANFAR | 2068 | config GIANFAR |
| 2062 | tristate "Gianfar Ethernet" | 2069 | tristate "Gianfar Ethernet" |
| 2063 | depends on 85xx || 83xx | 2070 | depends on 85xx || 83xx |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 5baafcd55610..8645c843cf4d 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
| @@ -54,6 +54,8 @@ obj-$(CONFIG_STNIC) += stnic.o 8390.o | |||
| 54 | obj-$(CONFIG_FEALNX) += fealnx.o | 54 | obj-$(CONFIG_FEALNX) += fealnx.o |
| 55 | obj-$(CONFIG_TIGON3) += tg3.o | 55 | obj-$(CONFIG_TIGON3) += tg3.o |
| 56 | obj-$(CONFIG_BNX2) += bnx2.o | 56 | obj-$(CONFIG_BNX2) += bnx2.o |
| 57 | spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o | ||
| 58 | obj-$(CONFIG_SPIDER_NET) += spidernet.o | ||
| 57 | obj-$(CONFIG_TC35815) += tc35815.o | 59 | obj-$(CONFIG_TC35815) += tc35815.o |
| 58 | obj-$(CONFIG_SKGE) += skge.o | 60 | obj-$(CONFIG_SKGE) += skge.o |
| 59 | obj-$(CONFIG_SK98LIN) += sk98lin/ | 61 | obj-$(CONFIG_SK98LIN) += sk98lin/ |
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 91791ba37769..8a0af5453e21 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c | |||
| @@ -275,7 +275,7 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev) | |||
| 275 | return 0; | 275 | return 0; |
| 276 | out2: | 276 | out2: |
| 277 | if (ei_status.reg0) | 277 | if (ei_status.reg0) |
| 278 | iounmap((void *)dev->mem_start); | 278 | iounmap(ei_status.mem); |
| 279 | out1: | 279 | out1: |
| 280 | free_irq(dev->irq, dev); | 280 | free_irq(dev->irq, dev); |
| 281 | out: | 281 | out: |
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 4f9f69e22c1b..12ef52c193a3 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c | |||
| @@ -597,7 +597,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 597 | struct ArcProto *proto; | 597 | struct ArcProto *proto; |
| 598 | int txbuf; | 598 | int txbuf; |
| 599 | unsigned long flags; | 599 | unsigned long flags; |
| 600 | int freeskb = 0; | 600 | int freeskb, retval; |
| 601 | 601 | ||
| 602 | BUGMSG(D_DURING, | 602 | BUGMSG(D_DURING, |
| 603 | "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n", | 603 | "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n", |
| @@ -615,7 +615,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 615 | if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) { | 615 | if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) { |
| 616 | BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n"); | 616 | BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n"); |
| 617 | dev_kfree_skb(skb); | 617 | dev_kfree_skb(skb); |
| 618 | return 0; /* don't try again */ | 618 | return NETDEV_TX_OK; /* don't try again */ |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | /* We're busy transmitting a packet... */ | 621 | /* We're busy transmitting a packet... */ |
| @@ -623,8 +623,11 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 623 | 623 | ||
| 624 | spin_lock_irqsave(&lp->lock, flags); | 624 | spin_lock_irqsave(&lp->lock, flags); |
| 625 | AINTMASK(0); | 625 | AINTMASK(0); |
| 626 | 626 | if(lp->next_tx == -1) | |
| 627 | txbuf = get_arcbuf(dev); | 627 | txbuf = get_arcbuf(dev); |
| 628 | else { | ||
| 629 | txbuf = -1; | ||
| 630 | } | ||
| 628 | if (txbuf != -1) { | 631 | if (txbuf != -1) { |
| 629 | if (proto->prepare_tx(dev, pkt, skb->len, txbuf) && | 632 | if (proto->prepare_tx(dev, pkt, skb->len, txbuf) && |
| 630 | !proto->ack_tx) { | 633 | !proto->ack_tx) { |
| @@ -638,6 +641,8 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 638 | lp->outgoing.skb = skb; | 641 | lp->outgoing.skb = skb; |
| 639 | lp->outgoing.pkt = pkt; | 642 | lp->outgoing.pkt = pkt; |
| 640 | 643 | ||
| 644 | freeskb = 0; | ||
| 645 | |||
| 641 | if (proto->continue_tx && | 646 | if (proto->continue_tx && |
| 642 | proto->continue_tx(dev, txbuf)) { | 647 | proto->continue_tx(dev, txbuf)) { |
| 643 | BUGMSG(D_NORMAL, | 648 | BUGMSG(D_NORMAL, |
| @@ -645,10 +650,12 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 645 | "(proto='%c')\n", proto->suffix); | 650 | "(proto='%c')\n", proto->suffix); |
| 646 | } | 651 | } |
| 647 | } | 652 | } |
| 648 | 653 | retval = NETDEV_TX_OK; | |
| 654 | dev->trans_start = jiffies; | ||
| 649 | lp->next_tx = txbuf; | 655 | lp->next_tx = txbuf; |
| 650 | } else { | 656 | } else { |
| 651 | freeskb = 1; | 657 | retval = NETDEV_TX_BUSY; |
| 658 | freeskb = 0; | ||
| 652 | } | 659 | } |
| 653 | 660 | ||
| 654 | BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS()); | 661 | BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS()); |
| @@ -664,7 +671,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 664 | if (freeskb) { | 671 | if (freeskb) { |
| 665 | dev_kfree_skb(skb); | 672 | dev_kfree_skb(skb); |
| 666 | } | 673 | } |
| 667 | return 0; /* no need to try again */ | 674 | return retval; /* no need to try again */ |
| 668 | } | 675 | } |
| 669 | 676 | ||
| 670 | 677 | ||
| @@ -690,7 +697,6 @@ static int go_tx(struct net_device *dev) | |||
| 690 | /* start sending */ | 697 | /* start sending */ |
| 691 | ACOMMAND(TXcmd | (lp->cur_tx << 3)); | 698 | ACOMMAND(TXcmd | (lp->cur_tx << 3)); |
| 692 | 699 | ||
| 693 | dev->trans_start = jiffies; | ||
| 694 | lp->stats.tx_packets++; | 700 | lp->stats.tx_packets++; |
| 695 | lp->lasttrans_dest = lp->lastload_dest; | 701 | lp->lasttrans_dest = lp->lastload_dest; |
| 696 | lp->lastload_dest = 0; | 702 | lp->lastload_dest = 0; |
| @@ -917,6 +923,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 917 | 923 | ||
| 918 | BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n", | 924 | BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n", |
| 919 | status); | 925 | status); |
| 926 | /* MYRECON bit is at bit 7 of diagstatus */ | ||
| 927 | if(diagstatus & 0x80) | ||
| 928 | BUGMSG(D_RECON,"Put out that recon myself\n"); | ||
| 920 | 929 | ||
| 921 | /* is the RECON info empty or old? */ | 930 | /* is the RECON info empty or old? */ |
| 922 | if (!lp->first_recon || !lp->last_recon || | 931 | if (!lp->first_recon || !lp->last_recon || |
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index ad011214c7f2..e01b6a78ec63 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c | |||
| @@ -235,7 +235,7 @@ struct lance_private { | |||
| 235 | #define MEM lp->mem | 235 | #define MEM lp->mem |
| 236 | #define DREG IO->data | 236 | #define DREG IO->data |
| 237 | #define AREG IO->addr | 237 | #define AREG IO->addr |
| 238 | #define REGA(a) ( AREG = (a), DREG ) | 238 | #define REGA(a) (*( AREG = (a), &DREG )) |
| 239 | 239 | ||
| 240 | /* Definitions for packet buffer access: */ | 240 | /* Definitions for packet buffer access: */ |
| 241 | #define PKT_BUF_SZ 1544 | 241 | #define PKT_BUF_SZ 1544 |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 6440a892bb81..e54fc10f6846 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
| @@ -1140,7 +1140,7 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) | |||
| 1140 | } | 1140 | } |
| 1141 | 1141 | ||
| 1142 | static int | 1142 | static int |
| 1143 | dm9000_drv_suspend(struct device *dev, u32 state, u32 level) | 1143 | dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level) |
| 1144 | { | 1144 | { |
| 1145 | struct net_device *ndev = dev_get_drvdata(dev); | 1145 | struct net_device *ndev = dev_get_drvdata(dev); |
| 1146 | 1146 | ||
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 7d93948aec83..d6eefdb71c17 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -1372,7 +1372,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1372 | 1372 | ||
| 1373 | /* synchronized against open : rtnl_lock() held by caller */ | 1373 | /* synchronized against open : rtnl_lock() held by caller */ |
| 1374 | if (netif_running(dev)) { | 1374 | if (netif_running(dev)) { |
| 1375 | u8 *base = get_hwbase(dev); | 1375 | u8 __iomem *base = get_hwbase(dev); |
| 1376 | /* | 1376 | /* |
| 1377 | * It seems that the nic preloads valid ring entries into an | 1377 | * It seems that the nic preloads valid ring entries into an |
| 1378 | * internal buffer. The procedure for flushing everything is | 1378 | * internal buffer. The procedure for flushing everything is |
| @@ -1423,7 +1423,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1423 | 1423 | ||
| 1424 | static void nv_copy_mac_to_hw(struct net_device *dev) | 1424 | static void nv_copy_mac_to_hw(struct net_device *dev) |
| 1425 | { | 1425 | { |
| 1426 | u8 *base = get_hwbase(dev); | 1426 | u8 __iomem *base = get_hwbase(dev); |
| 1427 | u32 mac[2]; | 1427 | u32 mac[2]; |
| 1428 | 1428 | ||
| 1429 | mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + | 1429 | mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + |
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index d9df1d9a5739..bc9a3bf8d560 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c | |||
| @@ -204,6 +204,10 @@ KERN_INFO " Further modifications by Keith Underwood <keithu@parl.clemson.edu> | |||
| 204 | 204 | ||
| 205 | #define RUN_AT(x) (jiffies + (x)) | 205 | #define RUN_AT(x) (jiffies + (x)) |
| 206 | 206 | ||
| 207 | #ifndef ADDRLEN | ||
| 208 | #define ADDRLEN 32 | ||
| 209 | #endif | ||
| 210 | |||
| 207 | /* Condensed bus+endian portability operations. */ | 211 | /* Condensed bus+endian portability operations. */ |
| 208 | #if ADDRLEN == 64 | 212 | #if ADDRLEN == 64 |
| 209 | #define cpu_to_leXX(addr) cpu_to_le64(addr) | 213 | #define cpu_to_leXX(addr) cpu_to_le64(addr) |
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 10125a1dba22..dd89bda1f131 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
| @@ -4,10 +4,10 @@ | |||
| 4 | * Description: Driver for the SMC Infrared Communications Controller | 4 | * Description: Driver for the SMC Infrared Communications Controller |
| 5 | * Status: Experimental. | 5 | * Status: Experimental. |
| 6 | * Author: Daniele Peri (peri@csai.unipa.it) | 6 | * Author: Daniele Peri (peri@csai.unipa.it) |
| 7 | * Created at: | 7 | * Created at: |
| 8 | * Modified at: | 8 | * Modified at: |
| 9 | * Modified by: | 9 | * Modified by: |
| 10 | * | 10 | * |
| 11 | * Copyright (c) 2002 Daniele Peri | 11 | * Copyright (c) 2002 Daniele Peri |
| 12 | * All Rights Reserved. | 12 | * All Rights Reserved. |
| 13 | * Copyright (c) 2002 Jean Tourrilhes | 13 | * Copyright (c) 2002 Jean Tourrilhes |
| @@ -17,26 +17,26 @@ | |||
| 17 | * | 17 | * |
| 18 | * Copyright (c) 2001 Stefani Seibold | 18 | * Copyright (c) 2001 Stefani Seibold |
| 19 | * Copyright (c) 1999-2001 Dag Brattli | 19 | * Copyright (c) 1999-2001 Dag Brattli |
| 20 | * Copyright (c) 1998-1999 Thomas Davis, | 20 | * Copyright (c) 1998-1999 Thomas Davis, |
| 21 | * | 21 | * |
| 22 | * and irport.c: | 22 | * and irport.c: |
| 23 | * | 23 | * |
| 24 | * Copyright (c) 1997, 1998, 1999-2000 Dag Brattli, All Rights Reserved. | 24 | * Copyright (c) 1997, 1998, 1999-2000 Dag Brattli, All Rights Reserved. |
| 25 | * | 25 | * |
| 26 | * | 26 | * |
| 27 | * This program is free software; you can redistribute it and/or | 27 | * This program is free software; you can redistribute it and/or |
| 28 | * modify it under the terms of the GNU General Public License as | 28 | * modify it under the terms of the GNU General Public License as |
| 29 | * published by the Free Software Foundation; either version 2 of | 29 | * published by the Free Software Foundation; either version 2 of |
| 30 | * the License, or (at your option) any later version. | 30 | * the License, or (at your option) any later version. |
| 31 | * | 31 | * |
| 32 | * This program is distributed in the hope that it will be useful, | 32 | * This program is distributed in the hope that it will be useful, |
| 33 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 33 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 35 | * GNU General Public License for more details. | 35 | * GNU General Public License for more details. |
| 36 | * | 36 | * |
| 37 | * You should have received a copy of the GNU General Public License | 37 | * You should have received a copy of the GNU General Public License |
| 38 | * along with this program; if not, write to the Free Software | 38 | * along with this program; if not, write to the Free Software |
| 39 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 39 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| 40 | * MA 02111-1307 USA | 40 | * MA 02111-1307 USA |
| 41 | * | 41 | * |
| 42 | ********************************************************************/ | 42 | ********************************************************************/ |
| @@ -68,24 +68,42 @@ | |||
| 68 | #include "smsc-ircc2.h" | 68 | #include "smsc-ircc2.h" |
| 69 | #include "smsc-sio.h" | 69 | #include "smsc-sio.h" |
| 70 | 70 | ||
| 71 | |||
| 72 | MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>"); | ||
| 73 | MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); | ||
| 74 | MODULE_LICENSE("GPL"); | ||
| 75 | |||
| 76 | static int ircc_dma = 255; | ||
| 77 | module_param(ircc_dma, int, 0); | ||
| 78 | MODULE_PARM_DESC(ircc_dma, "DMA channel"); | ||
| 79 | |||
| 80 | static int ircc_irq = 255; | ||
| 81 | module_param(ircc_irq, int, 0); | ||
| 82 | MODULE_PARM_DESC(ircc_irq, "IRQ line"); | ||
| 83 | |||
| 84 | static int ircc_fir; | ||
| 85 | module_param(ircc_fir, int, 0); | ||
| 86 | MODULE_PARM_DESC(ircc_fir, "FIR Base Address"); | ||
| 87 | |||
| 88 | static int ircc_sir; | ||
| 89 | module_param(ircc_sir, int, 0); | ||
| 90 | MODULE_PARM_DESC(ircc_sir, "SIR Base Address"); | ||
| 91 | |||
| 92 | static int ircc_cfg; | ||
| 93 | module_param(ircc_cfg, int, 0); | ||
| 94 | MODULE_PARM_DESC(ircc_cfg, "Configuration register base address"); | ||
| 95 | |||
| 96 | static int ircc_transceiver; | ||
| 97 | module_param(ircc_transceiver, int, 0); | ||
| 98 | MODULE_PARM_DESC(ircc_transceiver, "Transceiver type"); | ||
| 99 | |||
| 71 | /* Types */ | 100 | /* Types */ |
| 72 | 101 | ||
| 73 | struct smsc_transceiver { | 102 | struct smsc_transceiver { |
| 74 | char *name; | 103 | char *name; |
| 75 | void (*set_for_speed)(int fir_base, u32 speed); | 104 | void (*set_for_speed)(int fir_base, u32 speed); |
| 76 | int (*probe)(int fir_base); | 105 | int (*probe)(int fir_base); |
| 77 | }; | 106 | }; |
| 78 | typedef struct smsc_transceiver smsc_transceiver_t; | ||
| 79 | |||
| 80 | #if 0 | ||
| 81 | struct smc_chip { | ||
| 82 | char *name; | ||
| 83 | u16 flags; | ||
| 84 | u8 devid; | ||
| 85 | u8 rev; | ||
| 86 | }; | ||
| 87 | typedef struct smc_chip smc_chip_t; | ||
| 88 | #endif | ||
| 89 | 107 | ||
| 90 | struct smsc_chip { | 108 | struct smsc_chip { |
| 91 | char *name; | 109 | char *name; |
| @@ -96,20 +114,18 @@ struct smsc_chip { | |||
| 96 | u8 devid; | 114 | u8 devid; |
| 97 | u8 rev; | 115 | u8 rev; |
| 98 | }; | 116 | }; |
| 99 | typedef struct smsc_chip smsc_chip_t; | ||
| 100 | 117 | ||
| 101 | struct smsc_chip_address { | 118 | struct smsc_chip_address { |
| 102 | unsigned int cfg_base; | 119 | unsigned int cfg_base; |
| 103 | unsigned int type; | 120 | unsigned int type; |
| 104 | }; | 121 | }; |
| 105 | typedef struct smsc_chip_address smsc_chip_address_t; | ||
| 106 | 122 | ||
| 107 | /* Private data for each instance */ | 123 | /* Private data for each instance */ |
| 108 | struct smsc_ircc_cb { | 124 | struct smsc_ircc_cb { |
| 109 | struct net_device *netdev; /* Yes! we are some kind of netdevice */ | 125 | struct net_device *netdev; /* Yes! we are some kind of netdevice */ |
| 110 | struct net_device_stats stats; | 126 | struct net_device_stats stats; |
| 111 | struct irlap_cb *irlap; /* The link layer we are binded to */ | 127 | struct irlap_cb *irlap; /* The link layer we are binded to */ |
| 112 | 128 | ||
| 113 | chipio_t io; /* IrDA controller information */ | 129 | chipio_t io; /* IrDA controller information */ |
| 114 | iobuff_t tx_buff; /* Transmit buffer */ | 130 | iobuff_t tx_buff; /* Transmit buffer */ |
| 115 | iobuff_t rx_buff; /* Receive buffer */ | 131 | iobuff_t rx_buff; /* Receive buffer */ |
| @@ -119,7 +135,7 @@ struct smsc_ircc_cb { | |||
| 119 | struct qos_info qos; /* QoS capabilities for this device */ | 135 | struct qos_info qos; /* QoS capabilities for this device */ |
| 120 | 136 | ||
| 121 | spinlock_t lock; /* For serializing operations */ | 137 | spinlock_t lock; /* For serializing operations */ |
| 122 | 138 | ||
| 123 | __u32 new_speed; | 139 | __u32 new_speed; |
| 124 | __u32 flags; /* Interface flags */ | 140 | __u32 flags; /* Interface flags */ |
| 125 | 141 | ||
| @@ -127,18 +143,20 @@ struct smsc_ircc_cb { | |||
| 127 | int tx_len; /* Number of frames in tx_buff */ | 143 | int tx_len; /* Number of frames in tx_buff */ |
| 128 | 144 | ||
| 129 | int transceiver; | 145 | int transceiver; |
| 130 | struct pm_dev *pmdev; | 146 | struct platform_device *pldev; |
| 131 | }; | 147 | }; |
| 132 | 148 | ||
| 133 | /* Constants */ | 149 | /* Constants */ |
| 134 | 150 | ||
| 135 | static const char *driver_name = "smsc-ircc2"; | 151 | #define SMSC_IRCC2_DRIVER_NAME "smsc-ircc2" |
| 136 | #define DIM(x) (sizeof(x)/(sizeof(*(x)))) | 152 | |
| 137 | #define SMSC_IRCC2_C_IRDA_FALLBACK_SPEED 9600 | 153 | #define SMSC_IRCC2_C_IRDA_FALLBACK_SPEED 9600 |
| 138 | #define SMSC_IRCC2_C_DEFAULT_TRANSCEIVER 1 | 154 | #define SMSC_IRCC2_C_DEFAULT_TRANSCEIVER 1 |
| 139 | #define SMSC_IRCC2_C_NET_TIMEOUT 0 | 155 | #define SMSC_IRCC2_C_NET_TIMEOUT 0 |
| 140 | #define SMSC_IRCC2_C_SIR_STOP 0 | 156 | #define SMSC_IRCC2_C_SIR_STOP 0 |
| 141 | 157 | ||
| 158 | static const char *driver_name = SMSC_IRCC2_DRIVER_NAME; | ||
| 159 | |||
| 142 | /* Prototypes */ | 160 | /* Prototypes */ |
| 143 | 161 | ||
| 144 | static int smsc_ircc_open(unsigned int firbase, unsigned int sirbase, u8 dma, u8 irq); | 162 | static int smsc_ircc_open(unsigned int firbase, unsigned int sirbase, u8 dma, u8 irq); |
| @@ -147,15 +165,15 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, unsigned int fir_base, | |||
| 147 | static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self); | 165 | static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self); |
| 148 | static void smsc_ircc_init_chip(struct smsc_ircc_cb *self); | 166 | static void smsc_ircc_init_chip(struct smsc_ircc_cb *self); |
| 149 | static int __exit smsc_ircc_close(struct smsc_ircc_cb *self); | 167 | static int __exit smsc_ircc_close(struct smsc_ircc_cb *self); |
| 150 | static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase); | 168 | static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self); |
| 151 | static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self, int iobase); | 169 | static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self); |
| 152 | static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self); | 170 | static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self); |
| 153 | static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev); | 171 | static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev); |
| 154 | static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev); | 172 | static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev); |
| 155 | static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int iobase, int bofs); | 173 | static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs); |
| 156 | static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self, int iobase); | 174 | static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self); |
| 157 | static void smsc_ircc_change_speed(void *priv, u32 speed); | 175 | static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed); |
| 158 | static void smsc_ircc_set_sir_speed(void *priv, u32 speed); | 176 | static void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, u32 speed); |
| 159 | static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 177 | static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
| 160 | static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev); | 178 | static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev); |
| 161 | static void smsc_ircc_sir_start(struct smsc_ircc_cb *self); | 179 | static void smsc_ircc_sir_start(struct smsc_ircc_cb *self); |
| @@ -171,7 +189,6 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cm | |||
| 171 | static void smsc_ircc_timeout(struct net_device *dev); | 189 | static void smsc_ircc_timeout(struct net_device *dev); |
| 172 | #endif | 190 | #endif |
| 173 | static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev); | 191 | static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev); |
| 174 | static int smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data); | ||
| 175 | static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self); | 192 | static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self); |
| 176 | static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self); | 193 | static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self); |
| 177 | static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 speed); | 194 | static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 speed); |
| @@ -179,9 +196,9 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self); | |||
| 179 | 196 | ||
| 180 | /* Probing */ | 197 | /* Probing */ |
| 181 | static int __init smsc_ircc_look_for_chips(void); | 198 | static int __init smsc_ircc_look_for_chips(void); |
| 182 | static const smsc_chip_t * __init smsc_ircc_probe(unsigned short cfg_base,u8 reg,const smsc_chip_t *chip,char *type); | 199 | static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type); |
| 183 | static int __init smsc_superio_flat(const smsc_chip_t *chips, unsigned short cfg_base, char *type); | 200 | static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type); |
| 184 | static int __init smsc_superio_paged(const smsc_chip_t *chips, unsigned short cfg_base, char *type); | 201 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); |
| 185 | static int __init smsc_superio_fdc(unsigned short cfg_base); | 202 | static int __init smsc_superio_fdc(unsigned short cfg_base); |
| 186 | static int __init smsc_superio_lpc(unsigned short cfg_base); | 203 | static int __init smsc_superio_lpc(unsigned short cfg_base); |
| 187 | 204 | ||
| @@ -196,21 +213,26 @@ static int smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base); | |||
| 196 | 213 | ||
| 197 | /* Power Management */ | 214 | /* Power Management */ |
| 198 | 215 | ||
| 199 | static void smsc_ircc_suspend(struct smsc_ircc_cb *self); | 216 | static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level); |
| 200 | static void smsc_ircc_wakeup(struct smsc_ircc_cb *self); | 217 | static int smsc_ircc_resume(struct device *dev, u32 level); |
| 201 | static int smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data); | ||
| 202 | 218 | ||
| 219 | static struct device_driver smsc_ircc_driver = { | ||
| 220 | .name = SMSC_IRCC2_DRIVER_NAME, | ||
| 221 | .bus = &platform_bus_type, | ||
| 222 | .suspend = smsc_ircc_suspend, | ||
| 223 | .resume = smsc_ircc_resume, | ||
| 224 | }; | ||
| 203 | 225 | ||
| 204 | /* Transceivers for SMSC-ircc */ | 226 | /* Transceivers for SMSC-ircc */ |
| 205 | 227 | ||
| 206 | static smsc_transceiver_t smsc_transceivers[]= | 228 | static struct smsc_transceiver smsc_transceivers[] = |
| 207 | { | 229 | { |
| 208 | { "Toshiba Satellite 1800 (GP data pin select)", smsc_ircc_set_transceiver_toshiba_sat1800, smsc_ircc_probe_transceiver_toshiba_sat1800}, | 230 | { "Toshiba Satellite 1800 (GP data pin select)", smsc_ircc_set_transceiver_toshiba_sat1800, smsc_ircc_probe_transceiver_toshiba_sat1800 }, |
| 209 | { "Fast pin select", smsc_ircc_set_transceiver_smsc_ircc_fast_pin_select, smsc_ircc_probe_transceiver_smsc_ircc_fast_pin_select}, | 231 | { "Fast pin select", smsc_ircc_set_transceiver_smsc_ircc_fast_pin_select, smsc_ircc_probe_transceiver_smsc_ircc_fast_pin_select }, |
| 210 | { "ATC IRMode", smsc_ircc_set_transceiver_smsc_ircc_atc, smsc_ircc_probe_transceiver_smsc_ircc_atc}, | 232 | { "ATC IRMode", smsc_ircc_set_transceiver_smsc_ircc_atc, smsc_ircc_probe_transceiver_smsc_ircc_atc }, |
| 211 | { NULL, NULL} | 233 | { NULL, NULL } |
| 212 | }; | 234 | }; |
| 213 | #define SMSC_IRCC2_C_NUMBER_OF_TRANSCEIVERS (DIM(smsc_transceivers)-1) | 235 | #define SMSC_IRCC2_C_NUMBER_OF_TRANSCEIVERS (ARRAY_SIZE(smsc_transceivers) - 1) |
| 214 | 236 | ||
| 215 | /* SMC SuperIO chipsets definitions */ | 237 | /* SMC SuperIO chipsets definitions */ |
| 216 | 238 | ||
| @@ -221,7 +243,7 @@ static smsc_transceiver_t smsc_transceivers[]= | |||
| 221 | #define FIR 4 /* SuperIO Chip has fast IRDA */ | 243 | #define FIR 4 /* SuperIO Chip has fast IRDA */ |
| 222 | #define SERx4 8 /* SuperIO Chip supports 115,2 KBaud * 4=460,8 KBaud */ | 244 | #define SERx4 8 /* SuperIO Chip supports 115,2 KBaud * 4=460,8 KBaud */ |
| 223 | 245 | ||
| 224 | static smsc_chip_t __initdata fdc_chips_flat[]= | 246 | static struct smsc_chip __initdata fdc_chips_flat[] = |
| 225 | { | 247 | { |
| 226 | /* Base address 0x3f0 or 0x370 */ | 248 | /* Base address 0x3f0 or 0x370 */ |
| 227 | { "37C44", KEY55_1|NoIRDA, 0x00, 0x00 }, /* This chip cannot be detected */ | 249 | { "37C44", KEY55_1|NoIRDA, 0x00, 0x00 }, /* This chip cannot be detected */ |
| @@ -235,7 +257,7 @@ static smsc_chip_t __initdata fdc_chips_flat[]= | |||
| 235 | { NULL } | 257 | { NULL } |
| 236 | }; | 258 | }; |
| 237 | 259 | ||
| 238 | static smsc_chip_t __initdata fdc_chips_paged[]= | 260 | static struct smsc_chip __initdata fdc_chips_paged[] = |
| 239 | { | 261 | { |
| 240 | /* Base address 0x3f0 or 0x370 */ | 262 | /* Base address 0x3f0 or 0x370 */ |
| 241 | { "37B72X", KEY55_1|SIR|SERx4, 0x4c, 0x00 }, | 263 | { "37B72X", KEY55_1|SIR|SERx4, 0x4c, 0x00 }, |
| @@ -254,7 +276,7 @@ static smsc_chip_t __initdata fdc_chips_paged[]= | |||
| 254 | { NULL } | 276 | { NULL } |
| 255 | }; | 277 | }; |
| 256 | 278 | ||
| 257 | static smsc_chip_t __initdata lpc_chips_flat[]= | 279 | static struct smsc_chip __initdata lpc_chips_flat[] = |
| 258 | { | 280 | { |
| 259 | /* Base address 0x2E or 0x4E */ | 281 | /* Base address 0x2E or 0x4E */ |
| 260 | { "47N227", KEY55_1|FIR|SERx4, 0x5a, 0x00 }, | 282 | { "47N227", KEY55_1|FIR|SERx4, 0x5a, 0x00 }, |
| @@ -262,7 +284,7 @@ static smsc_chip_t __initdata lpc_chips_flat[]= | |||
| 262 | { NULL } | 284 | { NULL } |
| 263 | }; | 285 | }; |
| 264 | 286 | ||
| 265 | static smsc_chip_t __initdata lpc_chips_paged[]= | 287 | static struct smsc_chip __initdata lpc_chips_paged[] = |
| 266 | { | 288 | { |
| 267 | /* Base address 0x2E or 0x4E */ | 289 | /* Base address 0x2E or 0x4E */ |
| 268 | { "47B27X", KEY55_1|SIR|SERx4, 0x51, 0x00 }, | 290 | { "47B27X", KEY55_1|SIR|SERx4, 0x51, 0x00 }, |
| @@ -281,33 +303,25 @@ static smsc_chip_t __initdata lpc_chips_paged[]= | |||
| 281 | #define SMSCSIO_TYPE_FLAT 4 | 303 | #define SMSCSIO_TYPE_FLAT 4 |
| 282 | #define SMSCSIO_TYPE_PAGED 8 | 304 | #define SMSCSIO_TYPE_PAGED 8 |
| 283 | 305 | ||
| 284 | static smsc_chip_address_t __initdata possible_addresses[]= | 306 | static struct smsc_chip_address __initdata possible_addresses[] = |
| 285 | { | 307 | { |
| 286 | {0x3f0, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED}, | 308 | { 0x3f0, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED }, |
| 287 | {0x370, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED}, | 309 | { 0x370, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED }, |
| 288 | {0xe0, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED}, | 310 | { 0xe0, SMSCSIO_TYPE_FDC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED }, |
| 289 | {0x2e, SMSCSIO_TYPE_LPC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED}, | 311 | { 0x2e, SMSCSIO_TYPE_LPC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED }, |
| 290 | {0x4e, SMSCSIO_TYPE_LPC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED}, | 312 | { 0x4e, SMSCSIO_TYPE_LPC|SMSCSIO_TYPE_FLAT|SMSCSIO_TYPE_PAGED }, |
| 291 | {0,0} | 313 | { 0, 0 } |
| 292 | }; | 314 | }; |
| 293 | 315 | ||
| 294 | /* Globals */ | 316 | /* Globals */ |
| 295 | 317 | ||
| 296 | static struct smsc_ircc_cb *dev_self[] = { NULL, NULL}; | 318 | static struct smsc_ircc_cb *dev_self[] = { NULL, NULL }; |
| 297 | 319 | static unsigned short dev_count; | |
| 298 | static int ircc_irq=255; | ||
| 299 | static int ircc_dma=255; | ||
| 300 | static int ircc_fir=0; | ||
| 301 | static int ircc_sir=0; | ||
| 302 | static int ircc_cfg=0; | ||
| 303 | static int ircc_transceiver=0; | ||
| 304 | |||
| 305 | static unsigned short dev_count=0; | ||
| 306 | 320 | ||
| 307 | static inline void register_bank(int iobase, int bank) | 321 | static inline void register_bank(int iobase, int bank) |
| 308 | { | 322 | { |
| 309 | outb(((inb(iobase+IRCC_MASTER) & 0xf0) | (bank & 0x07)), | 323 | outb(((inb(iobase + IRCC_MASTER) & 0xf0) | (bank & 0x07)), |
| 310 | iobase+IRCC_MASTER); | 324 | iobase + IRCC_MASTER); |
| 311 | } | 325 | } |
| 312 | 326 | ||
| 313 | 327 | ||
| @@ -327,34 +341,44 @@ static inline void register_bank(int iobase, int bank) | |||
| 327 | */ | 341 | */ |
| 328 | static int __init smsc_ircc_init(void) | 342 | static int __init smsc_ircc_init(void) |
| 329 | { | 343 | { |
| 330 | int ret=-ENODEV; | 344 | int ret; |
| 331 | 345 | ||
| 332 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 346 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 333 | 347 | ||
| 334 | dev_count=0; | 348 | ret = driver_register(&smsc_ircc_driver); |
| 335 | 349 | if (ret) { | |
| 336 | if ((ircc_fir>0)&&(ircc_sir>0)) { | 350 | IRDA_ERROR("%s, Can't register driver!\n", driver_name); |
| 351 | return ret; | ||
| 352 | } | ||
| 353 | |||
| 354 | dev_count = 0; | ||
| 355 | |||
| 356 | if (ircc_fir > 0 && ircc_sir > 0) { | ||
| 337 | IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); | 357 | IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); |
| 338 | IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); | 358 | IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); |
| 339 | 359 | ||
| 340 | if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq) == 0) | 360 | if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) |
| 341 | return 0; | 361 | ret = -ENODEV; |
| 342 | 362 | } else { | |
| 343 | return -ENODEV; | 363 | ret = -ENODEV; |
| 344 | } | 364 | |
| 365 | /* try user provided configuration register base address */ | ||
| 366 | if (ircc_cfg > 0) { | ||
| 367 | IRDA_MESSAGE(" Overriding configuration address " | ||
| 368 | "0x%04x\n", ircc_cfg); | ||
| 369 | if (!smsc_superio_fdc(ircc_cfg)) | ||
| 370 | ret = 0; | ||
| 371 | if (!smsc_superio_lpc(ircc_cfg)) | ||
| 372 | ret = 0; | ||
| 373 | } | ||
| 345 | 374 | ||
| 346 | /* try user provided configuration register base address */ | 375 | if (smsc_ircc_look_for_chips() > 0) |
| 347 | if (ircc_cfg>0) { | ||
| 348 | IRDA_MESSAGE(" Overriding configuration address 0x%04x\n", | ||
| 349 | ircc_cfg); | ||
| 350 | if (!smsc_superio_fdc(ircc_cfg)) | ||
| 351 | ret = 0; | ||
| 352 | if (!smsc_superio_lpc(ircc_cfg)) | ||
| 353 | ret = 0; | 376 | ret = 0; |
| 354 | } | 377 | } |
| 355 | 378 | ||
| 356 | if(smsc_ircc_look_for_chips()>0) ret = 0; | 379 | if (ret) |
| 357 | 380 | driver_unregister(&smsc_ircc_driver); | |
| 381 | |||
| 358 | return ret; | 382 | return ret; |
| 359 | } | 383 | } |
| 360 | 384 | ||
| @@ -369,15 +393,15 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u | |||
| 369 | struct smsc_ircc_cb *self; | 393 | struct smsc_ircc_cb *self; |
| 370 | struct net_device *dev; | 394 | struct net_device *dev; |
| 371 | int err; | 395 | int err; |
| 372 | 396 | ||
| 373 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 397 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 374 | 398 | ||
| 375 | err = smsc_ircc_present(fir_base, sir_base); | 399 | err = smsc_ircc_present(fir_base, sir_base); |
| 376 | if(err) | 400 | if (err) |
| 377 | goto err_out; | 401 | goto err_out; |
| 378 | 402 | ||
| 379 | err = -ENOMEM; | 403 | err = -ENOMEM; |
| 380 | if (dev_count > DIM(dev_self)) { | 404 | if (dev_count >= ARRAY_SIZE(dev_self)) { |
| 381 | IRDA_WARNING("%s(), too many devices!\n", __FUNCTION__); | 405 | IRDA_WARNING("%s(), too many devices!\n", __FUNCTION__); |
| 382 | goto err_out1; | 406 | goto err_out1; |
| 383 | } | 407 | } |
| @@ -396,14 +420,14 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u | |||
| 396 | dev->hard_start_xmit = smsc_ircc_hard_xmit_sir; | 420 | dev->hard_start_xmit = smsc_ircc_hard_xmit_sir; |
| 397 | #if SMSC_IRCC2_C_NET_TIMEOUT | 421 | #if SMSC_IRCC2_C_NET_TIMEOUT |
| 398 | dev->tx_timeout = smsc_ircc_timeout; | 422 | dev->tx_timeout = smsc_ircc_timeout; |
| 399 | dev->watchdog_timeo = HZ*2; /* Allow enough time for speed change */ | 423 | dev->watchdog_timeo = HZ * 2; /* Allow enough time for speed change */ |
| 400 | #endif | 424 | #endif |
| 401 | dev->open = smsc_ircc_net_open; | 425 | dev->open = smsc_ircc_net_open; |
| 402 | dev->stop = smsc_ircc_net_close; | 426 | dev->stop = smsc_ircc_net_close; |
| 403 | dev->do_ioctl = smsc_ircc_net_ioctl; | 427 | dev->do_ioctl = smsc_ircc_net_ioctl; |
| 404 | dev->get_stats = smsc_ircc_net_get_stats; | 428 | dev->get_stats = smsc_ircc_net_get_stats; |
| 405 | 429 | ||
| 406 | self = dev->priv; | 430 | self = netdev_priv(dev); |
| 407 | self->netdev = dev; | 431 | self->netdev = dev; |
| 408 | 432 | ||
| 409 | /* Make ifconfig display some details */ | 433 | /* Make ifconfig display some details */ |
| @@ -411,10 +435,10 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u | |||
| 411 | dev->irq = self->io.irq = irq; | 435 | dev->irq = self->io.irq = irq; |
| 412 | 436 | ||
| 413 | /* Need to store self somewhere */ | 437 | /* Need to store self somewhere */ |
| 414 | dev_self[dev_count++] = self; | 438 | dev_self[dev_count] = self; |
| 415 | spin_lock_init(&self->lock); | 439 | spin_lock_init(&self->lock); |
| 416 | 440 | ||
| 417 | self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE; | 441 | self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE; |
| 418 | self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE; | 442 | self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE; |
| 419 | 443 | ||
| 420 | self->rx_buff.head = | 444 | self->rx_buff.head = |
| @@ -442,33 +466,40 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u | |||
| 442 | self->rx_buff.state = OUTSIDE_FRAME; | 466 | self->rx_buff.state = OUTSIDE_FRAME; |
| 443 | self->tx_buff.data = self->tx_buff.head; | 467 | self->tx_buff.data = self->tx_buff.head; |
| 444 | self->rx_buff.data = self->rx_buff.head; | 468 | self->rx_buff.data = self->rx_buff.head; |
| 445 | |||
| 446 | smsc_ircc_setup_io(self, fir_base, sir_base, dma, irq); | ||
| 447 | 469 | ||
| 470 | smsc_ircc_setup_io(self, fir_base, sir_base, dma, irq); | ||
| 448 | smsc_ircc_setup_qos(self); | 471 | smsc_ircc_setup_qos(self); |
| 449 | |||
| 450 | smsc_ircc_init_chip(self); | 472 | smsc_ircc_init_chip(self); |
| 451 | 473 | ||
| 452 | if(ircc_transceiver > 0 && | 474 | if (ircc_transceiver > 0 && |
| 453 | ircc_transceiver < SMSC_IRCC2_C_NUMBER_OF_TRANSCEIVERS) | 475 | ircc_transceiver < SMSC_IRCC2_C_NUMBER_OF_TRANSCEIVERS) |
| 454 | self->transceiver = ircc_transceiver; | 476 | self->transceiver = ircc_transceiver; |
| 455 | else | 477 | else |
| 456 | smsc_ircc_probe_transceiver(self); | 478 | smsc_ircc_probe_transceiver(self); |
| 457 | 479 | ||
| 458 | err = register_netdev(self->netdev); | 480 | err = register_netdev(self->netdev); |
| 459 | if(err) { | 481 | if (err) { |
| 460 | IRDA_ERROR("%s, Network device registration failed!\n", | 482 | IRDA_ERROR("%s, Network device registration failed!\n", |
| 461 | driver_name); | 483 | driver_name); |
| 462 | goto err_out4; | 484 | goto err_out4; |
| 463 | } | 485 | } |
| 464 | 486 | ||
| 465 | self->pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, smsc_ircc_pmproc); | 487 | self->pldev = platform_device_register_simple(SMSC_IRCC2_DRIVER_NAME, |
| 466 | if (self->pmdev) | 488 | dev_count, NULL, 0); |
| 467 | self->pmdev->data = self; | 489 | if (IS_ERR(self->pldev)) { |
| 490 | err = PTR_ERR(self->pldev); | ||
| 491 | goto err_out5; | ||
| 492 | } | ||
| 493 | dev_set_drvdata(&self->pldev->dev, self); | ||
| 468 | 494 | ||
| 469 | IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); | 495 | IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name); |
| 496 | dev_count++; | ||
| 470 | 497 | ||
| 471 | return 0; | 498 | return 0; |
| 499 | |||
| 500 | err_out5: | ||
| 501 | unregister_netdev(self->netdev); | ||
| 502 | |||
| 472 | err_out4: | 503 | err_out4: |
| 473 | dma_free_coherent(NULL, self->tx_buff.truesize, | 504 | dma_free_coherent(NULL, self->tx_buff.truesize, |
| 474 | self->tx_buff.head, self->tx_buff_dma); | 505 | self->tx_buff.head, self->tx_buff_dma); |
| @@ -477,7 +508,7 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u | |||
| 477 | self->rx_buff.head, self->rx_buff_dma); | 508 | self->rx_buff.head, self->rx_buff_dma); |
| 478 | err_out2: | 509 | err_out2: |
| 479 | free_netdev(self->netdev); | 510 | free_netdev(self->netdev); |
| 480 | dev_self[--dev_count] = NULL; | 511 | dev_self[dev_count] = NULL; |
| 481 | err_out1: | 512 | err_out1: |
| 482 | release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT); | 513 | release_region(fir_base, SMSC_IRCC2_FIR_CHIP_IO_EXTENT); |
| 483 | release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT); | 514 | release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT); |
| @@ -511,16 +542,16 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) | |||
| 511 | 542 | ||
| 512 | register_bank(fir_base, 3); | 543 | register_bank(fir_base, 3); |
| 513 | 544 | ||
| 514 | high = inb(fir_base+IRCC_ID_HIGH); | 545 | high = inb(fir_base + IRCC_ID_HIGH); |
| 515 | low = inb(fir_base+IRCC_ID_LOW); | 546 | low = inb(fir_base + IRCC_ID_LOW); |
| 516 | chip = inb(fir_base+IRCC_CHIP_ID); | 547 | chip = inb(fir_base + IRCC_CHIP_ID); |
| 517 | version = inb(fir_base+IRCC_VERSION); | 548 | version = inb(fir_base + IRCC_VERSION); |
| 518 | config = inb(fir_base+IRCC_INTERFACE); | 549 | config = inb(fir_base + IRCC_INTERFACE); |
| 519 | dma = config & IRCC_INTERFACE_DMA_MASK; | 550 | dma = config & IRCC_INTERFACE_DMA_MASK; |
| 520 | irq = (config & IRCC_INTERFACE_IRQ_MASK) >> 4; | 551 | irq = (config & IRCC_INTERFACE_IRQ_MASK) >> 4; |
| 521 | 552 | ||
| 522 | if (high != 0x10 || low != 0xb8 || (chip != 0xf1 && chip != 0xf2)) { | 553 | if (high != 0x10 || low != 0xb8 || (chip != 0xf1 && chip != 0xf2)) { |
| 523 | IRDA_WARNING("%s(), addr 0x%04x - no device found!\n", | 554 | IRDA_WARNING("%s(), addr 0x%04x - no device found!\n", |
| 524 | __FUNCTION__, fir_base); | 555 | __FUNCTION__, fir_base); |
| 525 | goto out3; | 556 | goto out3; |
| 526 | } | 557 | } |
| @@ -529,6 +560,7 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) | |||
| 529 | chip & 0x0f, version, fir_base, sir_base, dma, irq); | 560 | chip & 0x0f, version, fir_base, sir_base, dma, irq); |
| 530 | 561 | ||
| 531 | return 0; | 562 | return 0; |
| 563 | |||
| 532 | out3: | 564 | out3: |
| 533 | release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT); | 565 | release_region(sir_base, SMSC_IRCC2_SIR_CHIP_IO_EXTENT); |
| 534 | out2: | 566 | out2: |
| @@ -543,16 +575,16 @@ static int smsc_ircc_present(unsigned int fir_base, unsigned int sir_base) | |||
| 543 | * Setup I/O | 575 | * Setup I/O |
| 544 | * | 576 | * |
| 545 | */ | 577 | */ |
| 546 | static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, | 578 | static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, |
| 547 | unsigned int fir_base, unsigned int sir_base, | 579 | unsigned int fir_base, unsigned int sir_base, |
| 548 | u8 dma, u8 irq) | 580 | u8 dma, u8 irq) |
| 549 | { | 581 | { |
| 550 | unsigned char config, chip_dma, chip_irq; | 582 | unsigned char config, chip_dma, chip_irq; |
| 551 | 583 | ||
| 552 | register_bank(fir_base, 3); | 584 | register_bank(fir_base, 3); |
| 553 | config = inb(fir_base+IRCC_INTERFACE); | 585 | config = inb(fir_base + IRCC_INTERFACE); |
| 554 | chip_dma = config & IRCC_INTERFACE_DMA_MASK; | 586 | chip_dma = config & IRCC_INTERFACE_DMA_MASK; |
| 555 | chip_irq = (config & IRCC_INTERFACE_IRQ_MASK) >> 4; | 587 | chip_irq = (config & IRCC_INTERFACE_IRQ_MASK) >> 4; |
| 556 | 588 | ||
| 557 | self->io.fir_base = fir_base; | 589 | self->io.fir_base = fir_base; |
| 558 | self->io.sir_base = sir_base; | 590 | self->io.sir_base = sir_base; |
| @@ -566,17 +598,15 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, | |||
| 566 | IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", | 598 | IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", |
| 567 | driver_name, chip_irq, irq); | 599 | driver_name, chip_irq, irq); |
| 568 | self->io.irq = irq; | 600 | self->io.irq = irq; |
| 569 | } | 601 | } else |
| 570 | else | ||
| 571 | self->io.irq = chip_irq; | 602 | self->io.irq = chip_irq; |
| 572 | 603 | ||
| 573 | if (dma < 255) { | 604 | if (dma < 255) { |
| 574 | if (dma != chip_dma) | 605 | if (dma != chip_dma) |
| 575 | IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", | 606 | IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", |
| 576 | driver_name, chip_dma, dma); | 607 | driver_name, chip_dma, dma); |
| 577 | self->io.dma = dma; | 608 | self->io.dma = dma; |
| 578 | } | 609 | } else |
| 579 | else | ||
| 580 | self->io.dma = chip_dma; | 610 | self->io.dma = chip_dma; |
| 581 | 611 | ||
| 582 | } | 612 | } |
| @@ -591,7 +621,7 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self) | |||
| 591 | { | 621 | { |
| 592 | /* Initialize QoS for this device */ | 622 | /* Initialize QoS for this device */ |
| 593 | irda_init_max_qos_capabilies(&self->qos); | 623 | irda_init_max_qos_capabilies(&self->qos); |
| 594 | 624 | ||
| 595 | self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| | 625 | self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| |
| 596 | IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); | 626 | IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); |
| 597 | 627 | ||
| @@ -608,43 +638,43 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self) | |||
| 608 | */ | 638 | */ |
| 609 | static void smsc_ircc_init_chip(struct smsc_ircc_cb *self) | 639 | static void smsc_ircc_init_chip(struct smsc_ircc_cb *self) |
| 610 | { | 640 | { |
| 611 | int iobase, ir_mode, ctrl, fast; | 641 | int iobase, ir_mode, ctrl, fast; |
| 612 | 642 | ||
| 613 | IRDA_ASSERT( self != NULL, return; ); | 643 | IRDA_ASSERT(self != NULL, return;); |
| 614 | iobase = self->io.fir_base; | ||
| 615 | 644 | ||
| 645 | iobase = self->io.fir_base; | ||
| 616 | ir_mode = IRCC_CFGA_IRDA_SIR_A; | 646 | ir_mode = IRCC_CFGA_IRDA_SIR_A; |
| 617 | ctrl = 0; | 647 | ctrl = 0; |
| 618 | fast = 0; | 648 | fast = 0; |
| 619 | 649 | ||
| 620 | register_bank(iobase, 0); | 650 | register_bank(iobase, 0); |
| 621 | outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER); | 651 | outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER); |
| 622 | outb(0x00, iobase+IRCC_MASTER); | 652 | outb(0x00, iobase + IRCC_MASTER); |
| 623 | 653 | ||
| 624 | register_bank(iobase, 1); | 654 | register_bank(iobase, 1); |
| 625 | outb(((inb(iobase+IRCC_SCE_CFGA) & 0x87) | ir_mode), | 655 | outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode), |
| 626 | iobase+IRCC_SCE_CFGA); | 656 | iobase + IRCC_SCE_CFGA); |
| 627 | 657 | ||
| 628 | #ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */ | 658 | #ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */ |
| 629 | outb(((inb(iobase+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_COM), | 659 | outb(((inb(iobase + IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_COM), |
| 630 | iobase+IRCC_SCE_CFGB); | 660 | iobase + IRCC_SCE_CFGB); |
| 631 | #else | 661 | #else |
| 632 | outb(((inb(iobase+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_IR), | 662 | outb(((inb(iobase + IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_IR), |
| 633 | iobase+IRCC_SCE_CFGB); | 663 | iobase + IRCC_SCE_CFGB); |
| 634 | #endif | 664 | #endif |
| 635 | (void) inb(iobase+IRCC_FIFO_THRESHOLD); | 665 | (void) inb(iobase + IRCC_FIFO_THRESHOLD); |
| 636 | outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase+IRCC_FIFO_THRESHOLD); | 666 | outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD); |
| 637 | 667 | ||
| 638 | register_bank(iobase, 4); | 668 | register_bank(iobase, 4); |
| 639 | outb((inb(iobase+IRCC_CONTROL) & 0x30) | ctrl, iobase+IRCC_CONTROL); | 669 | outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL); |
| 640 | 670 | ||
| 641 | register_bank(iobase, 0); | 671 | register_bank(iobase, 0); |
| 642 | outb(fast, iobase+IRCC_LCR_A); | 672 | outb(fast, iobase + IRCC_LCR_A); |
| 643 | 673 | ||
| 644 | smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED); | 674 | smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED); |
| 645 | 675 | ||
| 646 | /* Power on device */ | 676 | /* Power on device */ |
| 647 | outb(0x00, iobase+IRCC_MASTER); | 677 | outb(0x00, iobase + IRCC_MASTER); |
| 648 | } | 678 | } |
| 649 | 679 | ||
| 650 | /* | 680 | /* |
| @@ -662,12 +692,12 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd | |||
| 662 | 692 | ||
| 663 | IRDA_ASSERT(dev != NULL, return -1;); | 693 | IRDA_ASSERT(dev != NULL, return -1;); |
| 664 | 694 | ||
| 665 | self = dev->priv; | 695 | self = netdev_priv(dev); |
| 666 | 696 | ||
| 667 | IRDA_ASSERT(self != NULL, return -1;); | 697 | IRDA_ASSERT(self != NULL, return -1;); |
| 668 | 698 | ||
| 669 | IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); | 699 | IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); |
| 670 | 700 | ||
| 671 | switch (cmd) { | 701 | switch (cmd) { |
| 672 | case SIOCSBANDWIDTH: /* Set bandwidth */ | 702 | case SIOCSBANDWIDTH: /* Set bandwidth */ |
| 673 | if (!capable(CAP_NET_ADMIN)) | 703 | if (!capable(CAP_NET_ADMIN)) |
| @@ -703,14 +733,14 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd | |||
| 703 | default: | 733 | default: |
| 704 | ret = -EOPNOTSUPP; | 734 | ret = -EOPNOTSUPP; |
| 705 | } | 735 | } |
| 706 | 736 | ||
| 707 | return ret; | 737 | return ret; |
| 708 | } | 738 | } |
| 709 | 739 | ||
| 710 | static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev) | 740 | static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev) |
| 711 | { | 741 | { |
| 712 | struct smsc_ircc_cb *self = (struct smsc_ircc_cb *) dev->priv; | 742 | struct smsc_ircc_cb *self = netdev_priv(dev); |
| 713 | 743 | ||
| 714 | return &self->stats; | 744 | return &self->stats; |
| 715 | } | 745 | } |
| 716 | 746 | ||
| @@ -724,11 +754,9 @@ static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev) | |||
| 724 | 754 | ||
| 725 | static void smsc_ircc_timeout(struct net_device *dev) | 755 | static void smsc_ircc_timeout(struct net_device *dev) |
| 726 | { | 756 | { |
| 727 | struct smsc_ircc_cb *self; | 757 | struct smsc_ircc_cb *self = netdev_priv(dev); |
| 728 | unsigned long flags; | 758 | unsigned long flags; |
| 729 | 759 | ||
| 730 | self = (struct smsc_ircc_cb *) dev->priv; | ||
| 731 | |||
| 732 | IRDA_WARNING("%s: transmit timed out, changing speed to: %d\n", | 760 | IRDA_WARNING("%s: transmit timed out, changing speed to: %d\n", |
| 733 | dev->name, self->io.speed); | 761 | dev->name, self->io.speed); |
| 734 | spin_lock_irqsave(&self->lock, flags); | 762 | spin_lock_irqsave(&self->lock, flags); |
| @@ -751,26 +779,23 @@ int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) | |||
| 751 | { | 779 | { |
| 752 | struct smsc_ircc_cb *self; | 780 | struct smsc_ircc_cb *self; |
| 753 | unsigned long flags; | 781 | unsigned long flags; |
| 754 | int iobase; | ||
| 755 | s32 speed; | 782 | s32 speed; |
| 756 | 783 | ||
| 757 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 784 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 758 | 785 | ||
| 759 | IRDA_ASSERT(dev != NULL, return 0;); | 786 | IRDA_ASSERT(dev != NULL, return 0;); |
| 760 | |||
| 761 | self = (struct smsc_ircc_cb *) dev->priv; | ||
| 762 | IRDA_ASSERT(self != NULL, return 0;); | ||
| 763 | 787 | ||
| 764 | iobase = self->io.sir_base; | 788 | self = netdev_priv(dev); |
| 789 | IRDA_ASSERT(self != NULL, return 0;); | ||
| 765 | 790 | ||
| 766 | netif_stop_queue(dev); | 791 | netif_stop_queue(dev); |
| 767 | 792 | ||
| 768 | /* Make sure test of self->io.speed & speed change are atomic */ | 793 | /* Make sure test of self->io.speed & speed change are atomic */ |
| 769 | spin_lock_irqsave(&self->lock, flags); | 794 | spin_lock_irqsave(&self->lock, flags); |
| 770 | 795 | ||
| 771 | /* Check if we need to change the speed */ | 796 | /* Check if we need to change the speed */ |
| 772 | speed = irda_get_next_speed(skb); | 797 | speed = irda_get_next_speed(skb); |
| 773 | if ((speed != self->io.speed) && (speed != -1)) { | 798 | if (speed != self->io.speed && speed != -1) { |
| 774 | /* Check for empty frame */ | 799 | /* Check for empty frame */ |
| 775 | if (!skb->len) { | 800 | if (!skb->len) { |
| 776 | /* | 801 | /* |
| @@ -787,27 +812,26 @@ int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) | |||
| 787 | spin_unlock_irqrestore(&self->lock, flags); | 812 | spin_unlock_irqrestore(&self->lock, flags); |
| 788 | dev_kfree_skb(skb); | 813 | dev_kfree_skb(skb); |
| 789 | return 0; | 814 | return 0; |
| 790 | } else { | ||
| 791 | self->new_speed = speed; | ||
| 792 | } | 815 | } |
| 816 | self->new_speed = speed; | ||
| 793 | } | 817 | } |
| 794 | 818 | ||
| 795 | /* Init tx buffer */ | 819 | /* Init tx buffer */ |
| 796 | self->tx_buff.data = self->tx_buff.head; | 820 | self->tx_buff.data = self->tx_buff.head; |
| 797 | 821 | ||
| 798 | /* Copy skb to tx_buff while wrapping, stuffing and making CRC */ | 822 | /* Copy skb to tx_buff while wrapping, stuffing and making CRC */ |
| 799 | self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, | 823 | self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, |
| 800 | self->tx_buff.truesize); | 824 | self->tx_buff.truesize); |
| 801 | 825 | ||
| 802 | self->stats.tx_bytes += self->tx_buff.len; | 826 | self->stats.tx_bytes += self->tx_buff.len; |
| 803 | 827 | ||
| 804 | /* Turn on transmit finished interrupt. Will fire immediately! */ | 828 | /* Turn on transmit finished interrupt. Will fire immediately! */ |
| 805 | outb(UART_IER_THRI, iobase+UART_IER); | 829 | outb(UART_IER_THRI, self->io.sir_base + UART_IER); |
| 806 | 830 | ||
| 807 | spin_unlock_irqrestore(&self->lock, flags); | 831 | spin_unlock_irqrestore(&self->lock, flags); |
| 808 | 832 | ||
| 809 | dev_kfree_skb(skb); | 833 | dev_kfree_skb(skb); |
| 810 | 834 | ||
| 811 | return 0; | 835 | return 0; |
| 812 | } | 836 | } |
| 813 | 837 | ||
| @@ -826,9 +850,9 @@ static void smsc_ircc_set_fir_speed(struct smsc_ircc_cb *self, u32 speed) | |||
| 826 | 850 | ||
| 827 | self->io.speed = speed; | 851 | self->io.speed = speed; |
| 828 | 852 | ||
| 829 | switch(speed) { | 853 | switch (speed) { |
| 830 | default: | 854 | default: |
| 831 | case 576000: | 855 | case 576000: |
| 832 | ir_mode = IRCC_CFGA_IRDA_HDLC; | 856 | ir_mode = IRCC_CFGA_IRDA_HDLC; |
| 833 | ctrl = IRCC_CRC; | 857 | ctrl = IRCC_CRC; |
| 834 | fast = 0; | 858 | fast = 0; |
| @@ -853,14 +877,14 @@ static void smsc_ircc_set_fir_speed(struct smsc_ircc_cb *self, u32 speed) | |||
| 853 | Now in tranceiver! | 877 | Now in tranceiver! |
| 854 | /* This causes an interrupt */ | 878 | /* This causes an interrupt */ |
| 855 | register_bank(fir_base, 0); | 879 | register_bank(fir_base, 0); |
| 856 | outb((inb(fir_base+IRCC_LCR_A) & 0xbf) | fast, fir_base+IRCC_LCR_A); | 880 | outb((inb(fir_base + IRCC_LCR_A) & 0xbf) | fast, fir_base + IRCC_LCR_A); |
| 857 | #endif | 881 | #endif |
| 858 | 882 | ||
| 859 | register_bank(fir_base, 1); | 883 | register_bank(fir_base, 1); |
| 860 | outb(((inb(fir_base+IRCC_SCE_CFGA) & IRCC_SCE_CFGA_BLOCK_CTRL_BITS_MASK) | ir_mode), fir_base+IRCC_SCE_CFGA); | 884 | outb(((inb(fir_base + IRCC_SCE_CFGA) & IRCC_SCE_CFGA_BLOCK_CTRL_BITS_MASK) | ir_mode), fir_base + IRCC_SCE_CFGA); |
| 861 | 885 | ||
| 862 | register_bank(fir_base, 4); | 886 | register_bank(fir_base, 4); |
| 863 | outb((inb(fir_base+IRCC_CONTROL) & 0x30) | ctrl, fir_base+IRCC_CONTROL); | 887 | outb((inb(fir_base + IRCC_CONTROL) & 0x30) | ctrl, fir_base + IRCC_CONTROL); |
| 864 | } | 888 | } |
| 865 | 889 | ||
| 866 | /* | 890 | /* |
| @@ -885,31 +909,31 @@ static void smsc_ircc_fir_start(struct smsc_ircc_cb *self) | |||
| 885 | /* Reset everything */ | 909 | /* Reset everything */ |
| 886 | 910 | ||
| 887 | /* Install FIR transmit handler */ | 911 | /* Install FIR transmit handler */ |
| 888 | dev->hard_start_xmit = smsc_ircc_hard_xmit_fir; | 912 | dev->hard_start_xmit = smsc_ircc_hard_xmit_fir; |
| 889 | 913 | ||
| 890 | /* Clear FIFO */ | 914 | /* Clear FIFO */ |
| 891 | outb(inb(fir_base+IRCC_LCR_A)|IRCC_LCR_A_FIFO_RESET, fir_base+IRCC_LCR_A); | 915 | outb(inb(fir_base + IRCC_LCR_A) | IRCC_LCR_A_FIFO_RESET, fir_base + IRCC_LCR_A); |
| 892 | 916 | ||
| 893 | /* Enable interrupt */ | 917 | /* Enable interrupt */ |
| 894 | /*outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, fir_base+IRCC_IER);*/ | 918 | /*outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, fir_base + IRCC_IER);*/ |
| 895 | 919 | ||
| 896 | register_bank(fir_base, 1); | 920 | register_bank(fir_base, 1); |
| 897 | 921 | ||
| 898 | /* Select the TX/RX interface */ | 922 | /* Select the TX/RX interface */ |
| 899 | #ifdef SMSC_669 /* Uses pin 88/89 for Rx/Tx */ | 923 | #ifdef SMSC_669 /* Uses pin 88/89 for Rx/Tx */ |
| 900 | outb(((inb(fir_base+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_COM), | 924 | outb(((inb(fir_base + IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_COM), |
| 901 | fir_base+IRCC_SCE_CFGB); | 925 | fir_base + IRCC_SCE_CFGB); |
| 902 | #else | 926 | #else |
| 903 | outb(((inb(fir_base+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_IR), | 927 | outb(((inb(fir_base + IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_IR), |
| 904 | fir_base+IRCC_SCE_CFGB); | 928 | fir_base + IRCC_SCE_CFGB); |
| 905 | #endif | 929 | #endif |
| 906 | (void) inb(fir_base+IRCC_FIFO_THRESHOLD); | 930 | (void) inb(fir_base + IRCC_FIFO_THRESHOLD); |
| 907 | 931 | ||
| 908 | /* Enable SCE interrupts */ | 932 | /* Enable SCE interrupts */ |
| 909 | outb(0, fir_base+IRCC_MASTER); | 933 | outb(0, fir_base + IRCC_MASTER); |
| 910 | register_bank(fir_base, 0); | 934 | register_bank(fir_base, 0); |
| 911 | outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, fir_base+IRCC_IER); | 935 | outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, fir_base + IRCC_IER); |
| 912 | outb(IRCC_MASTER_INT_EN, fir_base+IRCC_MASTER); | 936 | outb(IRCC_MASTER_INT_EN, fir_base + IRCC_MASTER); |
| 913 | } | 937 | } |
| 914 | 938 | ||
| 915 | /* | 939 | /* |
| @@ -923,13 +947,13 @@ static void smsc_ircc_fir_stop(struct smsc_ircc_cb *self) | |||
| 923 | int fir_base; | 947 | int fir_base; |
| 924 | 948 | ||
| 925 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 949 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 926 | 950 | ||
| 927 | IRDA_ASSERT(self != NULL, return;); | 951 | IRDA_ASSERT(self != NULL, return;); |
| 928 | 952 | ||
| 929 | fir_base = self->io.fir_base; | 953 | fir_base = self->io.fir_base; |
| 930 | register_bank(fir_base, 0); | 954 | register_bank(fir_base, 0); |
| 931 | /*outb(IRCC_MASTER_RESET, fir_base+IRCC_MASTER);*/ | 955 | /*outb(IRCC_MASTER_RESET, fir_base + IRCC_MASTER);*/ |
| 932 | outb(inb(fir_base+IRCC_LCR_B) & IRCC_LCR_B_SIP_ENABLE, fir_base+IRCC_LCR_B); | 956 | outb(inb(fir_base + IRCC_LCR_B) & IRCC_LCR_B_SIP_ENABLE, fir_base + IRCC_LCR_B); |
| 933 | } | 957 | } |
| 934 | 958 | ||
| 935 | 959 | ||
| @@ -941,18 +965,15 @@ static void smsc_ircc_fir_stop(struct smsc_ircc_cb *self) | |||
| 941 | * This function *must* be called with spinlock held, because it may | 965 | * This function *must* be called with spinlock held, because it may |
| 942 | * be called from the irq handler. - Jean II | 966 | * be called from the irq handler. - Jean II |
| 943 | */ | 967 | */ |
| 944 | static void smsc_ircc_change_speed(void *priv, u32 speed) | 968 | static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed) |
| 945 | { | 969 | { |
| 946 | struct smsc_ircc_cb *self = (struct smsc_ircc_cb *) priv; | ||
| 947 | struct net_device *dev; | 970 | struct net_device *dev; |
| 948 | int iobase; | ||
| 949 | int last_speed_was_sir; | 971 | int last_speed_was_sir; |
| 950 | 972 | ||
| 951 | IRDA_DEBUG(0, "%s() changing speed to: %d\n", __FUNCTION__, speed); | 973 | IRDA_DEBUG(0, "%s() changing speed to: %d\n", __FUNCTION__, speed); |
| 952 | 974 | ||
| 953 | IRDA_ASSERT(self != NULL, return;); | 975 | IRDA_ASSERT(self != NULL, return;); |
| 954 | dev = self->netdev; | 976 | dev = self->netdev; |
| 955 | iobase = self->io.fir_base; | ||
| 956 | 977 | ||
| 957 | last_speed_was_sir = self->io.speed <= SMSC_IRCC2_MAX_SIR_SPEED; | 978 | last_speed_was_sir = self->io.speed <= SMSC_IRCC2_MAX_SIR_SPEED; |
| 958 | 979 | ||
| @@ -961,30 +982,30 @@ static void smsc_ircc_change_speed(void *priv, u32 speed) | |||
| 961 | speed= 1152000; | 982 | speed= 1152000; |
| 962 | self->io.speed = speed; | 983 | self->io.speed = speed; |
| 963 | last_speed_was_sir = 0; | 984 | last_speed_was_sir = 0; |
| 964 | smsc_ircc_fir_start(self); | 985 | smsc_ircc_fir_start(self); |
| 965 | #endif | 986 | #endif |
| 966 | 987 | ||
| 967 | if(self->io.speed == 0) | 988 | if (self->io.speed == 0) |
| 968 | smsc_ircc_sir_start(self); | 989 | smsc_ircc_sir_start(self); |
| 969 | 990 | ||
| 970 | #if 0 | 991 | #if 0 |
| 971 | if(!last_speed_was_sir) speed = self->io.speed; | 992 | if (!last_speed_was_sir) speed = self->io.speed; |
| 972 | #endif | 993 | #endif |
| 973 | 994 | ||
| 974 | if(self->io.speed != speed) smsc_ircc_set_transceiver_for_speed(self, speed); | 995 | if (self->io.speed != speed) |
| 996 | smsc_ircc_set_transceiver_for_speed(self, speed); | ||
| 975 | 997 | ||
| 976 | self->io.speed = speed; | 998 | self->io.speed = speed; |
| 977 | 999 | ||
| 978 | if(speed <= SMSC_IRCC2_MAX_SIR_SPEED) { | 1000 | if (speed <= SMSC_IRCC2_MAX_SIR_SPEED) { |
| 979 | if(!last_speed_was_sir) { | 1001 | if (!last_speed_was_sir) { |
| 980 | smsc_ircc_fir_stop(self); | 1002 | smsc_ircc_fir_stop(self); |
| 981 | smsc_ircc_sir_start(self); | 1003 | smsc_ircc_sir_start(self); |
| 982 | } | 1004 | } |
| 983 | smsc_ircc_set_sir_speed(self, speed); | 1005 | smsc_ircc_set_sir_speed(self, speed); |
| 984 | } | 1006 | } else { |
| 985 | else { | 1007 | if (last_speed_was_sir) { |
| 986 | if(last_speed_was_sir) { | 1008 | #if SMSC_IRCC2_C_SIR_STOP |
| 987 | #if SMSC_IRCC2_C_SIR_STOP | ||
| 988 | smsc_ircc_sir_stop(self); | 1009 | smsc_ircc_sir_stop(self); |
| 989 | #endif | 1010 | #endif |
| 990 | smsc_ircc_fir_start(self); | 1011 | smsc_ircc_fir_start(self); |
| @@ -994,13 +1015,13 @@ static void smsc_ircc_change_speed(void *priv, u32 speed) | |||
| 994 | #if 0 | 1015 | #if 0 |
| 995 | self->tx_buff.len = 10; | 1016 | self->tx_buff.len = 10; |
| 996 | self->tx_buff.data = self->tx_buff.head; | 1017 | self->tx_buff.data = self->tx_buff.head; |
| 997 | 1018 | ||
| 998 | smsc_ircc_dma_xmit(self, iobase, 4000); | 1019 | smsc_ircc_dma_xmit(self, 4000); |
| 999 | #endif | 1020 | #endif |
| 1000 | /* Be ready for incoming frames */ | 1021 | /* Be ready for incoming frames */ |
| 1001 | smsc_ircc_dma_receive(self, iobase); | 1022 | smsc_ircc_dma_receive(self); |
| 1002 | } | 1023 | } |
| 1003 | 1024 | ||
| 1004 | netif_wake_queue(dev); | 1025 | netif_wake_queue(dev); |
| 1005 | } | 1026 | } |
| 1006 | 1027 | ||
| @@ -1010,10 +1031,9 @@ static void smsc_ircc_change_speed(void *priv, u32 speed) | |||
| 1010 | * Set speed of IrDA port to specified baudrate | 1031 | * Set speed of IrDA port to specified baudrate |
| 1011 | * | 1032 | * |
| 1012 | */ | 1033 | */ |
| 1013 | void smsc_ircc_set_sir_speed(void *priv, __u32 speed) | 1034 | void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, __u32 speed) |
| 1014 | { | 1035 | { |
| 1015 | struct smsc_ircc_cb *self = (struct smsc_ircc_cb *) priv; | 1036 | int iobase; |
| 1016 | int iobase; | ||
| 1017 | int fcr; /* FIFO control reg */ | 1037 | int fcr; /* FIFO control reg */ |
| 1018 | int lcr; /* Line control reg */ | 1038 | int lcr; /* Line control reg */ |
| 1019 | int divisor; | 1039 | int divisor; |
| @@ -1022,38 +1042,36 @@ void smsc_ircc_set_sir_speed(void *priv, __u32 speed) | |||
| 1022 | 1042 | ||
| 1023 | IRDA_ASSERT(self != NULL, return;); | 1043 | IRDA_ASSERT(self != NULL, return;); |
| 1024 | iobase = self->io.sir_base; | 1044 | iobase = self->io.sir_base; |
| 1025 | 1045 | ||
| 1026 | /* Update accounting for new speed */ | 1046 | /* Update accounting for new speed */ |
| 1027 | self->io.speed = speed; | 1047 | self->io.speed = speed; |
| 1028 | 1048 | ||
| 1029 | /* Turn off interrupts */ | 1049 | /* Turn off interrupts */ |
| 1030 | outb(0, iobase+UART_IER); | 1050 | outb(0, iobase + UART_IER); |
| 1051 | |||
| 1052 | divisor = SMSC_IRCC2_MAX_SIR_SPEED / speed; | ||
| 1031 | 1053 | ||
| 1032 | divisor = SMSC_IRCC2_MAX_SIR_SPEED/speed; | ||
| 1033 | |||
| 1034 | fcr = UART_FCR_ENABLE_FIFO; | 1054 | fcr = UART_FCR_ENABLE_FIFO; |
| 1035 | 1055 | ||
| 1036 | /* | 1056 | /* |
| 1037 | * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and | 1057 | * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and |
| 1038 | * almost 1,7 ms at 19200 bps. At speeds above that we can just forget | 1058 | * almost 1,7 ms at 19200 bps. At speeds above that we can just forget |
| 1039 | * about this timeout since it will always be fast enough. | 1059 | * about this timeout since it will always be fast enough. |
| 1040 | */ | 1060 | */ |
| 1041 | if (self->io.speed < 38400) | 1061 | fcr |= self->io.speed < 38400 ? |
| 1042 | fcr |= UART_FCR_TRIGGER_1; | 1062 | UART_FCR_TRIGGER_1 : UART_FCR_TRIGGER_14; |
| 1043 | else | 1063 | |
| 1044 | fcr |= UART_FCR_TRIGGER_14; | ||
| 1045 | |||
| 1046 | /* IrDA ports use 8N1 */ | 1064 | /* IrDA ports use 8N1 */ |
| 1047 | lcr = UART_LCR_WLEN8; | 1065 | lcr = UART_LCR_WLEN8; |
| 1048 | 1066 | ||
| 1049 | outb(UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */ | 1067 | outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */ |
| 1050 | outb(divisor & 0xff, iobase+UART_DLL); /* Set speed */ | 1068 | outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */ |
| 1051 | outb(divisor >> 8, iobase+UART_DLM); | 1069 | outb(divisor >> 8, iobase + UART_DLM); |
| 1052 | outb(lcr, iobase+UART_LCR); /* Set 8N1 */ | 1070 | outb(lcr, iobase + UART_LCR); /* Set 8N1 */ |
| 1053 | outb(fcr, iobase+UART_FCR); /* Enable FIFO's */ | 1071 | outb(fcr, iobase + UART_FCR); /* Enable FIFO's */ |
| 1054 | 1072 | ||
| 1055 | /* Turn on interrups */ | 1073 | /* Turn on interrups */ |
| 1056 | outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, iobase+UART_IER); | 1074 | outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER); |
| 1057 | 1075 | ||
| 1058 | IRDA_DEBUG(2, "%s() speed changed to: %d\n", __FUNCTION__, speed); | 1076 | IRDA_DEBUG(2, "%s() speed changed to: %d\n", __FUNCTION__, speed); |
| 1059 | } | 1077 | } |
| @@ -1070,15 +1088,12 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) | |||
| 1070 | struct smsc_ircc_cb *self; | 1088 | struct smsc_ircc_cb *self; |
| 1071 | unsigned long flags; | 1089 | unsigned long flags; |
| 1072 | s32 speed; | 1090 | s32 speed; |
| 1073 | int iobase; | ||
| 1074 | int mtt; | 1091 | int mtt; |
| 1075 | 1092 | ||
| 1076 | IRDA_ASSERT(dev != NULL, return 0;); | 1093 | IRDA_ASSERT(dev != NULL, return 0;); |
| 1077 | self = (struct smsc_ircc_cb *) dev->priv; | 1094 | self = netdev_priv(dev); |
| 1078 | IRDA_ASSERT(self != NULL, return 0;); | 1095 | IRDA_ASSERT(self != NULL, return 0;); |
| 1079 | 1096 | ||
| 1080 | iobase = self->io.fir_base; | ||
| 1081 | |||
| 1082 | netif_stop_queue(dev); | 1097 | netif_stop_queue(dev); |
| 1083 | 1098 | ||
| 1084 | /* Make sure test of self->io.speed & speed change are atomic */ | 1099 | /* Make sure test of self->io.speed & speed change are atomic */ |
| @@ -1086,30 +1101,31 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) | |||
| 1086 | 1101 | ||
| 1087 | /* Check if we need to change the speed after this frame */ | 1102 | /* Check if we need to change the speed after this frame */ |
| 1088 | speed = irda_get_next_speed(skb); | 1103 | speed = irda_get_next_speed(skb); |
| 1089 | if ((speed != self->io.speed) && (speed != -1)) { | 1104 | if (speed != self->io.speed && speed != -1) { |
| 1090 | /* Check for empty frame */ | 1105 | /* Check for empty frame */ |
| 1091 | if (!skb->len) { | 1106 | if (!skb->len) { |
| 1092 | /* Note : you should make sure that speed changes | 1107 | /* Note : you should make sure that speed changes |
| 1093 | * are not going to corrupt any outgoing frame. | 1108 | * are not going to corrupt any outgoing frame. |
| 1094 | * Look at nsc-ircc for the gory details - Jean II */ | 1109 | * Look at nsc-ircc for the gory details - Jean II */ |
| 1095 | smsc_ircc_change_speed(self, speed); | 1110 | smsc_ircc_change_speed(self, speed); |
| 1096 | spin_unlock_irqrestore(&self->lock, flags); | 1111 | spin_unlock_irqrestore(&self->lock, flags); |
| 1097 | dev_kfree_skb(skb); | 1112 | dev_kfree_skb(skb); |
| 1098 | return 0; | 1113 | return 0; |
| 1099 | } else | 1114 | } |
| 1100 | self->new_speed = speed; | 1115 | |
| 1116 | self->new_speed = speed; | ||
| 1101 | } | 1117 | } |
| 1102 | 1118 | ||
| 1103 | memcpy(self->tx_buff.head, skb->data, skb->len); | 1119 | memcpy(self->tx_buff.head, skb->data, skb->len); |
| 1104 | 1120 | ||
| 1105 | self->tx_buff.len = skb->len; | 1121 | self->tx_buff.len = skb->len; |
| 1106 | self->tx_buff.data = self->tx_buff.head; | 1122 | self->tx_buff.data = self->tx_buff.head; |
| 1107 | 1123 | ||
| 1108 | mtt = irda_get_mtt(skb); | 1124 | mtt = irda_get_mtt(skb); |
| 1109 | if (mtt) { | 1125 | if (mtt) { |
| 1110 | int bofs; | 1126 | int bofs; |
| 1111 | 1127 | ||
| 1112 | /* | 1128 | /* |
| 1113 | * Compute how many BOFs (STA or PA's) we need to waste the | 1129 | * Compute how many BOFs (STA or PA's) we need to waste the |
| 1114 | * min turn time given the speed of the link. | 1130 | * min turn time given the speed of the link. |
| 1115 | */ | 1131 | */ |
| @@ -1117,11 +1133,12 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) | |||
| 1117 | if (bofs > 4095) | 1133 | if (bofs > 4095) |
| 1118 | bofs = 4095; | 1134 | bofs = 4095; |
| 1119 | 1135 | ||
| 1120 | smsc_ircc_dma_xmit(self, iobase, bofs); | 1136 | smsc_ircc_dma_xmit(self, bofs); |
| 1121 | } else { | 1137 | } else { |
| 1122 | /* Transmit frame */ | 1138 | /* Transmit frame */ |
| 1123 | smsc_ircc_dma_xmit(self, iobase, 0); | 1139 | smsc_ircc_dma_xmit(self, 0); |
| 1124 | } | 1140 | } |
| 1141 | |||
| 1125 | spin_unlock_irqrestore(&self->lock, flags); | 1142 | spin_unlock_irqrestore(&self->lock, flags); |
| 1126 | dev_kfree_skb(skb); | 1143 | dev_kfree_skb(skb); |
| 1127 | 1144 | ||
| @@ -1129,43 +1146,44 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) | |||
| 1129 | } | 1146 | } |
| 1130 | 1147 | ||
| 1131 | /* | 1148 | /* |
| 1132 | * Function smsc_ircc_dma_xmit (self, iobase) | 1149 | * Function smsc_ircc_dma_xmit (self, bofs) |
| 1133 | * | 1150 | * |
| 1134 | * Transmit data using DMA | 1151 | * Transmit data using DMA |
| 1135 | * | 1152 | * |
| 1136 | */ | 1153 | */ |
| 1137 | static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int iobase, int bofs) | 1154 | static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs) |
| 1138 | { | 1155 | { |
| 1156 | int iobase = self->io.fir_base; | ||
| 1139 | u8 ctrl; | 1157 | u8 ctrl; |
| 1140 | 1158 | ||
| 1141 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); | 1159 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); |
| 1142 | #if 1 | 1160 | #if 1 |
| 1143 | /* Disable Rx */ | 1161 | /* Disable Rx */ |
| 1144 | register_bank(iobase, 0); | 1162 | register_bank(iobase, 0); |
| 1145 | outb(0x00, iobase+IRCC_LCR_B); | 1163 | outb(0x00, iobase + IRCC_LCR_B); |
| 1146 | #endif | 1164 | #endif |
| 1147 | register_bank(iobase, 1); | 1165 | register_bank(iobase, 1); |
| 1148 | outb(inb(iobase+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, | 1166 | outb(inb(iobase + IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, |
| 1149 | iobase+IRCC_SCE_CFGB); | 1167 | iobase + IRCC_SCE_CFGB); |
| 1150 | 1168 | ||
| 1151 | self->io.direction = IO_XMIT; | 1169 | self->io.direction = IO_XMIT; |
| 1152 | 1170 | ||
| 1153 | /* Set BOF additional count for generating the min turn time */ | 1171 | /* Set BOF additional count for generating the min turn time */ |
| 1154 | register_bank(iobase, 4); | 1172 | register_bank(iobase, 4); |
| 1155 | outb(bofs & 0xff, iobase+IRCC_BOF_COUNT_LO); | 1173 | outb(bofs & 0xff, iobase + IRCC_BOF_COUNT_LO); |
| 1156 | ctrl = inb(iobase+IRCC_CONTROL) & 0xf0; | 1174 | ctrl = inb(iobase + IRCC_CONTROL) & 0xf0; |
| 1157 | outb(ctrl | ((bofs >> 8) & 0x0f), iobase+IRCC_BOF_COUNT_HI); | 1175 | outb(ctrl | ((bofs >> 8) & 0x0f), iobase + IRCC_BOF_COUNT_HI); |
| 1158 | 1176 | ||
| 1159 | /* Set max Tx frame size */ | 1177 | /* Set max Tx frame size */ |
| 1160 | outb(self->tx_buff.len >> 8, iobase+IRCC_TX_SIZE_HI); | 1178 | outb(self->tx_buff.len >> 8, iobase + IRCC_TX_SIZE_HI); |
| 1161 | outb(self->tx_buff.len & 0xff, iobase+IRCC_TX_SIZE_LO); | 1179 | outb(self->tx_buff.len & 0xff, iobase + IRCC_TX_SIZE_LO); |
| 1162 | 1180 | ||
| 1163 | /*outb(UART_MCR_OUT2, self->io.sir_base + UART_MCR);*/ | 1181 | /*outb(UART_MCR_OUT2, self->io.sir_base + UART_MCR);*/ |
| 1164 | 1182 | ||
| 1165 | /* Enable burst mode chip Tx DMA */ | 1183 | /* Enable burst mode chip Tx DMA */ |
| 1166 | register_bank(iobase, 1); | 1184 | register_bank(iobase, 1); |
| 1167 | outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE | | 1185 | outb(inb(iobase + IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE | |
| 1168 | IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB); | 1186 | IRCC_CFGB_DMA_BURST, iobase + IRCC_SCE_CFGB); |
| 1169 | 1187 | ||
| 1170 | /* Setup DMA controller (must be done after enabling chip DMA) */ | 1188 | /* Setup DMA controller (must be done after enabling chip DMA) */ |
| 1171 | irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len, | 1189 | irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len, |
| @@ -1174,50 +1192,52 @@ static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int iobase, int bofs) | |||
| 1174 | /* Enable interrupt */ | 1192 | /* Enable interrupt */ |
| 1175 | 1193 | ||
| 1176 | register_bank(iobase, 0); | 1194 | register_bank(iobase, 0); |
| 1177 | outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase+IRCC_IER); | 1195 | outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase + IRCC_IER); |
| 1178 | outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER); | 1196 | outb(IRCC_MASTER_INT_EN, iobase + IRCC_MASTER); |
| 1179 | 1197 | ||
| 1180 | /* Enable transmit */ | 1198 | /* Enable transmit */ |
| 1181 | outb(IRCC_LCR_B_SCE_TRANSMIT | IRCC_LCR_B_SIP_ENABLE, iobase+IRCC_LCR_B); | 1199 | outb(IRCC_LCR_B_SCE_TRANSMIT | IRCC_LCR_B_SIP_ENABLE, iobase + IRCC_LCR_B); |
| 1182 | } | 1200 | } |
| 1183 | 1201 | ||
| 1184 | /* | 1202 | /* |
| 1185 | * Function smsc_ircc_dma_xmit_complete (self) | 1203 | * Function smsc_ircc_dma_xmit_complete (self) |
| 1186 | * | 1204 | * |
| 1187 | * The transfer of a frame in finished. This function will only be called | 1205 | * The transfer of a frame in finished. This function will only be called |
| 1188 | * by the interrupt handler | 1206 | * by the interrupt handler |
| 1189 | * | 1207 | * |
| 1190 | */ | 1208 | */ |
| 1191 | static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self, int iobase) | 1209 | static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self) |
| 1192 | { | 1210 | { |
| 1211 | int iobase = self->io.fir_base; | ||
| 1212 | |||
| 1193 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); | 1213 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); |
| 1194 | #if 0 | 1214 | #if 0 |
| 1195 | /* Disable Tx */ | 1215 | /* Disable Tx */ |
| 1196 | register_bank(iobase, 0); | 1216 | register_bank(iobase, 0); |
| 1197 | outb(0x00, iobase+IRCC_LCR_B); | 1217 | outb(0x00, iobase + IRCC_LCR_B); |
| 1198 | #endif | 1218 | #endif |
| 1199 | register_bank(self->io.fir_base, 1); | 1219 | register_bank(iobase, 1); |
| 1200 | outb(inb(self->io.fir_base+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, | 1220 | outb(inb(iobase + IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, |
| 1201 | self->io.fir_base+IRCC_SCE_CFGB); | 1221 | iobase + IRCC_SCE_CFGB); |
| 1202 | 1222 | ||
| 1203 | /* Check for underrun! */ | 1223 | /* Check for underrun! */ |
| 1204 | register_bank(iobase, 0); | 1224 | register_bank(iobase, 0); |
| 1205 | if (inb(iobase+IRCC_LSR) & IRCC_LSR_UNDERRUN) { | 1225 | if (inb(iobase + IRCC_LSR) & IRCC_LSR_UNDERRUN) { |
| 1206 | self->stats.tx_errors++; | 1226 | self->stats.tx_errors++; |
| 1207 | self->stats.tx_fifo_errors++; | 1227 | self->stats.tx_fifo_errors++; |
| 1208 | 1228 | ||
| 1209 | /* Reset error condition */ | 1229 | /* Reset error condition */ |
| 1210 | register_bank(iobase, 0); | 1230 | register_bank(iobase, 0); |
| 1211 | outb(IRCC_MASTER_ERROR_RESET, iobase+IRCC_MASTER); | 1231 | outb(IRCC_MASTER_ERROR_RESET, iobase + IRCC_MASTER); |
| 1212 | outb(0x00, iobase+IRCC_MASTER); | 1232 | outb(0x00, iobase + IRCC_MASTER); |
| 1213 | } else { | 1233 | } else { |
| 1214 | self->stats.tx_packets++; | 1234 | self->stats.tx_packets++; |
| 1215 | self->stats.tx_bytes += self->tx_buff.len; | 1235 | self->stats.tx_bytes += self->tx_buff.len; |
| 1216 | } | 1236 | } |
| 1217 | 1237 | ||
| 1218 | /* Check if it's time to change the speed */ | 1238 | /* Check if it's time to change the speed */ |
| 1219 | if (self->new_speed) { | 1239 | if (self->new_speed) { |
| 1220 | smsc_ircc_change_speed(self, self->new_speed); | 1240 | smsc_ircc_change_speed(self, self->new_speed); |
| 1221 | self->new_speed = 0; | 1241 | self->new_speed = 0; |
| 1222 | } | 1242 | } |
| 1223 | 1243 | ||
| @@ -1231,31 +1251,32 @@ static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self, int iobase) | |||
| 1231 | * if it starts to receive a frame. | 1251 | * if it starts to receive a frame. |
| 1232 | * | 1252 | * |
| 1233 | */ | 1253 | */ |
| 1234 | static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase) | 1254 | static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self) |
| 1235 | { | 1255 | { |
| 1256 | int iobase = self->io.fir_base; | ||
| 1236 | #if 0 | 1257 | #if 0 |
| 1237 | /* Turn off chip DMA */ | 1258 | /* Turn off chip DMA */ |
| 1238 | register_bank(iobase, 1); | 1259 | register_bank(iobase, 1); |
| 1239 | outb(inb(iobase+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, | 1260 | outb(inb(iobase + IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, |
| 1240 | iobase+IRCC_SCE_CFGB); | 1261 | iobase + IRCC_SCE_CFGB); |
| 1241 | #endif | 1262 | #endif |
| 1242 | 1263 | ||
| 1243 | /* Disable Tx */ | 1264 | /* Disable Tx */ |
| 1244 | register_bank(iobase, 0); | 1265 | register_bank(iobase, 0); |
| 1245 | outb(0x00, iobase+IRCC_LCR_B); | 1266 | outb(0x00, iobase + IRCC_LCR_B); |
| 1246 | 1267 | ||
| 1247 | /* Turn off chip DMA */ | 1268 | /* Turn off chip DMA */ |
| 1248 | register_bank(iobase, 1); | 1269 | register_bank(iobase, 1); |
| 1249 | outb(inb(iobase+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, | 1270 | outb(inb(iobase + IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, |
| 1250 | iobase+IRCC_SCE_CFGB); | 1271 | iobase + IRCC_SCE_CFGB); |
| 1251 | 1272 | ||
| 1252 | self->io.direction = IO_RECV; | 1273 | self->io.direction = IO_RECV; |
| 1253 | self->rx_buff.data = self->rx_buff.head; | 1274 | self->rx_buff.data = self->rx_buff.head; |
| 1254 | 1275 | ||
| 1255 | /* Set max Rx frame size */ | 1276 | /* Set max Rx frame size */ |
| 1256 | register_bank(iobase, 4); | 1277 | register_bank(iobase, 4); |
| 1257 | outb((2050 >> 8) & 0x0f, iobase+IRCC_RX_SIZE_HI); | 1278 | outb((2050 >> 8) & 0x0f, iobase + IRCC_RX_SIZE_HI); |
| 1258 | outb(2050 & 0xff, iobase+IRCC_RX_SIZE_LO); | 1279 | outb(2050 & 0xff, iobase + IRCC_RX_SIZE_LO); |
| 1259 | 1280 | ||
| 1260 | /* Setup DMA controller */ | 1281 | /* Setup DMA controller */ |
| 1261 | irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize, | 1282 | irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize, |
| @@ -1263,83 +1284,83 @@ static int smsc_ircc_dma_receive(struct smsc_ircc_cb *self, int iobase) | |||
| 1263 | 1284 | ||
| 1264 | /* Enable burst mode chip Rx DMA */ | 1285 | /* Enable burst mode chip Rx DMA */ |
| 1265 | register_bank(iobase, 1); | 1286 | register_bank(iobase, 1); |
| 1266 | outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE | | 1287 | outb(inb(iobase + IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE | |
| 1267 | IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB); | 1288 | IRCC_CFGB_DMA_BURST, iobase + IRCC_SCE_CFGB); |
| 1268 | 1289 | ||
| 1269 | /* Enable interrupt */ | 1290 | /* Enable interrupt */ |
| 1270 | register_bank(iobase, 0); | 1291 | register_bank(iobase, 0); |
| 1271 | outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase+IRCC_IER); | 1292 | outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase + IRCC_IER); |
| 1272 | outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER); | 1293 | outb(IRCC_MASTER_INT_EN, iobase + IRCC_MASTER); |
| 1273 | |||
| 1274 | 1294 | ||
| 1275 | /* Enable receiver */ | 1295 | /* Enable receiver */ |
| 1276 | register_bank(iobase, 0); | 1296 | register_bank(iobase, 0); |
| 1277 | outb(IRCC_LCR_B_SCE_RECEIVE | IRCC_LCR_B_SIP_ENABLE, | 1297 | outb(IRCC_LCR_B_SCE_RECEIVE | IRCC_LCR_B_SIP_ENABLE, |
| 1278 | iobase+IRCC_LCR_B); | 1298 | iobase + IRCC_LCR_B); |
| 1279 | 1299 | ||
| 1280 | return 0; | 1300 | return 0; |
| 1281 | } | 1301 | } |
| 1282 | 1302 | ||
| 1283 | /* | 1303 | /* |
| 1284 | * Function smsc_ircc_dma_receive_complete(self, iobase) | 1304 | * Function smsc_ircc_dma_receive_complete(self) |
| 1285 | * | 1305 | * |
| 1286 | * Finished with receiving frames | 1306 | * Finished with receiving frames |
| 1287 | * | 1307 | * |
| 1288 | */ | 1308 | */ |
| 1289 | static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self, int iobase) | 1309 | static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self) |
| 1290 | { | 1310 | { |
| 1291 | struct sk_buff *skb; | 1311 | struct sk_buff *skb; |
| 1292 | int len, msgcnt, lsr; | 1312 | int len, msgcnt, lsr; |
| 1293 | 1313 | int iobase = self->io.fir_base; | |
| 1314 | |||
| 1294 | register_bank(iobase, 0); | 1315 | register_bank(iobase, 0); |
| 1295 | 1316 | ||
| 1296 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); | 1317 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); |
| 1297 | #if 0 | 1318 | #if 0 |
| 1298 | /* Disable Rx */ | 1319 | /* Disable Rx */ |
| 1299 | register_bank(iobase, 0); | 1320 | register_bank(iobase, 0); |
| 1300 | outb(0x00, iobase+IRCC_LCR_B); | 1321 | outb(0x00, iobase + IRCC_LCR_B); |
| 1301 | #endif | 1322 | #endif |
| 1302 | register_bank(iobase, 0); | 1323 | register_bank(iobase, 0); |
| 1303 | outb(inb(iobase+IRCC_LSAR) & ~IRCC_LSAR_ADDRESS_MASK, iobase+IRCC_LSAR); | 1324 | outb(inb(iobase + IRCC_LSAR) & ~IRCC_LSAR_ADDRESS_MASK, iobase + IRCC_LSAR); |
| 1304 | lsr= inb(iobase+IRCC_LSR); | 1325 | lsr= inb(iobase + IRCC_LSR); |
| 1305 | msgcnt = inb(iobase+IRCC_LCR_B) & 0x08; | 1326 | msgcnt = inb(iobase + IRCC_LCR_B) & 0x08; |
| 1306 | 1327 | ||
| 1307 | IRDA_DEBUG(2, "%s: dma count = %d\n", __FUNCTION__, | 1328 | IRDA_DEBUG(2, "%s: dma count = %d\n", __FUNCTION__, |
| 1308 | get_dma_residue(self->io.dma)); | 1329 | get_dma_residue(self->io.dma)); |
| 1309 | 1330 | ||
| 1310 | len = self->rx_buff.truesize - get_dma_residue(self->io.dma); | 1331 | len = self->rx_buff.truesize - get_dma_residue(self->io.dma); |
| 1311 | 1332 | ||
| 1312 | /* Look for errors | 1333 | /* Look for errors */ |
| 1313 | */ | 1334 | if (lsr & (IRCC_LSR_FRAME_ERROR | IRCC_LSR_CRC_ERROR | IRCC_LSR_SIZE_ERROR)) { |
| 1314 | |||
| 1315 | if(lsr & (IRCC_LSR_FRAME_ERROR | IRCC_LSR_CRC_ERROR | IRCC_LSR_SIZE_ERROR)) { | ||
| 1316 | self->stats.rx_errors++; | 1335 | self->stats.rx_errors++; |
| 1317 | if(lsr & IRCC_LSR_FRAME_ERROR) self->stats.rx_frame_errors++; | 1336 | if (lsr & IRCC_LSR_FRAME_ERROR) |
| 1318 | if(lsr & IRCC_LSR_CRC_ERROR) self->stats.rx_crc_errors++; | 1337 | self->stats.rx_frame_errors++; |
| 1319 | if(lsr & IRCC_LSR_SIZE_ERROR) self->stats.rx_length_errors++; | 1338 | if (lsr & IRCC_LSR_CRC_ERROR) |
| 1320 | if(lsr & (IRCC_LSR_UNDERRUN | IRCC_LSR_OVERRUN)) self->stats.rx_length_errors++; | 1339 | self->stats.rx_crc_errors++; |
| 1340 | if (lsr & IRCC_LSR_SIZE_ERROR) | ||
| 1341 | self->stats.rx_length_errors++; | ||
| 1342 | if (lsr & (IRCC_LSR_UNDERRUN | IRCC_LSR_OVERRUN)) | ||
| 1343 | self->stats.rx_length_errors++; | ||
| 1321 | return; | 1344 | return; |
| 1322 | } | 1345 | } |
| 1346 | |||
| 1323 | /* Remove CRC */ | 1347 | /* Remove CRC */ |
| 1324 | if (self->io.speed < 4000000) | 1348 | len -= self->io.speed < 4000000 ? 2 : 4; |
| 1325 | len -= 2; | ||
| 1326 | else | ||
| 1327 | len -= 4; | ||
| 1328 | 1349 | ||
| 1329 | if ((len < 2) || (len > 2050)) { | 1350 | if (len < 2 || len > 2050) { |
| 1330 | IRDA_WARNING("%s(), bogus len=%d\n", __FUNCTION__, len); | 1351 | IRDA_WARNING("%s(), bogus len=%d\n", __FUNCTION__, len); |
| 1331 | return; | 1352 | return; |
| 1332 | } | 1353 | } |
| 1333 | IRDA_DEBUG(2, "%s: msgcnt = %d, len=%d\n", __FUNCTION__, msgcnt, len); | 1354 | IRDA_DEBUG(2, "%s: msgcnt = %d, len=%d\n", __FUNCTION__, msgcnt, len); |
| 1334 | 1355 | ||
| 1335 | skb = dev_alloc_skb(len+1); | 1356 | skb = dev_alloc_skb(len + 1); |
| 1336 | if (!skb) { | 1357 | if (!skb) { |
| 1337 | IRDA_WARNING("%s(), memory squeeze, dropping frame.\n", | 1358 | IRDA_WARNING("%s(), memory squeeze, dropping frame.\n", |
| 1338 | __FUNCTION__); | 1359 | __FUNCTION__); |
| 1339 | return; | 1360 | return; |
| 1340 | } | 1361 | } |
| 1341 | /* Make sure IP header gets aligned */ | 1362 | /* Make sure IP header gets aligned */ |
| 1342 | skb_reserve(skb, 1); | 1363 | skb_reserve(skb, 1); |
| 1343 | 1364 | ||
| 1344 | memcpy(skb_put(skb, len), self->rx_buff.data, len); | 1365 | memcpy(skb_put(skb, len), self->rx_buff.data, len); |
| 1345 | self->stats.rx_packets++; | 1366 | self->stats.rx_packets++; |
| @@ -1357,7 +1378,7 @@ static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self, int iobase | |||
| 1357 | * Receive one frame from the infrared port | 1378 | * Receive one frame from the infrared port |
| 1358 | * | 1379 | * |
| 1359 | */ | 1380 | */ |
| 1360 | static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) | 1381 | static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) |
| 1361 | { | 1382 | { |
| 1362 | int boguscount = 0; | 1383 | int boguscount = 0; |
| 1363 | int iobase; | 1384 | int iobase; |
| @@ -1366,20 +1387,20 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) | |||
| 1366 | 1387 | ||
| 1367 | iobase = self->io.sir_base; | 1388 | iobase = self->io.sir_base; |
| 1368 | 1389 | ||
| 1369 | /* | 1390 | /* |
| 1370 | * Receive all characters in Rx FIFO, unwrap and unstuff them. | 1391 | * Receive all characters in Rx FIFO, unwrap and unstuff them. |
| 1371 | * async_unwrap_char will deliver all found frames | 1392 | * async_unwrap_char will deliver all found frames |
| 1372 | */ | 1393 | */ |
| 1373 | do { | 1394 | do { |
| 1374 | async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, | 1395 | async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, |
| 1375 | inb(iobase+UART_RX)); | 1396 | inb(iobase + UART_RX)); |
| 1376 | 1397 | ||
| 1377 | /* Make sure we don't stay here to long */ | 1398 | /* Make sure we don't stay here to long */ |
| 1378 | if (boguscount++ > 32) { | 1399 | if (boguscount++ > 32) { |
| 1379 | IRDA_DEBUG(2, "%s(), breaking!\n", __FUNCTION__); | 1400 | IRDA_DEBUG(2, "%s(), breaking!\n", __FUNCTION__); |
| 1380 | break; | 1401 | break; |
| 1381 | } | 1402 | } |
| 1382 | } while (inb(iobase+UART_LSR) & UART_LSR_DR); | 1403 | } while (inb(iobase + UART_LSR) & UART_LSR_DR); |
| 1383 | } | 1404 | } |
| 1384 | 1405 | ||
| 1385 | 1406 | ||
| @@ -1397,18 +1418,19 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re | |||
| 1397 | irqreturn_t ret = IRQ_NONE; | 1418 | irqreturn_t ret = IRQ_NONE; |
| 1398 | 1419 | ||
| 1399 | if (dev == NULL) { | 1420 | if (dev == NULL) { |
| 1400 | printk(KERN_WARNING "%s: irq %d for unknown device.\n", | 1421 | printk(KERN_WARNING "%s: irq %d for unknown device.\n", |
| 1401 | driver_name, irq); | 1422 | driver_name, irq); |
| 1402 | goto irq_ret; | 1423 | goto irq_ret; |
| 1403 | } | 1424 | } |
| 1404 | self = (struct smsc_ircc_cb *) dev->priv; | 1425 | |
| 1426 | self = netdev_priv(dev); | ||
| 1405 | IRDA_ASSERT(self != NULL, return IRQ_NONE;); | 1427 | IRDA_ASSERT(self != NULL, return IRQ_NONE;); |
| 1406 | 1428 | ||
| 1407 | /* Serialise the interrupt handler in various CPUs, stop Tx path */ | 1429 | /* Serialise the interrupt handler in various CPUs, stop Tx path */ |
| 1408 | spin_lock(&self->lock); | 1430 | spin_lock(&self->lock); |
| 1409 | 1431 | ||
| 1410 | /* Check if we should use the SIR interrupt handler */ | 1432 | /* Check if we should use the SIR interrupt handler */ |
| 1411 | if (self->io.speed <= SMSC_IRCC2_MAX_SIR_SPEED) { | 1433 | if (self->io.speed <= SMSC_IRCC2_MAX_SIR_SPEED) { |
| 1412 | ret = smsc_ircc_interrupt_sir(dev); | 1434 | ret = smsc_ircc_interrupt_sir(dev); |
| 1413 | goto irq_ret_unlock; | 1435 | goto irq_ret_unlock; |
| 1414 | } | 1436 | } |
| @@ -1416,25 +1438,25 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re | |||
| 1416 | iobase = self->io.fir_base; | 1438 | iobase = self->io.fir_base; |
| 1417 | 1439 | ||
| 1418 | register_bank(iobase, 0); | 1440 | register_bank(iobase, 0); |
| 1419 | iir = inb(iobase+IRCC_IIR); | 1441 | iir = inb(iobase + IRCC_IIR); |
| 1420 | if (iir == 0) | 1442 | if (iir == 0) |
| 1421 | goto irq_ret_unlock; | 1443 | goto irq_ret_unlock; |
| 1422 | ret = IRQ_HANDLED; | 1444 | ret = IRQ_HANDLED; |
| 1423 | 1445 | ||
| 1424 | /* Disable interrupts */ | 1446 | /* Disable interrupts */ |
| 1425 | outb(0, iobase+IRCC_IER); | 1447 | outb(0, iobase + IRCC_IER); |
| 1426 | lcra = inb(iobase+IRCC_LCR_A); | 1448 | lcra = inb(iobase + IRCC_LCR_A); |
| 1427 | lsr = inb(iobase+IRCC_LSR); | 1449 | lsr = inb(iobase + IRCC_LSR); |
| 1428 | 1450 | ||
| 1429 | IRDA_DEBUG(2, "%s(), iir = 0x%02x\n", __FUNCTION__, iir); | 1451 | IRDA_DEBUG(2, "%s(), iir = 0x%02x\n", __FUNCTION__, iir); |
| 1430 | 1452 | ||
| 1431 | if (iir & IRCC_IIR_EOM) { | 1453 | if (iir & IRCC_IIR_EOM) { |
| 1432 | if (self->io.direction == IO_RECV) | 1454 | if (self->io.direction == IO_RECV) |
| 1433 | smsc_ircc_dma_receive_complete(self, iobase); | 1455 | smsc_ircc_dma_receive_complete(self); |
| 1434 | else | 1456 | else |
| 1435 | smsc_ircc_dma_xmit_complete(self, iobase); | 1457 | smsc_ircc_dma_xmit_complete(self); |
| 1436 | 1458 | ||
| 1437 | smsc_ircc_dma_receive(self, iobase); | 1459 | smsc_ircc_dma_receive(self); |
| 1438 | } | 1460 | } |
| 1439 | 1461 | ||
| 1440 | if (iir & IRCC_IIR_ACTIVE_FRAME) { | 1462 | if (iir & IRCC_IIR_ACTIVE_FRAME) { |
| @@ -1444,7 +1466,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re | |||
| 1444 | /* Enable interrupts again */ | 1466 | /* Enable interrupts again */ |
| 1445 | 1467 | ||
| 1446 | register_bank(iobase, 0); | 1468 | register_bank(iobase, 0); |
| 1447 | outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, iobase+IRCC_IER); | 1469 | outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase + IRCC_IER); |
| 1448 | 1470 | ||
| 1449 | irq_ret_unlock: | 1471 | irq_ret_unlock: |
| 1450 | spin_unlock(&self->lock); | 1472 | spin_unlock(&self->lock); |
| @@ -1459,7 +1481,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re | |||
| 1459 | */ | 1481 | */ |
| 1460 | static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) | 1482 | static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) |
| 1461 | { | 1483 | { |
| 1462 | struct smsc_ircc_cb *self = dev->priv; | 1484 | struct smsc_ircc_cb *self = netdev_priv(dev); |
| 1463 | int boguscount = 0; | 1485 | int boguscount = 0; |
| 1464 | int iobase; | 1486 | int iobase; |
| 1465 | int iir, lsr; | 1487 | int iir, lsr; |
| @@ -1469,14 +1491,14 @@ static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) | |||
| 1469 | 1491 | ||
| 1470 | iobase = self->io.sir_base; | 1492 | iobase = self->io.sir_base; |
| 1471 | 1493 | ||
| 1472 | iir = inb(iobase+UART_IIR) & UART_IIR_ID; | 1494 | iir = inb(iobase + UART_IIR) & UART_IIR_ID; |
| 1473 | if (iir == 0) | 1495 | if (iir == 0) |
| 1474 | return IRQ_NONE; | 1496 | return IRQ_NONE; |
| 1475 | while (iir) { | 1497 | while (iir) { |
| 1476 | /* Clear interrupt */ | 1498 | /* Clear interrupt */ |
| 1477 | lsr = inb(iobase+UART_LSR); | 1499 | lsr = inb(iobase + UART_LSR); |
| 1478 | 1500 | ||
| 1479 | IRDA_DEBUG(4, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", | 1501 | IRDA_DEBUG(4, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", |
| 1480 | __FUNCTION__, iir, lsr, iobase); | 1502 | __FUNCTION__, iir, lsr, iobase); |
| 1481 | 1503 | ||
| 1482 | switch (iir) { | 1504 | switch (iir) { |
| @@ -1496,13 +1518,13 @@ static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev) | |||
| 1496 | IRDA_DEBUG(0, "%s(), unhandled IIR=%#x\n", | 1518 | IRDA_DEBUG(0, "%s(), unhandled IIR=%#x\n", |
| 1497 | __FUNCTION__, iir); | 1519 | __FUNCTION__, iir); |
| 1498 | break; | 1520 | break; |
| 1499 | } | 1521 | } |
| 1500 | 1522 | ||
| 1501 | /* Make sure we don't stay here to long */ | 1523 | /* Make sure we don't stay here to long */ |
| 1502 | if (boguscount++ > 100) | 1524 | if (boguscount++ > 100) |
| 1503 | break; | 1525 | break; |
| 1504 | 1526 | ||
| 1505 | iir = inb(iobase + UART_IIR) & UART_IIR_ID; | 1527 | iir = inb(iobase + UART_IIR) & UART_IIR_ID; |
| 1506 | } | 1528 | } |
| 1507 | /*spin_unlock(&self->lock);*/ | 1529 | /*spin_unlock(&self->lock);*/ |
| 1508 | return IRQ_HANDLED; | 1530 | return IRQ_HANDLED; |
| @@ -1529,7 +1551,7 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self) | |||
| 1529 | get_dma_residue(self->io.dma)); | 1551 | get_dma_residue(self->io.dma)); |
| 1530 | 1552 | ||
| 1531 | status = (self->rx_buff.state != OUTSIDE_FRAME); | 1553 | status = (self->rx_buff.state != OUTSIDE_FRAME); |
| 1532 | 1554 | ||
| 1533 | return status; | 1555 | return status; |
| 1534 | } | 1556 | } |
| 1535 | #endif /* unused */ | 1557 | #endif /* unused */ |
| @@ -1544,19 +1566,16 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self) | |||
| 1544 | static int smsc_ircc_net_open(struct net_device *dev) | 1566 | static int smsc_ircc_net_open(struct net_device *dev) |
| 1545 | { | 1567 | { |
| 1546 | struct smsc_ircc_cb *self; | 1568 | struct smsc_ircc_cb *self; |
| 1547 | int iobase; | ||
| 1548 | char hwname[16]; | 1569 | char hwname[16]; |
| 1549 | unsigned long flags; | 1570 | unsigned long flags; |
| 1550 | 1571 | ||
| 1551 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 1572 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 1552 | 1573 | ||
| 1553 | IRDA_ASSERT(dev != NULL, return -1;); | 1574 | IRDA_ASSERT(dev != NULL, return -1;); |
| 1554 | self = (struct smsc_ircc_cb *) dev->priv; | 1575 | self = netdev_priv(dev); |
| 1555 | IRDA_ASSERT(self != NULL, return 0;); | 1576 | IRDA_ASSERT(self != NULL, return 0;); |
| 1556 | |||
| 1557 | iobase = self->io.fir_base; | ||
| 1558 | 1577 | ||
| 1559 | if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name, | 1578 | if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name, |
| 1560 | (void *) dev)) { | 1579 | (void *) dev)) { |
| 1561 | IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n", | 1580 | IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n", |
| 1562 | __FUNCTION__, self->io.irq); | 1581 | __FUNCTION__, self->io.irq); |
| @@ -1568,14 +1587,14 @@ static int smsc_ircc_net_open(struct net_device *dev) | |||
| 1568 | self->io.speed = 0; | 1587 | self->io.speed = 0; |
| 1569 | smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED); | 1588 | smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED); |
| 1570 | spin_unlock_irqrestore(&self->lock, flags); | 1589 | spin_unlock_irqrestore(&self->lock, flags); |
| 1571 | 1590 | ||
| 1572 | /* Give self a hardware name */ | 1591 | /* Give self a hardware name */ |
| 1573 | /* It would be cool to offer the chip revision here - Jean II */ | 1592 | /* It would be cool to offer the chip revision here - Jean II */ |
| 1574 | sprintf(hwname, "SMSC @ 0x%03x", self->io.fir_base); | 1593 | sprintf(hwname, "SMSC @ 0x%03x", self->io.fir_base); |
| 1575 | 1594 | ||
| 1576 | /* | 1595 | /* |
| 1577 | * Open new IrLAP layer instance, now that everything should be | 1596 | * Open new IrLAP layer instance, now that everything should be |
| 1578 | * initialized properly | 1597 | * initialized properly |
| 1579 | */ | 1598 | */ |
| 1580 | self->irlap = irlap_open(dev, &self->qos, hwname); | 1599 | self->irlap = irlap_open(dev, &self->qos, hwname); |
| 1581 | 1600 | ||
| @@ -1590,7 +1609,7 @@ static int smsc_ircc_net_open(struct net_device *dev) | |||
| 1590 | __FUNCTION__, self->io.dma); | 1609 | __FUNCTION__, self->io.dma); |
| 1591 | return -EAGAIN; | 1610 | return -EAGAIN; |
| 1592 | } | 1611 | } |
| 1593 | 1612 | ||
| 1594 | netif_start_queue(dev); | 1613 | netif_start_queue(dev); |
| 1595 | 1614 | ||
| 1596 | return 0; | 1615 | return 0; |
| @@ -1605,73 +1624,53 @@ static int smsc_ircc_net_open(struct net_device *dev) | |||
| 1605 | static int smsc_ircc_net_close(struct net_device *dev) | 1624 | static int smsc_ircc_net_close(struct net_device *dev) |
| 1606 | { | 1625 | { |
| 1607 | struct smsc_ircc_cb *self; | 1626 | struct smsc_ircc_cb *self; |
| 1608 | int iobase; | ||
| 1609 | 1627 | ||
| 1610 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 1628 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 1611 | 1629 | ||
| 1612 | IRDA_ASSERT(dev != NULL, return -1;); | 1630 | IRDA_ASSERT(dev != NULL, return -1;); |
| 1613 | self = (struct smsc_ircc_cb *) dev->priv; | 1631 | self = netdev_priv(dev); |
| 1614 | IRDA_ASSERT(self != NULL, return 0;); | 1632 | IRDA_ASSERT(self != NULL, return 0;); |
| 1615 | |||
| 1616 | iobase = self->io.fir_base; | ||
| 1617 | 1633 | ||
| 1618 | /* Stop device */ | 1634 | /* Stop device */ |
| 1619 | netif_stop_queue(dev); | 1635 | netif_stop_queue(dev); |
| 1620 | 1636 | ||
| 1621 | /* Stop and remove instance of IrLAP */ | 1637 | /* Stop and remove instance of IrLAP */ |
| 1622 | if (self->irlap) | 1638 | if (self->irlap) |
| 1623 | irlap_close(self->irlap); | 1639 | irlap_close(self->irlap); |
| 1624 | self->irlap = NULL; | 1640 | self->irlap = NULL; |
| 1625 | 1641 | ||
| 1626 | free_irq(self->io.irq, dev); | 1642 | free_irq(self->io.irq, dev); |
| 1627 | |||
| 1628 | disable_dma(self->io.dma); | 1643 | disable_dma(self->io.dma); |
| 1629 | |||
| 1630 | free_dma(self->io.dma); | 1644 | free_dma(self->io.dma); |
| 1631 | 1645 | ||
| 1632 | return 0; | 1646 | return 0; |
| 1633 | } | 1647 | } |
| 1634 | 1648 | ||
| 1635 | 1649 | static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level) | |
| 1636 | static void smsc_ircc_suspend(struct smsc_ircc_cb *self) | ||
| 1637 | { | 1650 | { |
| 1638 | IRDA_MESSAGE("%s, Suspending\n", driver_name); | 1651 | struct smsc_ircc_cb *self = dev_get_drvdata(dev); |
| 1639 | 1652 | ||
| 1640 | if (self->io.suspended) | 1653 | IRDA_MESSAGE("%s, Suspending\n", driver_name); |
| 1641 | return; | ||
| 1642 | 1654 | ||
| 1643 | smsc_ircc_net_close(self->netdev); | 1655 | if (level == SUSPEND_DISABLE && !self->io.suspended) { |
| 1656 | smsc_ircc_net_close(self->netdev); | ||
| 1657 | self->io.suspended = 1; | ||
| 1658 | } | ||
| 1644 | 1659 | ||
| 1645 | self->io.suspended = 1; | 1660 | return 0; |
| 1646 | } | 1661 | } |
| 1647 | 1662 | ||
| 1648 | static void smsc_ircc_wakeup(struct smsc_ircc_cb *self) | 1663 | static int smsc_ircc_resume(struct device *dev, u32 level) |
| 1649 | { | 1664 | { |
| 1650 | if (!self->io.suspended) | 1665 | struct smsc_ircc_cb *self = dev_get_drvdata(dev); |
| 1651 | return; | ||
| 1652 | 1666 | ||
| 1653 | /* The code was doing a "cli()" here, but this can't be right. | 1667 | if (level == RESUME_ENABLE && self->io.suspended) { |
| 1654 | * If you need protection, do it in net_open with a spinlock | ||
| 1655 | * or give a good reason. - Jean II */ | ||
| 1656 | 1668 | ||
| 1657 | smsc_ircc_net_open(self->netdev); | 1669 | smsc_ircc_net_open(self->netdev); |
| 1658 | 1670 | self->io.suspended = 0; | |
| 1659 | IRDA_MESSAGE("%s, Waking up\n", driver_name); | ||
| 1660 | } | ||
| 1661 | 1671 | ||
| 1662 | static int smsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data) | 1672 | IRDA_MESSAGE("%s, Waking up\n", driver_name); |
| 1663 | { | 1673 | } |
| 1664 | struct smsc_ircc_cb *self = (struct smsc_ircc_cb*) dev->data; | ||
| 1665 | if (self) { | ||
| 1666 | switch (rqst) { | ||
| 1667 | case PM_SUSPEND: | ||
| 1668 | smsc_ircc_suspend(self); | ||
| 1669 | break; | ||
| 1670 | case PM_RESUME: | ||
| 1671 | smsc_ircc_wakeup(self); | ||
| 1672 | break; | ||
| 1673 | } | ||
| 1674 | } | ||
| 1675 | return 0; | 1674 | return 0; |
| 1676 | } | 1675 | } |
| 1677 | 1676 | ||
| @@ -1690,10 +1689,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) | |||
| 1690 | 1689 | ||
| 1691 | IRDA_ASSERT(self != NULL, return -1;); | 1690 | IRDA_ASSERT(self != NULL, return -1;); |
| 1692 | 1691 | ||
| 1693 | iobase = self->io.fir_base; | 1692 | platform_device_unregister(self->pldev); |
| 1694 | |||
| 1695 | if (self->pmdev) | ||
| 1696 | pm_unregister(self->pmdev); | ||
| 1697 | 1693 | ||
| 1698 | /* Remove netdevice */ | 1694 | /* Remove netdevice */ |
| 1699 | unregister_netdev(self->netdev); | 1695 | unregister_netdev(self->netdev); |
| @@ -1702,15 +1698,16 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) | |||
| 1702 | spin_lock_irqsave(&self->lock, flags); | 1698 | spin_lock_irqsave(&self->lock, flags); |
| 1703 | 1699 | ||
| 1704 | /* Stop interrupts */ | 1700 | /* Stop interrupts */ |
| 1701 | iobase = self->io.fir_base; | ||
| 1705 | register_bank(iobase, 0); | 1702 | register_bank(iobase, 0); |
| 1706 | outb(0, iobase+IRCC_IER); | 1703 | outb(0, iobase + IRCC_IER); |
| 1707 | outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER); | 1704 | outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER); |
| 1708 | outb(0x00, iobase+IRCC_MASTER); | 1705 | outb(0x00, iobase + IRCC_MASTER); |
| 1709 | #if 0 | 1706 | #if 0 |
| 1710 | /* Reset to SIR mode */ | 1707 | /* Reset to SIR mode */ |
| 1711 | register_bank(iobase, 1); | 1708 | register_bank(iobase, 1); |
| 1712 | outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase+IRCC_SCE_CFGA); | 1709 | outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase + IRCC_SCE_CFGA); |
| 1713 | outb(IRCC_CFGB_IR, iobase+IRCC_SCE_CFGB); | 1710 | outb(IRCC_CFGB_IR, iobase + IRCC_SCE_CFGB); |
| 1714 | #endif | 1711 | #endif |
| 1715 | spin_unlock_irqrestore(&self->lock, flags); | 1712 | spin_unlock_irqrestore(&self->lock, flags); |
| 1716 | 1713 | ||
| @@ -1720,7 +1717,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) | |||
| 1720 | 1717 | ||
| 1721 | release_region(self->io.fir_base, self->io.fir_ext); | 1718 | release_region(self->io.fir_base, self->io.fir_ext); |
| 1722 | 1719 | ||
| 1723 | IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__, | 1720 | IRDA_DEBUG(0, "%s(), releasing 0x%03x\n", __FUNCTION__, |
| 1724 | self->io.sir_base); | 1721 | self->io.sir_base); |
| 1725 | 1722 | ||
| 1726 | release_region(self->io.sir_base, self->io.sir_ext); | 1723 | release_region(self->io.sir_base, self->io.sir_ext); |
| @@ -1728,7 +1725,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self) | |||
| 1728 | if (self->tx_buff.head) | 1725 | if (self->tx_buff.head) |
| 1729 | dma_free_coherent(NULL, self->tx_buff.truesize, | 1726 | dma_free_coherent(NULL, self->tx_buff.truesize, |
| 1730 | self->tx_buff.head, self->tx_buff_dma); | 1727 | self->tx_buff.head, self->tx_buff_dma); |
| 1731 | 1728 | ||
| 1732 | if (self->rx_buff.head) | 1729 | if (self->rx_buff.head) |
| 1733 | dma_free_coherent(NULL, self->rx_buff.truesize, | 1730 | dma_free_coherent(NULL, self->rx_buff.truesize, |
| 1734 | self->rx_buff.head, self->rx_buff_dma); | 1731 | self->rx_buff.head, self->rx_buff_dma); |
| @@ -1744,10 +1741,12 @@ static void __exit smsc_ircc_cleanup(void) | |||
| 1744 | 1741 | ||
| 1745 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 1742 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 1746 | 1743 | ||
| 1747 | for (i=0; i < 2; i++) { | 1744 | for (i = 0; i < 2; i++) { |
| 1748 | if (dev_self[i]) | 1745 | if (dev_self[i]) |
| 1749 | smsc_ircc_close(dev_self[i]); | 1746 | smsc_ircc_close(dev_self[i]); |
| 1750 | } | 1747 | } |
| 1748 | |||
| 1749 | driver_unregister(&smsc_ircc_driver); | ||
| 1751 | } | 1750 | } |
| 1752 | 1751 | ||
| 1753 | /* | 1752 | /* |
| @@ -1763,34 +1762,34 @@ void smsc_ircc_sir_start(struct smsc_ircc_cb *self) | |||
| 1763 | 1762 | ||
| 1764 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); | 1763 | IRDA_DEBUG(3, "%s\n", __FUNCTION__); |
| 1765 | 1764 | ||
| 1766 | IRDA_ASSERT(self != NULL, return;); | 1765 | IRDA_ASSERT(self != NULL, return;); |
| 1767 | dev= self->netdev; | 1766 | dev = self->netdev; |
| 1768 | IRDA_ASSERT(dev != NULL, return;); | 1767 | IRDA_ASSERT(dev != NULL, return;); |
| 1769 | dev->hard_start_xmit = &smsc_ircc_hard_xmit_sir; | 1768 | dev->hard_start_xmit = &smsc_ircc_hard_xmit_sir; |
| 1770 | 1769 | ||
| 1771 | fir_base = self->io.fir_base; | 1770 | fir_base = self->io.fir_base; |
| 1772 | sir_base = self->io.sir_base; | 1771 | sir_base = self->io.sir_base; |
| 1773 | 1772 | ||
| 1774 | /* Reset everything */ | 1773 | /* Reset everything */ |
| 1775 | outb(IRCC_MASTER_RESET, fir_base+IRCC_MASTER); | 1774 | outb(IRCC_MASTER_RESET, fir_base + IRCC_MASTER); |
| 1776 | 1775 | ||
| 1777 | #if SMSC_IRCC2_C_SIR_STOP | 1776 | #if SMSC_IRCC2_C_SIR_STOP |
| 1778 | /*smsc_ircc_sir_stop(self);*/ | 1777 | /*smsc_ircc_sir_stop(self);*/ |
| 1779 | #endif | 1778 | #endif |
| 1780 | 1779 | ||
| 1781 | register_bank(fir_base, 1); | 1780 | register_bank(fir_base, 1); |
| 1782 | outb(((inb(fir_base+IRCC_SCE_CFGA) & IRCC_SCE_CFGA_BLOCK_CTRL_BITS_MASK) | IRCC_CFGA_IRDA_SIR_A), fir_base+IRCC_SCE_CFGA); | 1781 | outb(((inb(fir_base + IRCC_SCE_CFGA) & IRCC_SCE_CFGA_BLOCK_CTRL_BITS_MASK) | IRCC_CFGA_IRDA_SIR_A), fir_base + IRCC_SCE_CFGA); |
| 1783 | 1782 | ||
| 1784 | /* Initialize UART */ | 1783 | /* Initialize UART */ |
| 1785 | outb(UART_LCR_WLEN8, sir_base+UART_LCR); /* Reset DLAB */ | 1784 | outb(UART_LCR_WLEN8, sir_base + UART_LCR); /* Reset DLAB */ |
| 1786 | outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), sir_base+UART_MCR); | 1785 | outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), sir_base + UART_MCR); |
| 1787 | 1786 | ||
| 1788 | /* Turn on interrups */ | 1787 | /* Turn on interrups */ |
| 1789 | outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, sir_base+UART_IER); | 1788 | outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, sir_base + UART_IER); |
| 1790 | 1789 | ||
| 1791 | IRDA_DEBUG(3, "%s() - exit\n", __FUNCTION__); | 1790 | IRDA_DEBUG(3, "%s() - exit\n", __FUNCTION__); |
| 1792 | 1791 | ||
| 1793 | outb(0x00, fir_base+IRCC_MASTER); | 1792 | outb(0x00, fir_base + IRCC_MASTER); |
| 1794 | } | 1793 | } |
| 1795 | 1794 | ||
| 1796 | #if SMSC_IRCC2_C_SIR_STOP | 1795 | #if SMSC_IRCC2_C_SIR_STOP |
| @@ -1802,10 +1801,10 @@ void smsc_ircc_sir_stop(struct smsc_ircc_cb *self) | |||
| 1802 | iobase = self->io.sir_base; | 1801 | iobase = self->io.sir_base; |
| 1803 | 1802 | ||
| 1804 | /* Reset UART */ | 1803 | /* Reset UART */ |
| 1805 | outb(0, iobase+UART_MCR); | 1804 | outb(0, iobase + UART_MCR); |
| 1806 | 1805 | ||
| 1807 | /* Turn off interrupts */ | 1806 | /* Turn off interrupts */ |
| 1808 | outb(0, iobase+UART_IER); | 1807 | outb(0, iobase + UART_IER); |
| 1809 | } | 1808 | } |
| 1810 | #endif | 1809 | #endif |
| 1811 | 1810 | ||
| @@ -1831,16 +1830,16 @@ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self) | |||
| 1831 | /* Finished with frame? */ | 1830 | /* Finished with frame? */ |
| 1832 | if (self->tx_buff.len > 0) { | 1831 | if (self->tx_buff.len > 0) { |
| 1833 | /* Write data left in transmit buffer */ | 1832 | /* Write data left in transmit buffer */ |
| 1834 | actual = smsc_ircc_sir_write(iobase, self->io.fifo_size, | 1833 | actual = smsc_ircc_sir_write(iobase, self->io.fifo_size, |
| 1835 | self->tx_buff.data, self->tx_buff.len); | 1834 | self->tx_buff.data, self->tx_buff.len); |
| 1836 | self->tx_buff.data += actual; | 1835 | self->tx_buff.data += actual; |
| 1837 | self->tx_buff.len -= actual; | 1836 | self->tx_buff.len -= actual; |
| 1838 | } else { | 1837 | } else { |
| 1839 | 1838 | ||
| 1840 | /*if (self->tx_buff.len ==0) {*/ | 1839 | /*if (self->tx_buff.len ==0) {*/ |
| 1841 | 1840 | ||
| 1842 | /* | 1841 | /* |
| 1843 | * Now serial buffer is almost free & we can start | 1842 | * Now serial buffer is almost free & we can start |
| 1844 | * transmission of another packet. But first we must check | 1843 | * transmission of another packet. But first we must check |
| 1845 | * if we need to change the speed of the hardware | 1844 | * if we need to change the speed of the hardware |
| 1846 | */ | 1845 | */ |
| @@ -1856,21 +1855,19 @@ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self) | |||
| 1856 | } | 1855 | } |
| 1857 | self->stats.tx_packets++; | 1856 | self->stats.tx_packets++; |
| 1858 | 1857 | ||
| 1859 | if(self->io.speed <= 115200) { | 1858 | if (self->io.speed <= 115200) { |
| 1860 | /* | 1859 | /* |
| 1861 | * Reset Rx FIFO to make sure that all reflected transmit data | 1860 | * Reset Rx FIFO to make sure that all reflected transmit data |
| 1862 | * is discarded. This is needed for half duplex operation | 1861 | * is discarded. This is needed for half duplex operation |
| 1863 | */ | 1862 | */ |
| 1864 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR; | 1863 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR; |
| 1865 | if (self->io.speed < 38400) | 1864 | fcr |= self->io.speed < 38400 ? |
| 1866 | fcr |= UART_FCR_TRIGGER_1; | 1865 | UART_FCR_TRIGGER_1 : UART_FCR_TRIGGER_14; |
| 1867 | else | ||
| 1868 | fcr |= UART_FCR_TRIGGER_14; | ||
| 1869 | 1866 | ||
| 1870 | outb(fcr, iobase+UART_FCR); | 1867 | outb(fcr, iobase + UART_FCR); |
| 1871 | 1868 | ||
| 1872 | /* Turn on receive interrupts */ | 1869 | /* Turn on receive interrupts */ |
| 1873 | outb(UART_IER_RDI, iobase+UART_IER); | 1870 | outb(UART_IER_RDI, iobase + UART_IER); |
| 1874 | } | 1871 | } |
| 1875 | } | 1872 | } |
| 1876 | } | 1873 | } |
| @@ -1884,17 +1881,17 @@ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self) | |||
| 1884 | static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) | 1881 | static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) |
| 1885 | { | 1882 | { |
| 1886 | int actual = 0; | 1883 | int actual = 0; |
| 1887 | 1884 | ||
| 1888 | /* Tx FIFO should be empty! */ | 1885 | /* Tx FIFO should be empty! */ |
| 1889 | if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { | 1886 | if (!(inb(iobase + UART_LSR) & UART_LSR_THRE)) { |
| 1890 | IRDA_WARNING("%s(), failed, fifo not empty!\n", __FUNCTION__); | 1887 | IRDA_WARNING("%s(), failed, fifo not empty!\n", __FUNCTION__); |
| 1891 | return 0; | 1888 | return 0; |
| 1892 | } | 1889 | } |
| 1893 | 1890 | ||
| 1894 | /* Fill FIFO with current frame */ | 1891 | /* Fill FIFO with current frame */ |
| 1895 | while ((fifo_size-- > 0) && (actual < len)) { | 1892 | while (fifo_size-- > 0 && actual < len) { |
| 1896 | /* Transmit next byte */ | 1893 | /* Transmit next byte */ |
| 1897 | outb(buf[actual], iobase+UART_TX); | 1894 | outb(buf[actual], iobase + UART_TX); |
| 1898 | actual++; | 1895 | actual++; |
| 1899 | } | 1896 | } |
| 1900 | return actual; | 1897 | return actual; |
| @@ -1921,20 +1918,21 @@ static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self) | |||
| 1921 | static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self) | 1918 | static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self) |
| 1922 | { | 1919 | { |
| 1923 | unsigned int i; | 1920 | unsigned int i; |
| 1924 | 1921 | ||
| 1925 | IRDA_ASSERT(self != NULL, return;); | 1922 | IRDA_ASSERT(self != NULL, return;); |
| 1926 | 1923 | ||
| 1927 | for(i=0; smsc_transceivers[i].name!=NULL; i++) | 1924 | for (i = 0; smsc_transceivers[i].name != NULL; i++) |
| 1928 | if((*smsc_transceivers[i].probe)(self->io.fir_base)) { | 1925 | if (smsc_transceivers[i].probe(self->io.fir_base)) { |
| 1929 | IRDA_MESSAGE(" %s transceiver found\n", | 1926 | IRDA_MESSAGE(" %s transceiver found\n", |
| 1930 | smsc_transceivers[i].name); | 1927 | smsc_transceivers[i].name); |
| 1931 | self->transceiver= i+1; | 1928 | self->transceiver= i + 1; |
| 1932 | return; | 1929 | return; |
| 1933 | } | 1930 | } |
| 1931 | |||
| 1934 | IRDA_MESSAGE("No transceiver found. Defaulting to %s\n", | 1932 | IRDA_MESSAGE("No transceiver found. Defaulting to %s\n", |
| 1935 | smsc_transceivers[SMSC_IRCC2_C_DEFAULT_TRANSCEIVER].name); | 1933 | smsc_transceivers[SMSC_IRCC2_C_DEFAULT_TRANSCEIVER].name); |
| 1936 | 1934 | ||
| 1937 | self->transceiver= SMSC_IRCC2_C_DEFAULT_TRANSCEIVER; | 1935 | self->transceiver = SMSC_IRCC2_C_DEFAULT_TRANSCEIVER; |
| 1938 | } | 1936 | } |
| 1939 | 1937 | ||
| 1940 | 1938 | ||
| @@ -1947,9 +1945,10 @@ static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self) | |||
| 1947 | static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 speed) | 1945 | static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 speed) |
| 1948 | { | 1946 | { |
| 1949 | unsigned int trx; | 1947 | unsigned int trx; |
| 1950 | 1948 | ||
| 1951 | trx = self->transceiver; | 1949 | trx = self->transceiver; |
| 1952 | if(trx>0) (*smsc_transceivers[trx-1].set_for_speed)(self->io.fir_base, speed); | 1950 | if (trx > 0) |
| 1951 | smsc_transceivers[trx - 1].set_for_speed(self->io.fir_base, speed); | ||
| 1953 | } | 1952 | } |
| 1954 | 1953 | ||
| 1955 | /* | 1954 | /* |
| @@ -1977,16 +1976,14 @@ static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 s | |||
| 1977 | 1976 | ||
| 1978 | static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self) | 1977 | static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self) |
| 1979 | { | 1978 | { |
| 1980 | int iobase; | 1979 | int iobase = self->io.sir_base; |
| 1981 | int count = SMSC_IRCC2_HW_TRANSMITTER_TIMEOUT_US; | 1980 | int count = SMSC_IRCC2_HW_TRANSMITTER_TIMEOUT_US; |
| 1982 | 1981 | ||
| 1983 | iobase = self->io.sir_base; | ||
| 1984 | |||
| 1985 | /* Calibrated busy loop */ | 1982 | /* Calibrated busy loop */ |
| 1986 | while((count-- > 0) && !(inb(iobase+UART_LSR) & UART_LSR_TEMT)) | 1983 | while (count-- > 0 && !(inb(iobase + UART_LSR) & UART_LSR_TEMT)) |
| 1987 | udelay(1); | 1984 | udelay(1); |
| 1988 | 1985 | ||
| 1989 | if(count == 0) | 1986 | if (count == 0) |
| 1990 | IRDA_DEBUG(0, "%s(): stuck transmitter\n", __FUNCTION__); | 1987 | IRDA_DEBUG(0, "%s(): stuck transmitter\n", __FUNCTION__); |
| 1991 | } | 1988 | } |
| 1992 | 1989 | ||
| @@ -1998,40 +1995,42 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self) | |||
| 1998 | 1995 | ||
| 1999 | static int __init smsc_ircc_look_for_chips(void) | 1996 | static int __init smsc_ircc_look_for_chips(void) |
| 2000 | { | 1997 | { |
| 2001 | smsc_chip_address_t *address; | 1998 | struct smsc_chip_address *address; |
| 2002 | char *type; | 1999 | char *type; |
| 2003 | unsigned int cfg_base, found; | 2000 | unsigned int cfg_base, found; |
| 2004 | 2001 | ||
| 2005 | found = 0; | 2002 | found = 0; |
| 2006 | address = possible_addresses; | 2003 | address = possible_addresses; |
| 2007 | 2004 | ||
| 2008 | while(address->cfg_base){ | 2005 | while (address->cfg_base) { |
| 2009 | cfg_base = address->cfg_base; | 2006 | cfg_base = address->cfg_base; |
| 2010 | 2007 | ||
| 2011 | /*printk(KERN_WARNING "%s(): probing: 0x%02x for: 0x%02x\n", __FUNCTION__, cfg_base, address->type);*/ | 2008 | /*printk(KERN_WARNING "%s(): probing: 0x%02x for: 0x%02x\n", __FUNCTION__, cfg_base, address->type);*/ |
| 2012 | 2009 | ||
| 2013 | if( address->type & SMSCSIO_TYPE_FDC){ | 2010 | if (address->type & SMSCSIO_TYPE_FDC) { |
| 2014 | type = "FDC"; | 2011 | type = "FDC"; |
| 2015 | if((address->type) & SMSCSIO_TYPE_FLAT) { | 2012 | if (address->type & SMSCSIO_TYPE_FLAT) |
| 2016 | if(!smsc_superio_flat(fdc_chips_flat,cfg_base, type)) found++; | 2013 | if (!smsc_superio_flat(fdc_chips_flat, cfg_base, type)) |
| 2017 | } | 2014 | found++; |
| 2018 | if((address->type) & SMSCSIO_TYPE_PAGED) { | 2015 | |
| 2019 | if(!smsc_superio_paged(fdc_chips_paged,cfg_base, type)) found++; | 2016 | if (address->type & SMSCSIO_TYPE_PAGED) |
| 2020 | } | 2017 | if (!smsc_superio_paged(fdc_chips_paged, cfg_base, type)) |
| 2018 | found++; | ||
| 2021 | } | 2019 | } |
| 2022 | if( address->type & SMSCSIO_TYPE_LPC){ | 2020 | if (address->type & SMSCSIO_TYPE_LPC) { |
| 2023 | type = "LPC"; | 2021 | type = "LPC"; |
| 2024 | if((address->type) & SMSCSIO_TYPE_FLAT) { | 2022 | if (address->type & SMSCSIO_TYPE_FLAT) |
| 2025 | if(!smsc_superio_flat(lpc_chips_flat,cfg_base,type)) found++; | 2023 | if (!smsc_superio_flat(lpc_chips_flat, cfg_base, type)) |
| 2026 | } | 2024 | found++; |
| 2027 | if((address->type) & SMSCSIO_TYPE_PAGED) { | 2025 | |
| 2028 | if(!smsc_superio_paged(lpc_chips_paged,cfg_base,"LPC")) found++; | 2026 | if (address->type & SMSCSIO_TYPE_PAGED) |
| 2029 | } | 2027 | if (!smsc_superio_paged(lpc_chips_paged, cfg_base, type)) |
| 2028 | found++; | ||
| 2030 | } | 2029 | } |
| 2031 | address++; | 2030 | address++; |
| 2032 | } | 2031 | } |
| 2033 | return found; | 2032 | return found; |
| 2034 | } | 2033 | } |
| 2035 | 2034 | ||
| 2036 | /* | 2035 | /* |
| 2037 | * Function smsc_superio_flat (chip, base, type) | 2036 | * Function smsc_superio_flat (chip, base, type) |
| @@ -2039,7 +2038,7 @@ static int __init smsc_ircc_look_for_chips(void) | |||
| 2039 | * Try to get configuration of a smc SuperIO chip with flat register model | 2038 | * Try to get configuration of a smc SuperIO chip with flat register model |
| 2040 | * | 2039 | * |
| 2041 | */ | 2040 | */ |
| 2042 | static int __init smsc_superio_flat(const smsc_chip_t *chips, unsigned short cfgbase, char *type) | 2041 | static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfgbase, char *type) |
| 2043 | { | 2042 | { |
| 2044 | unsigned short firbase, sirbase; | 2043 | unsigned short firbase, sirbase; |
| 2045 | u8 mode, dma, irq; | 2044 | u8 mode, dma, irq; |
| @@ -2047,39 +2046,37 @@ static int __init smsc_superio_flat(const smsc_chip_t *chips, unsigned short cfg | |||
| 2047 | 2046 | ||
| 2048 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 2047 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 2049 | 2048 | ||
| 2050 | if (smsc_ircc_probe(cfgbase, SMSCSIOFLAT_DEVICEID_REG, chips, type)==NULL) | 2049 | if (smsc_ircc_probe(cfgbase, SMSCSIOFLAT_DEVICEID_REG, chips, type) == NULL) |
| 2051 | return ret; | 2050 | return ret; |
| 2052 | 2051 | ||
| 2053 | outb(SMSCSIOFLAT_UARTMODE0C_REG, cfgbase); | 2052 | outb(SMSCSIOFLAT_UARTMODE0C_REG, cfgbase); |
| 2054 | mode = inb(cfgbase+1); | 2053 | mode = inb(cfgbase + 1); |
| 2055 | 2054 | ||
| 2056 | /*printk(KERN_WARNING "%s(): mode: 0x%02x\n", __FUNCTION__, mode);*/ | 2055 | /*printk(KERN_WARNING "%s(): mode: 0x%02x\n", __FUNCTION__, mode);*/ |
| 2057 | 2056 | ||
| 2058 | if(!(mode & SMSCSIOFLAT_UART2MODE_VAL_IRDA)) | 2057 | if (!(mode & SMSCSIOFLAT_UART2MODE_VAL_IRDA)) |
| 2059 | IRDA_WARNING("%s(): IrDA not enabled\n", __FUNCTION__); | 2058 | IRDA_WARNING("%s(): IrDA not enabled\n", __FUNCTION__); |
| 2060 | 2059 | ||
| 2061 | outb(SMSCSIOFLAT_UART2BASEADDR_REG, cfgbase); | 2060 | outb(SMSCSIOFLAT_UART2BASEADDR_REG, cfgbase); |
| 2062 | sirbase = inb(cfgbase+1) << 2; | 2061 | sirbase = inb(cfgbase + 1) << 2; |
| 2063 | 2062 | ||
| 2064 | /* FIR iobase */ | 2063 | /* FIR iobase */ |
| 2065 | outb(SMSCSIOFLAT_FIRBASEADDR_REG, cfgbase); | 2064 | outb(SMSCSIOFLAT_FIRBASEADDR_REG, cfgbase); |
| 2066 | firbase = inb(cfgbase+1) << 3; | 2065 | firbase = inb(cfgbase + 1) << 3; |
| 2067 | 2066 | ||
| 2068 | /* DMA */ | 2067 | /* DMA */ |
| 2069 | outb(SMSCSIOFLAT_FIRDMASELECT_REG, cfgbase); | 2068 | outb(SMSCSIOFLAT_FIRDMASELECT_REG, cfgbase); |
| 2070 | dma = inb(cfgbase+1) & SMSCSIOFLAT_FIRDMASELECT_MASK; | 2069 | dma = inb(cfgbase + 1) & SMSCSIOFLAT_FIRDMASELECT_MASK; |
| 2071 | 2070 | ||
| 2072 | /* IRQ */ | 2071 | /* IRQ */ |
| 2073 | outb(SMSCSIOFLAT_UARTIRQSELECT_REG, cfgbase); | 2072 | outb(SMSCSIOFLAT_UARTIRQSELECT_REG, cfgbase); |
| 2074 | irq = inb(cfgbase+1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; | 2073 | irq = inb(cfgbase + 1) & SMSCSIOFLAT_UART2IRQSELECT_MASK; |
| 2075 | 2074 | ||
| 2076 | IRDA_MESSAGE("%s(): fir: 0x%02x, sir: 0x%02x, dma: %02d, irq: %d, mode: 0x%02x\n", __FUNCTION__, firbase, sirbase, dma, irq, mode); | 2075 | IRDA_MESSAGE("%s(): fir: 0x%02x, sir: 0x%02x, dma: %02d, irq: %d, mode: 0x%02x\n", __FUNCTION__, firbase, sirbase, dma, irq, mode); |
| 2077 | 2076 | ||
| 2078 | if (firbase) { | 2077 | if (firbase && smsc_ircc_open(firbase, sirbase, dma, irq) == 0) |
| 2079 | if (smsc_ircc_open(firbase, sirbase, dma, irq) == 0) | 2078 | ret = 0; |
| 2080 | ret=0; | 2079 | |
| 2081 | } | ||
| 2082 | |||
| 2083 | /* Exit configuration */ | 2080 | /* Exit configuration */ |
| 2084 | outb(SMSCSIO_CFGEXITKEY, cfgbase); | 2081 | outb(SMSCSIO_CFGEXITKEY, cfgbase); |
| 2085 | 2082 | ||
| @@ -2092,26 +2089,26 @@ static int __init smsc_superio_flat(const smsc_chip_t *chips, unsigned short cfg | |||
| 2092 | * Try to get configuration of a smc SuperIO chip with paged register model | 2089 | * Try to get configuration of a smc SuperIO chip with paged register model |
| 2093 | * | 2090 | * |
| 2094 | */ | 2091 | */ |
| 2095 | static int __init smsc_superio_paged(const smsc_chip_t *chips, unsigned short cfg_base, char *type) | 2092 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type) |
| 2096 | { | 2093 | { |
| 2097 | unsigned short fir_io, sir_io; | 2094 | unsigned short fir_io, sir_io; |
| 2098 | int ret = -ENODEV; | 2095 | int ret = -ENODEV; |
| 2099 | 2096 | ||
| 2100 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 2097 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 2101 | 2098 | ||
| 2102 | if (smsc_ircc_probe(cfg_base,0x20,chips,type)==NULL) | 2099 | if (smsc_ircc_probe(cfg_base, 0x20, chips, type) == NULL) |
| 2103 | return ret; | 2100 | return ret; |
| 2104 | 2101 | ||
| 2105 | /* Select logical device (UART2) */ | 2102 | /* Select logical device (UART2) */ |
| 2106 | outb(0x07, cfg_base); | 2103 | outb(0x07, cfg_base); |
| 2107 | outb(0x05, cfg_base + 1); | 2104 | outb(0x05, cfg_base + 1); |
| 2108 | 2105 | ||
| 2109 | /* SIR iobase */ | 2106 | /* SIR iobase */ |
| 2110 | outb(0x60, cfg_base); | 2107 | outb(0x60, cfg_base); |
| 2111 | sir_io = inb(cfg_base + 1) << 8; | 2108 | sir_io = inb(cfg_base + 1) << 8; |
| 2112 | outb(0x61, cfg_base); | 2109 | outb(0x61, cfg_base); |
| 2113 | sir_io |= inb(cfg_base + 1); | 2110 | sir_io |= inb(cfg_base + 1); |
| 2114 | 2111 | ||
| 2115 | /* Read FIR base */ | 2112 | /* Read FIR base */ |
| 2116 | outb(0x62, cfg_base); | 2113 | outb(0x62, cfg_base); |
| 2117 | fir_io = inb(cfg_base + 1) << 8; | 2114 | fir_io = inb(cfg_base + 1) << 8; |
| @@ -2119,11 +2116,9 @@ static int __init smsc_superio_paged(const smsc_chip_t *chips, unsigned short cf | |||
| 2119 | fir_io |= inb(cfg_base + 1); | 2116 | fir_io |= inb(cfg_base + 1); |
| 2120 | outb(0x2b, cfg_base); /* ??? */ | 2117 | outb(0x2b, cfg_base); /* ??? */ |
| 2121 | 2118 | ||
| 2122 | if (fir_io) { | 2119 | if (fir_io && smsc_ircc_open(fir_io, sir_io, ircc_dma, ircc_irq) == 0) |
| 2123 | if (smsc_ircc_open(fir_io, sir_io, ircc_dma, ircc_irq) == 0) | 2120 | ret = 0; |
| 2124 | ret=0; | 2121 | |
| 2125 | } | ||
| 2126 | |||
| 2127 | /* Exit configuration */ | 2122 | /* Exit configuration */ |
| 2128 | outb(SMSCSIO_CFGEXITKEY, cfg_base); | 2123 | outb(SMSCSIO_CFGEXITKEY, cfg_base); |
| 2129 | 2124 | ||
| @@ -2131,21 +2126,17 @@ static int __init smsc_superio_paged(const smsc_chip_t *chips, unsigned short cf | |||
| 2131 | } | 2126 | } |
| 2132 | 2127 | ||
| 2133 | 2128 | ||
| 2134 | static int __init smsc_access(unsigned short cfg_base,unsigned char reg) | 2129 | static int __init smsc_access(unsigned short cfg_base, unsigned char reg) |
| 2135 | { | 2130 | { |
| 2136 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 2131 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 2137 | 2132 | ||
| 2138 | outb(reg, cfg_base); | 2133 | outb(reg, cfg_base); |
| 2139 | 2134 | return inb(cfg_base) != reg ? -1 : 0; | |
| 2140 | if (inb(cfg_base)!=reg) | ||
| 2141 | return -1; | ||
| 2142 | |||
| 2143 | return 0; | ||
| 2144 | } | 2135 | } |
| 2145 | 2136 | ||
| 2146 | static const smsc_chip_t * __init smsc_ircc_probe(unsigned short cfg_base,u8 reg,const smsc_chip_t *chip,char *type) | 2137 | static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type) |
| 2147 | { | 2138 | { |
| 2148 | u8 devid,xdevid,rev; | 2139 | u8 devid, xdevid, rev; |
| 2149 | 2140 | ||
| 2150 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); | 2141 | IRDA_DEBUG(1, "%s\n", __FUNCTION__); |
| 2151 | 2142 | ||
| @@ -2158,7 +2149,7 @@ static const smsc_chip_t * __init smsc_ircc_probe(unsigned short cfg_base,u8 reg | |||
| 2158 | 2149 | ||
| 2159 | outb(reg, cfg_base); | 2150 | outb(reg, cfg_base); |
| 2160 | 2151 | ||
| 2161 | xdevid=inb(cfg_base+1); | 2152 | xdevid = inb(cfg_base + 1); |
| 2162 | 2153 | ||
| 2163 | /* Enter configuration */ | 2154 | /* Enter configuration */ |
| 2164 | 2155 | ||
| @@ -2168,51 +2159,49 @@ static const smsc_chip_t * __init smsc_ircc_probe(unsigned short cfg_base,u8 reg | |||
| 2168 | if (smsc_access(cfg_base,0x55)) /* send second key and check */ | 2159 | if (smsc_access(cfg_base,0x55)) /* send second key and check */ |
| 2169 | return NULL; | 2160 | return NULL; |
| 2170 | #endif | 2161 | #endif |
| 2171 | 2162 | ||
| 2172 | /* probe device ID */ | 2163 | /* probe device ID */ |
| 2173 | 2164 | ||
| 2174 | if (smsc_access(cfg_base,reg)) | 2165 | if (smsc_access(cfg_base, reg)) |
| 2175 | return NULL; | 2166 | return NULL; |
| 2176 | 2167 | ||
| 2177 | devid=inb(cfg_base+1); | 2168 | devid = inb(cfg_base + 1); |
| 2178 | |||
| 2179 | if (devid==0) /* typical value for unused port */ | ||
| 2180 | return NULL; | ||
| 2181 | 2169 | ||
| 2182 | if (devid==0xff) /* typical value for unused port */ | 2170 | if (devid == 0 || devid == 0xff) /* typical values for unused port */ |
| 2183 | return NULL; | 2171 | return NULL; |
| 2184 | 2172 | ||
| 2185 | /* probe revision ID */ | 2173 | /* probe revision ID */ |
| 2186 | 2174 | ||
| 2187 | if (smsc_access(cfg_base,reg+1)) | 2175 | if (smsc_access(cfg_base, reg + 1)) |
| 2188 | return NULL; | 2176 | return NULL; |
| 2189 | 2177 | ||
| 2190 | rev=inb(cfg_base+1); | 2178 | rev = inb(cfg_base + 1); |
| 2191 | 2179 | ||
| 2192 | if (rev>=128) /* i think this will make no sense */ | 2180 | if (rev >= 128) /* i think this will make no sense */ |
| 2193 | return NULL; | 2181 | return NULL; |
| 2194 | 2182 | ||
| 2195 | if (devid==xdevid) /* protection against false positives */ | 2183 | if (devid == xdevid) /* protection against false positives */ |
| 2196 | return NULL; | 2184 | return NULL; |
| 2197 | 2185 | ||
| 2198 | /* Check for expected device ID; are there others? */ | 2186 | /* Check for expected device ID; are there others? */ |
| 2199 | 2187 | ||
| 2200 | while(chip->devid!=devid) { | 2188 | while (chip->devid != devid) { |
| 2201 | 2189 | ||
| 2202 | chip++; | 2190 | chip++; |
| 2203 | 2191 | ||
| 2204 | if (chip->name==NULL) | 2192 | if (chip->name == NULL) |
| 2205 | return NULL; | 2193 | return NULL; |
| 2206 | } | 2194 | } |
| 2207 | 2195 | ||
| 2208 | IRDA_MESSAGE("found SMC SuperIO Chip (devid=0x%02x rev=%02X base=0x%04x): %s%s\n",devid,rev,cfg_base,type,chip->name); | 2196 | IRDA_MESSAGE("found SMC SuperIO Chip (devid=0x%02x rev=%02X base=0x%04x): %s%s\n", |
| 2197 | devid, rev, cfg_base, type, chip->name); | ||
| 2209 | 2198 | ||
| 2210 | if (chip->rev>rev){ | 2199 | if (chip->rev > rev) { |
| 2211 | IRDA_MESSAGE("Revision higher than expected\n"); | 2200 | IRDA_MESSAGE("Revision higher than expected\n"); |
| 2212 | return NULL; | 2201 | return NULL; |
| 2213 | } | 2202 | } |
| 2214 | 2203 | ||
| 2215 | if (chip->flags&NoIRDA) | 2204 | if (chip->flags & NoIRDA) |
| 2216 | IRDA_MESSAGE("chipset does not support IRDA\n"); | 2205 | IRDA_MESSAGE("chipset does not support IRDA\n"); |
| 2217 | 2206 | ||
| 2218 | return chip; | 2207 | return chip; |
| @@ -2226,8 +2215,8 @@ static int __init smsc_superio_fdc(unsigned short cfg_base) | |||
| 2226 | IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", | 2215 | IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", |
| 2227 | __FUNCTION__, cfg_base); | 2216 | __FUNCTION__, cfg_base); |
| 2228 | } else { | 2217 | } else { |
| 2229 | if (!smsc_superio_flat(fdc_chips_flat,cfg_base,"FDC") | 2218 | if (!smsc_superio_flat(fdc_chips_flat, cfg_base, "FDC") || |
| 2230 | ||!smsc_superio_paged(fdc_chips_paged,cfg_base,"FDC")) | 2219 | !smsc_superio_paged(fdc_chips_paged, cfg_base, "FDC")) |
| 2231 | ret = 0; | 2220 | ret = 0; |
| 2232 | 2221 | ||
| 2233 | release_region(cfg_base, 2); | 2222 | release_region(cfg_base, 2); |
| @@ -2244,9 +2233,10 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) | |||
| 2244 | IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", | 2233 | IRDA_WARNING("%s: can't get cfg_base of 0x%03x\n", |
| 2245 | __FUNCTION__, cfg_base); | 2234 | __FUNCTION__, cfg_base); |
| 2246 | } else { | 2235 | } else { |
| 2247 | if (!smsc_superio_flat(lpc_chips_flat,cfg_base,"LPC") | 2236 | if (!smsc_superio_flat(lpc_chips_flat, cfg_base, "LPC") || |
| 2248 | ||!smsc_superio_paged(lpc_chips_paged,cfg_base,"LPC")) | 2237 | !smsc_superio_paged(lpc_chips_paged, cfg_base, "LPC")) |
| 2249 | ret = 0; | 2238 | ret = 0; |
| 2239 | |||
| 2250 | release_region(cfg_base, 2); | 2240 | release_region(cfg_base, 2); |
| 2251 | } | 2241 | } |
| 2252 | return ret; | 2242 | return ret; |
| @@ -2269,18 +2259,23 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) | |||
| 2269 | static void smsc_ircc_set_transceiver_smsc_ircc_atc(int fir_base, u32 speed) | 2259 | static void smsc_ircc_set_transceiver_smsc_ircc_atc(int fir_base, u32 speed) |
| 2270 | { | 2260 | { |
| 2271 | unsigned long jiffies_now, jiffies_timeout; | 2261 | unsigned long jiffies_now, jiffies_timeout; |
| 2272 | u8 val; | 2262 | u8 val; |
| 2273 | 2263 | ||
| 2274 | jiffies_now= jiffies; | 2264 | jiffies_now = jiffies; |
| 2275 | jiffies_timeout= jiffies+SMSC_IRCC2_ATC_PROGRAMMING_TIMEOUT_JIFFIES; | 2265 | jiffies_timeout = jiffies + SMSC_IRCC2_ATC_PROGRAMMING_TIMEOUT_JIFFIES; |
| 2276 | 2266 | ||
| 2277 | /* ATC */ | 2267 | /* ATC */ |
| 2278 | register_bank(fir_base, 4); | 2268 | register_bank(fir_base, 4); |
| 2279 | outb((inb(fir_base+IRCC_ATC) & IRCC_ATC_MASK) |IRCC_ATC_nPROGREADY|IRCC_ATC_ENABLE, fir_base+IRCC_ATC); | 2269 | outb((inb(fir_base + IRCC_ATC) & IRCC_ATC_MASK) | IRCC_ATC_nPROGREADY|IRCC_ATC_ENABLE, |
| 2280 | while((val=(inb(fir_base+IRCC_ATC) & IRCC_ATC_nPROGREADY)) && !time_after(jiffies, jiffies_timeout)); | 2270 | fir_base + IRCC_ATC); |
| 2281 | if(val) | 2271 | |
| 2272 | while ((val = (inb(fir_base + IRCC_ATC) & IRCC_ATC_nPROGREADY)) && | ||
| 2273 | !time_after(jiffies, jiffies_timeout)) | ||
| 2274 | /* empty */; | ||
| 2275 | |||
| 2276 | if (val) | ||
| 2282 | IRDA_WARNING("%s(): ATC: 0x%02x\n", __FUNCTION__, | 2277 | IRDA_WARNING("%s(): ATC: 0x%02x\n", __FUNCTION__, |
| 2283 | inb(fir_base+IRCC_ATC)); | 2278 | inb(fir_base + IRCC_ATC)); |
| 2284 | } | 2279 | } |
| 2285 | 2280 | ||
| 2286 | /* | 2281 | /* |
| @@ -2298,34 +2293,32 @@ static int smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base) | |||
| 2298 | /* | 2293 | /* |
| 2299 | * Function smsc_ircc_set_transceiver_smsc_ircc_fast_pin_select(self, speed) | 2294 | * Function smsc_ircc_set_transceiver_smsc_ircc_fast_pin_select(self, speed) |
| 2300 | * | 2295 | * |
| 2301 | * Set transceiver | 2296 | * Set transceiver |
| 2302 | * | 2297 | * |
| 2303 | */ | 2298 | */ |
| 2304 | 2299 | ||
| 2305 | static void smsc_ircc_set_transceiver_smsc_ircc_fast_pin_select(int fir_base, u32 speed) | 2300 | static void smsc_ircc_set_transceiver_smsc_ircc_fast_pin_select(int fir_base, u32 speed) |
| 2306 | { | 2301 | { |
| 2307 | u8 fast_mode; | 2302 | u8 fast_mode; |
| 2308 | 2303 | ||
| 2309 | switch(speed) | 2304 | switch (speed) { |
| 2310 | { | 2305 | default: |
| 2311 | default: | 2306 | case 576000 : |
| 2312 | case 576000 : | 2307 | fast_mode = 0; |
| 2313 | fast_mode = 0; | ||
| 2314 | break; | 2308 | break; |
| 2315 | case 1152000 : | 2309 | case 1152000 : |
| 2316 | case 4000000 : | 2310 | case 4000000 : |
| 2317 | fast_mode = IRCC_LCR_A_FAST; | 2311 | fast_mode = IRCC_LCR_A_FAST; |
| 2318 | break; | 2312 | break; |
| 2319 | |||
| 2320 | } | 2313 | } |
| 2321 | register_bank(fir_base, 0); | 2314 | register_bank(fir_base, 0); |
| 2322 | outb((inb(fir_base+IRCC_LCR_A) & 0xbf) | fast_mode, fir_base+IRCC_LCR_A); | 2315 | outb((inb(fir_base + IRCC_LCR_A) & 0xbf) | fast_mode, fir_base + IRCC_LCR_A); |
| 2323 | } | 2316 | } |
| 2324 | 2317 | ||
| 2325 | /* | 2318 | /* |
| 2326 | * Function smsc_ircc_probe_transceiver_smsc_ircc_fast_pin_select(fir_base) | 2319 | * Function smsc_ircc_probe_transceiver_smsc_ircc_fast_pin_select(fir_base) |
| 2327 | * | 2320 | * |
| 2328 | * Probe transceiver | 2321 | * Probe transceiver |
| 2329 | * | 2322 | * |
| 2330 | */ | 2323 | */ |
| 2331 | 2324 | ||
| @@ -2337,35 +2330,34 @@ static int smsc_ircc_probe_transceiver_smsc_ircc_fast_pin_select(int fir_base) | |||
| 2337 | /* | 2330 | /* |
| 2338 | * Function smsc_ircc_set_transceiver_toshiba_sat1800(fir_base, speed) | 2331 | * Function smsc_ircc_set_transceiver_toshiba_sat1800(fir_base, speed) |
| 2339 | * | 2332 | * |
| 2340 | * Set transceiver | 2333 | * Set transceiver |
| 2341 | * | 2334 | * |
| 2342 | */ | 2335 | */ |
| 2343 | 2336 | ||
| 2344 | static void smsc_ircc_set_transceiver_toshiba_sat1800(int fir_base, u32 speed) | 2337 | static void smsc_ircc_set_transceiver_toshiba_sat1800(int fir_base, u32 speed) |
| 2345 | { | 2338 | { |
| 2346 | u8 fast_mode; | 2339 | u8 fast_mode; |
| 2347 | 2340 | ||
| 2348 | switch(speed) | 2341 | switch (speed) { |
| 2349 | { | 2342 | default: |
| 2350 | default: | 2343 | case 576000 : |
| 2351 | case 576000 : | 2344 | fast_mode = 0; |
| 2352 | fast_mode = 0; | ||
| 2353 | break; | 2345 | break; |
| 2354 | case 1152000 : | 2346 | case 1152000 : |
| 2355 | case 4000000 : | 2347 | case 4000000 : |
| 2356 | fast_mode = /*IRCC_LCR_A_FAST |*/ IRCC_LCR_A_GP_DATA; | 2348 | fast_mode = /*IRCC_LCR_A_FAST |*/ IRCC_LCR_A_GP_DATA; |
| 2357 | break; | 2349 | break; |
| 2358 | 2350 | ||
| 2359 | } | 2351 | } |
| 2360 | /* This causes an interrupt */ | 2352 | /* This causes an interrupt */ |
| 2361 | register_bank(fir_base, 0); | 2353 | register_bank(fir_base, 0); |
| 2362 | outb((inb(fir_base+IRCC_LCR_A) & 0xbf) | fast_mode, fir_base+IRCC_LCR_A); | 2354 | outb((inb(fir_base + IRCC_LCR_A) & 0xbf) | fast_mode, fir_base + IRCC_LCR_A); |
| 2363 | } | 2355 | } |
| 2364 | 2356 | ||
| 2365 | /* | 2357 | /* |
| 2366 | * Function smsc_ircc_probe_transceiver_toshiba_sat1800(fir_base) | 2358 | * Function smsc_ircc_probe_transceiver_toshiba_sat1800(fir_base) |
| 2367 | * | 2359 | * |
| 2368 | * Probe transceiver | 2360 | * Probe transceiver |
| 2369 | * | 2361 | * |
| 2370 | */ | 2362 | */ |
| 2371 | 2363 | ||
| @@ -2377,20 +2369,3 @@ static int smsc_ircc_probe_transceiver_toshiba_sat1800(int fir_base) | |||
| 2377 | 2369 | ||
| 2378 | module_init(smsc_ircc_init); | 2370 | module_init(smsc_ircc_init); |
| 2379 | module_exit(smsc_ircc_cleanup); | 2371 | module_exit(smsc_ircc_cleanup); |
| 2380 | |||
| 2381 | MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>"); | ||
| 2382 | MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); | ||
| 2383 | MODULE_LICENSE("GPL"); | ||
| 2384 | |||
| 2385 | module_param(ircc_dma, int, 0); | ||
| 2386 | MODULE_PARM_DESC(ircc_dma, "DMA channel"); | ||
| 2387 | module_param(ircc_irq, int, 0); | ||
| 2388 | MODULE_PARM_DESC(ircc_irq, "IRQ line"); | ||
| 2389 | module_param(ircc_fir, int, 0); | ||
| 2390 | MODULE_PARM_DESC(ircc_fir, "FIR Base Address"); | ||
| 2391 | module_param(ircc_sir, int, 0); | ||
| 2392 | MODULE_PARM_DESC(ircc_sir, "SIR Base Address"); | ||
| 2393 | module_param(ircc_cfg, int, 0); | ||
| 2394 | MODULE_PARM_DESC(ircc_cfg, "Configuration register base address"); | ||
| 2395 | module_param(ircc_transceiver, int, 0); | ||
| 2396 | MODULE_PARM_DESC(ircc_transceiver, "Transceiver type"); | ||
diff --git a/drivers/net/irda/smsc-ircc2.h b/drivers/net/irda/smsc-ircc2.h index 458611cc0d40..0c36286d87f7 100644 --- a/drivers/net/irda/smsc-ircc2.h +++ b/drivers/net/irda/smsc-ircc2.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /********************************************************************* | 1 | /********************************************************************* |
| 2 | * $Id: smsc-ircc2.h,v 1.12.2.1 2002/10/27 10:52:37 dip Exp $ | 2 | * $Id: smsc-ircc2.h,v 1.12.2.1 2002/10/27 10:52:37 dip Exp $ |
| 3 | * | 3 | * |
| 4 | * Description: Definitions for the SMC IrCC chipset | 4 | * Description: Definitions for the SMC IrCC chipset |
| 5 | * Status: Experimental. | 5 | * Status: Experimental. |
| @@ -9,25 +9,25 @@ | |||
| 9 | * All Rights Reserved. | 9 | * All Rights Reserved. |
| 10 | * | 10 | * |
| 11 | * Based on smc-ircc.h: | 11 | * Based on smc-ircc.h: |
| 12 | * | 12 | * |
| 13 | * Copyright (c) 1999-2000, Dag Brattli <dagb@cs.uit.no> | 13 | * Copyright (c) 1999-2000, Dag Brattli <dagb@cs.uit.no> |
| 14 | * Copyright (c) 1998-1999, Thomas Davis (tadavis@jps.net> | 14 | * Copyright (c) 1998-1999, Thomas Davis (tadavis@jps.net> |
| 15 | * All Rights Reserved | 15 | * All Rights Reserved |
| 16 | * | 16 | * |
| 17 | * | 17 | * |
| 18 | * This program is free software; you can redistribute it and/or | 18 | * This program is free software; you can redistribute it and/or |
| 19 | * modify it under the terms of the GNU General Public License as | 19 | * modify it under the terms of the GNU General Public License as |
| 20 | * published by the Free Software Foundation; either version 2 of | 20 | * published by the Free Software Foundation; either version 2 of |
| 21 | * the License, or (at your option) any later version. | 21 | * the License, or (at your option) any later version. |
| 22 | * | 22 | * |
| 23 | * This program is distributed in the hope that it will be useful, | 23 | * This program is distributed in the hope that it will be useful, |
| 24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 26 | * GNU General Public License for more details. | 26 | * GNU General Public License for more details. |
| 27 | * | 27 | * |
| 28 | * You should have received a copy of the GNU General Public License | 28 | * You should have received a copy of the GNU General Public License |
| 29 | * along with this program; if not, write to the Free Software | 29 | * along with this program; if not, write to the Free Software |
| 30 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 30 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| 31 | * MA 02111-1307 USA | 31 | * MA 02111-1307 USA |
| 32 | * | 32 | * |
| 33 | ********************************************************************/ | 33 | ********************************************************************/ |
| @@ -112,10 +112,10 @@ | |||
| 112 | 112 | ||
| 113 | #define IRCC_CFGA_COM 0x00 | 113 | #define IRCC_CFGA_COM 0x00 |
| 114 | #define IRCC_SCE_CFGA_BLOCK_CTRL_BITS_MASK 0x87 | 114 | #define IRCC_SCE_CFGA_BLOCK_CTRL_BITS_MASK 0x87 |
| 115 | #define IRCC_CFGA_IRDA_SIR_A 0x08 | 115 | #define IRCC_CFGA_IRDA_SIR_A 0x08 |
| 116 | #define IRCC_CFGA_ASK_SIR 0x10 | 116 | #define IRCC_CFGA_ASK_SIR 0x10 |
| 117 | #define IRCC_CFGA_IRDA_SIR_B 0x18 | 117 | #define IRCC_CFGA_IRDA_SIR_B 0x18 |
| 118 | #define IRCC_CFGA_IRDA_HDLC 0x20 | 118 | #define IRCC_CFGA_IRDA_HDLC 0x20 |
| 119 | #define IRCC_CFGA_IRDA_4PPM 0x28 | 119 | #define IRCC_CFGA_IRDA_4PPM 0x28 |
| 120 | #define IRCC_CFGA_CONSUMER 0x30 | 120 | #define IRCC_CFGA_CONSUMER 0x30 |
| 121 | #define IRCC_CFGA_RAW_IR 0x38 | 121 | #define IRCC_CFGA_RAW_IR 0x38 |
| @@ -130,7 +130,7 @@ | |||
| 130 | #define IRCC_CFGB_LPBCK_TX_CRC 0x10 | 130 | #define IRCC_CFGB_LPBCK_TX_CRC 0x10 |
| 131 | #define IRCC_CFGB_NOWAIT 0x08 | 131 | #define IRCC_CFGB_NOWAIT 0x08 |
| 132 | #define IRCC_CFGB_STRING_MOVE 0x04 | 132 | #define IRCC_CFGB_STRING_MOVE 0x04 |
| 133 | #define IRCC_CFGB_DMA_BURST 0x02 | 133 | #define IRCC_CFGB_DMA_BURST 0x02 |
| 134 | #define IRCC_CFGB_DMA_ENABLE 0x01 | 134 | #define IRCC_CFGB_DMA_ENABLE 0x01 |
| 135 | 135 | ||
| 136 | #define IRCC_CFGB_MUX_COM 0x00 | 136 | #define IRCC_CFGB_MUX_COM 0x00 |
| @@ -141,11 +141,11 @@ | |||
| 141 | /* Register block 3 - Identification Registers! */ | 141 | /* Register block 3 - Identification Registers! */ |
| 142 | #define IRCC_ID_HIGH 0x00 /* 0x10 */ | 142 | #define IRCC_ID_HIGH 0x00 /* 0x10 */ |
| 143 | #define IRCC_ID_LOW 0x01 /* 0xB8 */ | 143 | #define IRCC_ID_LOW 0x01 /* 0xB8 */ |
| 144 | #define IRCC_CHIP_ID 0x02 /* 0xF1 */ | 144 | #define IRCC_CHIP_ID 0x02 /* 0xF1 */ |
| 145 | #define IRCC_VERSION 0x03 /* 0x01 */ | 145 | #define IRCC_VERSION 0x03 /* 0x01 */ |
| 146 | #define IRCC_INTERFACE 0x04 /* low 4 = DMA, high 4 = IRQ */ | 146 | #define IRCC_INTERFACE 0x04 /* low 4 = DMA, high 4 = IRQ */ |
| 147 | #define IRCC_INTERFACE_DMA_MASK 0x0F /* low 4 = DMA, high 4 = IRQ */ | 147 | #define IRCC_INTERFACE_DMA_MASK 0x0F /* low 4 = DMA, high 4 = IRQ */ |
| 148 | #define IRCC_INTERFACE_IRQ_MASK 0xF0 /* low 4 = DMA, high 4 = IRQ */ | 148 | #define IRCC_INTERFACE_IRQ_MASK 0xF0 /* low 4 = DMA, high 4 = IRQ */ |
| 149 | 149 | ||
| 150 | /* Register block 4 - IrDA */ | 150 | /* Register block 4 - IrDA */ |
| 151 | #define IRCC_CONTROL 0x00 | 151 | #define IRCC_CONTROL 0x00 |
| @@ -163,10 +163,10 @@ | |||
| 163 | 163 | ||
| 164 | /* Register block 5 - IrDA */ | 164 | /* Register block 5 - IrDA */ |
| 165 | #define IRCC_ATC 0x00 | 165 | #define IRCC_ATC 0x00 |
| 166 | #define IRCC_ATC_nPROGREADY 0x80 | 166 | #define IRCC_ATC_nPROGREADY 0x80 |
| 167 | #define IRCC_ATC_SPEED 0x40 | 167 | #define IRCC_ATC_SPEED 0x40 |
| 168 | #define IRCC_ATC_ENABLE 0x20 | 168 | #define IRCC_ATC_ENABLE 0x20 |
| 169 | #define IRCC_ATC_MASK 0xE0 | 169 | #define IRCC_ATC_MASK 0xE0 |
| 170 | 170 | ||
| 171 | 171 | ||
| 172 | #define IRCC_IRHALFDUPLEX_TIMEOUT 0x01 | 172 | #define IRCC_IRHALFDUPLEX_TIMEOUT 0x01 |
| @@ -178,8 +178,8 @@ | |||
| 178 | */ | 178 | */ |
| 179 | 179 | ||
| 180 | #define SMSC_IRCC2_MAX_SIR_SPEED 115200 | 180 | #define SMSC_IRCC2_MAX_SIR_SPEED 115200 |
| 181 | #define SMSC_IRCC2_FIR_CHIP_IO_EXTENT 8 | 181 | #define SMSC_IRCC2_FIR_CHIP_IO_EXTENT 8 |
| 182 | #define SMSC_IRCC2_SIR_CHIP_IO_EXTENT 8 | 182 | #define SMSC_IRCC2_SIR_CHIP_IO_EXTENT 8 |
| 183 | #define SMSC_IRCC2_FIFO_SIZE 16 | 183 | #define SMSC_IRCC2_FIFO_SIZE 16 |
| 184 | #define SMSC_IRCC2_FIFO_THRESHOLD 64 | 184 | #define SMSC_IRCC2_FIFO_THRESHOLD 64 |
| 185 | /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ | 185 | /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ |
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index dc5d089bf184..3d56cf5a4e23 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * Copyright (C) 2001 Kyle A. Lucke (klucke@us.ibm.com), IBM Corp. | 4 | * Copyright (C) 2001 Kyle A. Lucke (klucke@us.ibm.com), IBM Corp. |
| 5 | * Substantially cleaned up by: | 5 | * Substantially cleaned up by: |
| 6 | * Copyright (C) 2003 David Gibson <dwg@au1.ibm.com>, IBM Corporation. | 6 | * Copyright (C) 2003 David Gibson <dwg@au1.ibm.com>, IBM Corporation. |
| 7 | * Copyright (C) 2004-2005 Michael Ellerman, IBM Corporation. | ||
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 2234a8f05eb2..7cefe5507b9e 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /************************************************************************ | 1 | /************************************************************************ |
| 2 | * regs.h: A Linux PCI-X Ethernet driver for S2IO 10GbE Server NIC | 2 | * regs.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC |
| 3 | * Copyright(c) 2002-2005 Neterion Inc. | 3 | * Copyright(c) 2002-2005 Neterion Inc. |
| 4 | 4 | ||
| 5 | * This software may be used and distributed according to the terms of | 5 | * This software may be used and distributed according to the terms of |
| @@ -713,13 +713,16 @@ typedef struct _XENA_dev_config { | |||
| 713 | u64 mc_err_reg; | 713 | u64 mc_err_reg; |
| 714 | #define MC_ERR_REG_ECC_DB_ERR_L BIT(14) | 714 | #define MC_ERR_REG_ECC_DB_ERR_L BIT(14) |
| 715 | #define MC_ERR_REG_ECC_DB_ERR_U BIT(15) | 715 | #define MC_ERR_REG_ECC_DB_ERR_U BIT(15) |
| 716 | #define MC_ERR_REG_MIRI_ECC_DB_ERR_0 BIT(18) | ||
| 717 | #define MC_ERR_REG_MIRI_ECC_DB_ERR_1 BIT(20) | ||
| 716 | #define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22) | 718 | #define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22) |
| 717 | #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) | 719 | #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) |
| 718 | #define MC_ERR_REG_SM_ERR BIT(31) | 720 | #define MC_ERR_REG_SM_ERR BIT(31) |
| 719 | #define MC_ERR_REG_ECC_ALL_SNG (BIT(6) | \ | 721 | #define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\ |
| 720 | BIT(7) | BIT(17) | BIT(19)) | 722 | BIT(6) | BIT(7) | BIT(17) | BIT(19)) |
| 721 | #define MC_ERR_REG_ECC_ALL_DBL (BIT(14) | \ | 723 | #define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\ |
| 722 | BIT(15) | BIT(18) | BIT(20)) | 724 | BIT(13) | BIT(14) | BIT(15) |\ |
| 725 | BIT(18) | BIT(20)) | ||
| 723 | u64 mc_err_mask; | 726 | u64 mc_err_mask; |
| 724 | u64 mc_err_alarm; | 727 | u64 mc_err_alarm; |
| 725 | 728 | ||
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 5dda043bd9d7..c829e6a2e8a6 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /************************************************************************ | 1 | /************************************************************************ |
| 2 | * s2io.c: A Linux PCI-X Ethernet driver for S2IO 10GbE Server NIC | 2 | * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC |
| 3 | * Copyright(c) 2002-2005 Neterion Inc. | 3 | * Copyright(c) 2002-2005 Neterion Inc. |
| 4 | 4 | ||
| 5 | * This software may be used and distributed according to the terms of | 5 | * This software may be used and distributed according to the terms of |
| @@ -28,7 +28,7 @@ | |||
| 28 | * explaination of all the variables. | 28 | * explaination of all the variables. |
| 29 | * rx_ring_num : This can be used to program the number of receive rings used | 29 | * rx_ring_num : This can be used to program the number of receive rings used |
| 30 | * in the driver. | 30 | * in the driver. |
| 31 | * rx_ring_len: This defines the number of descriptors each ring can have. This | 31 | * rx_ring_sz: This defines the number of descriptors each ring can have. This |
| 32 | * is also an array of size 8. | 32 | * is also an array of size 8. |
| 33 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. | 33 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. |
| 34 | * tx_fifo_len: This too is an array of 8. Each element defines the number of | 34 | * tx_fifo_len: This too is an array of 8. Each element defines the number of |
| @@ -67,7 +67,7 @@ | |||
| 67 | 67 | ||
| 68 | /* S2io Driver name & version. */ | 68 | /* S2io Driver name & version. */ |
| 69 | static char s2io_driver_name[] = "Neterion"; | 69 | static char s2io_driver_name[] = "Neterion"; |
| 70 | static char s2io_driver_version[] = "Version 2.0.3.1"; | 70 | static char s2io_driver_version[] = "Version 2.0.8.1"; |
| 71 | 71 | ||
| 72 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) | 72 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) |
| 73 | { | 73 | { |
| @@ -354,7 +354,7 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
| 354 | int lst_size, lst_per_page; | 354 | int lst_size, lst_per_page; |
| 355 | struct net_device *dev = nic->dev; | 355 | struct net_device *dev = nic->dev; |
| 356 | #ifdef CONFIG_2BUFF_MODE | 356 | #ifdef CONFIG_2BUFF_MODE |
| 357 | u64 tmp; | 357 | unsigned long tmp; |
| 358 | buffAdd_t *ba; | 358 | buffAdd_t *ba; |
| 359 | #endif | 359 | #endif |
| 360 | 360 | ||
| @@ -404,7 +404,7 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
| 404 | config->tx_cfg[i].fifo_len - 1; | 404 | config->tx_cfg[i].fifo_len - 1; |
| 405 | mac_control->fifos[i].fifo_no = i; | 405 | mac_control->fifos[i].fifo_no = i; |
| 406 | mac_control->fifos[i].nic = nic; | 406 | mac_control->fifos[i].nic = nic; |
| 407 | mac_control->fifos[i].max_txds = MAX_SKB_FRAGS; | 407 | mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 1; |
| 408 | 408 | ||
| 409 | for (j = 0; j < page_num; j++) { | 409 | for (j = 0; j < page_num; j++) { |
| 410 | int k = 0; | 410 | int k = 0; |
| @@ -418,6 +418,26 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
| 418 | DBG_PRINT(ERR_DBG, "failed for TxDL\n"); | 418 | DBG_PRINT(ERR_DBG, "failed for TxDL\n"); |
| 419 | return -ENOMEM; | 419 | return -ENOMEM; |
| 420 | } | 420 | } |
| 421 | /* If we got a zero DMA address(can happen on | ||
| 422 | * certain platforms like PPC), reallocate. | ||
| 423 | * Store virtual address of page we don't want, | ||
| 424 | * to be freed later. | ||
| 425 | */ | ||
| 426 | if (!tmp_p) { | ||
| 427 | mac_control->zerodma_virt_addr = tmp_v; | ||
| 428 | DBG_PRINT(INIT_DBG, | ||
| 429 | "%s: Zero DMA address for TxDL. ", dev->name); | ||
| 430 | DBG_PRINT(INIT_DBG, | ||
| 431 | "Virtual address %llx\n", (u64)tmp_v); | ||
| 432 | tmp_v = pci_alloc_consistent(nic->pdev, | ||
| 433 | PAGE_SIZE, &tmp_p); | ||
| 434 | if (!tmp_v) { | ||
| 435 | DBG_PRINT(ERR_DBG, | ||
| 436 | "pci_alloc_consistent "); | ||
| 437 | DBG_PRINT(ERR_DBG, "failed for TxDL\n"); | ||
| 438 | return -ENOMEM; | ||
| 439 | } | ||
| 440 | } | ||
| 421 | while (k < lst_per_page) { | 441 | while (k < lst_per_page) { |
| 422 | int l = (j * lst_per_page) + k; | 442 | int l = (j * lst_per_page) + k; |
| 423 | if (l == config->tx_cfg[i].fifo_len) | 443 | if (l == config->tx_cfg[i].fifo_len) |
| @@ -542,18 +562,18 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
| 542 | (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); | 562 | (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); |
| 543 | if (!ba->ba_0_org) | 563 | if (!ba->ba_0_org) |
| 544 | return -ENOMEM; | 564 | return -ENOMEM; |
| 545 | tmp = (u64) ba->ba_0_org; | 565 | tmp = (unsigned long) ba->ba_0_org; |
| 546 | tmp += ALIGN_SIZE; | 566 | tmp += ALIGN_SIZE; |
| 547 | tmp &= ~((u64) ALIGN_SIZE); | 567 | tmp &= ~((unsigned long) ALIGN_SIZE); |
| 548 | ba->ba_0 = (void *) tmp; | 568 | ba->ba_0 = (void *) tmp; |
| 549 | 569 | ||
| 550 | ba->ba_1_org = (void *) kmalloc | 570 | ba->ba_1_org = (void *) kmalloc |
| 551 | (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); | 571 | (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); |
| 552 | if (!ba->ba_1_org) | 572 | if (!ba->ba_1_org) |
| 553 | return -ENOMEM; | 573 | return -ENOMEM; |
| 554 | tmp = (u64) ba->ba_1_org; | 574 | tmp = (unsigned long) ba->ba_1_org; |
| 555 | tmp += ALIGN_SIZE; | 575 | tmp += ALIGN_SIZE; |
| 556 | tmp &= ~((u64) ALIGN_SIZE); | 576 | tmp &= ~((unsigned long) ALIGN_SIZE); |
| 557 | ba->ba_1 = (void *) tmp; | 577 | ba->ba_1 = (void *) tmp; |
| 558 | k++; | 578 | k++; |
| 559 | } | 579 | } |
| @@ -600,7 +620,7 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
| 600 | mac_info_t *mac_control; | 620 | mac_info_t *mac_control; |
| 601 | struct config_param *config; | 621 | struct config_param *config; |
| 602 | int lst_size, lst_per_page; | 622 | int lst_size, lst_per_page; |
| 603 | 623 | struct net_device *dev = nic->dev; | |
| 604 | 624 | ||
| 605 | if (!nic) | 625 | if (!nic) |
| 606 | return; | 626 | return; |
| @@ -616,9 +636,10 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
| 616 | lst_per_page); | 636 | lst_per_page); |
| 617 | for (j = 0; j < page_num; j++) { | 637 | for (j = 0; j < page_num; j++) { |
| 618 | int mem_blks = (j * lst_per_page); | 638 | int mem_blks = (j * lst_per_page); |
| 619 | if ((!mac_control->fifos[i].list_info) || | 639 | if (!mac_control->fifos[i].list_info) |
| 620 | (!mac_control->fifos[i].list_info[mem_blks]. | 640 | return; |
| 621 | list_virt_addr)) | 641 | if (!mac_control->fifos[i].list_info[mem_blks]. |
| 642 | list_virt_addr) | ||
| 622 | break; | 643 | break; |
| 623 | pci_free_consistent(nic->pdev, PAGE_SIZE, | 644 | pci_free_consistent(nic->pdev, PAGE_SIZE, |
| 624 | mac_control->fifos[i]. | 645 | mac_control->fifos[i]. |
| @@ -628,6 +649,18 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
| 628 | list_info[mem_blks]. | 649 | list_info[mem_blks]. |
| 629 | list_phy_addr); | 650 | list_phy_addr); |
| 630 | } | 651 | } |
| 652 | /* If we got a zero DMA address during allocation, | ||
| 653 | * free the page now | ||
| 654 | */ | ||
| 655 | if (mac_control->zerodma_virt_addr) { | ||
| 656 | pci_free_consistent(nic->pdev, PAGE_SIZE, | ||
| 657 | mac_control->zerodma_virt_addr, | ||
| 658 | (dma_addr_t)0); | ||
| 659 | DBG_PRINT(INIT_DBG, | ||
| 660 | "%s: Freeing TxDL with zero DMA addr. ", dev->name); | ||
| 661 | DBG_PRINT(INIT_DBG, "Virtual address %llx\n", | ||
| 662 | (u64)(mac_control->zerodma_virt_addr)); | ||
| 663 | } | ||
| 631 | kfree(mac_control->fifos[i].list_info); | 664 | kfree(mac_control->fifos[i].list_info); |
| 632 | } | 665 | } |
| 633 | 666 | ||
| @@ -2479,9 +2512,10 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
| 2479 | #endif | 2512 | #endif |
| 2480 | spin_lock(&nic->rx_lock); | 2513 | spin_lock(&nic->rx_lock); |
| 2481 | if (atomic_read(&nic->card_state) == CARD_DOWN) { | 2514 | if (atomic_read(&nic->card_state) == CARD_DOWN) { |
| 2482 | DBG_PRINT(ERR_DBG, "%s: %s going down for reset\n", | 2515 | DBG_PRINT(INTR_DBG, "%s: %s going down for reset\n", |
| 2483 | __FUNCTION__, dev->name); | 2516 | __FUNCTION__, dev->name); |
| 2484 | spin_unlock(&nic->rx_lock); | 2517 | spin_unlock(&nic->rx_lock); |
| 2518 | return; | ||
| 2485 | } | 2519 | } |
| 2486 | 2520 | ||
| 2487 | get_info = ring_data->rx_curr_get_info; | 2521 | get_info = ring_data->rx_curr_get_info; |
| @@ -2596,8 +2630,14 @@ static void tx_intr_handler(fifo_info_t *fifo_data) | |||
| 2596 | if (txdlp->Control_1 & TXD_T_CODE) { | 2630 | if (txdlp->Control_1 & TXD_T_CODE) { |
| 2597 | unsigned long long err; | 2631 | unsigned long long err; |
| 2598 | err = txdlp->Control_1 & TXD_T_CODE; | 2632 | err = txdlp->Control_1 & TXD_T_CODE; |
| 2599 | DBG_PRINT(ERR_DBG, "***TxD error %llx\n", | 2633 | if ((err >> 48) == 0xA) { |
| 2600 | err); | 2634 | DBG_PRINT(TX_DBG, "TxD returned due \ |
| 2635 | to loss of link\n"); | ||
| 2636 | } | ||
| 2637 | else { | ||
| 2638 | DBG_PRINT(ERR_DBG, "***TxD error \ | ||
| 2639 | %llx\n", err); | ||
| 2640 | } | ||
| 2601 | } | 2641 | } |
| 2602 | 2642 | ||
| 2603 | skb = (struct sk_buff *) ((unsigned long) | 2643 | skb = (struct sk_buff *) ((unsigned long) |
| @@ -2689,12 +2729,16 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 2689 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { | 2729 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { |
| 2690 | nic->mac_control.stats_info->sw_stat. | 2730 | nic->mac_control.stats_info->sw_stat. |
| 2691 | double_ecc_errs++; | 2731 | double_ecc_errs++; |
| 2692 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", | 2732 | DBG_PRINT(INIT_DBG, "%s: Device indicates ", |
| 2693 | dev->name); | 2733 | dev->name); |
| 2694 | DBG_PRINT(ERR_DBG, "double ECC error!!\n"); | 2734 | DBG_PRINT(INIT_DBG, "double ECC error!!\n"); |
| 2695 | if (nic->device_type != XFRAME_II_DEVICE) { | 2735 | if (nic->device_type != XFRAME_II_DEVICE) { |
| 2696 | netif_stop_queue(dev); | 2736 | /* Reset XframeI only if critical error */ |
| 2697 | schedule_work(&nic->rst_timer_task); | 2737 | if (val64 & (MC_ERR_REG_MIRI_ECC_DB_ERR_0 | |
| 2738 | MC_ERR_REG_MIRI_ECC_DB_ERR_1)) { | ||
| 2739 | netif_stop_queue(dev); | ||
| 2740 | schedule_work(&nic->rst_timer_task); | ||
| 2741 | } | ||
| 2698 | } | 2742 | } |
| 2699 | } else { | 2743 | } else { |
| 2700 | nic->mac_control.stats_info->sw_stat. | 2744 | nic->mac_control.stats_info->sw_stat. |
| @@ -2706,7 +2750,8 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 2706 | val64 = readq(&bar0->serr_source); | 2750 | val64 = readq(&bar0->serr_source); |
| 2707 | if (val64 & SERR_SOURCE_ANY) { | 2751 | if (val64 & SERR_SOURCE_ANY) { |
| 2708 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); | 2752 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); |
| 2709 | DBG_PRINT(ERR_DBG, "serious error!!\n"); | 2753 | DBG_PRINT(ERR_DBG, "serious error %llx!!\n", |
| 2754 | (unsigned long long)val64); | ||
| 2710 | netif_stop_queue(dev); | 2755 | netif_stop_queue(dev); |
| 2711 | schedule_work(&nic->rst_timer_task); | 2756 | schedule_work(&nic->rst_timer_task); |
| 2712 | } | 2757 | } |
| @@ -3130,7 +3175,7 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 3130 | queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; | 3175 | queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; |
| 3131 | /* Avoid "put" pointer going beyond "get" pointer */ | 3176 | /* Avoid "put" pointer going beyond "get" pointer */ |
| 3132 | if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { | 3177 | if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { |
| 3133 | DBG_PRINT(ERR_DBG, "Error in xmit, No free TXDs.\n"); | 3178 | DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); |
| 3134 | netif_stop_queue(dev); | 3179 | netif_stop_queue(dev); |
| 3135 | dev_kfree_skb(skb); | 3180 | dev_kfree_skb(skb); |
| 3136 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 3181 | spin_unlock_irqrestore(&sp->tx_lock, flags); |
| @@ -3528,7 +3573,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
| 3528 | 3573 | ||
| 3529 | val64 = readq(&bar0->mac_cfg); | 3574 | val64 = readq(&bar0->mac_cfg); |
| 3530 | sp->promisc_flg = 1; | 3575 | sp->promisc_flg = 1; |
| 3531 | DBG_PRINT(ERR_DBG, "%s: entered promiscuous mode\n", | 3576 | DBG_PRINT(INFO_DBG, "%s: entered promiscuous mode\n", |
| 3532 | dev->name); | 3577 | dev->name); |
| 3533 | } else if (!(dev->flags & IFF_PROMISC) && (sp->promisc_flg)) { | 3578 | } else if (!(dev->flags & IFF_PROMISC) && (sp->promisc_flg)) { |
| 3534 | /* Remove the NIC from promiscuous mode */ | 3579 | /* Remove the NIC from promiscuous mode */ |
| @@ -3543,7 +3588,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
| 3543 | 3588 | ||
| 3544 | val64 = readq(&bar0->mac_cfg); | 3589 | val64 = readq(&bar0->mac_cfg); |
| 3545 | sp->promisc_flg = 0; | 3590 | sp->promisc_flg = 0; |
| 3546 | DBG_PRINT(ERR_DBG, "%s: left promiscuous mode\n", | 3591 | DBG_PRINT(INFO_DBG, "%s: left promiscuous mode\n", |
| 3547 | dev->name); | 3592 | dev->name); |
| 3548 | } | 3593 | } |
| 3549 | 3594 | ||
| @@ -5325,7 +5370,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 5325 | break; | 5370 | break; |
| 5326 | } | 5371 | } |
| 5327 | } | 5372 | } |
| 5328 | config->max_txds = MAX_SKB_FRAGS; | 5373 | config->max_txds = MAX_SKB_FRAGS + 1; |
| 5329 | 5374 | ||
| 5330 | /* Rx side parameters. */ | 5375 | /* Rx side parameters. */ |
| 5331 | if (rx_ring_sz[0] == 0) | 5376 | if (rx_ring_sz[0] == 0) |
| @@ -5525,9 +5570,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 5525 | if (sp->device_type & XFRAME_II_DEVICE) { | 5570 | if (sp->device_type & XFRAME_II_DEVICE) { |
| 5526 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", | 5571 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", |
| 5527 | dev->name); | 5572 | dev->name); |
| 5528 | DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n", | 5573 | DBG_PRINT(ERR_DBG, "(rev %d), %s", |
| 5529 | get_xena_rev_id(sp->pdev), | 5574 | get_xena_rev_id(sp->pdev), |
| 5530 | s2io_driver_version); | 5575 | s2io_driver_version); |
| 5576 | #ifdef CONFIG_2BUFF_MODE | ||
| 5577 | DBG_PRINT(ERR_DBG, ", Buffer mode %d",2); | ||
| 5578 | #endif | ||
| 5579 | |||
| 5580 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); | ||
| 5531 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | 5581 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", |
| 5532 | sp->def_mac_addr[0].mac_addr[0], | 5582 | sp->def_mac_addr[0].mac_addr[0], |
| 5533 | sp->def_mac_addr[0].mac_addr[1], | 5583 | sp->def_mac_addr[0].mac_addr[1], |
| @@ -5544,9 +5594,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 5544 | } else { | 5594 | } else { |
| 5545 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", | 5595 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", |
| 5546 | dev->name); | 5596 | dev->name); |
| 5547 | DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n", | 5597 | DBG_PRINT(ERR_DBG, "(rev %d), %s", |
| 5548 | get_xena_rev_id(sp->pdev), | 5598 | get_xena_rev_id(sp->pdev), |
| 5549 | s2io_driver_version); | 5599 | s2io_driver_version); |
| 5600 | #ifdef CONFIG_2BUFF_MODE | ||
| 5601 | DBG_PRINT(ERR_DBG, ", Buffer mode %d",2); | ||
| 5602 | #endif | ||
| 5603 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); | ||
| 5550 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | 5604 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", |
| 5551 | sp->def_mac_addr[0].mac_addr[0], | 5605 | sp->def_mac_addr[0].mac_addr[0], |
| 5552 | sp->def_mac_addr[0].mac_addr[1], | 5606 | sp->def_mac_addr[0].mac_addr[1], |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index bc64d967f080..89151cb52181 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /************************************************************************ | 1 | /************************************************************************ |
| 2 | * s2io.h: A Linux PCI-X Ethernet driver for S2IO 10GbE Server NIC | 2 | * s2io.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC |
| 3 | * Copyright(c) 2002-2005 Neterion Inc. | 3 | * Copyright(c) 2002-2005 Neterion Inc. |
| 4 | 4 | ||
| 5 | * This software may be used and distributed according to the terms of | 5 | * This software may be used and distributed according to the terms of |
| @@ -622,6 +622,9 @@ typedef struct mac_info { | |||
| 622 | /* Fifo specific structure */ | 622 | /* Fifo specific structure */ |
| 623 | fifo_info_t fifos[MAX_TX_FIFOS]; | 623 | fifo_info_t fifos[MAX_TX_FIFOS]; |
| 624 | 624 | ||
| 625 | /* Save virtual address of TxD page with zero DMA addr(if any) */ | ||
| 626 | void *zerodma_virt_addr; | ||
| 627 | |||
| 625 | /* rx side stuff */ | 628 | /* rx side stuff */ |
| 626 | /* Ring specific structure */ | 629 | /* Ring specific structure */ |
| 627 | ring_info_t rings[MAX_RX_RINGS]; | 630 | ring_info_t rings[MAX_RX_RINGS]; |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index a9b06b8d8e3f..ac9ce6509eee 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
| @@ -986,7 +986,7 @@ static const char * chip_ids[ 16 ] = { | |||
| 986 | }) | 986 | }) |
| 987 | #endif | 987 | #endif |
| 988 | 988 | ||
| 989 | #if SMC_CAN_USE_DATACS | 989 | #ifdef SMC_CAN_USE_DATACS |
| 990 | #define SMC_PUSH_DATA(p, l) \ | 990 | #define SMC_PUSH_DATA(p, l) \ |
| 991 | if ( lp->datacs ) { \ | 991 | if ( lp->datacs ) { \ |
| 992 | unsigned char *__ptr = (p); \ | 992 | unsigned char *__ptr = (p); \ |
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c new file mode 100644 index 000000000000..4e19220473d0 --- /dev/null +++ b/drivers/net/spider_net.c | |||
| @@ -0,0 +1,2334 @@ | |||
| 1 | /* | ||
| 2 | * Network device driver for Cell Processor-Based Blade | ||
| 3 | * | ||
| 4 | * (C) Copyright IBM Corp. 2005 | ||
| 5 | * | ||
| 6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | ||
| 7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/config.h> | ||
| 25 | |||
| 26 | #include <linux/compiler.h> | ||
| 27 | #include <linux/crc32.h> | ||
| 28 | #include <linux/delay.h> | ||
| 29 | #include <linux/etherdevice.h> | ||
| 30 | #include <linux/ethtool.h> | ||
| 31 | #include <linux/firmware.h> | ||
| 32 | #include <linux/if_vlan.h> | ||
| 33 | #include <linux/init.h> | ||
| 34 | #include <linux/ioport.h> | ||
| 35 | #include <linux/ip.h> | ||
| 36 | #include <linux/kernel.h> | ||
| 37 | #include <linux/mii.h> | ||
| 38 | #include <linux/module.h> | ||
| 39 | #include <linux/netdevice.h> | ||
| 40 | #include <linux/device.h> | ||
| 41 | #include <linux/pci.h> | ||
| 42 | #include <linux/skbuff.h> | ||
| 43 | #include <linux/slab.h> | ||
| 44 | #include <linux/tcp.h> | ||
| 45 | #include <linux/types.h> | ||
| 46 | #include <linux/wait.h> | ||
| 47 | #include <linux/workqueue.h> | ||
| 48 | #include <asm/bitops.h> | ||
| 49 | #include <asm/pci-bridge.h> | ||
| 50 | #include <net/checksum.h> | ||
| 51 | |||
| 52 | #include "spider_net.h" | ||
| 53 | |||
| 54 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com> and Jens Osterkamp " \ | ||
| 55 | "<Jens.Osterkamp@de.ibm.com>"); | ||
| 56 | MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); | ||
| 57 | MODULE_LICENSE("GPL"); | ||
| 58 | |||
| 59 | static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; | ||
| 60 | static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; | ||
| 61 | |||
| 62 | module_param(rx_descriptors, int, 0644); | ||
| 63 | module_param(tx_descriptors, int, 0644); | ||
| 64 | |||
| 65 | MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ | ||
| 66 | "in rx chains"); | ||
| 67 | MODULE_PARM_DESC(tx_descriptors, "number of descriptors used " \ | ||
| 68 | "in tx chain"); | ||
| 69 | |||
| 70 | char spider_net_driver_name[] = "spidernet"; | ||
| 71 | |||
| 72 | static struct pci_device_id spider_net_pci_tbl[] = { | ||
| 73 | { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SPIDER_NET, | ||
| 74 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 75 | { 0, } | ||
| 76 | }; | ||
| 77 | |||
| 78 | MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl); | ||
| 79 | |||
| 80 | /** | ||
| 81 | * spider_net_read_reg - reads an SMMIO register of a card | ||
| 82 | * @card: device structure | ||
| 83 | * @reg: register to read from | ||
| 84 | * | ||
| 85 | * returns the content of the specified SMMIO register. | ||
| 86 | */ | ||
| 87 | static u32 | ||
| 88 | spider_net_read_reg(struct spider_net_card *card, u32 reg) | ||
| 89 | { | ||
| 90 | u32 value; | ||
| 91 | |||
| 92 | value = readl(card->regs + reg); | ||
| 93 | value = le32_to_cpu(value); | ||
| 94 | |||
| 95 | return value; | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * spider_net_write_reg - writes to an SMMIO register of a card | ||
| 100 | * @card: device structure | ||
| 101 | * @reg: register to write to | ||
| 102 | * @value: value to write into the specified SMMIO register | ||
| 103 | */ | ||
| 104 | static void | ||
| 105 | spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) | ||
| 106 | { | ||
| 107 | value = cpu_to_le32(value); | ||
| 108 | writel(value, card->regs + reg); | ||
| 109 | } | ||
| 110 | |||
| 111 | /** | ||
| 112 | * spider_net_write_reg_sync - writes to an SMMIO register of a card | ||
| 113 | * @card: device structure | ||
| 114 | * @reg: register to write to | ||
| 115 | * @value: value to write into the specified SMMIO register | ||
| 116 | * | ||
| 117 | * Unlike spider_net_write_reg, this will also make sure the | ||
| 118 | * data arrives on the card by reading the reg again. | ||
| 119 | */ | ||
| 120 | static void | ||
| 121 | spider_net_write_reg_sync(struct spider_net_card *card, u32 reg, u32 value) | ||
| 122 | { | ||
| 123 | value = cpu_to_le32(value); | ||
| 124 | writel(value, card->regs + reg); | ||
| 125 | (void)readl(card->regs + reg); | ||
| 126 | } | ||
| 127 | |||
| 128 | /** | ||
| 129 | * spider_net_rx_irq_off - switch off rx irq on this spider card | ||
| 130 | * @card: device structure | ||
| 131 | * | ||
| 132 | * switches off rx irq by masking them out in the GHIINTnMSK register | ||
| 133 | */ | ||
| 134 | static void | ||
| 135 | spider_net_rx_irq_off(struct spider_net_card *card) | ||
| 136 | { | ||
| 137 | u32 regvalue; | ||
| 138 | unsigned long flags; | ||
| 139 | |||
| 140 | spin_lock_irqsave(&card->intmask_lock, flags); | ||
| 141 | regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); | ||
| 142 | regvalue &= ~SPIDER_NET_RXINT; | ||
| 143 | spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); | ||
| 144 | spin_unlock_irqrestore(&card->intmask_lock, flags); | ||
| 145 | } | ||
| 146 | |||
| 147 | /** spider_net_write_phy - write to phy register | ||
| 148 | * @netdev: adapter to be written to | ||
| 149 | * @mii_id: id of MII | ||
| 150 | * @reg: PHY register | ||
| 151 | * @val: value to be written to phy register | ||
| 152 | * | ||
| 153 | * spider_net_write_phy_register writes to an arbitrary PHY | ||
| 154 | * register via the spider GPCWOPCMD register. We assume the queue does | ||
| 155 | * not run full (not more than 15 commands outstanding). | ||
| 156 | **/ | ||
| 157 | static void | ||
| 158 | spider_net_write_phy(struct net_device *netdev, int mii_id, | ||
| 159 | int reg, int val) | ||
| 160 | { | ||
| 161 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 162 | u32 writevalue; | ||
| 163 | |||
| 164 | writevalue = ((u32)mii_id << 21) | | ||
| 165 | ((u32)reg << 16) | ((u32)val); | ||
| 166 | |||
| 167 | spider_net_write_reg(card, SPIDER_NET_GPCWOPCMD, writevalue); | ||
| 168 | } | ||
| 169 | |||
| 170 | /** spider_net_read_phy - read from phy register | ||
| 171 | * @netdev: network device to be read from | ||
| 172 | * @mii_id: id of MII | ||
| 173 | * @reg: PHY register | ||
| 174 | * | ||
| 175 | * Returns value read from PHY register | ||
| 176 | * | ||
| 177 | * spider_net_write_phy reads from an arbitrary PHY | ||
| 178 | * register via the spider GPCROPCMD register | ||
| 179 | **/ | ||
| 180 | static int | ||
| 181 | spider_net_read_phy(struct net_device *netdev, int mii_id, int reg) | ||
| 182 | { | ||
| 183 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 184 | u32 readvalue; | ||
| 185 | |||
| 186 | readvalue = ((u32)mii_id << 21) | ((u32)reg << 16); | ||
| 187 | spider_net_write_reg(card, SPIDER_NET_GPCROPCMD, readvalue); | ||
| 188 | |||
| 189 | /* we don't use semaphores to wait for an SPIDER_NET_GPROPCMPINT | ||
| 190 | * interrupt, as we poll for the completion of the read operation | ||
| 191 | * in spider_net_read_phy. Should take about 50 us */ | ||
| 192 | do { | ||
| 193 | readvalue = spider_net_read_reg(card, SPIDER_NET_GPCROPCMD); | ||
| 194 | } while (readvalue & SPIDER_NET_GPREXEC); | ||
| 195 | |||
| 196 | readvalue &= SPIDER_NET_GPRDAT_MASK; | ||
| 197 | |||
| 198 | return readvalue; | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * spider_net_rx_irq_on - switch on rx irq on this spider card | ||
| 203 | * @card: device structure | ||
| 204 | * | ||
| 205 | * switches on rx irq by enabling them in the GHIINTnMSK register | ||
| 206 | */ | ||
| 207 | static void | ||
| 208 | spider_net_rx_irq_on(struct spider_net_card *card) | ||
| 209 | { | ||
| 210 | u32 regvalue; | ||
| 211 | unsigned long flags; | ||
| 212 | |||
| 213 | spin_lock_irqsave(&card->intmask_lock, flags); | ||
| 214 | regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); | ||
| 215 | regvalue |= SPIDER_NET_RXINT; | ||
| 216 | spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); | ||
| 217 | spin_unlock_irqrestore(&card->intmask_lock, flags); | ||
| 218 | } | ||
| 219 | |||
| 220 | /** | ||
| 221 | * spider_net_tx_irq_off - switch off tx irq on this spider card | ||
| 222 | * @card: device structure | ||
| 223 | * | ||
| 224 | * switches off tx irq by masking them out in the GHIINTnMSK register | ||
| 225 | */ | ||
| 226 | static void | ||
| 227 | spider_net_tx_irq_off(struct spider_net_card *card) | ||
| 228 | { | ||
| 229 | u32 regvalue; | ||
| 230 | unsigned long flags; | ||
| 231 | |||
| 232 | spin_lock_irqsave(&card->intmask_lock, flags); | ||
| 233 | regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); | ||
| 234 | regvalue &= ~SPIDER_NET_TXINT; | ||
| 235 | spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); | ||
| 236 | spin_unlock_irqrestore(&card->intmask_lock, flags); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * spider_net_tx_irq_on - switch on tx irq on this spider card | ||
| 241 | * @card: device structure | ||
| 242 | * | ||
| 243 | * switches on tx irq by enabling them in the GHIINTnMSK register | ||
| 244 | */ | ||
| 245 | static void | ||
| 246 | spider_net_tx_irq_on(struct spider_net_card *card) | ||
| 247 | { | ||
| 248 | u32 regvalue; | ||
| 249 | unsigned long flags; | ||
| 250 | |||
| 251 | spin_lock_irqsave(&card->intmask_lock, flags); | ||
| 252 | regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); | ||
| 253 | regvalue |= SPIDER_NET_TXINT; | ||
| 254 | spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); | ||
| 255 | spin_unlock_irqrestore(&card->intmask_lock, flags); | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * spider_net_set_promisc - sets the unicast address or the promiscuous mode | ||
| 260 | * @card: card structure | ||
| 261 | * | ||
| 262 | * spider_net_set_promisc sets the unicast destination address filter and | ||
| 263 | * thus either allows for non-promisc mode or promisc mode | ||
| 264 | */ | ||
| 265 | static void | ||
| 266 | spider_net_set_promisc(struct spider_net_card *card) | ||
| 267 | { | ||
| 268 | u32 macu, macl; | ||
| 269 | struct net_device *netdev = card->netdev; | ||
| 270 | |||
| 271 | if (netdev->flags & IFF_PROMISC) { | ||
| 272 | /* clear destination entry 0 */ | ||
| 273 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR, 0); | ||
| 274 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR + 0x04, 0); | ||
| 275 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, | ||
| 276 | SPIDER_NET_PROMISC_VALUE); | ||
| 277 | } else { | ||
| 278 | macu = netdev->dev_addr[0]; | ||
| 279 | macu <<= 8; | ||
| 280 | macu |= netdev->dev_addr[1]; | ||
| 281 | memcpy(&macl, &netdev->dev_addr[2], sizeof(macl)); | ||
| 282 | |||
| 283 | macu |= SPIDER_NET_UA_DESCR_VALUE; | ||
| 284 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR, macu); | ||
| 285 | spider_net_write_reg(card, SPIDER_NET_GMRUAFILnR + 0x04, macl); | ||
| 286 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, | ||
| 287 | SPIDER_NET_NONPROMISC_VALUE); | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | /** | ||
| 292 | * spider_net_get_mac_address - read mac address from spider card | ||
| 293 | * @card: device structure | ||
| 294 | * | ||
| 295 | * reads MAC address from GMACUNIMACU and GMACUNIMACL registers | ||
| 296 | */ | ||
| 297 | static int | ||
| 298 | spider_net_get_mac_address(struct net_device *netdev) | ||
| 299 | { | ||
| 300 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 301 | u32 macl, macu; | ||
| 302 | |||
| 303 | macl = spider_net_read_reg(card, SPIDER_NET_GMACUNIMACL); | ||
| 304 | macu = spider_net_read_reg(card, SPIDER_NET_GMACUNIMACU); | ||
| 305 | |||
| 306 | netdev->dev_addr[0] = (macu >> 24) & 0xff; | ||
| 307 | netdev->dev_addr[1] = (macu >> 16) & 0xff; | ||
| 308 | netdev->dev_addr[2] = (macu >> 8) & 0xff; | ||
| 309 | netdev->dev_addr[3] = macu & 0xff; | ||
| 310 | netdev->dev_addr[4] = (macl >> 8) & 0xff; | ||
| 311 | netdev->dev_addr[5] = macl & 0xff; | ||
| 312 | |||
| 313 | if (!is_valid_ether_addr(&netdev->dev_addr[0])) | ||
| 314 | return -EINVAL; | ||
| 315 | |||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | /** | ||
| 320 | * spider_net_get_descr_status -- returns the status of a descriptor | ||
| 321 | * @descr: descriptor to look at | ||
| 322 | * | ||
| 323 | * returns the status as in the dmac_cmd_status field of the descriptor | ||
| 324 | */ | ||
| 325 | static enum spider_net_descr_status | ||
| 326 | spider_net_get_descr_status(struct spider_net_descr *descr) | ||
| 327 | { | ||
| 328 | u32 cmd_status; | ||
| 329 | rmb(); | ||
| 330 | cmd_status = descr->dmac_cmd_status; | ||
| 331 | rmb(); | ||
| 332 | cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT; | ||
| 333 | /* no need to mask out any bits, as cmd_status is 32 bits wide only | ||
| 334 | * (and unsigned) */ | ||
| 335 | return cmd_status; | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * spider_net_set_descr_status -- sets the status of a descriptor | ||
| 340 | * @descr: descriptor to change | ||
| 341 | * @status: status to set in the descriptor | ||
| 342 | * | ||
| 343 | * changes the status to the specified value. Doesn't change other bits | ||
| 344 | * in the status | ||
| 345 | */ | ||
| 346 | static void | ||
| 347 | spider_net_set_descr_status(struct spider_net_descr *descr, | ||
| 348 | enum spider_net_descr_status status) | ||
| 349 | { | ||
| 350 | u32 cmd_status; | ||
| 351 | /* read the status */ | ||
| 352 | mb(); | ||
| 353 | cmd_status = descr->dmac_cmd_status; | ||
| 354 | /* clean the upper 4 bits */ | ||
| 355 | cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO; | ||
| 356 | /* add the status to it */ | ||
| 357 | cmd_status |= ((u32)status)<<SPIDER_NET_DESCR_IND_PROC_SHIFT; | ||
| 358 | /* and write it back */ | ||
| 359 | descr->dmac_cmd_status = cmd_status; | ||
| 360 | wmb(); | ||
| 361 | } | ||
| 362 | |||
| 363 | /** | ||
| 364 | * spider_net_free_chain - free descriptor chain | ||
| 365 | * @card: card structure | ||
| 366 | * @chain: address of chain | ||
| 367 | * | ||
| 368 | */ | ||
| 369 | static void | ||
| 370 | spider_net_free_chain(struct spider_net_card *card, | ||
| 371 | struct spider_net_descr_chain *chain) | ||
| 372 | { | ||
| 373 | struct spider_net_descr *descr; | ||
| 374 | |||
| 375 | for (descr = chain->tail; !descr->bus_addr; descr = descr->next) { | ||
| 376 | pci_unmap_single(card->pdev, descr->bus_addr, | ||
| 377 | SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
| 378 | descr->bus_addr = 0; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | /** | ||
| 383 | * spider_net_init_chain - links descriptor chain | ||
| 384 | * @card: card structure | ||
| 385 | * @chain: address of chain | ||
| 386 | * @start_descr: address of descriptor array | ||
| 387 | * @no: number of descriptors | ||
| 388 | * | ||
| 389 | * we manage a circular list that mirrors the hardware structure, | ||
| 390 | * except that the hardware uses bus addresses. | ||
| 391 | * | ||
| 392 | * returns 0 on success, <0 on failure | ||
| 393 | */ | ||
| 394 | static int | ||
| 395 | spider_net_init_chain(struct spider_net_card *card, | ||
| 396 | struct spider_net_descr_chain *chain, | ||
| 397 | struct spider_net_descr *start_descr, int no) | ||
| 398 | { | ||
| 399 | int i; | ||
| 400 | struct spider_net_descr *descr; | ||
| 401 | |||
| 402 | spin_lock_init(&card->chain_lock); | ||
| 403 | |||
| 404 | descr = start_descr; | ||
| 405 | memset(descr, 0, sizeof(*descr) * no); | ||
| 406 | |||
| 407 | /* set up the hardware pointers in each descriptor */ | ||
| 408 | for (i=0; i<no; i++, descr++) { | ||
| 409 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | ||
| 410 | |||
| 411 | descr->bus_addr = | ||
| 412 | pci_map_single(card->pdev, descr, | ||
| 413 | SPIDER_NET_DESCR_SIZE, | ||
| 414 | PCI_DMA_BIDIRECTIONAL); | ||
| 415 | |||
| 416 | if (descr->bus_addr == DMA_ERROR_CODE) | ||
| 417 | goto iommu_error; | ||
| 418 | |||
| 419 | descr->next = descr + 1; | ||
| 420 | descr->prev = descr - 1; | ||
| 421 | |||
| 422 | } | ||
| 423 | /* do actual circular list */ | ||
| 424 | (descr-1)->next = start_descr; | ||
| 425 | start_descr->prev = descr-1; | ||
| 426 | |||
| 427 | descr = start_descr; | ||
| 428 | for (i=0; i < no; i++, descr++) { | ||
| 429 | descr->next_descr_addr = descr->next->bus_addr; | ||
| 430 | } | ||
| 431 | |||
| 432 | chain->head = start_descr; | ||
| 433 | chain->tail = start_descr; | ||
| 434 | |||
| 435 | return 0; | ||
| 436 | |||
| 437 | iommu_error: | ||
| 438 | descr = start_descr; | ||
| 439 | for (i=0; i < no; i++, descr++) | ||
| 440 | if (descr->bus_addr) | ||
| 441 | pci_unmap_single(card->pdev, descr->bus_addr, | ||
| 442 | SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
| 443 | return -ENOMEM; | ||
| 444 | } | ||
| 445 | |||
| 446 | /** | ||
| 447 | * spider_net_free_rx_chain_contents - frees descr contents in rx chain | ||
| 448 | * @card: card structure | ||
| 449 | * | ||
| 450 | * returns 0 on success, <0 on failure | ||
| 451 | */ | ||
| 452 | static void | ||
| 453 | spider_net_free_rx_chain_contents(struct spider_net_card *card) | ||
| 454 | { | ||
| 455 | struct spider_net_descr *descr; | ||
| 456 | |||
| 457 | descr = card->rx_chain.head; | ||
| 458 | while (descr->next != card->rx_chain.head) { | ||
| 459 | if (descr->skb) { | ||
| 460 | dev_kfree_skb(descr->skb); | ||
| 461 | pci_unmap_single(card->pdev, descr->buf_addr, | ||
| 462 | SPIDER_NET_MAX_MTU, | ||
| 463 | PCI_DMA_BIDIRECTIONAL); | ||
| 464 | } | ||
| 465 | descr = descr->next; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 469 | /** | ||
| 470 | * spider_net_prepare_rx_descr - reinitializes a rx descriptor | ||
| 471 | * @card: card structure | ||
| 472 | * @descr: descriptor to re-init | ||
| 473 | * | ||
| 474 | * return 0 on succes, <0 on failure | ||
| 475 | * | ||
| 476 | * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. | ||
| 477 | * Activate the descriptor state-wise | ||
| 478 | */ | ||
| 479 | static int | ||
| 480 | spider_net_prepare_rx_descr(struct spider_net_card *card, | ||
| 481 | struct spider_net_descr *descr) | ||
| 482 | { | ||
| 483 | int error = 0; | ||
| 484 | int offset; | ||
| 485 | int bufsize; | ||
| 486 | |||
| 487 | /* we need to round up the buffer size to a multiple of 128 */ | ||
| 488 | bufsize = (SPIDER_NET_MAX_MTU + SPIDER_NET_RXBUF_ALIGN - 1) & | ||
| 489 | (~(SPIDER_NET_RXBUF_ALIGN - 1)); | ||
| 490 | |||
| 491 | /* and we need to have it 128 byte aligned, therefore we allocate a | ||
| 492 | * bit more */ | ||
| 493 | /* allocate an skb */ | ||
| 494 | descr->skb = dev_alloc_skb(bufsize + SPIDER_NET_RXBUF_ALIGN - 1); | ||
| 495 | if (!descr->skb) { | ||
| 496 | if (net_ratelimit()) | ||
| 497 | if (netif_msg_rx_err(card)) | ||
| 498 | pr_err("Not enough memory to allocate " | ||
| 499 | "rx buffer\n"); | ||
| 500 | return -ENOMEM; | ||
| 501 | } | ||
| 502 | descr->buf_size = bufsize; | ||
| 503 | descr->result_size = 0; | ||
| 504 | descr->valid_size = 0; | ||
| 505 | descr->data_status = 0; | ||
| 506 | descr->data_error = 0; | ||
| 507 | |||
| 508 | offset = ((unsigned long)descr->skb->data) & | ||
| 509 | (SPIDER_NET_RXBUF_ALIGN - 1); | ||
| 510 | if (offset) | ||
| 511 | skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); | ||
| 512 | /* io-mmu-map the skb */ | ||
| 513 | descr->buf_addr = pci_map_single(card->pdev, descr->skb->data, | ||
| 514 | SPIDER_NET_MAX_MTU, | ||
| 515 | PCI_DMA_BIDIRECTIONAL); | ||
| 516 | if (descr->buf_addr == DMA_ERROR_CODE) { | ||
| 517 | dev_kfree_skb_any(descr->skb); | ||
| 518 | if (netif_msg_rx_err(card)) | ||
| 519 | pr_err("Could not iommu-map rx buffer\n"); | ||
| 520 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | ||
| 521 | } else { | ||
| 522 | descr->dmac_cmd_status = SPIDER_NET_DMAC_RX_CARDOWNED; | ||
| 523 | } | ||
| 524 | |||
| 525 | return error; | ||
| 526 | } | ||
| 527 | |||
| 528 | /** | ||
| 529 | * spider_net_enable_rxctails - sets RX dmac chain tail addresses | ||
| 530 | * @card: card structure | ||
| 531 | * | ||
| 532 | * spider_net_enable_rxctails sets the RX DMAC chain tail adresses in the | ||
| 533 | * chip by writing to the appropriate register. DMA is enabled in | ||
| 534 | * spider_net_enable_rxdmac. | ||
| 535 | */ | ||
| 536 | static void | ||
| 537 | spider_net_enable_rxchtails(struct spider_net_card *card) | ||
| 538 | { | ||
| 539 | /* assume chain is aligned correctly */ | ||
| 540 | spider_net_write_reg(card, SPIDER_NET_GDADCHA , | ||
| 541 | card->rx_chain.tail->bus_addr); | ||
| 542 | } | ||
| 543 | |||
| 544 | /** | ||
| 545 | * spider_net_enable_rxdmac - enables a receive DMA controller | ||
| 546 | * @card: card structure | ||
| 547 | * | ||
| 548 | * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN | ||
| 549 | * in the GDADMACCNTR register | ||
| 550 | */ | ||
| 551 | static void | ||
| 552 | spider_net_enable_rxdmac(struct spider_net_card *card) | ||
| 553 | { | ||
| 554 | spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, | ||
| 555 | SPIDER_NET_DMA_RX_VALUE); | ||
| 556 | } | ||
| 557 | |||
| 558 | /** | ||
| 559 | * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains | ||
| 560 | * @card: card structure | ||
| 561 | * | ||
| 562 | * refills descriptors in all chains (last used chain first): allocates skbs | ||
| 563 | * and iommu-maps them. | ||
| 564 | */ | ||
| 565 | static void | ||
| 566 | spider_net_refill_rx_chain(struct spider_net_card *card) | ||
| 567 | { | ||
| 568 | struct spider_net_descr_chain *chain; | ||
| 569 | int count = 0; | ||
| 570 | unsigned long flags; | ||
| 571 | |||
| 572 | chain = &card->rx_chain; | ||
| 573 | |||
| 574 | spin_lock_irqsave(&card->chain_lock, flags); | ||
| 575 | while (spider_net_get_descr_status(chain->head) == | ||
| 576 | SPIDER_NET_DESCR_NOT_IN_USE) { | ||
| 577 | if (spider_net_prepare_rx_descr(card, chain->head)) | ||
| 578 | break; | ||
| 579 | count++; | ||
| 580 | chain->head = chain->head->next; | ||
| 581 | } | ||
| 582 | spin_unlock_irqrestore(&card->chain_lock, flags); | ||
| 583 | |||
| 584 | /* could be optimized, only do that, if we know the DMA processing | ||
| 585 | * has terminated */ | ||
| 586 | if (count) | ||
| 587 | spider_net_enable_rxdmac(card); | ||
| 588 | } | ||
| 589 | |||
| 590 | /** | ||
| 591 | * spider_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains | ||
| 592 | * @card: card structure | ||
| 593 | * | ||
| 594 | * returns 0 on success, <0 on failure | ||
| 595 | */ | ||
| 596 | static int | ||
| 597 | spider_net_alloc_rx_skbs(struct spider_net_card *card) | ||
| 598 | { | ||
| 599 | int result; | ||
| 600 | struct spider_net_descr_chain *chain; | ||
| 601 | |||
| 602 | result = -ENOMEM; | ||
| 603 | |||
| 604 | chain = &card->rx_chain; | ||
| 605 | /* put at least one buffer into the chain. if this fails, | ||
| 606 | * we've got a problem. if not, spider_net_refill_rx_chain | ||
| 607 | * will do the rest at the end of this function */ | ||
| 608 | if (spider_net_prepare_rx_descr(card, chain->head)) | ||
| 609 | goto error; | ||
| 610 | else | ||
| 611 | chain->head = chain->head->next; | ||
| 612 | |||
| 613 | /* this will allocate the rest of the rx buffers; if not, it's | ||
| 614 | * business as usual later on */ | ||
| 615 | spider_net_refill_rx_chain(card); | ||
| 616 | return 0; | ||
| 617 | |||
| 618 | error: | ||
| 619 | spider_net_free_rx_chain_contents(card); | ||
| 620 | return result; | ||
| 621 | } | ||
| 622 | |||
| 623 | /** | ||
| 624 | * spider_net_release_tx_descr - processes a used tx descriptor | ||
| 625 | * @card: card structure | ||
| 626 | * @descr: descriptor to release | ||
| 627 | * | ||
| 628 | * releases a used tx descriptor (unmapping, freeing of skb) | ||
| 629 | */ | ||
| 630 | static void | ||
| 631 | spider_net_release_tx_descr(struct spider_net_card *card, | ||
| 632 | struct spider_net_descr *descr) | ||
| 633 | { | ||
| 634 | struct sk_buff *skb; | ||
| 635 | |||
| 636 | /* unmap the skb */ | ||
| 637 | skb = descr->skb; | ||
| 638 | pci_unmap_single(card->pdev, descr->buf_addr, skb->len, | ||
| 639 | PCI_DMA_BIDIRECTIONAL); | ||
| 640 | |||
| 641 | dev_kfree_skb_any(skb); | ||
| 642 | |||
| 643 | /* set status to not used */ | ||
| 644 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | ||
| 645 | } | ||
| 646 | |||
| 647 | /** | ||
| 648 | * spider_net_release_tx_chain - processes sent tx descriptors | ||
| 649 | * @card: adapter structure | ||
| 650 | * @brutal: if set, don't care about whether descriptor seems to be in use | ||
| 651 | * | ||
| 652 | * releases the tx descriptors that spider has finished with (if non-brutal) | ||
| 653 | * or simply release tx descriptors (if brutal) | ||
| 654 | */ | ||
| 655 | static void | ||
| 656 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | ||
| 657 | { | ||
| 658 | struct spider_net_descr_chain *tx_chain = &card->tx_chain; | ||
| 659 | enum spider_net_descr_status status; | ||
| 660 | |||
| 661 | spider_net_tx_irq_off(card); | ||
| 662 | |||
| 663 | /* no lock for chain needed, if this is only executed once at a time */ | ||
| 664 | again: | ||
| 665 | for (;;) { | ||
| 666 | status = spider_net_get_descr_status(tx_chain->tail); | ||
| 667 | switch (status) { | ||
| 668 | case SPIDER_NET_DESCR_CARDOWNED: | ||
| 669 | if (!brutal) goto out; | ||
| 670 | /* fallthrough, if we release the descriptors | ||
| 671 | * brutally (then we don't care about | ||
| 672 | * SPIDER_NET_DESCR_CARDOWNED) */ | ||
| 673 | case SPIDER_NET_DESCR_RESPONSE_ERROR: | ||
| 674 | case SPIDER_NET_DESCR_PROTECTION_ERROR: | ||
| 675 | case SPIDER_NET_DESCR_FORCE_END: | ||
| 676 | if (netif_msg_tx_err(card)) | ||
| 677 | pr_err("%s: forcing end of tx descriptor " | ||
| 678 | "with status x%02x\n", | ||
| 679 | card->netdev->name, status); | ||
| 680 | card->netdev_stats.tx_dropped++; | ||
| 681 | break; | ||
| 682 | |||
| 683 | case SPIDER_NET_DESCR_COMPLETE: | ||
| 684 | card->netdev_stats.tx_packets++; | ||
| 685 | card->netdev_stats.tx_bytes += | ||
| 686 | tx_chain->tail->skb->len; | ||
| 687 | break; | ||
| 688 | |||
| 689 | default: /* any other value (== SPIDER_NET_DESCR_NOT_IN_USE) */ | ||
| 690 | goto out; | ||
| 691 | } | ||
| 692 | spider_net_release_tx_descr(card, tx_chain->tail); | ||
| 693 | tx_chain->tail = tx_chain->tail->next; | ||
| 694 | } | ||
| 695 | out: | ||
| 696 | netif_wake_queue(card->netdev); | ||
| 697 | |||
| 698 | if (!brutal) { | ||
| 699 | /* switch on tx irqs (while we are still in the interrupt | ||
| 700 | * handler, so we don't get an interrupt), check again | ||
| 701 | * for done descriptors. This results in fewer interrupts */ | ||
| 702 | spider_net_tx_irq_on(card); | ||
| 703 | status = spider_net_get_descr_status(tx_chain->tail); | ||
| 704 | switch (status) { | ||
| 705 | case SPIDER_NET_DESCR_RESPONSE_ERROR: | ||
| 706 | case SPIDER_NET_DESCR_PROTECTION_ERROR: | ||
| 707 | case SPIDER_NET_DESCR_FORCE_END: | ||
| 708 | case SPIDER_NET_DESCR_COMPLETE: | ||
| 709 | goto again; | ||
| 710 | default: | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | } | ||
| 714 | |||
| 715 | } | ||
| 716 | |||
| 717 | /** | ||
| 718 | * spider_net_get_multicast_hash - generates hash for multicast filter table | ||
| 719 | * @addr: multicast address | ||
| 720 | * | ||
| 721 | * returns the hash value. | ||
| 722 | * | ||
| 723 | * spider_net_get_multicast_hash calculates a hash value for a given multicast | ||
| 724 | * address, that is used to set the multicast filter tables | ||
| 725 | */ | ||
| 726 | static u8 | ||
| 727 | spider_net_get_multicast_hash(struct net_device *netdev, __u8 *addr) | ||
| 728 | { | ||
| 729 | /* FIXME: an addr of 01:00:5e:00:00:01 must result in 0xa9, | ||
| 730 | * ff:ff:ff:ff:ff:ff must result in 0xfd */ | ||
| 731 | u32 crc; | ||
| 732 | u8 hash; | ||
| 733 | |||
| 734 | crc = crc32_be(~0, addr, netdev->addr_len); | ||
| 735 | |||
| 736 | hash = (crc >> 27); | ||
| 737 | hash <<= 3; | ||
| 738 | hash |= crc & 7; | ||
| 739 | |||
| 740 | return hash; | ||
| 741 | } | ||
| 742 | |||
| 743 | /** | ||
| 744 | * spider_net_set_multi - sets multicast addresses and promisc flags | ||
| 745 | * @netdev: interface device structure | ||
| 746 | * | ||
| 747 | * spider_net_set_multi configures multicast addresses as needed for the | ||
| 748 | * netdev interface. It also sets up multicast, allmulti and promisc | ||
| 749 | * flags appropriately | ||
| 750 | */ | ||
| 751 | static void | ||
| 752 | spider_net_set_multi(struct net_device *netdev) | ||
| 753 | { | ||
| 754 | struct dev_mc_list *mc; | ||
| 755 | u8 hash; | ||
| 756 | int i; | ||
| 757 | u32 reg; | ||
| 758 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 759 | unsigned long bitmask[SPIDER_NET_MULTICAST_HASHES / BITS_PER_LONG] = | ||
| 760 | {0, }; | ||
| 761 | |||
| 762 | spider_net_set_promisc(card); | ||
| 763 | |||
| 764 | if (netdev->flags & IFF_ALLMULTI) { | ||
| 765 | for (i = 0; i < SPIDER_NET_MULTICAST_HASHES; i++) { | ||
| 766 | set_bit(i, bitmask); | ||
| 767 | } | ||
| 768 | goto write_hash; | ||
| 769 | } | ||
| 770 | |||
| 771 | /* well, we know, what the broadcast hash value is: it's xfd | ||
| 772 | hash = spider_net_get_multicast_hash(netdev, netdev->broadcast); */ | ||
| 773 | set_bit(0xfd, bitmask); | ||
| 774 | |||
| 775 | for (mc = netdev->mc_list; mc; mc = mc->next) { | ||
| 776 | hash = spider_net_get_multicast_hash(netdev, mc->dmi_addr); | ||
| 777 | set_bit(hash, bitmask); | ||
| 778 | } | ||
| 779 | |||
| 780 | write_hash: | ||
| 781 | for (i = 0; i < SPIDER_NET_MULTICAST_HASHES / 4; i++) { | ||
| 782 | reg = 0; | ||
| 783 | if (test_bit(i * 4, bitmask)) | ||
| 784 | reg += 0x08; | ||
| 785 | reg <<= 8; | ||
| 786 | if (test_bit(i * 4 + 1, bitmask)) | ||
| 787 | reg += 0x08; | ||
| 788 | reg <<= 8; | ||
| 789 | if (test_bit(i * 4 + 2, bitmask)) | ||
| 790 | reg += 0x08; | ||
| 791 | reg <<= 8; | ||
| 792 | if (test_bit(i * 4 + 3, bitmask)) | ||
| 793 | reg += 0x08; | ||
| 794 | |||
| 795 | spider_net_write_reg(card, SPIDER_NET_GMRMHFILnR + i * 4, reg); | ||
| 796 | } | ||
| 797 | } | ||
| 798 | |||
| 799 | /** | ||
| 800 | * spider_net_disable_rxdmac - disables the receive DMA controller | ||
| 801 | * @card: card structure | ||
| 802 | * | ||
| 803 | * spider_net_disable_rxdmac terminates processing on the DMA controller by | ||
| 804 | * turing off DMA and issueing a force end | ||
| 805 | */ | ||
| 806 | static void | ||
| 807 | spider_net_disable_rxdmac(struct spider_net_card *card) | ||
| 808 | { | ||
| 809 | spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, | ||
| 810 | SPIDER_NET_DMA_RX_FEND_VALUE); | ||
| 811 | } | ||
| 812 | |||
| 813 | /** | ||
| 814 | * spider_net_stop - called upon ifconfig down | ||
| 815 | * @netdev: interface device structure | ||
| 816 | * | ||
| 817 | * always returns 0 | ||
| 818 | */ | ||
| 819 | int | ||
| 820 | spider_net_stop(struct net_device *netdev) | ||
| 821 | { | ||
| 822 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 823 | |||
| 824 | netif_poll_disable(netdev); | ||
| 825 | netif_carrier_off(netdev); | ||
| 826 | netif_stop_queue(netdev); | ||
| 827 | |||
| 828 | /* disable/mask all interrupts */ | ||
| 829 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); | ||
| 830 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); | ||
| 831 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); | ||
| 832 | |||
| 833 | /* free_irq(netdev->irq, netdev);*/ | ||
| 834 | free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); | ||
| 835 | |||
| 836 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | ||
| 837 | SPIDER_NET_DMA_TX_FEND_VALUE); | ||
| 838 | |||
| 839 | /* turn off DMA, force end */ | ||
| 840 | spider_net_disable_rxdmac(card); | ||
| 841 | |||
| 842 | /* release chains */ | ||
| 843 | spider_net_release_tx_chain(card, 1); | ||
| 844 | |||
| 845 | spider_net_free_chain(card, &card->tx_chain); | ||
| 846 | spider_net_free_chain(card, &card->rx_chain); | ||
| 847 | |||
| 848 | return 0; | ||
| 849 | } | ||
| 850 | |||
| 851 | /** | ||
| 852 | * spider_net_get_next_tx_descr - returns the next available tx descriptor | ||
| 853 | * @card: device structure to get descriptor from | ||
| 854 | * | ||
| 855 | * returns the address of the next descriptor, or NULL if not available. | ||
| 856 | */ | ||
| 857 | static struct spider_net_descr * | ||
| 858 | spider_net_get_next_tx_descr(struct spider_net_card *card) | ||
| 859 | { | ||
| 860 | /* check, if head points to not-in-use descr */ | ||
| 861 | if ( spider_net_get_descr_status(card->tx_chain.head) == | ||
| 862 | SPIDER_NET_DESCR_NOT_IN_USE ) { | ||
| 863 | return card->tx_chain.head; | ||
| 864 | } else { | ||
| 865 | return NULL; | ||
| 866 | } | ||
| 867 | } | ||
| 868 | |||
| 869 | /** | ||
| 870 | * spider_net_set_txdescr_cmdstat - sets the tx descriptor command field | ||
| 871 | * @descr: descriptor structure to fill out | ||
| 872 | * @skb: packet to consider | ||
| 873 | * | ||
| 874 | * fills out the command and status field of the descriptor structure, | ||
| 875 | * depending on hardware checksum settings. This function assumes a wmb() | ||
| 876 | * has executed before. | ||
| 877 | */ | ||
| 878 | static void | ||
| 879 | spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, | ||
| 880 | struct sk_buff *skb) | ||
| 881 | { | ||
| 882 | if (skb->ip_summed != CHECKSUM_HW) { | ||
| 883 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; | ||
| 884 | return; | ||
| 885 | } | ||
| 886 | |||
| 887 | /* is packet ip? | ||
| 888 | * if yes: tcp? udp? */ | ||
| 889 | if (skb->protocol == htons(ETH_P_IP)) { | ||
| 890 | if (skb->nh.iph->protocol == IPPROTO_TCP) { | ||
| 891 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS; | ||
| 892 | } else if (skb->nh.iph->protocol == IPPROTO_UDP) { | ||
| 893 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS; | ||
| 894 | } else { /* the stack should checksum non-tcp and non-udp | ||
| 895 | packets on his own: NETIF_F_IP_CSUM */ | ||
| 896 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; | ||
| 897 | } | ||
| 898 | } | ||
| 899 | } | ||
| 900 | |||
| 901 | /** | ||
| 902 | * spider_net_prepare_tx_descr - fill tx descriptor with skb data | ||
| 903 | * @card: card structure | ||
| 904 | * @descr: descriptor structure to fill out | ||
| 905 | * @skb: packet to use | ||
| 906 | * | ||
| 907 | * returns 0 on success, <0 on failure. | ||
| 908 | * | ||
| 909 | * fills out the descriptor structure with skb data and len. Copies data, | ||
| 910 | * if needed (32bit DMA!) | ||
| 911 | */ | ||
| 912 | static int | ||
| 913 | spider_net_prepare_tx_descr(struct spider_net_card *card, | ||
| 914 | struct spider_net_descr *descr, | ||
| 915 | struct sk_buff *skb) | ||
| 916 | { | ||
| 917 | descr->buf_addr = pci_map_single(card->pdev, skb->data, | ||
| 918 | skb->len, PCI_DMA_BIDIRECTIONAL); | ||
| 919 | if (descr->buf_addr == DMA_ERROR_CODE) { | ||
| 920 | if (netif_msg_tx_err(card)) | ||
| 921 | pr_err("could not iommu-map packet (%p, %i). " | ||
| 922 | "Dropping packet\n", skb->data, skb->len); | ||
| 923 | return -ENOMEM; | ||
| 924 | } | ||
| 925 | |||
| 926 | descr->buf_size = skb->len; | ||
| 927 | descr->skb = skb; | ||
| 928 | descr->data_status = 0; | ||
| 929 | |||
| 930 | /* make sure the above values are in memory before we change the | ||
| 931 | * status */ | ||
| 932 | wmb(); | ||
| 933 | |||
| 934 | spider_net_set_txdescr_cmdstat(descr,skb); | ||
| 935 | |||
| 936 | return 0; | ||
| 937 | } | ||
| 938 | |||
| 939 | /** | ||
| 940 | * spider_net_kick_tx_dma - enables TX DMA processing | ||
| 941 | * @card: card structure | ||
| 942 | * @descr: descriptor address to enable TX processing at | ||
| 943 | * | ||
| 944 | * spider_net_kick_tx_dma writes the current tx chain head as start address | ||
| 945 | * of the tx descriptor chain and enables the transmission DMA engine | ||
| 946 | */ | ||
| 947 | static void | ||
| 948 | spider_net_kick_tx_dma(struct spider_net_card *card, | ||
| 949 | struct spider_net_descr *descr) | ||
| 950 | { | ||
| 951 | /* this is the only descriptor in the output chain. | ||
| 952 | * Enable TX DMA */ | ||
| 953 | |||
| 954 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | ||
| 955 | descr->bus_addr); | ||
| 956 | |||
| 957 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | ||
| 958 | SPIDER_NET_DMA_TX_VALUE); | ||
| 959 | } | ||
| 960 | |||
| 961 | /** | ||
| 962 | * spider_net_xmit - transmits a frame over the device | ||
| 963 | * @skb: packet to send out | ||
| 964 | * @netdev: interface device structure | ||
| 965 | * | ||
| 966 | * returns 0 on success, <0 on failure | ||
| 967 | */ | ||
| 968 | static int | ||
| 969 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) | ||
| 970 | { | ||
| 971 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 972 | struct spider_net_descr *descr; | ||
| 973 | int result; | ||
| 974 | |||
| 975 | descr = spider_net_get_next_tx_descr(card); | ||
| 976 | |||
| 977 | if (!descr) { | ||
| 978 | netif_stop_queue(netdev); | ||
| 979 | |||
| 980 | descr = spider_net_get_next_tx_descr(card); | ||
| 981 | if (!descr) | ||
| 982 | goto error; | ||
| 983 | else | ||
| 984 | netif_start_queue(netdev); | ||
| 985 | } | ||
| 986 | |||
| 987 | result = spider_net_prepare_tx_descr(card, descr, skb); | ||
| 988 | if (result) | ||
| 989 | goto error; | ||
| 990 | |||
| 991 | card->tx_chain.head = card->tx_chain.head->next; | ||
| 992 | |||
| 993 | /* make sure the status from spider_net_prepare_tx_descr is in | ||
| 994 | * memory before we check out the previous descriptor */ | ||
| 995 | wmb(); | ||
| 996 | |||
| 997 | if (spider_net_get_descr_status(descr->prev) != | ||
| 998 | SPIDER_NET_DESCR_CARDOWNED) | ||
| 999 | spider_net_kick_tx_dma(card, descr); | ||
| 1000 | |||
| 1001 | return NETDEV_TX_OK; | ||
| 1002 | |||
| 1003 | error: | ||
| 1004 | card->netdev_stats.tx_dropped++; | ||
| 1005 | return NETDEV_TX_LOCKED; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | /** | ||
| 1009 | * spider_net_do_ioctl - called for device ioctls | ||
| 1010 | * @netdev: interface device structure | ||
| 1011 | * @ifr: request parameter structure for ioctl | ||
| 1012 | * @cmd: command code for ioctl | ||
| 1013 | * | ||
| 1014 | * returns 0 on success, <0 on failure. Currently, we have no special ioctls. | ||
| 1015 | * -EOPNOTSUPP is returned, if an unknown ioctl was requested | ||
| 1016 | */ | ||
| 1017 | static int | ||
| 1018 | spider_net_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | ||
| 1019 | { | ||
| 1020 | switch (cmd) { | ||
| 1021 | default: | ||
| 1022 | return -EOPNOTSUPP; | ||
| 1023 | } | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | /** | ||
| 1027 | * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on | ||
| 1028 | * @descr: descriptor to process | ||
| 1029 | * @card: card structure | ||
| 1030 | * | ||
| 1031 | * returns 1 on success, 0 if no packet was passed to the stack | ||
| 1032 | * | ||
| 1033 | * iommu-unmaps the skb, fills out skb structure and passes the data to the | ||
| 1034 | * stack. The descriptor state is not changed. | ||
| 1035 | */ | ||
| 1036 | static int | ||
| 1037 | spider_net_pass_skb_up(struct spider_net_descr *descr, | ||
| 1038 | struct spider_net_card *card) | ||
| 1039 | { | ||
| 1040 | struct sk_buff *skb; | ||
| 1041 | struct net_device *netdev; | ||
| 1042 | u32 data_status, data_error; | ||
| 1043 | |||
| 1044 | data_status = descr->data_status; | ||
| 1045 | data_error = descr->data_error; | ||
| 1046 | |||
| 1047 | netdev = card->netdev; | ||
| 1048 | |||
| 1049 | /* check for errors in the data_error flag */ | ||
| 1050 | if ((data_error & SPIDER_NET_DATA_ERROR_MASK) && | ||
| 1051 | netif_msg_rx_err(card)) | ||
| 1052 | pr_err("error in received descriptor found, " | ||
| 1053 | "data_status=x%08x, data_error=x%08x\n", | ||
| 1054 | data_status, data_error); | ||
| 1055 | |||
| 1056 | /* prepare skb, unmap descriptor */ | ||
| 1057 | skb = descr->skb; | ||
| 1058 | pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_MTU, | ||
| 1059 | PCI_DMA_BIDIRECTIONAL); | ||
| 1060 | |||
| 1061 | /* the cases we'll throw away the packet immediately */ | ||
| 1062 | if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) | ||
| 1063 | return 0; | ||
| 1064 | |||
| 1065 | skb->dev = netdev; | ||
| 1066 | skb_put(skb, descr->valid_size); | ||
| 1067 | |||
| 1068 | /* the card seems to add 2 bytes of junk in front | ||
| 1069 | * of the ethernet frame */ | ||
| 1070 | #define SPIDER_MISALIGN 2 | ||
| 1071 | skb_pull(skb, SPIDER_MISALIGN); | ||
| 1072 | skb->protocol = eth_type_trans(skb, netdev); | ||
| 1073 | |||
| 1074 | /* checksum offload */ | ||
| 1075 | if (card->options.rx_csum) { | ||
| 1076 | if ( (data_status & SPIDER_NET_DATA_STATUS_CHK_MASK) && | ||
| 1077 | (!(data_error & SPIDER_NET_DATA_ERROR_CHK_MASK)) ) | ||
| 1078 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 1079 | else | ||
| 1080 | skb->ip_summed = CHECKSUM_NONE; | ||
| 1081 | } else { | ||
| 1082 | skb->ip_summed = CHECKSUM_NONE; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | if (data_status & SPIDER_NET_VLAN_PACKET) { | ||
| 1086 | /* further enhancements: HW-accel VLAN | ||
| 1087 | * vlan_hwaccel_receive_skb | ||
| 1088 | */ | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | /* pass skb up to stack */ | ||
| 1092 | netif_receive_skb(skb); | ||
| 1093 | |||
| 1094 | /* update netdevice statistics */ | ||
| 1095 | card->netdev_stats.rx_packets++; | ||
| 1096 | card->netdev_stats.rx_bytes += skb->len; | ||
| 1097 | |||
| 1098 | return 1; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | /** | ||
| 1102 | * spider_net_decode_descr - processes an rx descriptor | ||
| 1103 | * @card: card structure | ||
| 1104 | * | ||
| 1105 | * returns 1 if a packet has been sent to the stack, otherwise 0 | ||
| 1106 | * | ||
| 1107 | * processes an rx descriptor by iommu-unmapping the data buffer and passing | ||
| 1108 | * the packet up to the stack | ||
| 1109 | */ | ||
| 1110 | static int | ||
| 1111 | spider_net_decode_one_descr(struct spider_net_card *card) | ||
| 1112 | { | ||
| 1113 | enum spider_net_descr_status status; | ||
| 1114 | struct spider_net_descr *descr; | ||
| 1115 | struct spider_net_descr_chain *chain; | ||
| 1116 | int result; | ||
| 1117 | |||
| 1118 | chain = &card->rx_chain; | ||
| 1119 | descr = chain->tail; | ||
| 1120 | |||
| 1121 | status = spider_net_get_descr_status(descr); | ||
| 1122 | |||
| 1123 | if (status == SPIDER_NET_DESCR_CARDOWNED) { | ||
| 1124 | /* nothing in the descriptor yet */ | ||
| 1125 | return 0; | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) { | ||
| 1129 | /* not initialized yet, I bet chain->tail == chain->head | ||
| 1130 | * and the ring is empty */ | ||
| 1131 | spider_net_refill_rx_chain(card); | ||
| 1132 | return 0; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | /* descriptor definitively used -- move on head */ | ||
| 1136 | chain->tail = descr->next; | ||
| 1137 | |||
| 1138 | result = 0; | ||
| 1139 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || | ||
| 1140 | (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || | ||
| 1141 | (status == SPIDER_NET_DESCR_FORCE_END) ) { | ||
| 1142 | if (netif_msg_rx_err(card)) | ||
| 1143 | pr_err("%s: dropping RX descriptor with state %d\n", | ||
| 1144 | card->netdev->name, status); | ||
| 1145 | card->netdev_stats.rx_dropped++; | ||
| 1146 | goto refill; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && | ||
| 1150 | (status != SPIDER_NET_DESCR_FRAME_END) ) { | ||
| 1151 | if (netif_msg_rx_err(card)) | ||
| 1152 | pr_err("%s: RX descriptor with state %d\n", | ||
| 1153 | card->netdev->name, status); | ||
| 1154 | goto refill; | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | /* ok, we've got a packet in descr */ | ||
| 1158 | result = spider_net_pass_skb_up(descr, card); | ||
| 1159 | refill: | ||
| 1160 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | ||
| 1161 | /* change the descriptor state: */ | ||
| 1162 | spider_net_refill_rx_chain(card); | ||
| 1163 | |||
| 1164 | return result; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | /** | ||
| 1168 | * spider_net_poll - NAPI poll function called by the stack to return packets | ||
| 1169 | * @netdev: interface device structure | ||
| 1170 | * @budget: number of packets we can pass to the stack at most | ||
| 1171 | * | ||
| 1172 | * returns 0 if no more packets available to the driver/stack. Returns 1, | ||
| 1173 | * if the quota is exceeded, but the driver has still packets. | ||
| 1174 | * | ||
| 1175 | * spider_net_poll returns all packets from the rx descriptors to the stack | ||
| 1176 | * (using netif_receive_skb). If all/enough packets are up, the driver | ||
| 1177 | * reenables interrupts and returns 0. If not, 1 is returned. | ||
| 1178 | */ | ||
| 1179 | static int | ||
| 1180 | spider_net_poll(struct net_device *netdev, int *budget) | ||
| 1181 | { | ||
| 1182 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 1183 | int packets_to_do, packets_done = 0; | ||
| 1184 | int no_more_packets = 0; | ||
| 1185 | |||
| 1186 | packets_to_do = min(*budget, netdev->quota); | ||
| 1187 | |||
| 1188 | while (packets_to_do) { | ||
| 1189 | if (spider_net_decode_one_descr(card)) { | ||
| 1190 | packets_done++; | ||
| 1191 | packets_to_do--; | ||
| 1192 | } else { | ||
| 1193 | /* no more packets for the stack */ | ||
| 1194 | no_more_packets = 1; | ||
| 1195 | break; | ||
| 1196 | } | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | netdev->quota -= packets_done; | ||
| 1200 | *budget -= packets_done; | ||
| 1201 | |||
| 1202 | /* if all packets are in the stack, enable interrupts and return 0 */ | ||
| 1203 | /* if not, return 1 */ | ||
| 1204 | if (no_more_packets) { | ||
| 1205 | netif_rx_complete(netdev); | ||
| 1206 | spider_net_rx_irq_on(card); | ||
| 1207 | return 0; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | return 1; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | /** | ||
| 1214 | * spider_net_vlan_rx_reg - initializes VLAN structures in the driver and card | ||
| 1215 | * @netdev: interface device structure | ||
| 1216 | * @grp: vlan_group structure that is registered (NULL on destroying interface) | ||
| 1217 | */ | ||
| 1218 | static void | ||
| 1219 | spider_net_vlan_rx_reg(struct net_device *netdev, struct vlan_group *grp) | ||
| 1220 | { | ||
| 1221 | /* further enhancement... yet to do */ | ||
| 1222 | return; | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | /** | ||
| 1226 | * spider_net_vlan_rx_add - adds VLAN id to the card filter | ||
| 1227 | * @netdev: interface device structure | ||
| 1228 | * @vid: VLAN id to add | ||
| 1229 | */ | ||
| 1230 | static void | ||
| 1231 | spider_net_vlan_rx_add(struct net_device *netdev, uint16_t vid) | ||
| 1232 | { | ||
| 1233 | /* further enhancement... yet to do */ | ||
| 1234 | /* add vid to card's VLAN filter table */ | ||
| 1235 | return; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | /** | ||
| 1239 | * spider_net_vlan_rx_kill - removes VLAN id to the card filter | ||
| 1240 | * @netdev: interface device structure | ||
| 1241 | * @vid: VLAN id to remove | ||
| 1242 | */ | ||
| 1243 | static void | ||
| 1244 | spider_net_vlan_rx_kill(struct net_device *netdev, uint16_t vid) | ||
| 1245 | { | ||
| 1246 | /* further enhancement... yet to do */ | ||
| 1247 | /* remove vid from card's VLAN filter table */ | ||
| 1248 | } | ||
| 1249 | |||
| 1250 | /** | ||
| 1251 | * spider_net_get_stats - get interface statistics | ||
| 1252 | * @netdev: interface device structure | ||
| 1253 | * | ||
| 1254 | * returns the interface statistics residing in the spider_net_card struct | ||
| 1255 | */ | ||
| 1256 | static struct net_device_stats * | ||
| 1257 | spider_net_get_stats(struct net_device *netdev) | ||
| 1258 | { | ||
| 1259 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 1260 | struct net_device_stats *stats = &card->netdev_stats; | ||
| 1261 | return stats; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | /** | ||
| 1265 | * spider_net_change_mtu - changes the MTU of an interface | ||
| 1266 | * @netdev: interface device structure | ||
| 1267 | * @new_mtu: new MTU value | ||
| 1268 | * | ||
| 1269 | * returns 0 on success, <0 on failure | ||
| 1270 | */ | ||
| 1271 | static int | ||
| 1272 | spider_net_change_mtu(struct net_device *netdev, int new_mtu) | ||
| 1273 | { | ||
| 1274 | /* no need to re-alloc skbs or so -- the max mtu is about 2.3k | ||
| 1275 | * and mtu is outbound only anyway */ | ||
| 1276 | if ( (new_mtu < SPIDER_NET_MIN_MTU ) || | ||
| 1277 | (new_mtu > SPIDER_NET_MAX_MTU) ) | ||
| 1278 | return -EINVAL; | ||
| 1279 | netdev->mtu = new_mtu; | ||
| 1280 | return 0; | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | /** | ||
| 1284 | * spider_net_set_mac - sets the MAC of an interface | ||
| 1285 | * @netdev: interface device structure | ||
| 1286 | * @ptr: pointer to new MAC address | ||
| 1287 | * | ||
| 1288 | * Returns 0 on success, <0 on failure. Currently, we don't support this | ||
| 1289 | * and will always return EOPNOTSUPP. | ||
| 1290 | */ | ||
| 1291 | static int | ||
| 1292 | spider_net_set_mac(struct net_device *netdev, void *p) | ||
| 1293 | { | ||
| 1294 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 1295 | u32 macl, macu, regvalue; | ||
| 1296 | struct sockaddr *addr = p; | ||
| 1297 | |||
| 1298 | if (!is_valid_ether_addr(addr->sa_data)) | ||
| 1299 | return -EADDRNOTAVAIL; | ||
| 1300 | |||
| 1301 | /* switch off GMACTPE and GMACRPE */ | ||
| 1302 | regvalue = spider_net_read_reg(card, SPIDER_NET_GMACOPEMD); | ||
| 1303 | regvalue &= ~((1 << 5) | (1 << 6)); | ||
| 1304 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, regvalue); | ||
| 1305 | |||
| 1306 | /* write mac */ | ||
| 1307 | macu = (addr->sa_data[0]<<24) + (addr->sa_data[1]<<16) + | ||
| 1308 | (addr->sa_data[2]<<8) + (addr->sa_data[3]); | ||
| 1309 | macl = (addr->sa_data[4]<<8) + (addr->sa_data[5]); | ||
| 1310 | spider_net_write_reg(card, SPIDER_NET_GMACUNIMACU, macu); | ||
| 1311 | spider_net_write_reg(card, SPIDER_NET_GMACUNIMACL, macl); | ||
| 1312 | |||
| 1313 | /* switch GMACTPE and GMACRPE back on */ | ||
| 1314 | regvalue = spider_net_read_reg(card, SPIDER_NET_GMACOPEMD); | ||
| 1315 | regvalue |= ((1 << 5) | (1 << 6)); | ||
| 1316 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, regvalue); | ||
| 1317 | |||
| 1318 | spider_net_set_promisc(card); | ||
| 1319 | |||
| 1320 | /* look up, whether we have been successful */ | ||
| 1321 | if (spider_net_get_mac_address(netdev)) | ||
| 1322 | return -EADDRNOTAVAIL; | ||
| 1323 | if (memcmp(netdev->dev_addr,addr->sa_data,netdev->addr_len)) | ||
| 1324 | return -EADDRNOTAVAIL; | ||
| 1325 | |||
| 1326 | return 0; | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | /** | ||
| 1330 | * spider_net_enable_txdmac - enables a TX DMA controller | ||
| 1331 | * @card: card structure | ||
| 1332 | * | ||
| 1333 | * spider_net_enable_txdmac enables the TX DMA controller by setting the | ||
| 1334 | * descriptor chain tail address | ||
| 1335 | */ | ||
| 1336 | static void | ||
| 1337 | spider_net_enable_txdmac(struct spider_net_card *card) | ||
| 1338 | { | ||
| 1339 | /* assume chain is aligned correctly */ | ||
| 1340 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | ||
| 1341 | card->tx_chain.tail->bus_addr); | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | /** | ||
| 1345 | * spider_net_handle_error_irq - handles errors raised by an interrupt | ||
| 1346 | * @card: card structure | ||
| 1347 | * @status_reg: interrupt status register 0 (GHIINT0STS) | ||
| 1348 | * | ||
| 1349 | * spider_net_handle_error_irq treats or ignores all error conditions | ||
| 1350 | * found when an interrupt is presented | ||
| 1351 | */ | ||
| 1352 | static void | ||
| 1353 | spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | ||
| 1354 | { | ||
| 1355 | u32 error_reg1, error_reg2; | ||
| 1356 | u32 i; | ||
| 1357 | int show_error = 1; | ||
| 1358 | |||
| 1359 | error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); | ||
| 1360 | error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); | ||
| 1361 | |||
| 1362 | /* check GHIINT0STS ************************************/ | ||
| 1363 | if (status_reg) | ||
| 1364 | for (i = 0; i < 32; i++) | ||
| 1365 | if (status_reg & (1<<i)) | ||
| 1366 | switch (i) | ||
| 1367 | { | ||
| 1368 | /* let error_reg1 and error_reg2 evaluation decide, what to do | ||
| 1369 | case SPIDER_NET_PHYINT: | ||
| 1370 | case SPIDER_NET_GMAC2INT: | ||
| 1371 | case SPIDER_NET_GMAC1INT: | ||
| 1372 | case SPIDER_NET_GIPSINT: | ||
| 1373 | case SPIDER_NET_GFIFOINT: | ||
| 1374 | case SPIDER_NET_DMACINT: | ||
| 1375 | case SPIDER_NET_GSYSINT: | ||
| 1376 | break; */ | ||
| 1377 | |||
| 1378 | case SPIDER_NET_GPWOPCMPINT: | ||
| 1379 | /* PHY write operation completed */ | ||
| 1380 | show_error = 0; | ||
| 1381 | break; | ||
| 1382 | case SPIDER_NET_GPROPCMPINT: | ||
| 1383 | /* PHY read operation completed */ | ||
| 1384 | /* we don't use semaphores, as we poll for the completion | ||
| 1385 | * of the read operation in spider_net_read_phy. Should take | ||
| 1386 | * about 50 us */ | ||
| 1387 | show_error = 0; | ||
| 1388 | break; | ||
| 1389 | case SPIDER_NET_GPWFFINT: | ||
| 1390 | /* PHY command queue full */ | ||
| 1391 | if (netif_msg_intr(card)) | ||
| 1392 | pr_err("PHY write queue full\n"); | ||
| 1393 | show_error = 0; | ||
| 1394 | break; | ||
| 1395 | |||
| 1396 | /* case SPIDER_NET_GRMDADRINT: not used. print a message */ | ||
| 1397 | /* case SPIDER_NET_GRMARPINT: not used. print a message */ | ||
| 1398 | /* case SPIDER_NET_GRMMPINT: not used. print a message */ | ||
| 1399 | |||
| 1400 | case SPIDER_NET_GDTDEN0INT: | ||
| 1401 | /* someone has set TX_DMA_EN to 0 */ | ||
| 1402 | show_error = 0; | ||
| 1403 | break; | ||
| 1404 | |||
| 1405 | case SPIDER_NET_GDDDEN0INT: /* fallthrough */ | ||
| 1406 | case SPIDER_NET_GDCDEN0INT: /* fallthrough */ | ||
| 1407 | case SPIDER_NET_GDBDEN0INT: /* fallthrough */ | ||
| 1408 | case SPIDER_NET_GDADEN0INT: | ||
| 1409 | /* someone has set RX_DMA_EN to 0 */ | ||
| 1410 | show_error = 0; | ||
| 1411 | break; | ||
| 1412 | |||
| 1413 | /* RX interrupts */ | ||
| 1414 | case SPIDER_NET_GDDFDCINT: | ||
| 1415 | case SPIDER_NET_GDCFDCINT: | ||
| 1416 | case SPIDER_NET_GDBFDCINT: | ||
| 1417 | case SPIDER_NET_GDAFDCINT: | ||
| 1418 | /* case SPIDER_NET_GDNMINT: not used. print a message */ | ||
| 1419 | /* case SPIDER_NET_GCNMINT: not used. print a message */ | ||
| 1420 | /* case SPIDER_NET_GBNMINT: not used. print a message */ | ||
| 1421 | /* case SPIDER_NET_GANMINT: not used. print a message */ | ||
| 1422 | /* case SPIDER_NET_GRFNMINT: not used. print a message */ | ||
| 1423 | show_error = 0; | ||
| 1424 | break; | ||
| 1425 | |||
| 1426 | /* TX interrupts */ | ||
| 1427 | case SPIDER_NET_GDTFDCINT: | ||
| 1428 | show_error = 0; | ||
| 1429 | break; | ||
| 1430 | case SPIDER_NET_GTTEDINT: | ||
| 1431 | show_error = 0; | ||
| 1432 | break; | ||
| 1433 | case SPIDER_NET_GDTDCEINT: | ||
| 1434 | /* chain end. If a descriptor should be sent, kick off | ||
| 1435 | * tx dma | ||
| 1436 | if (card->tx_chain.tail == card->tx_chain.head) | ||
| 1437 | spider_net_kick_tx_dma(card); | ||
| 1438 | show_error = 0; */ | ||
| 1439 | break; | ||
| 1440 | |||
| 1441 | /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ | ||
| 1442 | /* case SPIDER_NET_GFREECNTINT: not used. print a message */ | ||
| 1443 | } | ||
| 1444 | |||
| 1445 | /* check GHIINT1STS ************************************/ | ||
| 1446 | if (error_reg1) | ||
| 1447 | for (i = 0; i < 32; i++) | ||
| 1448 | if (error_reg1 & (1<<i)) | ||
| 1449 | switch (i) | ||
| 1450 | { | ||
| 1451 | case SPIDER_NET_GTMFLLINT: | ||
| 1452 | if (netif_msg_intr(card)) | ||
| 1453 | pr_err("Spider TX RAM full\n"); | ||
| 1454 | show_error = 0; | ||
| 1455 | break; | ||
| 1456 | case SPIDER_NET_GRMFLLINT: | ||
| 1457 | if (netif_msg_intr(card)) | ||
| 1458 | pr_err("Spider RX RAM full, incoming packets " | ||
| 1459 | "might be discarded !\n"); | ||
| 1460 | netif_rx_schedule(card->netdev); | ||
| 1461 | spider_net_enable_rxchtails(card); | ||
| 1462 | spider_net_enable_rxdmac(card); | ||
| 1463 | break; | ||
| 1464 | |||
| 1465 | /* case SPIDER_NET_GTMSHTINT: problem, print a message */ | ||
| 1466 | case SPIDER_NET_GDTINVDINT: | ||
| 1467 | /* allrighty. tx from previous descr ok */ | ||
| 1468 | show_error = 0; | ||
| 1469 | break; | ||
| 1470 | /* case SPIDER_NET_GRFDFLLINT: print a message down there */ | ||
| 1471 | /* case SPIDER_NET_GRFCFLLINT: print a message down there */ | ||
| 1472 | /* case SPIDER_NET_GRFBFLLINT: print a message down there */ | ||
| 1473 | /* case SPIDER_NET_GRFAFLLINT: print a message down there */ | ||
| 1474 | |||
| 1475 | /* chain end */ | ||
| 1476 | case SPIDER_NET_GDDDCEINT: /* fallthrough */ | ||
| 1477 | case SPIDER_NET_GDCDCEINT: /* fallthrough */ | ||
| 1478 | case SPIDER_NET_GDBDCEINT: /* fallthrough */ | ||
| 1479 | case SPIDER_NET_GDADCEINT: | ||
| 1480 | if (netif_msg_intr(card)) | ||
| 1481 | pr_err("got descriptor chain end interrupt, " | ||
| 1482 | "restarting DMAC %c.\n", | ||
| 1483 | 'D'+i-SPIDER_NET_GDDDCEINT); | ||
| 1484 | spider_net_refill_rx_chain(card); | ||
| 1485 | show_error = 0; | ||
| 1486 | break; | ||
| 1487 | |||
| 1488 | /* invalid descriptor */ | ||
| 1489 | case SPIDER_NET_GDDINVDINT: /* fallthrough */ | ||
| 1490 | case SPIDER_NET_GDCINVDINT: /* fallthrough */ | ||
| 1491 | case SPIDER_NET_GDBINVDINT: /* fallthrough */ | ||
| 1492 | case SPIDER_NET_GDAINVDINT: | ||
| 1493 | /* could happen when rx chain is full */ | ||
| 1494 | spider_net_refill_rx_chain(card); | ||
| 1495 | show_error = 0; | ||
| 1496 | break; | ||
| 1497 | |||
| 1498 | /* case SPIDER_NET_GDTRSERINT: problem, print a message */ | ||
| 1499 | /* case SPIDER_NET_GDDRSERINT: problem, print a message */ | ||
| 1500 | /* case SPIDER_NET_GDCRSERINT: problem, print a message */ | ||
| 1501 | /* case SPIDER_NET_GDBRSERINT: problem, print a message */ | ||
| 1502 | /* case SPIDER_NET_GDARSERINT: problem, print a message */ | ||
| 1503 | /* case SPIDER_NET_GDSERINT: problem, print a message */ | ||
| 1504 | /* case SPIDER_NET_GDTPTERINT: problem, print a message */ | ||
| 1505 | /* case SPIDER_NET_GDDPTERINT: problem, print a message */ | ||
| 1506 | /* case SPIDER_NET_GDCPTERINT: problem, print a message */ | ||
| 1507 | /* case SPIDER_NET_GDBPTERINT: problem, print a message */ | ||
| 1508 | /* case SPIDER_NET_GDAPTERINT: problem, print a message */ | ||
| 1509 | default: | ||
| 1510 | show_error = 1; | ||
| 1511 | break; | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | /* check GHIINT2STS ************************************/ | ||
| 1515 | if (error_reg2) | ||
| 1516 | for (i = 0; i < 32; i++) | ||
| 1517 | if (error_reg2 & (1<<i)) | ||
| 1518 | switch (i) | ||
| 1519 | { | ||
| 1520 | /* there is nothing we can (want to) do at this time. Log a | ||
| 1521 | * message, we can switch on and off the specific values later on | ||
| 1522 | case SPIDER_NET_GPROPERINT: | ||
| 1523 | case SPIDER_NET_GMCTCRSNGINT: | ||
| 1524 | case SPIDER_NET_GMCTLCOLINT: | ||
| 1525 | case SPIDER_NET_GMCTTMOTINT: | ||
| 1526 | case SPIDER_NET_GMCRCAERINT: | ||
| 1527 | case SPIDER_NET_GMCRCALERINT: | ||
| 1528 | case SPIDER_NET_GMCRALNERINT: | ||
| 1529 | case SPIDER_NET_GMCROVRINT: | ||
| 1530 | case SPIDER_NET_GMCRRNTINT: | ||
| 1531 | case SPIDER_NET_GMCRRXERINT: | ||
| 1532 | case SPIDER_NET_GTITCSERINT: | ||
| 1533 | case SPIDER_NET_GTIFMTERINT: | ||
| 1534 | case SPIDER_NET_GTIPKTRVKINT: | ||
| 1535 | case SPIDER_NET_GTISPINGINT: | ||
| 1536 | case SPIDER_NET_GTISADNGINT: | ||
| 1537 | case SPIDER_NET_GTISPDNGINT: | ||
| 1538 | case SPIDER_NET_GRIFMTERINT: | ||
| 1539 | case SPIDER_NET_GRIPKTRVKINT: | ||
| 1540 | case SPIDER_NET_GRISPINGINT: | ||
| 1541 | case SPIDER_NET_GRISADNGINT: | ||
| 1542 | case SPIDER_NET_GRISPDNGINT: | ||
| 1543 | break; | ||
| 1544 | */ | ||
| 1545 | default: | ||
| 1546 | break; | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | if ((show_error) && (netif_msg_intr(card))) | ||
| 1550 | pr_err("Got error interrupt, GHIINT0STS = 0x%08x, " | ||
| 1551 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", | ||
| 1552 | status_reg, error_reg1, error_reg2); | ||
| 1553 | |||
| 1554 | /* clear interrupt sources */ | ||
| 1555 | spider_net_write_reg(card, SPIDER_NET_GHIINT1STS, error_reg1); | ||
| 1556 | spider_net_write_reg(card, SPIDER_NET_GHIINT2STS, error_reg2); | ||
| 1557 | } | ||
| 1558 | |||
| 1559 | /** | ||
| 1560 | * spider_net_interrupt - interrupt handler for spider_net | ||
| 1561 | * @irq: interupt number | ||
| 1562 | * @ptr: pointer to net_device | ||
| 1563 | * @regs: PU registers | ||
| 1564 | * | ||
| 1565 | * returns IRQ_HANDLED, if interrupt was for driver, or IRQ_NONE, if no | ||
| 1566 | * interrupt found raised by card. | ||
| 1567 | * | ||
| 1568 | * This is the interrupt handler, that turns off | ||
| 1569 | * interrupts for this device and makes the stack poll the driver | ||
| 1570 | */ | ||
| 1571 | static irqreturn_t | ||
| 1572 | spider_net_interrupt(int irq, void *ptr, struct pt_regs *regs) | ||
| 1573 | { | ||
| 1574 | struct net_device *netdev = ptr; | ||
| 1575 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 1576 | u32 status_reg; | ||
| 1577 | |||
| 1578 | status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); | ||
| 1579 | |||
| 1580 | if (!status_reg) | ||
| 1581 | return IRQ_NONE; | ||
| 1582 | |||
| 1583 | if (status_reg & SPIDER_NET_TXINT) | ||
| 1584 | spider_net_release_tx_chain(card, 0); | ||
| 1585 | |||
| 1586 | if (status_reg & SPIDER_NET_RXINT ) { | ||
| 1587 | spider_net_rx_irq_off(card); | ||
| 1588 | netif_rx_schedule(netdev); | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | /* we do this after rx and tx processing, as we want the tx chain | ||
| 1592 | * processed to see, whether we should restart tx dma processing */ | ||
| 1593 | spider_net_handle_error_irq(card, status_reg); | ||
| 1594 | |||
| 1595 | /* clear interrupt sources */ | ||
| 1596 | spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg); | ||
| 1597 | |||
| 1598 | return IRQ_HANDLED; | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 1602 | /** | ||
| 1603 | * spider_net_poll_controller - artificial interrupt for netconsole etc. | ||
| 1604 | * @netdev: interface device structure | ||
| 1605 | * | ||
| 1606 | * see Documentation/networking/netconsole.txt | ||
| 1607 | */ | ||
| 1608 | static void | ||
| 1609 | spider_net_poll_controller(struct net_device *netdev) | ||
| 1610 | { | ||
| 1611 | disable_irq(netdev->irq); | ||
| 1612 | spider_net_interrupt(netdev->irq, netdev, NULL); | ||
| 1613 | enable_irq(netdev->irq); | ||
| 1614 | } | ||
| 1615 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | ||
| 1616 | |||
| 1617 | /** | ||
| 1618 | * spider_net_init_card - initializes the card | ||
| 1619 | * @card: card structure | ||
| 1620 | * | ||
| 1621 | * spider_net_init_card initializes the card so that other registers can | ||
| 1622 | * be used | ||
| 1623 | */ | ||
| 1624 | static void | ||
| 1625 | spider_net_init_card(struct spider_net_card *card) | ||
| 1626 | { | ||
| 1627 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | ||
| 1628 | SPIDER_NET_CKRCTRL_STOP_VALUE); | ||
| 1629 | |||
| 1630 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | ||
| 1631 | SPIDER_NET_CKRCTRL_RUN_VALUE); | ||
| 1632 | } | ||
| 1633 | |||
| 1634 | /** | ||
| 1635 | * spider_net_enable_card - enables the card by setting all kinds of regs | ||
| 1636 | * @card: card structure | ||
| 1637 | * | ||
| 1638 | * spider_net_enable_card sets a lot of SMMIO registers to enable the device | ||
| 1639 | */ | ||
| 1640 | static void | ||
| 1641 | spider_net_enable_card(struct spider_net_card *card) | ||
| 1642 | { | ||
| 1643 | int i; | ||
| 1644 | /* the following array consists of (register),(value) pairs | ||
| 1645 | * that are set in this function. A register of 0 ends the list */ | ||
| 1646 | u32 regs[][2] = { | ||
| 1647 | { SPIDER_NET_GRESUMINTNUM, 0 }, | ||
| 1648 | { SPIDER_NET_GREINTNUM, 0 }, | ||
| 1649 | |||
| 1650 | /* set interrupt frame number registers */ | ||
| 1651 | /* clear the single DMA engine registers first */ | ||
| 1652 | { SPIDER_NET_GFAFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | ||
| 1653 | { SPIDER_NET_GFBFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | ||
| 1654 | { SPIDER_NET_GFCFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | ||
| 1655 | { SPIDER_NET_GFDFRMNUM, SPIDER_NET_GFXFRAMES_VALUE }, | ||
| 1656 | /* then set, what we really need */ | ||
| 1657 | { SPIDER_NET_GFFRMNUM, SPIDER_NET_FRAMENUM_VALUE }, | ||
| 1658 | |||
| 1659 | /* timer counter registers and stuff */ | ||
| 1660 | { SPIDER_NET_GFREECNNUM, 0 }, | ||
| 1661 | { SPIDER_NET_GONETIMENUM, 0 }, | ||
| 1662 | { SPIDER_NET_GTOUTFRMNUM, 0 }, | ||
| 1663 | |||
| 1664 | /* RX mode setting */ | ||
| 1665 | { SPIDER_NET_GRXMDSET, SPIDER_NET_RXMODE_VALUE }, | ||
| 1666 | /* TX mode setting */ | ||
| 1667 | { SPIDER_NET_GTXMDSET, SPIDER_NET_TXMODE_VALUE }, | ||
| 1668 | /* IPSEC mode setting */ | ||
| 1669 | { SPIDER_NET_GIPSECINIT, SPIDER_NET_IPSECINIT_VALUE }, | ||
| 1670 | |||
| 1671 | { SPIDER_NET_GFTRESTRT, SPIDER_NET_RESTART_VALUE }, | ||
| 1672 | |||
| 1673 | { SPIDER_NET_GMRWOLCTRL, 0 }, | ||
| 1674 | { SPIDER_NET_GTESTMD, 0 }, | ||
| 1675 | |||
| 1676 | { SPIDER_NET_GMACINTEN, 0 }, | ||
| 1677 | |||
| 1678 | /* flow control stuff */ | ||
| 1679 | { SPIDER_NET_GMACAPAUSE, SPIDER_NET_MACAPAUSE_VALUE }, | ||
| 1680 | { SPIDER_NET_GMACTXPAUSE, SPIDER_NET_TXPAUSE_VALUE }, | ||
| 1681 | |||
| 1682 | { SPIDER_NET_GMACBSTLMT, SPIDER_NET_BURSTLMT_VALUE }, | ||
| 1683 | { 0, 0} | ||
| 1684 | }; | ||
| 1685 | |||
| 1686 | i = 0; | ||
| 1687 | while (regs[i][0]) { | ||
| 1688 | spider_net_write_reg(card, regs[i][0], regs[i][1]); | ||
| 1689 | i++; | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | /* clear unicast filter table entries 1 to 14 */ | ||
| 1693 | for (i = 1; i <= 14; i++) { | ||
| 1694 | spider_net_write_reg(card, | ||
| 1695 | SPIDER_NET_GMRUAFILnR + i * 8, | ||
| 1696 | 0x00080000); | ||
| 1697 | spider_net_write_reg(card, | ||
| 1698 | SPIDER_NET_GMRUAFILnR + i * 8 + 4, | ||
| 1699 | 0x00000000); | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | spider_net_write_reg(card, SPIDER_NET_GMRUA0FIL15R, 0x08080000); | ||
| 1703 | |||
| 1704 | spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE); | ||
| 1705 | |||
| 1706 | /* set chain tail adress for RX chains and | ||
| 1707 | * enable DMA */ | ||
| 1708 | spider_net_enable_rxchtails(card); | ||
| 1709 | spider_net_enable_rxdmac(card); | ||
| 1710 | |||
| 1711 | spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE); | ||
| 1712 | |||
| 1713 | /* set chain tail adress for TX chain */ | ||
| 1714 | spider_net_enable_txdmac(card); | ||
| 1715 | |||
| 1716 | spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, | ||
| 1717 | SPIDER_NET_LENLMT_VALUE); | ||
| 1718 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, | ||
| 1719 | SPIDER_NET_MACMODE_VALUE); | ||
| 1720 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, | ||
| 1721 | SPIDER_NET_OPMODE_VALUE); | ||
| 1722 | |||
| 1723 | /* set interrupt mask registers */ | ||
| 1724 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, | ||
| 1725 | SPIDER_NET_INT0_MASK_VALUE); | ||
| 1726 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, | ||
| 1727 | SPIDER_NET_INT1_MASK_VALUE); | ||
| 1728 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, | ||
| 1729 | SPIDER_NET_INT2_MASK_VALUE); | ||
| 1730 | } | ||
| 1731 | |||
| 1732 | /** | ||
| 1733 | * spider_net_open - called upon ifonfig up | ||
| 1734 | * @netdev: interface device structure | ||
| 1735 | * | ||
| 1736 | * returns 0 on success, <0 on failure | ||
| 1737 | * | ||
| 1738 | * spider_net_open allocates all the descriptors and memory needed for | ||
| 1739 | * operation, sets up multicast list and enables interrupts | ||
| 1740 | */ | ||
| 1741 | int | ||
| 1742 | spider_net_open(struct net_device *netdev) | ||
| 1743 | { | ||
| 1744 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 1745 | int result; | ||
| 1746 | |||
| 1747 | result = -ENOMEM; | ||
| 1748 | if (spider_net_init_chain(card, &card->tx_chain, | ||
| 1749 | card->descr, tx_descriptors)) | ||
| 1750 | goto alloc_tx_failed; | ||
| 1751 | if (spider_net_init_chain(card, &card->rx_chain, | ||
| 1752 | card->descr + tx_descriptors, rx_descriptors)) | ||
| 1753 | goto alloc_rx_failed; | ||
| 1754 | |||
| 1755 | /* allocate rx skbs */ | ||
| 1756 | if (spider_net_alloc_rx_skbs(card)) | ||
| 1757 | goto alloc_skbs_failed; | ||
| 1758 | |||
| 1759 | spider_net_set_multi(netdev); | ||
| 1760 | |||
| 1761 | /* further enhancement: setup hw vlan, if needed */ | ||
| 1762 | |||
| 1763 | result = -EBUSY; | ||
| 1764 | if (request_irq(netdev->irq, spider_net_interrupt, | ||
| 1765 | SA_SHIRQ, netdev->name, netdev)) | ||
| 1766 | goto register_int_failed; | ||
| 1767 | |||
| 1768 | spider_net_enable_card(card); | ||
| 1769 | |||
| 1770 | netif_start_queue(netdev); | ||
| 1771 | netif_carrier_on(netdev); | ||
| 1772 | netif_poll_enable(netdev); | ||
| 1773 | |||
| 1774 | return 0; | ||
| 1775 | |||
| 1776 | register_int_failed: | ||
| 1777 | spider_net_free_rx_chain_contents(card); | ||
| 1778 | alloc_skbs_failed: | ||
| 1779 | spider_net_free_chain(card, &card->rx_chain); | ||
| 1780 | alloc_rx_failed: | ||
| 1781 | spider_net_free_chain(card, &card->tx_chain); | ||
| 1782 | alloc_tx_failed: | ||
| 1783 | return result; | ||
| 1784 | } | ||
| 1785 | |||
| 1786 | /** | ||
| 1787 | * spider_net_setup_phy - setup PHY | ||
| 1788 | * @card: card structure | ||
| 1789 | * | ||
| 1790 | * returns 0 on success, <0 on failure | ||
| 1791 | * | ||
| 1792 | * spider_net_setup_phy is used as part of spider_net_probe. Sets | ||
| 1793 | * the PHY to 1000 Mbps | ||
| 1794 | **/ | ||
| 1795 | static int | ||
| 1796 | spider_net_setup_phy(struct spider_net_card *card) | ||
| 1797 | { | ||
| 1798 | struct mii_phy *phy = &card->phy; | ||
| 1799 | |||
| 1800 | spider_net_write_reg(card, SPIDER_NET_GDTDMASEL, | ||
| 1801 | SPIDER_NET_DMASEL_VALUE); | ||
| 1802 | spider_net_write_reg(card, SPIDER_NET_GPCCTRL, | ||
| 1803 | SPIDER_NET_PHY_CTRL_VALUE); | ||
| 1804 | phy->mii_id = 1; | ||
| 1805 | phy->dev = card->netdev; | ||
| 1806 | phy->mdio_read = spider_net_read_phy; | ||
| 1807 | phy->mdio_write = spider_net_write_phy; | ||
| 1808 | |||
| 1809 | mii_phy_probe(phy, phy->mii_id); | ||
| 1810 | |||
| 1811 | if (phy->def->ops->setup_forced) | ||
| 1812 | phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL); | ||
| 1813 | |||
| 1814 | /* the following two writes could be moved to sungem_phy.c */ | ||
| 1815 | /* enable fiber mode */ | ||
| 1816 | spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x9020); | ||
| 1817 | /* LEDs active in both modes, autosense prio = fiber */ | ||
| 1818 | spider_net_write_phy(card->netdev, 1, MII_NCONFIG, 0x945f); | ||
| 1819 | |||
| 1820 | phy->def->ops->read_link(phy); | ||
| 1821 | pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name, | ||
| 1822 | phy->speed, phy->duplex==1 ? "Full" : "Half"); | ||
| 1823 | |||
| 1824 | return 0; | ||
| 1825 | } | ||
| 1826 | |||
| 1827 | /** | ||
| 1828 | * spider_net_download_firmware - loads firmware into the adapter | ||
| 1829 | * @card: card structure | ||
| 1830 | * @firmware: firmware pointer | ||
| 1831 | * | ||
| 1832 | * spider_net_download_firmware loads the firmware opened by | ||
| 1833 | * spider_net_init_firmware into the adapter. | ||
| 1834 | */ | ||
| 1835 | static void | ||
| 1836 | spider_net_download_firmware(struct spider_net_card *card, | ||
| 1837 | const struct firmware *firmware) | ||
| 1838 | { | ||
| 1839 | int sequencer, i; | ||
| 1840 | u32 *fw_ptr = (u32 *)firmware->data; | ||
| 1841 | |||
| 1842 | /* stop sequencers */ | ||
| 1843 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | ||
| 1844 | SPIDER_NET_STOP_SEQ_VALUE); | ||
| 1845 | |||
| 1846 | for (sequencer = 0; sequencer < 6; sequencer++) { | ||
| 1847 | spider_net_write_reg(card, | ||
| 1848 | SPIDER_NET_GSnPRGADR + sequencer * 8, 0); | ||
| 1849 | for (i = 0; i < SPIDER_NET_FIRMWARE_LEN; i++) { | ||
| 1850 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | ||
| 1851 | sequencer * 8, *fw_ptr); | ||
| 1852 | fw_ptr++; | ||
| 1853 | } | ||
| 1854 | } | ||
| 1855 | |||
| 1856 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | ||
| 1857 | SPIDER_NET_RUN_SEQ_VALUE); | ||
| 1858 | } | ||
| 1859 | |||
| 1860 | /** | ||
| 1861 | * spider_net_init_firmware - reads in firmware parts | ||
| 1862 | * @card: card structure | ||
| 1863 | * | ||
| 1864 | * Returns 0 on success, <0 on failure | ||
| 1865 | * | ||
| 1866 | * spider_net_init_firmware opens the sequencer firmware and does some basic | ||
| 1867 | * checks. This function opens and releases the firmware structure. A call | ||
| 1868 | * to download the firmware is performed before the release. | ||
| 1869 | * | ||
| 1870 | * Firmware format | ||
| 1871 | * =============== | ||
| 1872 | * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being | ||
| 1873 | * the program for each sequencer. Use the command | ||
| 1874 | * tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt \ | ||
| 1875 | * Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt \ | ||
| 1876 | * Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin | ||
| 1877 | * | ||
| 1878 | * to generate spider_fw.bin, if you have sequencer programs with something | ||
| 1879 | * like the following contents for each sequencer: | ||
| 1880 | * <ONE LINE COMMENT> | ||
| 1881 | * <FIRST 4-BYTES-WORD FOR SEQUENCER> | ||
| 1882 | * <SECOND 4-BYTES-WORD FOR SEQUENCER> | ||
| 1883 | * ... | ||
| 1884 | * <1024th 4-BYTES-WORD FOR SEQUENCER> | ||
| 1885 | */ | ||
| 1886 | static int | ||
| 1887 | spider_net_init_firmware(struct spider_net_card *card) | ||
| 1888 | { | ||
| 1889 | const struct firmware *firmware; | ||
| 1890 | int err = -EIO; | ||
| 1891 | |||
| 1892 | if (request_firmware(&firmware, | ||
| 1893 | SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) < 0) { | ||
| 1894 | if (netif_msg_probe(card)) | ||
| 1895 | pr_err("Couldn't read in sequencer data file %s.\n", | ||
| 1896 | SPIDER_NET_FIRMWARE_NAME); | ||
| 1897 | firmware = NULL; | ||
| 1898 | goto out; | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | if (firmware->size != 6 * SPIDER_NET_FIRMWARE_LEN * sizeof(u32)) { | ||
| 1902 | if (netif_msg_probe(card)) | ||
| 1903 | pr_err("Invalid size of sequencer data file %s.\n", | ||
| 1904 | SPIDER_NET_FIRMWARE_NAME); | ||
| 1905 | goto out; | ||
| 1906 | } | ||
| 1907 | |||
| 1908 | spider_net_download_firmware(card, firmware); | ||
| 1909 | |||
| 1910 | err = 0; | ||
| 1911 | out: | ||
| 1912 | release_firmware(firmware); | ||
| 1913 | |||
| 1914 | return err; | ||
| 1915 | } | ||
| 1916 | |||
| 1917 | /** | ||
| 1918 | * spider_net_workaround_rxramfull - work around firmware bug | ||
| 1919 | * @card: card structure | ||
| 1920 | * | ||
| 1921 | * no return value | ||
| 1922 | **/ | ||
| 1923 | static void | ||
| 1924 | spider_net_workaround_rxramfull(struct spider_net_card *card) | ||
| 1925 | { | ||
| 1926 | int i, sequencer = 0; | ||
| 1927 | |||
| 1928 | /* cancel reset */ | ||
| 1929 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | ||
| 1930 | SPIDER_NET_CKRCTRL_RUN_VALUE); | ||
| 1931 | |||
| 1932 | /* empty sequencer data */ | ||
| 1933 | for (sequencer = 0; sequencer < 6; sequencer++) { | ||
| 1934 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | ||
| 1935 | sequencer * 8, 0x0); | ||
| 1936 | for (i = 0; i < SPIDER_NET_FIRMWARE_LEN; i++) { | ||
| 1937 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | ||
| 1938 | sequencer * 8, 0x0); | ||
| 1939 | } | ||
| 1940 | } | ||
| 1941 | |||
| 1942 | /* set sequencer operation */ | ||
| 1943 | spider_net_write_reg(card, SPIDER_NET_GSINIT, 0x000000fe); | ||
| 1944 | |||
| 1945 | /* reset */ | ||
| 1946 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | ||
| 1947 | SPIDER_NET_CKRCTRL_STOP_VALUE); | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | /** | ||
| 1951 | * spider_net_tx_timeout_task - task scheduled by the watchdog timeout | ||
| 1952 | * function (to be called not under interrupt status) | ||
| 1953 | * @data: data, is interface device structure | ||
| 1954 | * | ||
| 1955 | * called as task when tx hangs, resets interface (if interface is up) | ||
| 1956 | */ | ||
| 1957 | static void | ||
| 1958 | spider_net_tx_timeout_task(void *data) | ||
| 1959 | { | ||
| 1960 | struct net_device *netdev = data; | ||
| 1961 | struct spider_net_card *card = netdev_priv(netdev); | ||
| 1962 | |||
| 1963 | if (!(netdev->flags & IFF_UP)) | ||
| 1964 | goto out; | ||
| 1965 | |||
| 1966 | netif_device_detach(netdev); | ||
| 1967 | spider_net_stop(netdev); | ||
| 1968 | |||
| 1969 | spider_net_workaround_rxramfull(card); | ||
| 1970 | spider_net_init_card(card); | ||
| 1971 | |||
| 1972 | if (spider_net_setup_phy(card)) | ||
| 1973 | goto out; | ||
| 1974 | if (spider_net_init_firmware(card)) | ||
| 1975 | goto out; | ||
| 1976 | |||
| 1977 | spider_net_open(netdev); | ||
| 1978 | spider_net_kick_tx_dma(card, card->tx_chain.head); | ||
| 1979 | netif_device_attach(netdev); | ||
| 1980 | |||
| 1981 | out: | ||
| 1982 | atomic_dec(&card->tx_timeout_task_counter); | ||
| 1983 | } | ||
| 1984 | |||
| 1985 | /** | ||
| 1986 | * spider_net_tx_timeout - called when the tx timeout watchdog kicks in. | ||
| 1987 | * @netdev: interface device structure | ||
| 1988 | * | ||
| 1989 | * called, if tx hangs. Schedules a task that resets the interface | ||
| 1990 | */ | ||
| 1991 | static void | ||
| 1992 | spider_net_tx_timeout(struct net_device *netdev) | ||
| 1993 | { | ||
| 1994 | struct spider_net_card *card; | ||
| 1995 | |||
| 1996 | card = netdev_priv(netdev); | ||
| 1997 | atomic_inc(&card->tx_timeout_task_counter); | ||
| 1998 | if (netdev->flags & IFF_UP) | ||
| 1999 | schedule_work(&card->tx_timeout_task); | ||
| 2000 | else | ||
| 2001 | atomic_dec(&card->tx_timeout_task_counter); | ||
| 2002 | } | ||
| 2003 | |||
| 2004 | /** | ||
| 2005 | * spider_net_setup_netdev_ops - initialization of net_device operations | ||
| 2006 | * @netdev: net_device structure | ||
| 2007 | * | ||
| 2008 | * fills out function pointers in the net_device structure | ||
| 2009 | */ | ||
| 2010 | static void | ||
| 2011 | spider_net_setup_netdev_ops(struct net_device *netdev) | ||
| 2012 | { | ||
| 2013 | netdev->open = &spider_net_open; | ||
| 2014 | netdev->stop = &spider_net_stop; | ||
| 2015 | netdev->hard_start_xmit = &spider_net_xmit; | ||
| 2016 | netdev->get_stats = &spider_net_get_stats; | ||
| 2017 | netdev->set_multicast_list = &spider_net_set_multi; | ||
| 2018 | netdev->set_mac_address = &spider_net_set_mac; | ||
| 2019 | netdev->change_mtu = &spider_net_change_mtu; | ||
| 2020 | netdev->do_ioctl = &spider_net_do_ioctl; | ||
| 2021 | /* tx watchdog */ | ||
| 2022 | netdev->tx_timeout = &spider_net_tx_timeout; | ||
| 2023 | netdev->watchdog_timeo = SPIDER_NET_WATCHDOG_TIMEOUT; | ||
| 2024 | /* NAPI */ | ||
| 2025 | netdev->poll = &spider_net_poll; | ||
| 2026 | netdev->weight = SPIDER_NET_NAPI_WEIGHT; | ||
| 2027 | /* HW VLAN */ | ||
| 2028 | netdev->vlan_rx_register = &spider_net_vlan_rx_reg; | ||
| 2029 | netdev->vlan_rx_add_vid = &spider_net_vlan_rx_add; | ||
| 2030 | netdev->vlan_rx_kill_vid = &spider_net_vlan_rx_kill; | ||
| 2031 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 2032 | /* poll controller */ | ||
| 2033 | netdev->poll_controller = &spider_net_poll_controller; | ||
| 2034 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | ||
| 2035 | /* ethtool ops */ | ||
| 2036 | netdev->ethtool_ops = &spider_net_ethtool_ops; | ||
| 2037 | } | ||
| 2038 | |||
| 2039 | /** | ||
| 2040 | * spider_net_setup_netdev - initialization of net_device | ||
| 2041 | * @card: card structure | ||
| 2042 | * | ||
| 2043 | * Returns 0 on success or <0 on failure | ||
| 2044 | * | ||
| 2045 | * spider_net_setup_netdev initializes the net_device structure | ||
| 2046 | **/ | ||
| 2047 | static int | ||
| 2048 | spider_net_setup_netdev(struct spider_net_card *card) | ||
| 2049 | { | ||
| 2050 | int result; | ||
| 2051 | struct net_device *netdev = card->netdev; | ||
| 2052 | struct device_node *dn; | ||
| 2053 | struct sockaddr addr; | ||
| 2054 | u8 *mac; | ||
| 2055 | |||
| 2056 | SET_MODULE_OWNER(netdev); | ||
| 2057 | SET_NETDEV_DEV(netdev, &card->pdev->dev); | ||
| 2058 | |||
| 2059 | pci_set_drvdata(card->pdev, netdev); | ||
| 2060 | spin_lock_init(&card->intmask_lock); | ||
| 2061 | netdev->irq = card->pdev->irq; | ||
| 2062 | |||
| 2063 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; | ||
| 2064 | |||
| 2065 | spider_net_setup_netdev_ops(netdev); | ||
| 2066 | |||
| 2067 | netdev->features = 0; | ||
| 2068 | /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | | ||
| 2069 | * NETIF_F_HW_VLAN_FILTER */ | ||
| 2070 | |||
| 2071 | netdev->irq = card->pdev->irq; | ||
| 2072 | |||
| 2073 | dn = pci_device_to_OF_node(card->pdev); | ||
| 2074 | if (!dn) | ||
| 2075 | return -EIO; | ||
| 2076 | |||
| 2077 | mac = (u8 *)get_property(dn, "local-mac-address", NULL); | ||
| 2078 | if (!mac) | ||
| 2079 | return -EIO; | ||
| 2080 | memcpy(addr.sa_data, mac, ETH_ALEN); | ||
| 2081 | |||
| 2082 | result = spider_net_set_mac(netdev, &addr); | ||
| 2083 | if ((result) && (netif_msg_probe(card))) | ||
| 2084 | pr_err("Failed to set MAC address: %i\n", result); | ||
| 2085 | |||
| 2086 | result = register_netdev(netdev); | ||
| 2087 | if (result) { | ||
| 2088 | if (netif_msg_probe(card)) | ||
| 2089 | pr_err("Couldn't register net_device: %i\n", | ||
| 2090 | result); | ||
| 2091 | return result; | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | if (netif_msg_probe(card)) | ||
| 2095 | pr_info("Initialized device %s.\n", netdev->name); | ||
| 2096 | |||
| 2097 | return 0; | ||
| 2098 | } | ||
| 2099 | |||
| 2100 | /** | ||
| 2101 | * spider_net_alloc_card - allocates net_device and card structure | ||
| 2102 | * | ||
| 2103 | * returns the card structure or NULL in case of errors | ||
| 2104 | * | ||
| 2105 | * the card and net_device structures are linked to each other | ||
| 2106 | */ | ||
| 2107 | static struct spider_net_card * | ||
| 2108 | spider_net_alloc_card(void) | ||
| 2109 | { | ||
| 2110 | struct net_device *netdev; | ||
| 2111 | struct spider_net_card *card; | ||
| 2112 | size_t alloc_size; | ||
| 2113 | |||
| 2114 | alloc_size = sizeof (*card) + | ||
| 2115 | sizeof (struct spider_net_descr) * rx_descriptors + | ||
| 2116 | sizeof (struct spider_net_descr) * tx_descriptors; | ||
| 2117 | netdev = alloc_etherdev(alloc_size); | ||
| 2118 | if (!netdev) | ||
| 2119 | return NULL; | ||
| 2120 | |||
| 2121 | card = netdev_priv(netdev); | ||
| 2122 | card->netdev = netdev; | ||
| 2123 | card->msg_enable = SPIDER_NET_DEFAULT_MSG; | ||
| 2124 | INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task, netdev); | ||
| 2125 | init_waitqueue_head(&card->waitq); | ||
| 2126 | atomic_set(&card->tx_timeout_task_counter, 0); | ||
| 2127 | |||
| 2128 | return card; | ||
| 2129 | } | ||
| 2130 | |||
| 2131 | /** | ||
| 2132 | * spider_net_undo_pci_setup - releases PCI ressources | ||
| 2133 | * @card: card structure | ||
| 2134 | * | ||
| 2135 | * spider_net_undo_pci_setup releases the mapped regions | ||
| 2136 | */ | ||
| 2137 | static void | ||
| 2138 | spider_net_undo_pci_setup(struct spider_net_card *card) | ||
| 2139 | { | ||
| 2140 | iounmap(card->regs); | ||
| 2141 | pci_release_regions(card->pdev); | ||
| 2142 | } | ||
| 2143 | |||
| 2144 | /** | ||
| 2145 | * spider_net_setup_pci_dev - sets up the device in terms of PCI operations | ||
| 2146 | * @card: card structure | ||
| 2147 | * @pdev: PCI device | ||
| 2148 | * | ||
| 2149 | * Returns the card structure or NULL if any errors occur | ||
| 2150 | * | ||
| 2151 | * spider_net_setup_pci_dev initializes pdev and together with the | ||
| 2152 | * functions called in spider_net_open configures the device so that | ||
| 2153 | * data can be transferred over it | ||
| 2154 | * The net_device structure is attached to the card structure, if the | ||
| 2155 | * function returns without error. | ||
| 2156 | **/ | ||
| 2157 | static struct spider_net_card * | ||
| 2158 | spider_net_setup_pci_dev(struct pci_dev *pdev) | ||
| 2159 | { | ||
| 2160 | struct spider_net_card *card; | ||
| 2161 | unsigned long mmio_start, mmio_len; | ||
| 2162 | |||
| 2163 | if (pci_enable_device(pdev)) { | ||
| 2164 | pr_err("Couldn't enable PCI device\n"); | ||
| 2165 | return NULL; | ||
| 2166 | } | ||
| 2167 | |||
| 2168 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | ||
| 2169 | pr_err("Couldn't find proper PCI device base address.\n"); | ||
| 2170 | goto out_disable_dev; | ||
| 2171 | } | ||
| 2172 | |||
| 2173 | if (pci_request_regions(pdev, spider_net_driver_name)) { | ||
| 2174 | pr_err("Couldn't obtain PCI resources, aborting.\n"); | ||
| 2175 | goto out_disable_dev; | ||
| 2176 | } | ||
| 2177 | |||
| 2178 | pci_set_master(pdev); | ||
| 2179 | |||
| 2180 | card = spider_net_alloc_card(); | ||
| 2181 | if (!card) { | ||
| 2182 | pr_err("Couldn't allocate net_device structure, " | ||
| 2183 | "aborting.\n"); | ||
| 2184 | goto out_release_regions; | ||
| 2185 | } | ||
| 2186 | card->pdev = pdev; | ||
| 2187 | |||
| 2188 | /* fetch base address and length of first resource */ | ||
| 2189 | mmio_start = pci_resource_start(pdev, 0); | ||
| 2190 | mmio_len = pci_resource_len(pdev, 0); | ||
| 2191 | |||
| 2192 | card->netdev->mem_start = mmio_start; | ||
| 2193 | card->netdev->mem_end = mmio_start + mmio_len; | ||
| 2194 | card->regs = ioremap(mmio_start, mmio_len); | ||
| 2195 | |||
| 2196 | if (!card->regs) { | ||
| 2197 | pr_err("Couldn't obtain PCI resources, aborting.\n"); | ||
| 2198 | goto out_release_regions; | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | return card; | ||
| 2202 | |||
| 2203 | out_release_regions: | ||
| 2204 | pci_release_regions(pdev); | ||
| 2205 | out_disable_dev: | ||
| 2206 | pci_disable_device(pdev); | ||
| 2207 | pci_set_drvdata(pdev, NULL); | ||
| 2208 | return NULL; | ||
| 2209 | } | ||
| 2210 | |||
| 2211 | /** | ||
| 2212 | * spider_net_probe - initialization of a device | ||
| 2213 | * @pdev: PCI device | ||
| 2214 | * @ent: entry in the device id list | ||
| 2215 | * | ||
| 2216 | * Returns 0 on success, <0 on failure | ||
| 2217 | * | ||
| 2218 | * spider_net_probe initializes pdev and registers a net_device | ||
| 2219 | * structure for it. After that, the device can be ifconfig'ed up | ||
| 2220 | **/ | ||
| 2221 | static int __devinit | ||
| 2222 | spider_net_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
| 2223 | { | ||
| 2224 | int err = -EIO; | ||
| 2225 | struct spider_net_card *card; | ||
| 2226 | |||
| 2227 | card = spider_net_setup_pci_dev(pdev); | ||
| 2228 | if (!card) | ||
| 2229 | goto out; | ||
| 2230 | |||
| 2231 | spider_net_workaround_rxramfull(card); | ||
| 2232 | spider_net_init_card(card); | ||
| 2233 | |||
| 2234 | err = spider_net_setup_phy(card); | ||
| 2235 | if (err) | ||
| 2236 | goto out_undo_pci; | ||
| 2237 | |||
| 2238 | err = spider_net_init_firmware(card); | ||
| 2239 | if (err) | ||
| 2240 | goto out_undo_pci; | ||
| 2241 | |||
| 2242 | err = spider_net_setup_netdev(card); | ||
| 2243 | if (err) | ||
| 2244 | goto out_undo_pci; | ||
| 2245 | |||
| 2246 | return 0; | ||
| 2247 | |||
| 2248 | out_undo_pci: | ||
| 2249 | spider_net_undo_pci_setup(card); | ||
| 2250 | free_netdev(card->netdev); | ||
| 2251 | out: | ||
| 2252 | return err; | ||
| 2253 | } | ||
| 2254 | |||
| 2255 | /** | ||
| 2256 | * spider_net_remove - removal of a device | ||
| 2257 | * @pdev: PCI device | ||
| 2258 | * | ||
| 2259 | * Returns 0 on success, <0 on failure | ||
| 2260 | * | ||
| 2261 | * spider_net_remove is called to remove the device and unregisters the | ||
| 2262 | * net_device | ||
| 2263 | **/ | ||
| 2264 | static void __devexit | ||
| 2265 | spider_net_remove(struct pci_dev *pdev) | ||
| 2266 | { | ||
| 2267 | struct net_device *netdev; | ||
| 2268 | struct spider_net_card *card; | ||
| 2269 | |||
| 2270 | netdev = pci_get_drvdata(pdev); | ||
| 2271 | card = netdev_priv(netdev); | ||
| 2272 | |||
| 2273 | wait_event(card->waitq, | ||
| 2274 | atomic_read(&card->tx_timeout_task_counter) == 0); | ||
| 2275 | |||
| 2276 | unregister_netdev(netdev); | ||
| 2277 | |||
| 2278 | /* switch off card */ | ||
| 2279 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | ||
| 2280 | SPIDER_NET_CKRCTRL_STOP_VALUE); | ||
| 2281 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | ||
| 2282 | SPIDER_NET_CKRCTRL_RUN_VALUE); | ||
| 2283 | |||
| 2284 | spider_net_undo_pci_setup(card); | ||
| 2285 | free_netdev(netdev); | ||
| 2286 | } | ||
| 2287 | |||
| 2288 | static struct pci_driver spider_net_driver = { | ||
| 2289 | .owner = THIS_MODULE, | ||
| 2290 | .name = spider_net_driver_name, | ||
| 2291 | .id_table = spider_net_pci_tbl, | ||
| 2292 | .probe = spider_net_probe, | ||
| 2293 | .remove = __devexit_p(spider_net_remove) | ||
| 2294 | }; | ||
| 2295 | |||
| 2296 | /** | ||
| 2297 | * spider_net_init - init function when the driver is loaded | ||
| 2298 | * | ||
| 2299 | * spider_net_init registers the device driver | ||
| 2300 | */ | ||
| 2301 | static int __init spider_net_init(void) | ||
| 2302 | { | ||
| 2303 | if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { | ||
| 2304 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; | ||
| 2305 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); | ||
| 2306 | } | ||
| 2307 | if (rx_descriptors > SPIDER_NET_RX_DESCRIPTORS_MAX) { | ||
| 2308 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MAX; | ||
| 2309 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); | ||
| 2310 | } | ||
| 2311 | if (tx_descriptors < SPIDER_NET_TX_DESCRIPTORS_MIN) { | ||
| 2312 | tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_MIN; | ||
| 2313 | pr_info("adjusting tx descriptors to %i.\n", tx_descriptors); | ||
| 2314 | } | ||
| 2315 | if (tx_descriptors > SPIDER_NET_TX_DESCRIPTORS_MAX) { | ||
| 2316 | tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_MAX; | ||
| 2317 | pr_info("adjusting tx descriptors to %i.\n", tx_descriptors); | ||
| 2318 | } | ||
| 2319 | |||
| 2320 | return pci_register_driver(&spider_net_driver); | ||
| 2321 | } | ||
| 2322 | |||
| 2323 | /** | ||
| 2324 | * spider_net_cleanup - exit function when driver is unloaded | ||
| 2325 | * | ||
| 2326 | * spider_net_cleanup unregisters the device driver | ||
| 2327 | */ | ||
| 2328 | static void __exit spider_net_cleanup(void) | ||
| 2329 | { | ||
| 2330 | pci_unregister_driver(&spider_net_driver); | ||
| 2331 | } | ||
| 2332 | |||
| 2333 | module_init(spider_net_init); | ||
| 2334 | module_exit(spider_net_cleanup); | ||
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h new file mode 100644 index 000000000000..22b2f2347351 --- /dev/null +++ b/drivers/net/spider_net.h | |||
| @@ -0,0 +1,469 @@ | |||
| 1 | /* | ||
| 2 | * Network device driver for Cell Processor-Based Blade | ||
| 3 | * | ||
| 4 | * (C) Copyright IBM Corp. 2005 | ||
| 5 | * | ||
| 6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | ||
| 7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef _SPIDER_NET_H | ||
| 25 | #define _SPIDER_NET_H | ||
| 26 | |||
| 27 | #include "sungem_phy.h" | ||
| 28 | |||
| 29 | extern int spider_net_stop(struct net_device *netdev); | ||
| 30 | extern int spider_net_open(struct net_device *netdev); | ||
| 31 | |||
| 32 | extern struct ethtool_ops spider_net_ethtool_ops; | ||
| 33 | |||
| 34 | extern char spider_net_driver_name[]; | ||
| 35 | |||
| 36 | #define SPIDER_NET_MAX_MTU 2308 | ||
| 37 | #define SPIDER_NET_MIN_MTU 64 | ||
| 38 | |||
| 39 | #define SPIDER_NET_RXBUF_ALIGN 128 | ||
| 40 | |||
| 41 | #define SPIDER_NET_RX_DESCRIPTORS_DEFAULT 64 | ||
| 42 | #define SPIDER_NET_RX_DESCRIPTORS_MIN 16 | ||
| 43 | #define SPIDER_NET_RX_DESCRIPTORS_MAX 256 | ||
| 44 | |||
| 45 | #define SPIDER_NET_TX_DESCRIPTORS_DEFAULT 64 | ||
| 46 | #define SPIDER_NET_TX_DESCRIPTORS_MIN 16 | ||
| 47 | #define SPIDER_NET_TX_DESCRIPTORS_MAX 256 | ||
| 48 | |||
| 49 | #define SPIDER_NET_RX_CSUM_DEFAULT 1 | ||
| 50 | |||
| 51 | #define SPIDER_NET_WATCHDOG_TIMEOUT 5*HZ | ||
| 52 | #define SPIDER_NET_NAPI_WEIGHT 64 | ||
| 53 | |||
| 54 | #define SPIDER_NET_FIRMWARE_LEN 1024 | ||
| 55 | #define SPIDER_NET_FIRMWARE_NAME "spider_fw.bin" | ||
| 56 | |||
| 57 | /** spider_net SMMIO registers */ | ||
| 58 | #define SPIDER_NET_GHIINT0STS 0x00000000 | ||
| 59 | #define SPIDER_NET_GHIINT1STS 0x00000004 | ||
| 60 | #define SPIDER_NET_GHIINT2STS 0x00000008 | ||
| 61 | #define SPIDER_NET_GHIINT0MSK 0x00000010 | ||
| 62 | #define SPIDER_NET_GHIINT1MSK 0x00000014 | ||
| 63 | #define SPIDER_NET_GHIINT2MSK 0x00000018 | ||
| 64 | |||
| 65 | #define SPIDER_NET_GRESUMINTNUM 0x00000020 | ||
| 66 | #define SPIDER_NET_GREINTNUM 0x00000024 | ||
| 67 | |||
| 68 | #define SPIDER_NET_GFFRMNUM 0x00000028 | ||
| 69 | #define SPIDER_NET_GFAFRMNUM 0x0000002c | ||
| 70 | #define SPIDER_NET_GFBFRMNUM 0x00000030 | ||
| 71 | #define SPIDER_NET_GFCFRMNUM 0x00000034 | ||
| 72 | #define SPIDER_NET_GFDFRMNUM 0x00000038 | ||
| 73 | |||
| 74 | /* clear them (don't use it) */ | ||
| 75 | #define SPIDER_NET_GFREECNNUM 0x0000003c | ||
| 76 | #define SPIDER_NET_GONETIMENUM 0x00000040 | ||
| 77 | |||
| 78 | #define SPIDER_NET_GTOUTFRMNUM 0x00000044 | ||
| 79 | |||
| 80 | #define SPIDER_NET_GTXMDSET 0x00000050 | ||
| 81 | #define SPIDER_NET_GPCCTRL 0x00000054 | ||
| 82 | #define SPIDER_NET_GRXMDSET 0x00000058 | ||
| 83 | #define SPIDER_NET_GIPSECINIT 0x0000005c | ||
| 84 | #define SPIDER_NET_GFTRESTRT 0x00000060 | ||
| 85 | #define SPIDER_NET_GRXDMAEN 0x00000064 | ||
| 86 | #define SPIDER_NET_GMRWOLCTRL 0x00000068 | ||
| 87 | #define SPIDER_NET_GPCWOPCMD 0x0000006c | ||
| 88 | #define SPIDER_NET_GPCROPCMD 0x00000070 | ||
| 89 | #define SPIDER_NET_GTTFRMCNT 0x00000078 | ||
| 90 | #define SPIDER_NET_GTESTMD 0x0000007c | ||
| 91 | |||
| 92 | #define SPIDER_NET_GSINIT 0x00000080 | ||
| 93 | #define SPIDER_NET_GSnPRGADR 0x00000084 | ||
| 94 | #define SPIDER_NET_GSnPRGDAT 0x00000088 | ||
| 95 | |||
| 96 | #define SPIDER_NET_GMACOPEMD 0x00000100 | ||
| 97 | #define SPIDER_NET_GMACLENLMT 0x00000108 | ||
| 98 | #define SPIDER_NET_GMACINTEN 0x00000118 | ||
| 99 | #define SPIDER_NET_GMACPHYCTRL 0x00000120 | ||
| 100 | |||
| 101 | #define SPIDER_NET_GMACAPAUSE 0x00000154 | ||
| 102 | #define SPIDER_NET_GMACTXPAUSE 0x00000164 | ||
| 103 | |||
| 104 | #define SPIDER_NET_GMACMODE 0x000001b0 | ||
| 105 | #define SPIDER_NET_GMACBSTLMT 0x000001b4 | ||
| 106 | |||
| 107 | #define SPIDER_NET_GMACUNIMACU 0x000001c0 | ||
| 108 | #define SPIDER_NET_GMACUNIMACL 0x000001c8 | ||
| 109 | |||
| 110 | #define SPIDER_NET_GMRMHFILnR 0x00000400 | ||
| 111 | #define SPIDER_NET_MULTICAST_HASHES 256 | ||
| 112 | |||
| 113 | #define SPIDER_NET_GMRUAFILnR 0x00000500 | ||
| 114 | #define SPIDER_NET_GMRUA0FIL15R 0x00000578 | ||
| 115 | |||
| 116 | /* RX DMA controller registers, all 0x00000a.. are for DMA controller A, | ||
| 117 | * 0x00000b.. for DMA controller B, etc. */ | ||
| 118 | #define SPIDER_NET_GDADCHA 0x00000a00 | ||
| 119 | #define SPIDER_NET_GDADMACCNTR 0x00000a04 | ||
| 120 | #define SPIDER_NET_GDACTDPA 0x00000a08 | ||
| 121 | #define SPIDER_NET_GDACTDCNT 0x00000a0c | ||
| 122 | #define SPIDER_NET_GDACDBADDR 0x00000a20 | ||
| 123 | #define SPIDER_NET_GDACDBSIZE 0x00000a24 | ||
| 124 | #define SPIDER_NET_GDACNEXTDA 0x00000a28 | ||
| 125 | #define SPIDER_NET_GDACCOMST 0x00000a2c | ||
| 126 | #define SPIDER_NET_GDAWBCOMST 0x00000a30 | ||
| 127 | #define SPIDER_NET_GDAWBRSIZE 0x00000a34 | ||
| 128 | #define SPIDER_NET_GDAWBVSIZE 0x00000a38 | ||
| 129 | #define SPIDER_NET_GDAWBTRST 0x00000a3c | ||
| 130 | #define SPIDER_NET_GDAWBTRERR 0x00000a40 | ||
| 131 | |||
| 132 | /* TX DMA controller registers */ | ||
| 133 | #define SPIDER_NET_GDTDCHA 0x00000e00 | ||
| 134 | #define SPIDER_NET_GDTDMACCNTR 0x00000e04 | ||
| 135 | #define SPIDER_NET_GDTCDPA 0x00000e08 | ||
| 136 | #define SPIDER_NET_GDTDMASEL 0x00000e14 | ||
| 137 | |||
| 138 | #define SPIDER_NET_ECMODE 0x00000f00 | ||
| 139 | /* clock and reset control register */ | ||
| 140 | #define SPIDER_NET_CKRCTRL 0x00000ff0 | ||
| 141 | |||
| 142 | /** SCONFIG registers */ | ||
| 143 | #define SPIDER_NET_SCONFIG_IOACTE 0x00002810 | ||
| 144 | |||
| 145 | /** hardcoded register values */ | ||
| 146 | #define SPIDER_NET_INT0_MASK_VALUE 0x3f7fe3ff | ||
| 147 | #define SPIDER_NET_INT1_MASK_VALUE 0xffffffff | ||
| 148 | /* no MAC aborts -> auto retransmission */ | ||
| 149 | #define SPIDER_NET_INT2_MASK_VALUE 0xfffffff1 | ||
| 150 | |||
| 151 | /* clear counter when interrupt sources are cleared | ||
| 152 | #define SPIDER_NET_FRAMENUM_VALUE 0x0001f001 */ | ||
| 153 | /* we rely on flagged descriptor interrupts */ | ||
| 154 | #define SPIDER_NET_FRAMENUM_VALUE 0x00000000 | ||
| 155 | /* set this first, then the FRAMENUM_VALUE */ | ||
| 156 | #define SPIDER_NET_GFXFRAMES_VALUE 0x00000000 | ||
| 157 | |||
| 158 | #define SPIDER_NET_STOP_SEQ_VALUE 0x00000000 | ||
| 159 | #define SPIDER_NET_RUN_SEQ_VALUE 0x0000007e | ||
| 160 | |||
| 161 | #define SPIDER_NET_PHY_CTRL_VALUE 0x00040040 | ||
| 162 | /* #define SPIDER_NET_PHY_CTRL_VALUE 0x01070080*/ | ||
| 163 | #define SPIDER_NET_RXMODE_VALUE 0x00000011 | ||
| 164 | /* auto retransmission in case of MAC aborts */ | ||
| 165 | #define SPIDER_NET_TXMODE_VALUE 0x00010000 | ||
| 166 | #define SPIDER_NET_RESTART_VALUE 0x00000000 | ||
| 167 | #define SPIDER_NET_WOL_VALUE 0x00001111 | ||
| 168 | #if 0 | ||
| 169 | #define SPIDER_NET_WOL_VALUE 0x00000000 | ||
| 170 | #endif | ||
| 171 | #define SPIDER_NET_IPSECINIT_VALUE 0x00f000f8 | ||
| 172 | |||
| 173 | /* pause frames: automatic, no upper retransmission count */ | ||
| 174 | /* outside loopback mode: ETOMOD signal dont matter, not connected */ | ||
| 175 | #define SPIDER_NET_OPMODE_VALUE 0x00000063 | ||
| 176 | /*#define SPIDER_NET_OPMODE_VALUE 0x001b0062*/ | ||
| 177 | #define SPIDER_NET_LENLMT_VALUE 0x00000908 | ||
| 178 | |||
| 179 | #define SPIDER_NET_MACAPAUSE_VALUE 0x00000800 /* about 1 ms */ | ||
| 180 | #define SPIDER_NET_TXPAUSE_VALUE 0x00000000 | ||
| 181 | |||
| 182 | #define SPIDER_NET_MACMODE_VALUE 0x00000001 | ||
| 183 | #define SPIDER_NET_BURSTLMT_VALUE 0x00000200 /* about 16 us */ | ||
| 184 | |||
| 185 | /* 1(0) enable r/tx dma | ||
| 186 | * 0000000 fixed to 0 | ||
| 187 | * | ||
| 188 | * 000000 fixed to 0 | ||
| 189 | * 0(1) en/disable descr writeback on force end | ||
| 190 | * 0(1) force end | ||
| 191 | * | ||
| 192 | * 000000 fixed to 0 | ||
| 193 | * 00 burst alignment: 128 bytes | ||
| 194 | * | ||
| 195 | * 00000 fixed to 0 | ||
| 196 | * 0 descr writeback size 32 bytes | ||
| 197 | * 0(1) descr chain end interrupt enable | ||
| 198 | * 0(1) descr status writeback enable */ | ||
| 199 | |||
| 200 | /* to set RX_DMA_EN */ | ||
| 201 | #define SPIDER_NET_DMA_RX_VALUE 0x80000000 | ||
| 202 | #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 | ||
| 203 | /* to set TX_DMA_EN */ | ||
| 204 | #define SPIDER_NET_DMA_TX_VALUE 0x80000000 | ||
| 205 | #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 | ||
| 206 | |||
| 207 | /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ | ||
| 208 | #define SPIDER_NET_UA_DESCR_VALUE 0x00080000 | ||
| 209 | #define SPIDER_NET_PROMISC_VALUE 0x00080000 | ||
| 210 | #define SPIDER_NET_NONPROMISC_VALUE 0x00000000 | ||
| 211 | |||
| 212 | #define SPIDER_NET_DMASEL_VALUE 0x00000001 | ||
| 213 | |||
| 214 | #define SPIDER_NET_ECMODE_VALUE 0x00000000 | ||
| 215 | |||
| 216 | #define SPIDER_NET_CKRCTRL_RUN_VALUE 0x1fff010f | ||
| 217 | #define SPIDER_NET_CKRCTRL_STOP_VALUE 0x0000010f | ||
| 218 | |||
| 219 | #define SPIDER_NET_SBIMSTATE_VALUE 0x00000000 | ||
| 220 | #define SPIDER_NET_SBTMSTATE_VALUE 0x00000000 | ||
| 221 | |||
| 222 | /* SPIDER_NET_GHIINT0STS bits, in reverse order so that they can be used | ||
| 223 | * with 1 << SPIDER_NET_... */ | ||
| 224 | enum spider_net_int0_status { | ||
| 225 | SPIDER_NET_GPHYINT = 0, | ||
| 226 | SPIDER_NET_GMAC2INT, | ||
| 227 | SPIDER_NET_GMAC1INT, | ||
| 228 | SPIDER_NET_GIPSINT, | ||
| 229 | SPIDER_NET_GFIFOINT, | ||
| 230 | SPIDER_NET_GDMACINT, | ||
| 231 | SPIDER_NET_GSYSINT, | ||
| 232 | SPIDER_NET_GPWOPCMPINT, | ||
| 233 | SPIDER_NET_GPROPCMPINT, | ||
| 234 | SPIDER_NET_GPWFFINT, | ||
| 235 | SPIDER_NET_GRMDADRINT, | ||
| 236 | SPIDER_NET_GRMARPINT, | ||
| 237 | SPIDER_NET_GRMMPINT, | ||
| 238 | SPIDER_NET_GDTDEN0INT, | ||
| 239 | SPIDER_NET_GDDDEN0INT, | ||
| 240 | SPIDER_NET_GDCDEN0INT, | ||
| 241 | SPIDER_NET_GDBDEN0INT, | ||
| 242 | SPIDER_NET_GDADEN0INT, | ||
| 243 | SPIDER_NET_GDTFDCINT, | ||
| 244 | SPIDER_NET_GDDFDCINT, | ||
| 245 | SPIDER_NET_GDCFDCINT, | ||
| 246 | SPIDER_NET_GDBFDCINT, | ||
| 247 | SPIDER_NET_GDAFDCINT, | ||
| 248 | SPIDER_NET_GTTEDINT, | ||
| 249 | SPIDER_NET_GDTDCEINT, | ||
| 250 | SPIDER_NET_GRFDNMINT, | ||
| 251 | SPIDER_NET_GRFCNMINT, | ||
| 252 | SPIDER_NET_GRFBNMINT, | ||
| 253 | SPIDER_NET_GRFANMINT, | ||
| 254 | SPIDER_NET_GRFNMINT, | ||
| 255 | SPIDER_NET_G1TMCNTINT, | ||
| 256 | SPIDER_NET_GFREECNTINT | ||
| 257 | }; | ||
| 258 | /* GHIINT1STS bits */ | ||
| 259 | enum spider_net_int1_status { | ||
| 260 | SPIDER_NET_GTMFLLINT = 0, | ||
| 261 | SPIDER_NET_GRMFLLINT, | ||
| 262 | SPIDER_NET_GTMSHTINT, | ||
| 263 | SPIDER_NET_GDTINVDINT, | ||
| 264 | SPIDER_NET_GRFDFLLINT, | ||
| 265 | SPIDER_NET_GDDDCEINT, | ||
| 266 | SPIDER_NET_GDDINVDINT, | ||
| 267 | SPIDER_NET_GRFCFLLINT, | ||
| 268 | SPIDER_NET_GDCDCEINT, | ||
| 269 | SPIDER_NET_GDCINVDINT, | ||
| 270 | SPIDER_NET_GRFBFLLINT, | ||
| 271 | SPIDER_NET_GDBDCEINT, | ||
| 272 | SPIDER_NET_GDBINVDINT, | ||
| 273 | SPIDER_NET_GRFAFLLINT, | ||
| 274 | SPIDER_NET_GDADCEINT, | ||
| 275 | SPIDER_NET_GDAINVDINT, | ||
| 276 | SPIDER_NET_GDTRSERINT, | ||
| 277 | SPIDER_NET_GDDRSERINT, | ||
| 278 | SPIDER_NET_GDCRSERINT, | ||
| 279 | SPIDER_NET_GDBRSERINT, | ||
| 280 | SPIDER_NET_GDARSERINT, | ||
| 281 | SPIDER_NET_GDSERINT, | ||
| 282 | SPIDER_NET_GDTPTERINT, | ||
| 283 | SPIDER_NET_GDDPTERINT, | ||
| 284 | SPIDER_NET_GDCPTERINT, | ||
| 285 | SPIDER_NET_GDBPTERINT, | ||
| 286 | SPIDER_NET_GDAPTERINT | ||
| 287 | }; | ||
| 288 | /* GHIINT2STS bits */ | ||
| 289 | enum spider_net_int2_status { | ||
| 290 | SPIDER_NET_GPROPERINT = 0, | ||
| 291 | SPIDER_NET_GMCTCRSNGINT, | ||
| 292 | SPIDER_NET_GMCTLCOLINT, | ||
| 293 | SPIDER_NET_GMCTTMOTINT, | ||
| 294 | SPIDER_NET_GMCRCAERINT, | ||
| 295 | SPIDER_NET_GMCRCALERINT, | ||
| 296 | SPIDER_NET_GMCRALNERINT, | ||
| 297 | SPIDER_NET_GMCROVRINT, | ||
| 298 | SPIDER_NET_GMCRRNTINT, | ||
| 299 | SPIDER_NET_GMCRRXERINT, | ||
| 300 | SPIDER_NET_GTITCSERINT, | ||
| 301 | SPIDER_NET_GTIFMTERINT, | ||
| 302 | SPIDER_NET_GTIPKTRVKINT, | ||
| 303 | SPIDER_NET_GTISPINGINT, | ||
| 304 | SPIDER_NET_GTISADNGINT, | ||
| 305 | SPIDER_NET_GTISPDNGINT, | ||
| 306 | SPIDER_NET_GRIFMTERINT, | ||
| 307 | SPIDER_NET_GRIPKTRVKINT, | ||
| 308 | SPIDER_NET_GRISPINGINT, | ||
| 309 | SPIDER_NET_GRISADNGINT, | ||
| 310 | SPIDER_NET_GRISPDNGINT | ||
| 311 | }; | ||
| 312 | |||
| 313 | #define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GTTEDINT) | \ | ||
| 314 | (1 << SPIDER_NET_GDTDCEINT) | \ | ||
| 315 | (1 << SPIDER_NET_GDTFDCINT) ) | ||
| 316 | |||
| 317 | /* we rely on flagged descriptor interrupts*/ | ||
| 318 | #define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) | \ | ||
| 319 | (1 << SPIDER_NET_GRMFLLINT) ) | ||
| 320 | |||
| 321 | #define SPIDER_NET_GPREXEC 0x80000000 | ||
| 322 | #define SPIDER_NET_GPRDAT_MASK 0x0000ffff | ||
| 323 | |||
| 324 | /* descriptor bits | ||
| 325 | * | ||
| 326 | * 1010 descriptor ready | ||
| 327 | * 0 descr in middle of chain | ||
| 328 | * 000 fixed to 0 | ||
| 329 | * | ||
| 330 | * 0 no interrupt on completion | ||
| 331 | * 000 fixed to 0 | ||
| 332 | * 1 no ipsec processing | ||
| 333 | * 1 last descriptor for this frame | ||
| 334 | * 00 no checksum | ||
| 335 | * 10 tcp checksum | ||
| 336 | * 11 udp checksum | ||
| 337 | * | ||
| 338 | * 00 fixed to 0 | ||
| 339 | * 0 fixed to 0 | ||
| 340 | * 0 no interrupt on response errors | ||
| 341 | * 0 no interrupt on invalid descr | ||
| 342 | * 0 no interrupt on dma process termination | ||
| 343 | * 0 no interrupt on descr chain end | ||
| 344 | * 0 no interrupt on descr complete | ||
| 345 | * | ||
| 346 | * 000 fixed to 0 | ||
| 347 | * 0 response error interrupt status | ||
| 348 | * 0 invalid descr status | ||
| 349 | * 0 dma termination status | ||
| 350 | * 0 descr chain end status | ||
| 351 | * 0 descr complete status */ | ||
| 352 | #define SPIDER_NET_DMAC_CMDSTAT_NOCS 0xa00c0000 | ||
| 353 | #define SPIDER_NET_DMAC_CMDSTAT_TCPCS 0xa00e0000 | ||
| 354 | #define SPIDER_NET_DMAC_CMDSTAT_UDPCS 0xa00f0000 | ||
| 355 | #define SPIDER_NET_DESCR_IND_PROC_SHIFT 28 | ||
| 356 | #define SPIDER_NET_DESCR_IND_PROC_MASKO 0x0fffffff | ||
| 357 | |||
| 358 | /* descr ready, descr is in middle of chain, get interrupt on completion */ | ||
| 359 | #define SPIDER_NET_DMAC_RX_CARDOWNED 0xa0800000 | ||
| 360 | |||
| 361 | /* multicast is no problem */ | ||
| 362 | #define SPIDER_NET_DATA_ERROR_MASK 0xffffbfff | ||
| 363 | |||
| 364 | enum spider_net_descr_status { | ||
| 365 | SPIDER_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ | ||
| 366 | SPIDER_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ | ||
| 367 | SPIDER_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ | ||
| 368 | SPIDER_NET_DESCR_FRAME_END = 0x04, /* used in rx */ | ||
| 369 | SPIDER_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ | ||
| 370 | SPIDER_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ | ||
| 371 | SPIDER_NET_DESCR_NOT_IN_USE /* any other value */ | ||
| 372 | }; | ||
| 373 | |||
| 374 | struct spider_net_descr { | ||
| 375 | /* as defined by the hardware */ | ||
| 376 | dma_addr_t buf_addr; | ||
| 377 | u32 buf_size; | ||
| 378 | dma_addr_t next_descr_addr; | ||
| 379 | u32 dmac_cmd_status; | ||
| 380 | u32 result_size; | ||
| 381 | u32 valid_size; /* all zeroes for tx */ | ||
| 382 | u32 data_status; | ||
| 383 | u32 data_error; /* all zeroes for tx */ | ||
| 384 | |||
| 385 | /* used in the driver */ | ||
| 386 | struct sk_buff *skb; | ||
| 387 | dma_addr_t bus_addr; | ||
| 388 | struct spider_net_descr *next; | ||
| 389 | struct spider_net_descr *prev; | ||
| 390 | } __attribute__((aligned(32))); | ||
| 391 | |||
| 392 | struct spider_net_descr_chain { | ||
| 393 | /* we walk from tail to head */ | ||
| 394 | struct spider_net_descr *head; | ||
| 395 | struct spider_net_descr *tail; | ||
| 396 | }; | ||
| 397 | |||
| 398 | /* descriptor data_status bits */ | ||
| 399 | #define SPIDER_NET_RXIPCHK 29 | ||
| 400 | #define SPIDER_NET_TCPUDPIPCHK 28 | ||
| 401 | #define SPIDER_NET_DATA_STATUS_CHK_MASK (1 << SPIDER_NET_RXIPCHK | \ | ||
| 402 | 1 << SPIDER_NET_TCPUDPIPCHK) | ||
| 403 | |||
| 404 | #define SPIDER_NET_VLAN_PACKET 21 | ||
| 405 | |||
| 406 | /* descriptor data_error bits */ | ||
| 407 | #define SPIDER_NET_RXIPCHKERR 27 | ||
| 408 | #define SPIDER_NET_RXTCPCHKERR 26 | ||
| 409 | #define SPIDER_NET_DATA_ERROR_CHK_MASK (1 << SPIDER_NET_RXIPCHKERR | \ | ||
| 410 | 1 << SPIDER_NET_RXTCPCHKERR) | ||
| 411 | |||
| 412 | /* the cases we don't pass the packet to the stack */ | ||
| 413 | #define SPIDER_NET_DESTROY_RX_FLAGS 0x70138000 | ||
| 414 | |||
| 415 | #define SPIDER_NET_DESCR_SIZE 32 | ||
| 416 | |||
| 417 | /* this will be bigger some time */ | ||
| 418 | struct spider_net_options { | ||
| 419 | int rx_csum; /* for rx: if 0 ip_summed=NONE, | ||
| 420 | if 1 and hw has verified, ip_summed=UNNECESSARY */ | ||
| 421 | }; | ||
| 422 | |||
| 423 | #define SPIDER_NET_DEFAULT_MSG ( NETIF_MSG_DRV | \ | ||
| 424 | NETIF_MSG_PROBE | \ | ||
| 425 | NETIF_MSG_LINK | \ | ||
| 426 | NETIF_MSG_TIMER | \ | ||
| 427 | NETIF_MSG_IFDOWN | \ | ||
| 428 | NETIF_MSG_IFUP | \ | ||
| 429 | NETIF_MSG_RX_ERR | \ | ||
| 430 | NETIF_MSG_TX_ERR | \ | ||
| 431 | NETIF_MSG_TX_QUEUED | \ | ||
| 432 | NETIF_MSG_INTR | \ | ||
| 433 | NETIF_MSG_TX_DONE | \ | ||
| 434 | NETIF_MSG_RX_STATUS | \ | ||
| 435 | NETIF_MSG_PKTDATA | \ | ||
| 436 | NETIF_MSG_HW | \ | ||
| 437 | NETIF_MSG_WOL ) | ||
| 438 | |||
| 439 | struct spider_net_card { | ||
| 440 | struct net_device *netdev; | ||
| 441 | struct pci_dev *pdev; | ||
| 442 | struct mii_phy phy; | ||
| 443 | |||
| 444 | void __iomem *regs; | ||
| 445 | |||
| 446 | struct spider_net_descr_chain tx_chain; | ||
| 447 | struct spider_net_descr_chain rx_chain; | ||
| 448 | spinlock_t chain_lock; | ||
| 449 | |||
| 450 | struct net_device_stats netdev_stats; | ||
| 451 | |||
| 452 | struct spider_net_options options; | ||
| 453 | |||
| 454 | spinlock_t intmask_lock; | ||
| 455 | |||
| 456 | struct work_struct tx_timeout_task; | ||
| 457 | atomic_t tx_timeout_task_counter; | ||
| 458 | wait_queue_head_t waitq; | ||
| 459 | |||
| 460 | /* for ethtool */ | ||
| 461 | int msg_enable; | ||
| 462 | |||
| 463 | struct spider_net_descr descr[0]; | ||
| 464 | }; | ||
| 465 | |||
| 466 | #define pr_err(fmt,arg...) \ | ||
| 467 | printk(KERN_ERR fmt ,##arg) | ||
| 468 | |||
| 469 | #endif | ||
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c new file mode 100644 index 000000000000..d42e60ba74ce --- /dev/null +++ b/drivers/net/spider_net_ethtool.c | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * Network device driver for Cell Processor-Based Blade | ||
| 3 | * | ||
| 4 | * (C) Copyright IBM Corp. 2005 | ||
| 5 | * | ||
| 6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | ||
| 7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/netdevice.h> | ||
| 25 | #include <linux/ethtool.h> | ||
| 26 | #include <linux/pci.h> | ||
| 27 | |||
| 28 | #include "spider_net.h" | ||
| 29 | |||
| 30 | static int | ||
| 31 | spider_net_ethtool_get_settings(struct net_device *netdev, | ||
| 32 | struct ethtool_cmd *cmd) | ||
| 33 | { | ||
| 34 | struct spider_net_card *card; | ||
| 35 | card = netdev_priv(netdev); | ||
| 36 | |||
| 37 | cmd->supported = (SUPPORTED_1000baseT_Full | | ||
| 38 | SUPPORTED_FIBRE); | ||
| 39 | cmd->advertising = (ADVERTISED_1000baseT_Full | | ||
| 40 | ADVERTISED_FIBRE); | ||
| 41 | cmd->port = PORT_FIBRE; | ||
| 42 | cmd->speed = card->phy.speed; | ||
| 43 | cmd->duplex = DUPLEX_FULL; | ||
| 44 | |||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | static void | ||
| 49 | spider_net_ethtool_get_drvinfo(struct net_device *netdev, | ||
| 50 | struct ethtool_drvinfo *drvinfo) | ||
| 51 | { | ||
| 52 | struct spider_net_card *card; | ||
| 53 | card = netdev_priv(netdev); | ||
| 54 | |||
| 55 | /* clear and fill out info */ | ||
| 56 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); | ||
| 57 | strncpy(drvinfo->driver, spider_net_driver_name, 32); | ||
| 58 | strncpy(drvinfo->version, "0.1", 32); | ||
| 59 | strcpy(drvinfo->fw_version, "no information"); | ||
| 60 | strncpy(drvinfo->bus_info, pci_name(card->pdev), 32); | ||
| 61 | } | ||
| 62 | |||
| 63 | static void | ||
| 64 | spider_net_ethtool_get_wol(struct net_device *netdev, | ||
| 65 | struct ethtool_wolinfo *wolinfo) | ||
| 66 | { | ||
| 67 | /* no support for wol */ | ||
| 68 | wolinfo->supported = 0; | ||
| 69 | wolinfo->wolopts = 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static u32 | ||
| 73 | spider_net_ethtool_get_msglevel(struct net_device *netdev) | ||
| 74 | { | ||
| 75 | struct spider_net_card *card; | ||
| 76 | card = netdev_priv(netdev); | ||
| 77 | return card->msg_enable; | ||
| 78 | } | ||
| 79 | |||
| 80 | static void | ||
| 81 | spider_net_ethtool_set_msglevel(struct net_device *netdev, | ||
| 82 | u32 level) | ||
| 83 | { | ||
| 84 | struct spider_net_card *card; | ||
| 85 | card = netdev_priv(netdev); | ||
| 86 | card->msg_enable = level; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int | ||
| 90 | spider_net_ethtool_nway_reset(struct net_device *netdev) | ||
| 91 | { | ||
| 92 | if (netif_running(netdev)) { | ||
| 93 | spider_net_stop(netdev); | ||
| 94 | spider_net_open(netdev); | ||
| 95 | } | ||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static u32 | ||
| 100 | spider_net_ethtool_get_rx_csum(struct net_device *netdev) | ||
| 101 | { | ||
| 102 | struct spider_net_card *card = netdev->priv; | ||
| 103 | |||
| 104 | return card->options.rx_csum; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int | ||
| 108 | spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n) | ||
| 109 | { | ||
| 110 | struct spider_net_card *card = netdev->priv; | ||
| 111 | |||
| 112 | card->options.rx_csum = n; | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | struct ethtool_ops spider_net_ethtool_ops = { | ||
| 117 | .get_settings = spider_net_ethtool_get_settings, | ||
| 118 | .get_drvinfo = spider_net_ethtool_get_drvinfo, | ||
| 119 | .get_wol = spider_net_ethtool_get_wol, | ||
| 120 | .get_msglevel = spider_net_ethtool_get_msglevel, | ||
| 121 | .set_msglevel = spider_net_ethtool_set_msglevel, | ||
| 122 | .nway_reset = spider_net_ethtool_nway_reset, | ||
| 123 | .get_rx_csum = spider_net_ethtool_get_rx_csum, | ||
| 124 | .set_rx_csum = spider_net_ethtool_set_rx_csum, | ||
| 125 | }; | ||
| 126 | |||
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index 1f43bbfbc1c7..5c8fcd40ef4d 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c | |||
| @@ -162,7 +162,7 @@ struct lance_private { | |||
| 162 | #define MEM lp->mem | 162 | #define MEM lp->mem |
| 163 | #define DREG lp->iobase[0] | 163 | #define DREG lp->iobase[0] |
| 164 | #define AREG lp->iobase[1] | 164 | #define AREG lp->iobase[1] |
| 165 | #define REGA(a) ( AREG = (a), DREG ) | 165 | #define REGA(a) (*( AREG = (a), &DREG )) |
| 166 | 166 | ||
| 167 | /* Definitions for the Lance */ | 167 | /* Definitions for the Lance */ |
| 168 | 168 | ||
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index f58c794a963a..b56a7b516d24 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c | |||
| @@ -1440,6 +1440,7 @@ static void sppp_print_bytes (u_char *p, u16 len) | |||
| 1440 | * @skb: The buffer to process | 1440 | * @skb: The buffer to process |
| 1441 | * @dev: The device it arrived on | 1441 | * @dev: The device it arrived on |
| 1442 | * @p: Unused | 1442 | * @p: Unused |
| 1443 | * @orig_dev: Unused | ||
| 1443 | * | 1444 | * |
| 1444 | * Protocol glue. This drives the deferred processing mode the poorer | 1445 | * Protocol glue. This drives the deferred processing mode the poorer |
| 1445 | * cards use. This can be called directly by cards that do not have | 1446 | * cards use. This can be called directly by cards that do not have |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index dbcb5a8a2194..2be65d308fbe 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
| @@ -3258,7 +3258,7 @@ badrx: | |||
| 3258 | wstats.noise = apriv->wstats.qual.noise; | 3258 | wstats.noise = apriv->wstats.qual.noise; |
| 3259 | wstats.updated = IW_QUAL_LEVEL_UPDATED | 3259 | wstats.updated = IW_QUAL_LEVEL_UPDATED |
| 3260 | | IW_QUAL_QUAL_UPDATED | 3260 | | IW_QUAL_QUAL_UPDATED |
| 3261 | | IW_QUAL_NOISE_UPDATED; | 3261 | | IW_QUAL_DBM; |
| 3262 | /* Update spy records */ | 3262 | /* Update spy records */ |
| 3263 | wireless_spy_update(dev, sa, &wstats); | 3263 | wireless_spy_update(dev, sa, &wstats); |
| 3264 | } | 3264 | } |
| @@ -3604,7 +3604,7 @@ void mpi_receive_802_11 (struct airo_info *ai) | |||
| 3604 | wstats.noise = ai->wstats.qual.noise; | 3604 | wstats.noise = ai->wstats.qual.noise; |
| 3605 | wstats.updated = IW_QUAL_QUAL_UPDATED | 3605 | wstats.updated = IW_QUAL_QUAL_UPDATED |
| 3606 | | IW_QUAL_LEVEL_UPDATED | 3606 | | IW_QUAL_LEVEL_UPDATED |
| 3607 | | IW_QUAL_NOISE_UPDATED; | 3607 | | IW_QUAL_DBM; |
| 3608 | /* Update spy records */ | 3608 | /* Update spy records */ |
| 3609 | wireless_spy_update(ai->dev, sa, &wstats); | 3609 | wireless_spy_update(ai->dev, sa, &wstats); |
| 3610 | } | 3610 | } |
| @@ -6489,22 +6489,20 @@ static int airo_get_range(struct net_device *dev, | |||
| 6489 | range->max_qual.qual = 100; /* % */ | 6489 | range->max_qual.qual = 100; /* % */ |
| 6490 | else | 6490 | else |
| 6491 | range->max_qual.qual = airo_get_max_quality(&cap_rid); | 6491 | range->max_qual.qual = airo_get_max_quality(&cap_rid); |
| 6492 | range->max_qual.level = 0; /* 0 means we use dBm */ | 6492 | range->max_qual.level = 0x100 - 120; /* -120 dBm */ |
| 6493 | range->max_qual.noise = 0; | 6493 | range->max_qual.noise = 0x100 - 120; /* -120 dBm */ |
| 6494 | range->max_qual.updated = 0; | ||
| 6495 | 6494 | ||
| 6496 | /* Experimental measurements - boundary 11/5.5 Mb/s */ | 6495 | /* Experimental measurements - boundary 11/5.5 Mb/s */ |
| 6497 | /* Note : with or without the (local->rssi), results | 6496 | /* Note : with or without the (local->rssi), results |
| 6498 | * are somewhat different. - Jean II */ | 6497 | * are somewhat different. - Jean II */ |
| 6499 | if (local->rssi) { | 6498 | if (local->rssi) { |
| 6500 | range->avg_qual.qual = 50; /* % */ | 6499 | range->avg_qual.qual = 50; /* % */ |
| 6501 | range->avg_qual.level = 186; /* -70 dBm */ | 6500 | range->avg_qual.level = 0x100 - 70; /* -70 dBm */ |
| 6502 | } else { | 6501 | } else { |
| 6503 | range->avg_qual.qual = airo_get_avg_quality(&cap_rid); | 6502 | range->avg_qual.qual = airo_get_avg_quality(&cap_rid); |
| 6504 | range->avg_qual.level = 176; /* -80 dBm */ | 6503 | range->avg_qual.level = 0x100 - 80; /* -80 dBm */ |
| 6505 | } | 6504 | } |
| 6506 | range->avg_qual.noise = 0; | 6505 | range->avg_qual.noise = 0x100 - 85; /* -85 dBm */ |
| 6507 | range->avg_qual.updated = 0; | ||
| 6508 | 6506 | ||
| 6509 | for(i = 0 ; i < 8 ; i++) { | 6507 | for(i = 0 ; i < 8 ; i++) { |
| 6510 | range->bitrate[i] = cap_rid.supportedRates[i] * 500000; | 6508 | range->bitrate[i] = cap_rid.supportedRates[i] * 500000; |
| @@ -6727,15 +6725,17 @@ static int airo_get_aplist(struct net_device *dev, | |||
| 6727 | if (local->rssi) { | 6725 | if (local->rssi) { |
| 6728 | qual[i].level = 0x100 - BSSList.dBm; | 6726 | qual[i].level = 0x100 - BSSList.dBm; |
| 6729 | qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm ); | 6727 | qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm ); |
| 6730 | qual[i].updated = IW_QUAL_QUAL_UPDATED; | 6728 | qual[i].updated = IW_QUAL_QUAL_UPDATED |
| 6729 | | IW_QUAL_LEVEL_UPDATED | ||
| 6730 | | IW_QUAL_DBM; | ||
| 6731 | } else { | 6731 | } else { |
| 6732 | qual[i].level = (BSSList.dBm + 321) / 2; | 6732 | qual[i].level = (BSSList.dBm + 321) / 2; |
| 6733 | qual[i].qual = 0; | 6733 | qual[i].qual = 0; |
| 6734 | qual[i].updated = IW_QUAL_QUAL_INVALID; | 6734 | qual[i].updated = IW_QUAL_QUAL_INVALID |
| 6735 | | IW_QUAL_LEVEL_UPDATED | ||
| 6736 | | IW_QUAL_DBM; | ||
| 6735 | } | 6737 | } |
| 6736 | qual[i].noise = local->wstats.qual.noise; | 6738 | qual[i].noise = local->wstats.qual.noise; |
| 6737 | qual[i].updated = IW_QUAL_LEVEL_UPDATED | ||
| 6738 | | IW_QUAL_NOISE_UPDATED; | ||
| 6739 | if (BSSList.index == 0xffff) | 6739 | if (BSSList.index == 0xffff) |
| 6740 | break; | 6740 | break; |
| 6741 | } | 6741 | } |
| @@ -6861,15 +6861,17 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
| 6861 | if (ai->rssi) { | 6861 | if (ai->rssi) { |
| 6862 | iwe.u.qual.level = 0x100 - bss->dBm; | 6862 | iwe.u.qual.level = 0x100 - bss->dBm; |
| 6863 | iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm ); | 6863 | iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm ); |
| 6864 | iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED; | 6864 | iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED |
| 6865 | | IW_QUAL_LEVEL_UPDATED | ||
| 6866 | | IW_QUAL_DBM; | ||
| 6865 | } else { | 6867 | } else { |
| 6866 | iwe.u.qual.level = (bss->dBm + 321) / 2; | 6868 | iwe.u.qual.level = (bss->dBm + 321) / 2; |
| 6867 | iwe.u.qual.qual = 0; | 6869 | iwe.u.qual.qual = 0; |
| 6868 | iwe.u.qual.updated = IW_QUAL_QUAL_INVALID; | 6870 | iwe.u.qual.updated = IW_QUAL_QUAL_INVALID |
| 6871 | | IW_QUAL_LEVEL_UPDATED | ||
| 6872 | | IW_QUAL_DBM; | ||
| 6869 | } | 6873 | } |
| 6870 | iwe.u.qual.noise = ai->wstats.qual.noise; | 6874 | iwe.u.qual.noise = ai->wstats.qual.noise; |
| 6871 | iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED | ||
| 6872 | | IW_QUAL_NOISE_UPDATED; | ||
| 6873 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); | 6875 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); |
| 6874 | 6876 | ||
| 6875 | /* Add encryption capability */ | 6877 | /* Add encryption capability */ |
| @@ -7222,13 +7224,12 @@ static void airo_read_wireless_stats(struct airo_info *local) | |||
| 7222 | local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; | 7224 | local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; |
| 7223 | local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid); | 7225 | local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid); |
| 7224 | } | 7226 | } |
| 7225 | local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED; | ||
| 7226 | if (status_rid.len >= 124) { | 7227 | if (status_rid.len >= 124) { |
| 7227 | local->wstats.qual.noise = 0x100 - status_rid.noisedBm; | 7228 | local->wstats.qual.noise = 0x100 - status_rid.noisedBm; |
| 7228 | local->wstats.qual.updated |= IW_QUAL_NOISE_UPDATED; | 7229 | local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; |
| 7229 | } else { | 7230 | } else { |
| 7230 | local->wstats.qual.noise = 0; | 7231 | local->wstats.qual.noise = 0; |
| 7231 | local->wstats.qual.updated |= IW_QUAL_NOISE_INVALID; | 7232 | local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM; |
| 7232 | } | 7233 | } |
| 7233 | 7234 | ||
| 7234 | /* Packets discarded in the wireless adapter due to wireless | 7235 | /* Packets discarded in the wireless adapter due to wireless |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index f48a6e729224..587869d86eee 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
| @@ -1593,7 +1593,6 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT | |||
| 1593 | dev->set_mac_address = atmel_set_mac_address; | 1593 | dev->set_mac_address = atmel_set_mac_address; |
| 1594 | dev->hard_start_xmit = start_tx; | 1594 | dev->hard_start_xmit = start_tx; |
| 1595 | dev->get_stats = atmel_get_stats; | 1595 | dev->get_stats = atmel_get_stats; |
| 1596 | dev->get_wireless_stats = atmel_get_wireless_stats; | ||
| 1597 | dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def; | 1596 | dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def; |
| 1598 | dev->do_ioctl = atmel_ioctl; | 1597 | dev->do_ioctl = atmel_ioctl; |
| 1599 | dev->irq = irq; | 1598 | dev->irq = irq; |
| @@ -2411,7 +2410,8 @@ static const struct iw_handler_def atmel_handler_def = | |||
| 2411 | .num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args), | 2410 | .num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args), |
| 2412 | .standard = (iw_handler *) atmel_handler, | 2411 | .standard = (iw_handler *) atmel_handler, |
| 2413 | .private = (iw_handler *) atmel_private_handler, | 2412 | .private = (iw_handler *) atmel_private_handler, |
| 2414 | .private_args = (struct iw_priv_args *) atmel_private_args | 2413 | .private_args = (struct iw_priv_args *) atmel_private_args, |
| 2414 | .get_wireless_stats = atmel_get_wireless_stats | ||
| 2415 | }; | 2415 | }; |
| 2416 | 2416 | ||
| 2417 | static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 2417 | static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
| @@ -2424,19 +2424,6 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
| 2424 | char domain[REGDOMAINSZ+1]; | 2424 | char domain[REGDOMAINSZ+1]; |
| 2425 | 2425 | ||
| 2426 | switch (cmd) { | 2426 | switch (cmd) { |
| 2427 | case SIOCGIWPRIV: | ||
| 2428 | if(wrq->u.data.pointer) { | ||
| 2429 | /* Set the number of ioctl available */ | ||
| 2430 | wrq->u.data.length = sizeof(atmel_private_args) / sizeof(atmel_private_args[0]); | ||
| 2431 | |||
| 2432 | /* Copy structure to the user buffer */ | ||
| 2433 | if (copy_to_user(wrq->u.data.pointer, | ||
| 2434 | (u_char *) atmel_private_args, | ||
| 2435 | sizeof(atmel_private_args))) | ||
| 2436 | rc = -EFAULT; | ||
| 2437 | } | ||
| 2438 | break; | ||
| 2439 | |||
| 2440 | case ATMELIDIFC: | 2427 | case ATMELIDIFC: |
| 2441 | wrq->u.param.value = ATMELMAGIC; | 2428 | wrq->u.param.value = ATMELMAGIC; |
| 2442 | break; | 2429 | break; |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 2a3bd607a5cd..b7f275c00de3 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
| @@ -72,7 +72,8 @@ static void ipw_rx_queue_replenish(void *); | |||
| 72 | static int ipw_up(struct ipw_priv *); | 72 | static int ipw_up(struct ipw_priv *); |
| 73 | static void ipw_down(struct ipw_priv *); | 73 | static void ipw_down(struct ipw_priv *); |
| 74 | static int ipw_config(struct ipw_priv *); | 74 | static int ipw_config(struct ipw_priv *); |
| 75 | static int init_supported_rates(struct ipw_priv *priv, struct ipw_supported_rates *prates); | 75 | static int init_supported_rates(struct ipw_priv *priv, |
| 76 | struct ipw_supported_rates *prates); | ||
| 76 | 77 | ||
| 77 | static u8 band_b_active_channel[MAX_B_CHANNELS] = { | 78 | static u8 band_b_active_channel[MAX_B_CHANNELS] = { |
| 78 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 | 79 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 |
| @@ -102,7 +103,7 @@ static int is_valid_channel(int mode_mask, int channel) | |||
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | static char *snprint_line(char *buf, size_t count, | 105 | static char *snprint_line(char *buf, size_t count, |
| 105 | const u8 *data, u32 len, u32 ofs) | 106 | const u8 * data, u32 len, u32 ofs) |
| 106 | { | 107 | { |
| 107 | int out, i, j, l; | 108 | int out, i, j, l; |
| 108 | char c; | 109 | char c; |
| @@ -136,7 +137,7 @@ static char *snprint_line(char *buf, size_t count, | |||
| 136 | return buf; | 137 | return buf; |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | static void printk_buf(int level, const u8 *data, u32 len) | 140 | static void printk_buf(int level, const u8 * data, u32 len) |
| 140 | { | 141 | { |
| 141 | char line[81]; | 142 | char line[81]; |
| 142 | u32 ofs = 0; | 143 | u32 ofs = 0; |
| @@ -161,21 +162,24 @@ static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg); | |||
| 161 | static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value); | 162 | static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value); |
| 162 | static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) | 163 | static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) |
| 163 | { | 164 | { |
| 164 | IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); | 165 | IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__, |
| 166 | __LINE__, (u32) (b), (u32) (c)); | ||
| 165 | _ipw_write_reg8(a, b, c); | 167 | _ipw_write_reg8(a, b, c); |
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value); | 170 | static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value); |
| 169 | static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) | 171 | static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) |
| 170 | { | 172 | { |
| 171 | IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); | 173 | IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__, |
| 174 | __LINE__, (u32) (b), (u32) (c)); | ||
| 172 | _ipw_write_reg16(a, b, c); | 175 | _ipw_write_reg16(a, b, c); |
| 173 | } | 176 | } |
| 174 | 177 | ||
| 175 | static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value); | 178 | static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value); |
| 176 | static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) | 179 | static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) |
| 177 | { | 180 | { |
| 178 | IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); | 181 | IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__, |
| 182 | __LINE__, (u32) (b), (u32) (c)); | ||
| 179 | _ipw_write_reg32(a, b, c); | 183 | _ipw_write_reg32(a, b, c); |
| 180 | } | 184 | } |
| 181 | 185 | ||
| @@ -195,24 +199,30 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) | |||
| 195 | _ipw_write32(ipw, ofs, val) | 199 | _ipw_write32(ipw, ofs, val) |
| 196 | 200 | ||
| 197 | #define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs)) | 201 | #define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs)) |
| 198 | static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { | 202 | static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) |
| 199 | IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32)(ofs)); | 203 | { |
| 204 | IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs)); | ||
| 200 | return _ipw_read8(ipw, ofs); | 205 | return _ipw_read8(ipw, ofs); |
| 201 | } | 206 | } |
| 207 | |||
| 202 | #define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs) | 208 | #define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs) |
| 203 | 209 | ||
| 204 | #define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs)) | 210 | #define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs)) |
| 205 | static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { | 211 | static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) |
| 206 | IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32)(ofs)); | 212 | { |
| 213 | IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs)); | ||
| 207 | return _ipw_read16(ipw, ofs); | 214 | return _ipw_read16(ipw, ofs); |
| 208 | } | 215 | } |
| 216 | |||
| 209 | #define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs) | 217 | #define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs) |
| 210 | 218 | ||
| 211 | #define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs)) | 219 | #define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs)) |
| 212 | static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) { | 220 | static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs) |
| 213 | IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32)(ofs)); | 221 | { |
| 222 | IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs)); | ||
| 214 | return _ipw_read32(ipw, ofs); | 223 | return _ipw_read32(ipw, ofs); |
| 215 | } | 224 | } |
| 225 | |||
| 216 | #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) | 226 | #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) |
| 217 | 227 | ||
| 218 | static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); | 228 | static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); |
| @@ -220,34 +230,30 @@ static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); | |||
| 220 | IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ | 230 | IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ |
| 221 | _ipw_read_indirect(a, b, c, d) | 231 | _ipw_read_indirect(a, b, c, d) |
| 222 | 232 | ||
| 223 | static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *data, int num); | 233 | static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, |
| 234 | int num); | ||
| 224 | #define ipw_write_indirect(a, b, c, d) \ | 235 | #define ipw_write_indirect(a, b, c, d) \ |
| 225 | IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ | 236 | IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ |
| 226 | _ipw_write_indirect(a, b, c, d) | 237 | _ipw_write_indirect(a, b, c, d) |
| 227 | 238 | ||
| 228 | /* indirect write s */ | 239 | /* indirect write s */ |
| 229 | static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, | 240 | static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) |
| 230 | u32 value) | ||
| 231 | { | 241 | { |
| 232 | IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", | 242 | IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); |
| 233 | priv, reg, value); | ||
| 234 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); | 243 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); |
| 235 | _ipw_write32(priv, CX2_INDIRECT_DATA, value); | 244 | _ipw_write32(priv, CX2_INDIRECT_DATA, value); |
| 236 | } | 245 | } |
| 237 | 246 | ||
| 238 | |||
| 239 | static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) | 247 | static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) |
| 240 | { | 248 | { |
| 241 | IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); | 249 | IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); |
| 242 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); | 250 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); |
| 243 | _ipw_write8(priv, CX2_INDIRECT_DATA, value); | 251 | _ipw_write8(priv, CX2_INDIRECT_DATA, value); |
| 244 | IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n", | 252 | IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n", |
| 245 | (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), | 253 | (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value); |
| 246 | value); | ||
| 247 | } | 254 | } |
| 248 | 255 | ||
| 249 | static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, | 256 | static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) |
| 250 | u16 value) | ||
| 251 | { | 257 | { |
| 252 | IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); | 258 | IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); |
| 253 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); | 259 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); |
| @@ -262,7 +268,7 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) | |||
| 262 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); | 268 | _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); |
| 263 | IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); | 269 | IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); |
| 264 | word = _ipw_read32(priv, CX2_INDIRECT_DATA); | 270 | word = _ipw_read32(priv, CX2_INDIRECT_DATA); |
| 265 | return (word >> ((reg & 0x3)*8)) & 0xff; | 271 | return (word >> ((reg & 0x3) * 8)) & 0xff; |
| 266 | } | 272 | } |
| 267 | 273 | ||
| 268 | static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg) | 274 | static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg) |
| @@ -302,7 +308,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, | |||
| 302 | _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); | 308 | _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); |
| 303 | aligned_len = num & CX2_INDIRECT_ADDR_MASK; | 309 | aligned_len = num & CX2_INDIRECT_ADDR_MASK; |
| 304 | for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) | 310 | for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) |
| 305 | *(u32*)buf = ipw_read32(priv, CX2_AUTOINC_DATA); | 311 | *(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA); |
| 306 | 312 | ||
| 307 | /* Copy the last nibble */ | 313 | /* Copy the last nibble */ |
| 308 | dif_len = num - aligned_len; | 314 | dif_len = num - aligned_len; |
| @@ -311,7 +317,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, | |||
| 311 | *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); | 317 | *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); |
| 312 | } | 318 | } |
| 313 | 319 | ||
| 314 | static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *buf, | 320 | static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, |
| 315 | int num) | 321 | int num) |
| 316 | { | 322 | { |
| 317 | u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; | 323 | u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; |
| @@ -335,7 +341,7 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *buf, | |||
| 335 | _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); | 341 | _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); |
| 336 | aligned_len = num & CX2_INDIRECT_ADDR_MASK; | 342 | aligned_len = num & CX2_INDIRECT_ADDR_MASK; |
| 337 | for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) | 343 | for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) |
| 338 | _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32*)buf); | 344 | _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf); |
| 339 | 345 | ||
| 340 | /* Copy the last nibble */ | 346 | /* Copy the last nibble */ |
| 341 | dif_len = num - aligned_len; | 347 | dif_len = num - aligned_len; |
| @@ -428,20 +434,18 @@ static void ipw_dump_nic_error_log(struct ipw_priv *priv) | |||
| 428 | } | 434 | } |
| 429 | 435 | ||
| 430 | for (i = ERROR_START_OFFSET; | 436 | for (i = ERROR_START_OFFSET; |
| 431 | i <= count * ERROR_ELEM_SIZE; | 437 | i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) { |
| 432 | i += ERROR_ELEM_SIZE) { | 438 | desc = ipw_read_reg32(priv, base + i); |
| 433 | desc = ipw_read_reg32(priv, base + i); | 439 | time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32)); |
| 434 | time = ipw_read_reg32(priv, base + i + 1*sizeof(u32)); | 440 | blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32)); |
| 435 | blink1 = ipw_read_reg32(priv, base + i + 2*sizeof(u32)); | 441 | blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32)); |
| 436 | blink2 = ipw_read_reg32(priv, base + i + 3*sizeof(u32)); | 442 | ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32)); |
| 437 | ilink1 = ipw_read_reg32(priv, base + i + 4*sizeof(u32)); | 443 | ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32)); |
| 438 | ilink2 = ipw_read_reg32(priv, base + i + 5*sizeof(u32)); | 444 | idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32)); |
| 439 | idata = ipw_read_reg32(priv, base + i + 6*sizeof(u32)); | ||
| 440 | 445 | ||
| 441 | IPW_ERROR( | 446 | IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", |
| 442 | "%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", | 447 | ipw_error_desc(desc), time, blink1, blink2, |
| 443 | ipw_error_desc(desc), time, blink1, blink2, | 448 | ilink1, ilink2, idata); |
| 444 | ilink1, ilink2, idata); | ||
| 445 | } | 449 | } |
| 446 | } | 450 | } |
| 447 | 451 | ||
| @@ -456,11 +460,10 @@ static void ipw_dump_nic_event_log(struct ipw_priv *priv) | |||
| 456 | IPW_ERROR("Start IPW Event Log Dump:\n"); | 460 | IPW_ERROR("Start IPW Event Log Dump:\n"); |
| 457 | 461 | ||
| 458 | for (i = EVENT_START_OFFSET; | 462 | for (i = EVENT_START_OFFSET; |
| 459 | i <= count * EVENT_ELEM_SIZE; | 463 | i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) { |
| 460 | i += EVENT_ELEM_SIZE) { | ||
| 461 | ev = ipw_read_reg32(priv, base + i); | 464 | ev = ipw_read_reg32(priv, base + i); |
| 462 | time = ipw_read_reg32(priv, base + i + 1*sizeof(u32)); | 465 | time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32)); |
| 463 | data = ipw_read_reg32(priv, base + i + 2*sizeof(u32)); | 466 | data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32)); |
| 464 | 467 | ||
| 465 | #ifdef CONFIG_IPW_DEBUG | 468 | #ifdef CONFIG_IPW_DEBUG |
| 466 | IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev); | 469 | IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev); |
| @@ -468,8 +471,7 @@ static void ipw_dump_nic_event_log(struct ipw_priv *priv) | |||
| 468 | } | 471 | } |
| 469 | } | 472 | } |
| 470 | 473 | ||
| 471 | static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, | 474 | static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len) |
| 472 | u32 *len) | ||
| 473 | { | 475 | { |
| 474 | u32 addr, field_info, field_len, field_count, total_len; | 476 | u32 addr, field_info, field_len, field_count, total_len; |
| 475 | 477 | ||
| @@ -513,11 +515,11 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, | |||
| 513 | } | 515 | } |
| 514 | 516 | ||
| 515 | IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n", | 517 | IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n", |
| 516 | ord, priv->table0_addr + (ord << 2)); | 518 | ord, priv->table0_addr + (ord << 2)); |
| 517 | 519 | ||
| 518 | *len = sizeof(u32); | 520 | *len = sizeof(u32); |
| 519 | ord <<= 2; | 521 | ord <<= 2; |
| 520 | *((u32 *)val) = ipw_read32(priv, priv->table0_addr + ord); | 522 | *((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord); |
| 521 | break; | 523 | break; |
| 522 | 524 | ||
| 523 | case IPW_ORD_TABLE_1_MASK: | 525 | case IPW_ORD_TABLE_1_MASK: |
| @@ -545,7 +547,8 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, | |||
| 545 | return -EINVAL; | 547 | return -EINVAL; |
| 546 | } | 548 | } |
| 547 | 549 | ||
| 548 | *((u32 *)val) = ipw_read_reg32(priv, (priv->table1_addr + (ord << 2))); | 550 | *((u32 *) val) = |
| 551 | ipw_read_reg32(priv, (priv->table1_addr + (ord << 2))); | ||
| 549 | *len = sizeof(u32); | 552 | *len = sizeof(u32); |
| 550 | break; | 553 | break; |
| 551 | 554 | ||
| @@ -573,13 +576,16 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, | |||
| 573 | 576 | ||
| 574 | /* get the second DW of statistics ; | 577 | /* get the second DW of statistics ; |
| 575 | * two 16-bit words - first is length, second is count */ | 578 | * two 16-bit words - first is length, second is count */ |
| 576 | field_info = ipw_read_reg32(priv, priv->table2_addr + (ord << 3) + sizeof(u32)); | 579 | field_info = |
| 580 | ipw_read_reg32(priv, | ||
| 581 | priv->table2_addr + (ord << 3) + | ||
| 582 | sizeof(u32)); | ||
| 577 | 583 | ||
| 578 | /* get each entry length */ | 584 | /* get each entry length */ |
| 579 | field_len = *((u16 *)&field_info); | 585 | field_len = *((u16 *) & field_info); |
| 580 | 586 | ||
| 581 | /* get number of entries */ | 587 | /* get number of entries */ |
| 582 | field_count = *(((u16 *)&field_info) + 1); | 588 | field_count = *(((u16 *) & field_info) + 1); |
| 583 | 589 | ||
| 584 | /* abort if not enought memory */ | 590 | /* abort if not enought memory */ |
| 585 | total_len = field_len * field_count; | 591 | total_len = field_len * field_count; |
| @@ -604,7 +610,6 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, | |||
| 604 | 610 | ||
| 605 | } | 611 | } |
| 606 | 612 | ||
| 607 | |||
| 608 | return 0; | 613 | return 0; |
| 609 | } | 614 | } |
| 610 | 615 | ||
| @@ -624,7 +629,7 @@ static void ipw_init_ordinals(struct ipw_priv *priv) | |||
| 624 | 629 | ||
| 625 | priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2); | 630 | priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2); |
| 626 | priv->table2_len = ipw_read_reg32(priv, priv->table2_addr); | 631 | priv->table2_len = ipw_read_reg32(priv, priv->table2_addr); |
| 627 | priv->table2_len &= 0x0000ffff; /* use first two bytes */ | 632 | priv->table2_len &= 0x0000ffff; /* use first two bytes */ |
| 628 | 633 | ||
| 629 | IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n", | 634 | IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n", |
| 630 | priv->table2_addr, priv->table2_len); | 635 | priv->table2_addr, priv->table2_len); |
| @@ -643,7 +648,7 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf) | |||
| 643 | return sprintf(buf, "0x%08X\n", ipw_debug_level); | 648 | return sprintf(buf, "0x%08X\n", ipw_debug_level); |
| 644 | } | 649 | } |
| 645 | static ssize_t store_debug_level(struct device_driver *d, | 650 | static ssize_t store_debug_level(struct device_driver *d, |
| 646 | const char *buf, size_t count) | 651 | const char *buf, size_t count) |
| 647 | { | 652 | { |
| 648 | char *p = (char *)buf; | 653 | char *p = (char *)buf; |
| 649 | u32 val; | 654 | u32 val; |
| @@ -668,11 +673,12 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | |||
| 668 | show_debug_level, store_debug_level); | 673 | show_debug_level, store_debug_level); |
| 669 | 674 | ||
| 670 | static ssize_t show_status(struct device *d, | 675 | static ssize_t show_status(struct device *d, |
| 671 | struct device_attribute *attr, char *buf) | 676 | struct device_attribute *attr, char *buf) |
| 672 | { | 677 | { |
| 673 | struct ipw_priv *p = d->driver_data; | 678 | struct ipw_priv *p = d->driver_data; |
| 674 | return sprintf(buf, "0x%08x\n", (int)p->status); | 679 | return sprintf(buf, "0x%08x\n", (int)p->status); |
| 675 | } | 680 | } |
| 681 | |||
| 676 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | 682 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); |
| 677 | 683 | ||
| 678 | static ssize_t show_cfg(struct device *d, struct device_attribute *attr, | 684 | static ssize_t show_cfg(struct device *d, struct device_attribute *attr, |
| @@ -681,10 +687,11 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr, | |||
| 681 | struct ipw_priv *p = d->driver_data; | 687 | struct ipw_priv *p = d->driver_data; |
| 682 | return sprintf(buf, "0x%08x\n", (int)p->config); | 688 | return sprintf(buf, "0x%08x\n", (int)p->config); |
| 683 | } | 689 | } |
| 690 | |||
| 684 | static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); | 691 | static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); |
| 685 | 692 | ||
| 686 | static ssize_t show_nic_type(struct device *d, | 693 | static ssize_t show_nic_type(struct device *d, |
| 687 | struct device_attribute *attr, char *buf) | 694 | struct device_attribute *attr, char *buf) |
| 688 | { | 695 | { |
| 689 | struct ipw_priv *p = d->driver_data; | 696 | struct ipw_priv *p = d->driver_data; |
| 690 | u8 type = p->eeprom[EEPROM_NIC_TYPE]; | 697 | u8 type = p->eeprom[EEPROM_NIC_TYPE]; |
| @@ -704,44 +711,50 @@ static ssize_t show_nic_type(struct device *d, | |||
| 704 | 711 | ||
| 705 | return sprintf(buf, "UNKNOWN\n"); | 712 | return sprintf(buf, "UNKNOWN\n"); |
| 706 | } | 713 | } |
| 714 | |||
| 707 | static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); | 715 | static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); |
| 708 | 716 | ||
| 709 | static ssize_t dump_error_log(struct device *d, | 717 | static ssize_t dump_error_log(struct device *d, |
| 710 | struct device_attribute *attr, const char *buf, size_t count) | 718 | struct device_attribute *attr, const char *buf, |
| 719 | size_t count) | ||
| 711 | { | 720 | { |
| 712 | char *p = (char *)buf; | 721 | char *p = (char *)buf; |
| 713 | 722 | ||
| 714 | if (p[0] == '1') | 723 | if (p[0] == '1') |
| 715 | ipw_dump_nic_error_log((struct ipw_priv*)d->driver_data); | 724 | ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data); |
| 716 | 725 | ||
| 717 | return strnlen(buf, count); | 726 | return strnlen(buf, count); |
| 718 | } | 727 | } |
| 728 | |||
| 719 | static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); | 729 | static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); |
| 720 | 730 | ||
| 721 | static ssize_t dump_event_log(struct device *d, | 731 | static ssize_t dump_event_log(struct device *d, |
| 722 | struct device_attribute *attr, const char *buf, size_t count) | 732 | struct device_attribute *attr, const char *buf, |
| 733 | size_t count) | ||
| 723 | { | 734 | { |
| 724 | char *p = (char *)buf; | 735 | char *p = (char *)buf; |
| 725 | 736 | ||
| 726 | if (p[0] == '1') | 737 | if (p[0] == '1') |
| 727 | ipw_dump_nic_event_log((struct ipw_priv*)d->driver_data); | 738 | ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data); |
| 728 | 739 | ||
| 729 | return strnlen(buf, count); | 740 | return strnlen(buf, count); |
| 730 | } | 741 | } |
| 742 | |||
| 731 | static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); | 743 | static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); |
| 732 | 744 | ||
| 733 | static ssize_t show_ucode_version(struct device *d, | 745 | static ssize_t show_ucode_version(struct device *d, |
| 734 | struct device_attribute *attr, char *buf) | 746 | struct device_attribute *attr, char *buf) |
| 735 | { | 747 | { |
| 736 | u32 len = sizeof(u32), tmp = 0; | 748 | u32 len = sizeof(u32), tmp = 0; |
| 737 | struct ipw_priv *p = d->driver_data; | 749 | struct ipw_priv *p = d->driver_data; |
| 738 | 750 | ||
| 739 | if(ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len)) | 751 | if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len)) |
| 740 | return 0; | 752 | return 0; |
| 741 | 753 | ||
| 742 | return sprintf(buf, "0x%08x\n", tmp); | 754 | return sprintf(buf, "0x%08x\n", tmp); |
| 743 | } | 755 | } |
| 744 | static DEVICE_ATTR(ucode_version, S_IWUSR|S_IRUGO, show_ucode_version, NULL); | 756 | |
| 757 | static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL); | ||
| 745 | 758 | ||
| 746 | static ssize_t show_rtc(struct device *d, struct device_attribute *attr, | 759 | static ssize_t show_rtc(struct device *d, struct device_attribute *attr, |
| 747 | char *buf) | 760 | char *buf) |
| @@ -749,36 +762,38 @@ static ssize_t show_rtc(struct device *d, struct device_attribute *attr, | |||
| 749 | u32 len = sizeof(u32), tmp = 0; | 762 | u32 len = sizeof(u32), tmp = 0; |
| 750 | struct ipw_priv *p = d->driver_data; | 763 | struct ipw_priv *p = d->driver_data; |
| 751 | 764 | ||
| 752 | if(ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len)) | 765 | if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len)) |
| 753 | return 0; | 766 | return 0; |
| 754 | 767 | ||
| 755 | return sprintf(buf, "0x%08x\n", tmp); | 768 | return sprintf(buf, "0x%08x\n", tmp); |
| 756 | } | 769 | } |
| 757 | static DEVICE_ATTR(rtc, S_IWUSR|S_IRUGO, show_rtc, NULL); | 770 | |
| 771 | static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL); | ||
| 758 | 772 | ||
| 759 | /* | 773 | /* |
| 760 | * Add a device attribute to view/control the delay between eeprom | 774 | * Add a device attribute to view/control the delay between eeprom |
| 761 | * operations. | 775 | * operations. |
| 762 | */ | 776 | */ |
| 763 | static ssize_t show_eeprom_delay(struct device *d, | 777 | static ssize_t show_eeprom_delay(struct device *d, |
| 764 | struct device_attribute *attr, char *buf) | 778 | struct device_attribute *attr, char *buf) |
| 765 | { | 779 | { |
| 766 | int n = ((struct ipw_priv*)d->driver_data)->eeprom_delay; | 780 | int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay; |
| 767 | return sprintf(buf, "%i\n", n); | 781 | return sprintf(buf, "%i\n", n); |
| 768 | } | 782 | } |
| 769 | static ssize_t store_eeprom_delay(struct device *d, | 783 | static ssize_t store_eeprom_delay(struct device *d, |
| 770 | struct device_attribute *attr, const char *buf, | 784 | struct device_attribute *attr, |
| 771 | size_t count) | 785 | const char *buf, size_t count) |
| 772 | { | 786 | { |
| 773 | struct ipw_priv *p = d->driver_data; | 787 | struct ipw_priv *p = d->driver_data; |
| 774 | sscanf(buf, "%i", &p->eeprom_delay); | 788 | sscanf(buf, "%i", &p->eeprom_delay); |
| 775 | return strnlen(buf, count); | 789 | return strnlen(buf, count); |
| 776 | } | 790 | } |
| 777 | static DEVICE_ATTR(eeprom_delay, S_IWUSR|S_IRUGO, | 791 | |
| 778 | show_eeprom_delay,store_eeprom_delay); | 792 | static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO, |
| 793 | show_eeprom_delay, store_eeprom_delay); | ||
| 779 | 794 | ||
| 780 | static ssize_t show_command_event_reg(struct device *d, | 795 | static ssize_t show_command_event_reg(struct device *d, |
| 781 | struct device_attribute *attr, char *buf) | 796 | struct device_attribute *attr, char *buf) |
| 782 | { | 797 | { |
| 783 | u32 reg = 0; | 798 | u32 reg = 0; |
| 784 | struct ipw_priv *p = d->driver_data; | 799 | struct ipw_priv *p = d->driver_data; |
| @@ -787,8 +802,8 @@ static ssize_t show_command_event_reg(struct device *d, | |||
| 787 | return sprintf(buf, "0x%08x\n", reg); | 802 | return sprintf(buf, "0x%08x\n", reg); |
| 788 | } | 803 | } |
| 789 | static ssize_t store_command_event_reg(struct device *d, | 804 | static ssize_t store_command_event_reg(struct device *d, |
| 790 | struct device_attribute *attr, const char *buf, | 805 | struct device_attribute *attr, |
| 791 | size_t count) | 806 | const char *buf, size_t count) |
| 792 | { | 807 | { |
| 793 | u32 reg; | 808 | u32 reg; |
| 794 | struct ipw_priv *p = d->driver_data; | 809 | struct ipw_priv *p = d->driver_data; |
| @@ -797,11 +812,12 @@ static ssize_t store_command_event_reg(struct device *d, | |||
| 797 | ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg); | 812 | ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg); |
| 798 | return strnlen(buf, count); | 813 | return strnlen(buf, count); |
| 799 | } | 814 | } |
| 800 | static DEVICE_ATTR(command_event_reg, S_IWUSR|S_IRUGO, | 815 | |
| 801 | show_command_event_reg,store_command_event_reg); | 816 | static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO, |
| 817 | show_command_event_reg, store_command_event_reg); | ||
| 802 | 818 | ||
| 803 | static ssize_t show_mem_gpio_reg(struct device *d, | 819 | static ssize_t show_mem_gpio_reg(struct device *d, |
| 804 | struct device_attribute *attr, char *buf) | 820 | struct device_attribute *attr, char *buf) |
| 805 | { | 821 | { |
| 806 | u32 reg = 0; | 822 | u32 reg = 0; |
| 807 | struct ipw_priv *p = d->driver_data; | 823 | struct ipw_priv *p = d->driver_data; |
| @@ -810,8 +826,8 @@ static ssize_t show_mem_gpio_reg(struct device *d, | |||
| 810 | return sprintf(buf, "0x%08x\n", reg); | 826 | return sprintf(buf, "0x%08x\n", reg); |
| 811 | } | 827 | } |
| 812 | static ssize_t store_mem_gpio_reg(struct device *d, | 828 | static ssize_t store_mem_gpio_reg(struct device *d, |
| 813 | struct device_attribute *attr, const char *buf, | 829 | struct device_attribute *attr, |
| 814 | size_t count) | 830 | const char *buf, size_t count) |
| 815 | { | 831 | { |
| 816 | u32 reg; | 832 | u32 reg; |
| 817 | struct ipw_priv *p = d->driver_data; | 833 | struct ipw_priv *p = d->driver_data; |
| @@ -820,11 +836,12 @@ static ssize_t store_mem_gpio_reg(struct device *d, | |||
| 820 | ipw_write_reg32(p, 0x301100, reg); | 836 | ipw_write_reg32(p, 0x301100, reg); |
| 821 | return strnlen(buf, count); | 837 | return strnlen(buf, count); |
| 822 | } | 838 | } |
| 823 | static DEVICE_ATTR(mem_gpio_reg, S_IWUSR|S_IRUGO, | 839 | |
| 824 | show_mem_gpio_reg,store_mem_gpio_reg); | 840 | static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO, |
| 841 | show_mem_gpio_reg, store_mem_gpio_reg); | ||
| 825 | 842 | ||
| 826 | static ssize_t show_indirect_dword(struct device *d, | 843 | static ssize_t show_indirect_dword(struct device *d, |
| 827 | struct device_attribute *attr, char *buf) | 844 | struct device_attribute *attr, char *buf) |
| 828 | { | 845 | { |
| 829 | u32 reg = 0; | 846 | u32 reg = 0; |
| 830 | struct ipw_priv *priv = d->driver_data; | 847 | struct ipw_priv *priv = d->driver_data; |
| @@ -836,8 +853,8 @@ static ssize_t show_indirect_dword(struct device *d, | |||
| 836 | return sprintf(buf, "0x%08x\n", reg); | 853 | return sprintf(buf, "0x%08x\n", reg); |
| 837 | } | 854 | } |
| 838 | static ssize_t store_indirect_dword(struct device *d, | 855 | static ssize_t store_indirect_dword(struct device *d, |
| 839 | struct device_attribute *attr, const char *buf, | 856 | struct device_attribute *attr, |
| 840 | size_t count) | 857 | const char *buf, size_t count) |
| 841 | { | 858 | { |
| 842 | struct ipw_priv *priv = d->driver_data; | 859 | struct ipw_priv *priv = d->driver_data; |
| 843 | 860 | ||
| @@ -845,11 +862,12 @@ static ssize_t store_indirect_dword(struct device *d, | |||
| 845 | priv->status |= STATUS_INDIRECT_DWORD; | 862 | priv->status |= STATUS_INDIRECT_DWORD; |
| 846 | return strnlen(buf, count); | 863 | return strnlen(buf, count); |
| 847 | } | 864 | } |
| 848 | static DEVICE_ATTR(indirect_dword, S_IWUSR|S_IRUGO, | 865 | |
| 849 | show_indirect_dword,store_indirect_dword); | 866 | static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO, |
| 867 | show_indirect_dword, store_indirect_dword); | ||
| 850 | 868 | ||
| 851 | static ssize_t show_indirect_byte(struct device *d, | 869 | static ssize_t show_indirect_byte(struct device *d, |
| 852 | struct device_attribute *attr, char *buf) | 870 | struct device_attribute *attr, char *buf) |
| 853 | { | 871 | { |
| 854 | u8 reg = 0; | 872 | u8 reg = 0; |
| 855 | struct ipw_priv *priv = d->driver_data; | 873 | struct ipw_priv *priv = d->driver_data; |
| @@ -861,8 +879,8 @@ static ssize_t show_indirect_byte(struct device *d, | |||
| 861 | return sprintf(buf, "0x%02x\n", reg); | 879 | return sprintf(buf, "0x%02x\n", reg); |
| 862 | } | 880 | } |
| 863 | static ssize_t store_indirect_byte(struct device *d, | 881 | static ssize_t store_indirect_byte(struct device *d, |
| 864 | struct device_attribute *attr, const char *buf, | 882 | struct device_attribute *attr, |
| 865 | size_t count) | 883 | const char *buf, size_t count) |
| 866 | { | 884 | { |
| 867 | struct ipw_priv *priv = d->driver_data; | 885 | struct ipw_priv *priv = d->driver_data; |
| 868 | 886 | ||
| @@ -870,11 +888,12 @@ static ssize_t store_indirect_byte(struct device *d, | |||
| 870 | priv->status |= STATUS_INDIRECT_BYTE; | 888 | priv->status |= STATUS_INDIRECT_BYTE; |
| 871 | return strnlen(buf, count); | 889 | return strnlen(buf, count); |
| 872 | } | 890 | } |
| 873 | static DEVICE_ATTR(indirect_byte, S_IWUSR|S_IRUGO, | 891 | |
| 892 | static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO, | ||
| 874 | show_indirect_byte, store_indirect_byte); | 893 | show_indirect_byte, store_indirect_byte); |
| 875 | 894 | ||
| 876 | static ssize_t show_direct_dword(struct device *d, | 895 | static ssize_t show_direct_dword(struct device *d, |
| 877 | struct device_attribute *attr, char *buf) | 896 | struct device_attribute *attr, char *buf) |
| 878 | { | 897 | { |
| 879 | u32 reg = 0; | 898 | u32 reg = 0; |
| 880 | struct ipw_priv *priv = d->driver_data; | 899 | struct ipw_priv *priv = d->driver_data; |
| @@ -887,8 +906,8 @@ static ssize_t show_direct_dword(struct device *d, | |||
| 887 | return sprintf(buf, "0x%08x\n", reg); | 906 | return sprintf(buf, "0x%08x\n", reg); |
| 888 | } | 907 | } |
| 889 | static ssize_t store_direct_dword(struct device *d, | 908 | static ssize_t store_direct_dword(struct device *d, |
| 890 | struct device_attribute *attr, const char *buf, | 909 | struct device_attribute *attr, |
| 891 | size_t count) | 910 | const char *buf, size_t count) |
| 892 | { | 911 | { |
| 893 | struct ipw_priv *priv = d->driver_data; | 912 | struct ipw_priv *priv = d->driver_data; |
| 894 | 913 | ||
| @@ -896,9 +915,9 @@ static ssize_t store_direct_dword(struct device *d, | |||
| 896 | priv->status |= STATUS_DIRECT_DWORD; | 915 | priv->status |= STATUS_DIRECT_DWORD; |
| 897 | return strnlen(buf, count); | 916 | return strnlen(buf, count); |
| 898 | } | 917 | } |
| 899 | static DEVICE_ATTR(direct_dword, S_IWUSR|S_IRUGO, | ||
| 900 | show_direct_dword,store_direct_dword); | ||
| 901 | 918 | ||
| 919 | static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO, | ||
| 920 | show_direct_dword, store_direct_dword); | ||
| 902 | 921 | ||
| 903 | static inline int rf_kill_active(struct ipw_priv *priv) | 922 | static inline int rf_kill_active(struct ipw_priv *priv) |
| 904 | { | 923 | { |
| @@ -911,7 +930,7 @@ static inline int rf_kill_active(struct ipw_priv *priv) | |||
| 911 | } | 930 | } |
| 912 | 931 | ||
| 913 | static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, | 932 | static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, |
| 914 | char *buf) | 933 | char *buf) |
| 915 | { | 934 | { |
| 916 | /* 0 - RF kill not enabled | 935 | /* 0 - RF kill not enabled |
| 917 | 1 - SW based RF kill active (sysfs) | 936 | 1 - SW based RF kill active (sysfs) |
| @@ -919,7 +938,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, | |||
| 919 | 3 - Both HW and SW baed RF kill active */ | 938 | 3 - Both HW and SW baed RF kill active */ |
| 920 | struct ipw_priv *priv = d->driver_data; | 939 | struct ipw_priv *priv = d->driver_data; |
| 921 | int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) | | 940 | int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) | |
| 922 | (rf_kill_active(priv) ? 0x2 : 0x0); | 941 | (rf_kill_active(priv) ? 0x2 : 0x0); |
| 923 | return sprintf(buf, "%i\n", val); | 942 | return sprintf(buf, "%i\n", val); |
| 924 | } | 943 | } |
| 925 | 944 | ||
| @@ -927,7 +946,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) | |||
| 927 | { | 946 | { |
| 928 | if ((disable_radio ? 1 : 0) == | 947 | if ((disable_radio ? 1 : 0) == |
| 929 | (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) | 948 | (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) |
| 930 | return 0 ; | 949 | return 0; |
| 931 | 950 | ||
| 932 | IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", | 951 | IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", |
| 933 | disable_radio ? "OFF" : "ON"); | 952 | disable_radio ? "OFF" : "ON"); |
| @@ -956,8 +975,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) | |||
| 956 | return 1; | 975 | return 1; |
| 957 | } | 976 | } |
| 958 | 977 | ||
| 959 | static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, | 978 | static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, |
| 960 | const char *buf, size_t count) | 979 | const char *buf, size_t count) |
| 961 | { | 980 | { |
| 962 | struct ipw_priv *priv = d->driver_data; | 981 | struct ipw_priv *priv = d->driver_data; |
| 963 | 982 | ||
| @@ -965,7 +984,8 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, | |||
| 965 | 984 | ||
| 966 | return count; | 985 | return count; |
| 967 | } | 986 | } |
| 968 | static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill); | 987 | |
| 988 | static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); | ||
| 969 | 989 | ||
| 970 | static void ipw_irq_tasklet(struct ipw_priv *priv) | 990 | static void ipw_irq_tasklet(struct ipw_priv *priv) |
| 971 | { | 991 | { |
| @@ -990,7 +1010,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
| 990 | 1010 | ||
| 991 | if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) { | 1011 | if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) { |
| 992 | IPW_DEBUG_HC("Command completed.\n"); | 1012 | IPW_DEBUG_HC("Command completed.\n"); |
| 993 | rc = ipw_queue_tx_reclaim( priv, &priv->txq_cmd, -1); | 1013 | rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1); |
| 994 | priv->status &= ~STATUS_HCMD_ACTIVE; | 1014 | priv->status &= ~STATUS_HCMD_ACTIVE; |
| 995 | wake_up_interruptible(&priv->wait_command_queue); | 1015 | wake_up_interruptible(&priv->wait_command_queue); |
| 996 | handled |= CX2_INTA_BIT_TX_CMD_QUEUE; | 1016 | handled |= CX2_INTA_BIT_TX_CMD_QUEUE; |
| @@ -998,25 +1018,25 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
| 998 | 1018 | ||
| 999 | if (inta & CX2_INTA_BIT_TX_QUEUE_1) { | 1019 | if (inta & CX2_INTA_BIT_TX_QUEUE_1) { |
| 1000 | IPW_DEBUG_TX("TX_QUEUE_1\n"); | 1020 | IPW_DEBUG_TX("TX_QUEUE_1\n"); |
| 1001 | rc = ipw_queue_tx_reclaim( priv, &priv->txq[0], 0); | 1021 | rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0); |
| 1002 | handled |= CX2_INTA_BIT_TX_QUEUE_1; | 1022 | handled |= CX2_INTA_BIT_TX_QUEUE_1; |
| 1003 | } | 1023 | } |
| 1004 | 1024 | ||
| 1005 | if (inta & CX2_INTA_BIT_TX_QUEUE_2) { | 1025 | if (inta & CX2_INTA_BIT_TX_QUEUE_2) { |
| 1006 | IPW_DEBUG_TX("TX_QUEUE_2\n"); | 1026 | IPW_DEBUG_TX("TX_QUEUE_2\n"); |
| 1007 | rc = ipw_queue_tx_reclaim( priv, &priv->txq[1], 1); | 1027 | rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1); |
| 1008 | handled |= CX2_INTA_BIT_TX_QUEUE_2; | 1028 | handled |= CX2_INTA_BIT_TX_QUEUE_2; |
| 1009 | } | 1029 | } |
| 1010 | 1030 | ||
| 1011 | if (inta & CX2_INTA_BIT_TX_QUEUE_3) { | 1031 | if (inta & CX2_INTA_BIT_TX_QUEUE_3) { |
| 1012 | IPW_DEBUG_TX("TX_QUEUE_3\n"); | 1032 | IPW_DEBUG_TX("TX_QUEUE_3\n"); |
| 1013 | rc = ipw_queue_tx_reclaim( priv, &priv->txq[2], 2); | 1033 | rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2); |
| 1014 | handled |= CX2_INTA_BIT_TX_QUEUE_3; | 1034 | handled |= CX2_INTA_BIT_TX_QUEUE_3; |
| 1015 | } | 1035 | } |
| 1016 | 1036 | ||
| 1017 | if (inta & CX2_INTA_BIT_TX_QUEUE_4) { | 1037 | if (inta & CX2_INTA_BIT_TX_QUEUE_4) { |
| 1018 | IPW_DEBUG_TX("TX_QUEUE_4\n"); | 1038 | IPW_DEBUG_TX("TX_QUEUE_4\n"); |
| 1019 | rc = ipw_queue_tx_reclaim( priv, &priv->txq[3], 3); | 1039 | rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3); |
| 1020 | handled |= CX2_INTA_BIT_TX_QUEUE_4; | 1040 | handled |= CX2_INTA_BIT_TX_QUEUE_4; |
| 1021 | } | 1041 | } |
| 1022 | 1042 | ||
| @@ -1074,8 +1094,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
| 1074 | } | 1094 | } |
| 1075 | 1095 | ||
| 1076 | if (handled != inta) { | 1096 | if (handled != inta) { |
| 1077 | IPW_ERROR("Unhandled INTA bits 0x%08x\n", | 1097 | IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); |
| 1078 | inta & ~handled); | ||
| 1079 | } | 1098 | } |
| 1080 | 1099 | ||
| 1081 | /* enable all interrupts */ | 1100 | /* enable all interrupts */ |
| @@ -1143,7 +1162,7 @@ static char *get_cmd_string(u8 cmd) | |||
| 1143 | return "UNKNOWN"; | 1162 | return "UNKNOWN"; |
| 1144 | } | 1163 | } |
| 1145 | } | 1164 | } |
| 1146 | #endif /* CONFIG_IPW_DEBUG */ | 1165 | #endif /* CONFIG_IPW_DEBUG */ |
| 1147 | 1166 | ||
| 1148 | #define HOST_COMPLETE_TIMEOUT HZ | 1167 | #define HOST_COMPLETE_TIMEOUT HZ |
| 1149 | static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) | 1168 | static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) |
| @@ -1159,15 +1178,16 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) | |||
| 1159 | 1178 | ||
| 1160 | IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", | 1179 | IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", |
| 1161 | get_cmd_string(cmd->cmd), cmd->cmd, cmd->len); | 1180 | get_cmd_string(cmd->cmd), cmd->cmd, cmd->len); |
| 1162 | printk_buf(IPW_DL_HOST_COMMAND, (u8*)cmd->param, cmd->len); | 1181 | printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); |
| 1163 | 1182 | ||
| 1164 | rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); | 1183 | rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); |
| 1165 | if (rc) | 1184 | if (rc) |
| 1166 | return rc; | 1185 | return rc; |
| 1167 | 1186 | ||
| 1168 | rc = wait_event_interruptible_timeout( | 1187 | rc = wait_event_interruptible_timeout(priv->wait_command_queue, |
| 1169 | priv->wait_command_queue, !(priv->status & STATUS_HCMD_ACTIVE), | 1188 | !(priv-> |
| 1170 | HOST_COMPLETE_TIMEOUT); | 1189 | status & STATUS_HCMD_ACTIVE), |
| 1190 | HOST_COMPLETE_TIMEOUT); | ||
| 1171 | if (rc == 0) { | 1191 | if (rc == 0) { |
| 1172 | IPW_DEBUG_INFO("Command completion failed out after %dms.\n", | 1192 | IPW_DEBUG_INFO("Command completion failed out after %dms.\n", |
| 1173 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 1193 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
| @@ -1215,7 +1235,7 @@ static int ipw_send_system_config(struct ipw_priv *priv, | |||
| 1215 | return -1; | 1235 | return -1; |
| 1216 | } | 1236 | } |
| 1217 | 1237 | ||
| 1218 | memcpy(&cmd.param,config,sizeof(*config)); | 1238 | memcpy(&cmd.param, config, sizeof(*config)); |
| 1219 | if (ipw_send_cmd(priv, &cmd)) { | 1239 | if (ipw_send_cmd(priv, &cmd)) { |
| 1220 | IPW_ERROR("failed to send SYSTEM_CONFIG command\n"); | 1240 | IPW_ERROR("failed to send SYSTEM_CONFIG command\n"); |
| 1221 | return -1; | 1241 | return -1; |
| @@ -1224,7 +1244,7 @@ static int ipw_send_system_config(struct ipw_priv *priv, | |||
| 1224 | return 0; | 1244 | return 0; |
| 1225 | } | 1245 | } |
| 1226 | 1246 | ||
| 1227 | static int ipw_send_ssid(struct ipw_priv *priv, u8 *ssid, int len) | 1247 | static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) |
| 1228 | { | 1248 | { |
| 1229 | struct host_cmd cmd = { | 1249 | struct host_cmd cmd = { |
| 1230 | .cmd = IPW_CMD_SSID, | 1250 | .cmd = IPW_CMD_SSID, |
| @@ -1245,7 +1265,7 @@ static int ipw_send_ssid(struct ipw_priv *priv, u8 *ssid, int len) | |||
| 1245 | return 0; | 1265 | return 0; |
| 1246 | } | 1266 | } |
| 1247 | 1267 | ||
| 1248 | static int ipw_send_adapter_address(struct ipw_priv *priv, u8 *mac) | 1268 | static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) |
| 1249 | { | 1269 | { |
| 1250 | struct host_cmd cmd = { | 1270 | struct host_cmd cmd = { |
| 1251 | .cmd = IPW_CMD_ADAPTER_ADDRESS, | 1271 | .cmd = IPW_CMD_ADAPTER_ADDRESS, |
| @@ -1284,9 +1304,6 @@ static void ipw_adapter_restart(void *adapter) | |||
| 1284 | } | 1304 | } |
| 1285 | } | 1305 | } |
| 1286 | 1306 | ||
| 1287 | |||
| 1288 | |||
| 1289 | |||
| 1290 | #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) | 1307 | #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) |
| 1291 | 1308 | ||
| 1292 | static void ipw_scan_check(void *data) | 1309 | static void ipw_scan_check(void *data) |
| @@ -1313,7 +1330,7 @@ static int ipw_send_scan_request_ext(struct ipw_priv *priv, | |||
| 1313 | return -1; | 1330 | return -1; |
| 1314 | } | 1331 | } |
| 1315 | 1332 | ||
| 1316 | memcpy(&cmd.param,request,sizeof(*request)); | 1333 | memcpy(&cmd.param, request, sizeof(*request)); |
| 1317 | if (ipw_send_cmd(priv, &cmd)) { | 1334 | if (ipw_send_cmd(priv, &cmd)) { |
| 1318 | IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n"); | 1335 | IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n"); |
| 1319 | return -1; | 1336 | return -1; |
| @@ -1351,7 +1368,7 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) | |||
| 1351 | .len = sizeof(struct ipw_sensitivity_calib) | 1368 | .len = sizeof(struct ipw_sensitivity_calib) |
| 1352 | }; | 1369 | }; |
| 1353 | struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) | 1370 | struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) |
| 1354 | &cmd.param; | 1371 | &cmd.param; |
| 1355 | calib->beacon_rssi_raw = sens; | 1372 | calib->beacon_rssi_raw = sens; |
| 1356 | if (ipw_send_cmd(priv, &cmd)) { | 1373 | if (ipw_send_cmd(priv, &cmd)) { |
| 1357 | IPW_ERROR("failed to send SENSITIVITY CALIB command\n"); | 1374 | IPW_ERROR("failed to send SENSITIVITY CALIB command\n"); |
| @@ -1374,7 +1391,7 @@ static int ipw_send_associate(struct ipw_priv *priv, | |||
| 1374 | return -1; | 1391 | return -1; |
| 1375 | } | 1392 | } |
| 1376 | 1393 | ||
| 1377 | memcpy(&cmd.param,associate,sizeof(*associate)); | 1394 | memcpy(&cmd.param, associate, sizeof(*associate)); |
| 1378 | if (ipw_send_cmd(priv, &cmd)) { | 1395 | if (ipw_send_cmd(priv, &cmd)) { |
| 1379 | IPW_ERROR("failed to send ASSOCIATE command\n"); | 1396 | IPW_ERROR("failed to send ASSOCIATE command\n"); |
| 1380 | return -1; | 1397 | return -1; |
| @@ -1396,7 +1413,7 @@ static int ipw_send_supported_rates(struct ipw_priv *priv, | |||
| 1396 | return -1; | 1413 | return -1; |
| 1397 | } | 1414 | } |
| 1398 | 1415 | ||
| 1399 | memcpy(&cmd.param,rates,sizeof(*rates)); | 1416 | memcpy(&cmd.param, rates, sizeof(*rates)); |
| 1400 | if (ipw_send_cmd(priv, &cmd)) { | 1417 | if (ipw_send_cmd(priv, &cmd)) { |
| 1401 | IPW_ERROR("failed to send SUPPORTED_RATES command\n"); | 1418 | IPW_ERROR("failed to send SUPPORTED_RATES command\n"); |
| 1402 | return -1; | 1419 | return -1; |
| @@ -1440,7 +1457,7 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) | |||
| 1440 | return -1; | 1457 | return -1; |
| 1441 | } | 1458 | } |
| 1442 | 1459 | ||
| 1443 | *((u32*)&cmd.param) = phy_off; | 1460 | *((u32 *) & cmd.param) = phy_off; |
| 1444 | 1461 | ||
| 1445 | if (ipw_send_cmd(priv, &cmd)) { | 1462 | if (ipw_send_cmd(priv, &cmd)) { |
| 1446 | IPW_ERROR("failed to send CARD_DISABLE command\n"); | 1463 | IPW_ERROR("failed to send CARD_DISABLE command\n"); |
| @@ -1451,8 +1468,7 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) | |||
| 1451 | } | 1468 | } |
| 1452 | #endif | 1469 | #endif |
| 1453 | 1470 | ||
| 1454 | static int ipw_send_tx_power(struct ipw_priv *priv, | 1471 | static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) |
| 1455 | struct ipw_tx_power *power) | ||
| 1456 | { | 1472 | { |
| 1457 | struct host_cmd cmd = { | 1473 | struct host_cmd cmd = { |
| 1458 | .cmd = IPW_CMD_TX_POWER, | 1474 | .cmd = IPW_CMD_TX_POWER, |
| @@ -1464,7 +1480,7 @@ static int ipw_send_tx_power(struct ipw_priv *priv, | |||
| 1464 | return -1; | 1480 | return -1; |
| 1465 | } | 1481 | } |
| 1466 | 1482 | ||
| 1467 | memcpy(&cmd.param,power,sizeof(*power)); | 1483 | memcpy(&cmd.param, power, sizeof(*power)); |
| 1468 | if (ipw_send_cmd(priv, &cmd)) { | 1484 | if (ipw_send_cmd(priv, &cmd)) { |
| 1469 | IPW_ERROR("failed to send TX_POWER command\n"); | 1485 | IPW_ERROR("failed to send TX_POWER command\n"); |
| 1470 | return -1; | 1486 | return -1; |
| @@ -1527,7 +1543,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) | |||
| 1527 | .cmd = IPW_CMD_POWER_MODE, | 1543 | .cmd = IPW_CMD_POWER_MODE, |
| 1528 | .len = sizeof(u32) | 1544 | .len = sizeof(u32) |
| 1529 | }; | 1545 | }; |
| 1530 | u32 *param = (u32*)(&cmd.param); | 1546 | u32 *param = (u32 *) (&cmd.param); |
| 1531 | 1547 | ||
| 1532 | if (!priv) { | 1548 | if (!priv) { |
| 1533 | IPW_ERROR("Invalid args\n"); | 1549 | IPW_ERROR("Invalid args\n"); |
| @@ -1585,67 +1601,67 @@ static inline void eeprom_write_reg(struct ipw_priv *p, u32 data) | |||
| 1585 | } | 1601 | } |
| 1586 | 1602 | ||
| 1587 | /* perform a chip select operation */ | 1603 | /* perform a chip select operation */ |
| 1588 | static inline void eeprom_cs(struct ipw_priv* priv) | 1604 | static inline void eeprom_cs(struct ipw_priv *priv) |
| 1589 | { | 1605 | { |
| 1590 | eeprom_write_reg(priv,0); | 1606 | eeprom_write_reg(priv, 0); |
| 1591 | eeprom_write_reg(priv,EEPROM_BIT_CS); | 1607 | eeprom_write_reg(priv, EEPROM_BIT_CS); |
| 1592 | eeprom_write_reg(priv,EEPROM_BIT_CS|EEPROM_BIT_SK); | 1608 | eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK); |
| 1593 | eeprom_write_reg(priv,EEPROM_BIT_CS); | 1609 | eeprom_write_reg(priv, EEPROM_BIT_CS); |
| 1594 | } | 1610 | } |
| 1595 | 1611 | ||
| 1596 | /* perform a chip select operation */ | 1612 | /* perform a chip select operation */ |
| 1597 | static inline void eeprom_disable_cs(struct ipw_priv* priv) | 1613 | static inline void eeprom_disable_cs(struct ipw_priv *priv) |
| 1598 | { | 1614 | { |
| 1599 | eeprom_write_reg(priv,EEPROM_BIT_CS); | 1615 | eeprom_write_reg(priv, EEPROM_BIT_CS); |
| 1600 | eeprom_write_reg(priv,0); | 1616 | eeprom_write_reg(priv, 0); |
| 1601 | eeprom_write_reg(priv,EEPROM_BIT_SK); | 1617 | eeprom_write_reg(priv, EEPROM_BIT_SK); |
| 1602 | } | 1618 | } |
| 1603 | 1619 | ||
| 1604 | /* push a single bit down to the eeprom */ | 1620 | /* push a single bit down to the eeprom */ |
| 1605 | static inline void eeprom_write_bit(struct ipw_priv *p,u8 bit) | 1621 | static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit) |
| 1606 | { | 1622 | { |
| 1607 | int d = ( bit ? EEPROM_BIT_DI : 0); | 1623 | int d = (bit ? EEPROM_BIT_DI : 0); |
| 1608 | eeprom_write_reg(p,EEPROM_BIT_CS|d); | 1624 | eeprom_write_reg(p, EEPROM_BIT_CS | d); |
| 1609 | eeprom_write_reg(p,EEPROM_BIT_CS|d|EEPROM_BIT_SK); | 1625 | eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK); |
| 1610 | } | 1626 | } |
| 1611 | 1627 | ||
| 1612 | /* push an opcode followed by an address down to the eeprom */ | 1628 | /* push an opcode followed by an address down to the eeprom */ |
| 1613 | static void eeprom_op(struct ipw_priv* priv, u8 op, u8 addr) | 1629 | static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr) |
| 1614 | { | 1630 | { |
| 1615 | int i; | 1631 | int i; |
| 1616 | 1632 | ||
| 1617 | eeprom_cs(priv); | 1633 | eeprom_cs(priv); |
| 1618 | eeprom_write_bit(priv,1); | 1634 | eeprom_write_bit(priv, 1); |
| 1619 | eeprom_write_bit(priv,op&2); | 1635 | eeprom_write_bit(priv, op & 2); |
| 1620 | eeprom_write_bit(priv,op&1); | 1636 | eeprom_write_bit(priv, op & 1); |
| 1621 | for ( i=7; i>=0; i-- ) { | 1637 | for (i = 7; i >= 0; i--) { |
| 1622 | eeprom_write_bit(priv,addr&(1<<i)); | 1638 | eeprom_write_bit(priv, addr & (1 << i)); |
| 1623 | } | 1639 | } |
| 1624 | } | 1640 | } |
| 1625 | 1641 | ||
| 1626 | /* pull 16 bits off the eeprom, one bit at a time */ | 1642 | /* pull 16 bits off the eeprom, one bit at a time */ |
| 1627 | static u16 eeprom_read_u16(struct ipw_priv* priv, u8 addr) | 1643 | static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr) |
| 1628 | { | 1644 | { |
| 1629 | int i; | 1645 | int i; |
| 1630 | u16 r=0; | 1646 | u16 r = 0; |
| 1631 | 1647 | ||
| 1632 | /* Send READ Opcode */ | 1648 | /* Send READ Opcode */ |
| 1633 | eeprom_op(priv,EEPROM_CMD_READ,addr); | 1649 | eeprom_op(priv, EEPROM_CMD_READ, addr); |
| 1634 | 1650 | ||
| 1635 | /* Send dummy bit */ | 1651 | /* Send dummy bit */ |
| 1636 | eeprom_write_reg(priv,EEPROM_BIT_CS); | 1652 | eeprom_write_reg(priv, EEPROM_BIT_CS); |
| 1637 | 1653 | ||
| 1638 | /* Read the byte off the eeprom one bit at a time */ | 1654 | /* Read the byte off the eeprom one bit at a time */ |
| 1639 | for ( i=0; i<16; i++ ) { | 1655 | for (i = 0; i < 16; i++) { |
| 1640 | u32 data = 0; | 1656 | u32 data = 0; |
| 1641 | eeprom_write_reg(priv,EEPROM_BIT_CS|EEPROM_BIT_SK); | 1657 | eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK); |
| 1642 | eeprom_write_reg(priv,EEPROM_BIT_CS); | 1658 | eeprom_write_reg(priv, EEPROM_BIT_CS); |
| 1643 | data = ipw_read_reg32(priv,FW_MEM_REG_EEPROM_ACCESS); | 1659 | data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS); |
| 1644 | r = (r<<1) | ((data & EEPROM_BIT_DO)?1:0); | 1660 | r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0); |
| 1645 | } | 1661 | } |
| 1646 | 1662 | ||
| 1647 | /* Send another dummy bit */ | 1663 | /* Send another dummy bit */ |
| 1648 | eeprom_write_reg(priv,0); | 1664 | eeprom_write_reg(priv, 0); |
| 1649 | eeprom_disable_cs(priv); | 1665 | eeprom_disable_cs(priv); |
| 1650 | 1666 | ||
| 1651 | return r; | 1667 | return r; |
| @@ -1653,9 +1669,9 @@ static u16 eeprom_read_u16(struct ipw_priv* priv, u8 addr) | |||
| 1653 | 1669 | ||
| 1654 | /* helper function for pulling the mac address out of the private */ | 1670 | /* helper function for pulling the mac address out of the private */ |
| 1655 | /* data's copy of the eeprom data */ | 1671 | /* data's copy of the eeprom data */ |
| 1656 | static void eeprom_parse_mac(struct ipw_priv* priv, u8* mac) | 1672 | static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) |
| 1657 | { | 1673 | { |
| 1658 | u8* ee = (u8*)priv->eeprom; | 1674 | u8 *ee = (u8 *) priv->eeprom; |
| 1659 | memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6); | 1675 | memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6); |
| 1660 | } | 1676 | } |
| 1661 | 1677 | ||
| @@ -1670,26 +1686,25 @@ static void eeprom_parse_mac(struct ipw_priv* priv, u8* mac) | |||
| 1670 | static void ipw_eeprom_init_sram(struct ipw_priv *priv) | 1686 | static void ipw_eeprom_init_sram(struct ipw_priv *priv) |
| 1671 | { | 1687 | { |
| 1672 | int i; | 1688 | int i; |
| 1673 | u16 *eeprom = (u16 *)priv->eeprom; | 1689 | u16 *eeprom = (u16 *) priv->eeprom; |
| 1674 | 1690 | ||
| 1675 | IPW_DEBUG_TRACE(">>\n"); | 1691 | IPW_DEBUG_TRACE(">>\n"); |
| 1676 | 1692 | ||
| 1677 | /* read entire contents of eeprom into private buffer */ | 1693 | /* read entire contents of eeprom into private buffer */ |
| 1678 | for ( i=0; i<128; i++ ) | 1694 | for (i = 0; i < 128; i++) |
| 1679 | eeprom[i] = eeprom_read_u16(priv,(u8)i); | 1695 | eeprom[i] = eeprom_read_u16(priv, (u8) i); |
| 1680 | 1696 | ||
| 1681 | /* | 1697 | /* |
| 1682 | If the data looks correct, then copy it to our private | 1698 | If the data looks correct, then copy it to our private |
| 1683 | copy. Otherwise let the firmware know to perform the operation | 1699 | copy. Otherwise let the firmware know to perform the operation |
| 1684 | on it's own | 1700 | on it's own |
| 1685 | */ | 1701 | */ |
| 1686 | if ((priv->eeprom + EEPROM_VERSION) != 0) { | 1702 | if ((priv->eeprom + EEPROM_VERSION) != 0) { |
| 1687 | IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); | 1703 | IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); |
| 1688 | 1704 | ||
| 1689 | /* write the eeprom data to sram */ | 1705 | /* write the eeprom data to sram */ |
| 1690 | for( i=0; i<CX2_EEPROM_IMAGE_SIZE; i++ ) | 1706 | for (i = 0; i < CX2_EEPROM_IMAGE_SIZE; i++) |
| 1691 | ipw_write8(priv, IPW_EEPROM_DATA + i, | 1707 | ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]); |
| 1692 | priv->eeprom[i]); | ||
| 1693 | 1708 | ||
| 1694 | /* Do not load eeprom data on fatal error or suspend */ | 1709 | /* Do not load eeprom data on fatal error or suspend */ |
| 1695 | ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0); | 1710 | ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0); |
| @@ -1703,11 +1718,11 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv) | |||
| 1703 | IPW_DEBUG_TRACE("<<\n"); | 1718 | IPW_DEBUG_TRACE("<<\n"); |
| 1704 | } | 1719 | } |
| 1705 | 1720 | ||
| 1706 | |||
| 1707 | static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count) | 1721 | static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count) |
| 1708 | { | 1722 | { |
| 1709 | count >>= 2; | 1723 | count >>= 2; |
| 1710 | if (!count) return; | 1724 | if (!count) |
| 1725 | return; | ||
| 1711 | _ipw_write32(priv, CX2_AUTOINC_ADDR, start); | 1726 | _ipw_write32(priv, CX2_AUTOINC_ADDR, start); |
| 1712 | while (count--) | 1727 | while (count--) |
| 1713 | _ipw_write32(priv, CX2_AUTOINC_DATA, 0); | 1728 | _ipw_write32(priv, CX2_AUTOINC_DATA, 0); |
| @@ -1721,7 +1736,7 @@ static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv) | |||
| 1721 | } | 1736 | } |
| 1722 | 1737 | ||
| 1723 | static int ipw_fw_dma_enable(struct ipw_priv *priv) | 1738 | static int ipw_fw_dma_enable(struct ipw_priv *priv) |
| 1724 | { /* start dma engine but no transfers yet*/ | 1739 | { /* start dma engine but no transfers yet */ |
| 1725 | 1740 | ||
| 1726 | IPW_DEBUG_FW(">> : \n"); | 1741 | IPW_DEBUG_FW(">> : \n"); |
| 1727 | 1742 | ||
| @@ -1749,12 +1764,16 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv) | |||
| 1749 | IPW_DEBUG_FW("<< \n"); | 1764 | IPW_DEBUG_FW("<< \n"); |
| 1750 | } | 1765 | } |
| 1751 | 1766 | ||
| 1752 | static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index, struct command_block *cb) | 1767 | static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index, |
| 1768 | struct command_block *cb) | ||
| 1753 | { | 1769 | { |
| 1754 | u32 address = CX2_SHARED_SRAM_DMA_CONTROL + (sizeof(struct command_block) * index); | 1770 | u32 address = |
| 1771 | CX2_SHARED_SRAM_DMA_CONTROL + | ||
| 1772 | (sizeof(struct command_block) * index); | ||
| 1755 | IPW_DEBUG_FW(">> :\n"); | 1773 | IPW_DEBUG_FW(">> :\n"); |
| 1756 | 1774 | ||
| 1757 | ipw_write_indirect(priv, address, (u8*)cb, (int)sizeof(struct command_block)); | 1775 | ipw_write_indirect(priv, address, (u8 *) cb, |
| 1776 | (int)sizeof(struct command_block)); | ||
| 1758 | 1777 | ||
| 1759 | IPW_DEBUG_FW("<< :\n"); | 1778 | IPW_DEBUG_FW("<< :\n"); |
| 1760 | return 0; | 1779 | return 0; |
| @@ -1764,17 +1783,20 @@ static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index, stru | |||
| 1764 | static int ipw_fw_dma_kick(struct ipw_priv *priv) | 1783 | static int ipw_fw_dma_kick(struct ipw_priv *priv) |
| 1765 | { | 1784 | { |
| 1766 | u32 control = 0; | 1785 | u32 control = 0; |
| 1767 | u32 index=0; | 1786 | u32 index = 0; |
| 1768 | 1787 | ||
| 1769 | IPW_DEBUG_FW(">> :\n"); | 1788 | IPW_DEBUG_FW(">> :\n"); |
| 1770 | 1789 | ||
| 1771 | for (index = 0; index < priv->sram_desc.last_cb_index; index++) | 1790 | for (index = 0; index < priv->sram_desc.last_cb_index; index++) |
| 1772 | ipw_fw_dma_write_command_block(priv, index, &priv->sram_desc.cb_list[index]); | 1791 | ipw_fw_dma_write_command_block(priv, index, |
| 1792 | &priv->sram_desc.cb_list[index]); | ||
| 1773 | 1793 | ||
| 1774 | /* Enable the DMA in the CSR register */ | 1794 | /* Enable the DMA in the CSR register */ |
| 1775 | ipw_clear_bit(priv, CX2_RESET_REG,CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); | 1795 | ipw_clear_bit(priv, CX2_RESET_REG, |
| 1796 | CX2_RESET_REG_MASTER_DISABLED | | ||
| 1797 | CX2_RESET_REG_STOP_MASTER); | ||
| 1776 | 1798 | ||
| 1777 | /* Set the Start bit. */ | 1799 | /* Set the Start bit. */ |
| 1778 | control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START; | 1800 | control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START; |
| 1779 | ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); | 1801 | ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); |
| 1780 | 1802 | ||
| @@ -1785,25 +1807,25 @@ static int ipw_fw_dma_kick(struct ipw_priv *priv) | |||
| 1785 | static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv) | 1807 | static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv) |
| 1786 | { | 1808 | { |
| 1787 | u32 address; | 1809 | u32 address; |
| 1788 | u32 register_value=0; | 1810 | u32 register_value = 0; |
| 1789 | u32 cb_fields_address=0; | 1811 | u32 cb_fields_address = 0; |
| 1790 | 1812 | ||
| 1791 | IPW_DEBUG_FW(">> :\n"); | 1813 | IPW_DEBUG_FW(">> :\n"); |
| 1792 | address = ipw_read_reg32(priv,CX2_DMA_I_CURRENT_CB); | 1814 | address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); |
| 1793 | IPW_DEBUG_FW_INFO("Current CB is 0x%x \n",address); | 1815 | IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address); |
| 1794 | 1816 | ||
| 1795 | /* Read the DMA Controlor register */ | 1817 | /* Read the DMA Controlor register */ |
| 1796 | register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL); | 1818 | register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL); |
| 1797 | IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n",register_value); | 1819 | IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n", register_value); |
| 1798 | 1820 | ||
| 1799 | /* Print the CB values*/ | 1821 | /* Print the CB values */ |
| 1800 | cb_fields_address = address; | 1822 | cb_fields_address = address; |
| 1801 | register_value = ipw_read_reg32(priv, cb_fields_address); | 1823 | register_value = ipw_read_reg32(priv, cb_fields_address); |
| 1802 | IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n",register_value); | 1824 | IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n", register_value); |
| 1803 | 1825 | ||
| 1804 | cb_fields_address += sizeof(u32); | 1826 | cb_fields_address += sizeof(u32); |
| 1805 | register_value = ipw_read_reg32(priv, cb_fields_address); | 1827 | register_value = ipw_read_reg32(priv, cb_fields_address); |
| 1806 | IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n",register_value); | 1828 | IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n", register_value); |
| 1807 | 1829 | ||
| 1808 | cb_fields_address += sizeof(u32); | 1830 | cb_fields_address += sizeof(u32); |
| 1809 | register_value = ipw_read_reg32(priv, cb_fields_address); | 1831 | register_value = ipw_read_reg32(priv, cb_fields_address); |
| @@ -1812,7 +1834,7 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv) | |||
| 1812 | 1834 | ||
| 1813 | cb_fields_address += sizeof(u32); | 1835 | cb_fields_address += sizeof(u32); |
| 1814 | register_value = ipw_read_reg32(priv, cb_fields_address); | 1836 | register_value = ipw_read_reg32(priv, cb_fields_address); |
| 1815 | IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n",register_value); | 1837 | IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n", register_value); |
| 1816 | 1838 | ||
| 1817 | IPW_DEBUG_FW(">> :\n"); | 1839 | IPW_DEBUG_FW(">> :\n"); |
| 1818 | } | 1840 | } |
| @@ -1823,13 +1845,13 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv) | |||
| 1823 | u32 current_cb_index = 0; | 1845 | u32 current_cb_index = 0; |
| 1824 | 1846 | ||
| 1825 | IPW_DEBUG_FW("<< :\n"); | 1847 | IPW_DEBUG_FW("<< :\n"); |
| 1826 | current_cb_address= ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); | 1848 | current_cb_address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); |
| 1827 | 1849 | ||
| 1828 | current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL )/ | 1850 | current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL) / |
| 1829 | sizeof (struct command_block); | 1851 | sizeof(struct command_block); |
| 1830 | 1852 | ||
| 1831 | IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", | 1853 | IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", |
| 1832 | current_cb_index, current_cb_address ); | 1854 | current_cb_index, current_cb_address); |
| 1833 | 1855 | ||
| 1834 | IPW_DEBUG_FW(">> :\n"); | 1856 | IPW_DEBUG_FW(">> :\n"); |
| 1835 | return current_cb_index; | 1857 | return current_cb_index; |
| @@ -1840,15 +1862,14 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv, | |||
| 1840 | u32 src_address, | 1862 | u32 src_address, |
| 1841 | u32 dest_address, | 1863 | u32 dest_address, |
| 1842 | u32 length, | 1864 | u32 length, |
| 1843 | int interrupt_enabled, | 1865 | int interrupt_enabled, int is_last) |
| 1844 | int is_last) | ||
| 1845 | { | 1866 | { |
| 1846 | 1867 | ||
| 1847 | u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC | | 1868 | u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC | |
| 1848 | CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG | | 1869 | CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG | |
| 1849 | CB_DEST_SIZE_LONG; | 1870 | CB_DEST_SIZE_LONG; |
| 1850 | struct command_block *cb; | 1871 | struct command_block *cb; |
| 1851 | u32 last_cb_element=0; | 1872 | u32 last_cb_element = 0; |
| 1852 | 1873 | ||
| 1853 | IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n", | 1874 | IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n", |
| 1854 | src_address, dest_address, length); | 1875 | src_address, dest_address, length); |
| @@ -1861,7 +1882,7 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv, | |||
| 1861 | priv->sram_desc.last_cb_index++; | 1882 | priv->sram_desc.last_cb_index++; |
| 1862 | 1883 | ||
| 1863 | /* Calculate the new CB control word */ | 1884 | /* Calculate the new CB control word */ |
| 1864 | if (interrupt_enabled ) | 1885 | if (interrupt_enabled) |
| 1865 | control |= CB_INT_ENABLED; | 1886 | control |= CB_INT_ENABLED; |
| 1866 | 1887 | ||
| 1867 | if (is_last) | 1888 | if (is_last) |
| @@ -1870,7 +1891,7 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv, | |||
| 1870 | control |= length; | 1891 | control |= length; |
| 1871 | 1892 | ||
| 1872 | /* Calculate the CB Element's checksum value */ | 1893 | /* Calculate the CB Element's checksum value */ |
| 1873 | cb->status = control ^src_address ^dest_address; | 1894 | cb->status = control ^ src_address ^ dest_address; |
| 1874 | 1895 | ||
| 1875 | /* Copy the Source and Destination addresses */ | 1896 | /* Copy the Source and Destination addresses */ |
| 1876 | cb->dest_addr = dest_address; | 1897 | cb->dest_addr = dest_address; |
| @@ -1883,22 +1904,21 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv, | |||
| 1883 | } | 1904 | } |
| 1884 | 1905 | ||
| 1885 | static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, | 1906 | static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, |
| 1886 | u32 src_phys, | 1907 | u32 src_phys, u32 dest_address, u32 length) |
| 1887 | u32 dest_address, | ||
| 1888 | u32 length) | ||
| 1889 | { | 1908 | { |
| 1890 | u32 bytes_left = length; | 1909 | u32 bytes_left = length; |
| 1891 | u32 src_offset=0; | 1910 | u32 src_offset = 0; |
| 1892 | u32 dest_offset=0; | 1911 | u32 dest_offset = 0; |
| 1893 | int status = 0; | 1912 | int status = 0; |
| 1894 | IPW_DEBUG_FW(">> \n"); | 1913 | IPW_DEBUG_FW(">> \n"); |
| 1895 | IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n", | 1914 | IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n", |
| 1896 | src_phys, dest_address, length); | 1915 | src_phys, dest_address, length); |
| 1897 | while (bytes_left > CB_MAX_LENGTH) { | 1916 | while (bytes_left > CB_MAX_LENGTH) { |
| 1898 | status = ipw_fw_dma_add_command_block( priv, | 1917 | status = ipw_fw_dma_add_command_block(priv, |
| 1899 | src_phys + src_offset, | 1918 | src_phys + src_offset, |
| 1900 | dest_address + dest_offset, | 1919 | dest_address + |
| 1901 | CB_MAX_LENGTH, 0, 0); | 1920 | dest_offset, |
| 1921 | CB_MAX_LENGTH, 0, 0); | ||
| 1902 | if (status) { | 1922 | if (status) { |
| 1903 | IPW_DEBUG_FW_INFO(": Failed\n"); | 1923 | IPW_DEBUG_FW_INFO(": Failed\n"); |
| 1904 | return -1; | 1924 | return -1; |
| @@ -1912,18 +1932,18 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, | |||
| 1912 | 1932 | ||
| 1913 | /* add the buffer tail */ | 1933 | /* add the buffer tail */ |
| 1914 | if (bytes_left > 0) { | 1934 | if (bytes_left > 0) { |
| 1915 | status = ipw_fw_dma_add_command_block( | 1935 | status = |
| 1916 | priv, src_phys + src_offset, | 1936 | ipw_fw_dma_add_command_block(priv, src_phys + src_offset, |
| 1917 | dest_address + dest_offset, | 1937 | dest_address + dest_offset, |
| 1918 | bytes_left, 0, 0); | 1938 | bytes_left, 0, 0); |
| 1919 | if (status) { | 1939 | if (status) { |
| 1920 | IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n"); | 1940 | IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n"); |
| 1921 | return -1; | 1941 | return -1; |
| 1922 | } else | 1942 | } else |
| 1923 | IPW_DEBUG_FW_INFO(": Adding new cb - the buffer tail\n"); | 1943 | IPW_DEBUG_FW_INFO |
| 1944 | (": Adding new cb - the buffer tail\n"); | ||
| 1924 | } | 1945 | } |
| 1925 | 1946 | ||
| 1926 | |||
| 1927 | IPW_DEBUG_FW("<< \n"); | 1947 | IPW_DEBUG_FW("<< \n"); |
| 1928 | return 0; | 1948 | return 0; |
| 1929 | } | 1949 | } |
| @@ -1937,7 +1957,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv) | |||
| 1937 | 1957 | ||
| 1938 | current_index = ipw_fw_dma_command_block_index(priv); | 1958 | current_index = ipw_fw_dma_command_block_index(priv); |
| 1939 | IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", | 1959 | IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", |
| 1940 | (int) priv->sram_desc.last_cb_index); | 1960 | (int)priv->sram_desc.last_cb_index); |
| 1941 | 1961 | ||
| 1942 | while (current_index < priv->sram_desc.last_cb_index) { | 1962 | while (current_index < priv->sram_desc.last_cb_index) { |
| 1943 | udelay(50); | 1963 | udelay(50); |
| @@ -1955,8 +1975,8 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv) | |||
| 1955 | 1975 | ||
| 1956 | ipw_fw_dma_abort(priv); | 1976 | ipw_fw_dma_abort(priv); |
| 1957 | 1977 | ||
| 1958 | /*Disable the DMA in the CSR register*/ | 1978 | /*Disable the DMA in the CSR register */ |
| 1959 | ipw_set_bit(priv, CX2_RESET_REG, | 1979 | ipw_set_bit(priv, CX2_RESET_REG, |
| 1960 | CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); | 1980 | CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); |
| 1961 | 1981 | ||
| 1962 | IPW_DEBUG_FW("<< dmaWaitSync \n"); | 1982 | IPW_DEBUG_FW("<< dmaWaitSync \n"); |
| @@ -2011,8 +2031,7 @@ static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, | |||
| 2011 | * image and the caller is handling the memory allocation and clean up. | 2031 | * image and the caller is handling the memory allocation and clean up. |
| 2012 | */ | 2032 | */ |
| 2013 | 2033 | ||
| 2014 | 2034 | static int ipw_stop_master(struct ipw_priv *priv) | |
| 2015 | static int ipw_stop_master(struct ipw_priv * priv) | ||
| 2016 | { | 2035 | { |
| 2017 | int rc; | 2036 | int rc; |
| 2018 | 2037 | ||
| @@ -2071,14 +2090,13 @@ struct fw_chunk { | |||
| 2071 | #define IPW_FW_NAME(x) "ipw2200_" x ".fw" | 2090 | #define IPW_FW_NAME(x) "ipw2200_" x ".fw" |
| 2072 | #endif | 2091 | #endif |
| 2073 | 2092 | ||
| 2074 | static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, | 2093 | static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) |
| 2075 | size_t len) | ||
| 2076 | { | 2094 | { |
| 2077 | int rc = 0, i, addr; | 2095 | int rc = 0, i, addr; |
| 2078 | u8 cr = 0; | 2096 | u8 cr = 0; |
| 2079 | u16 *image; | 2097 | u16 *image; |
| 2080 | 2098 | ||
| 2081 | image = (u16 *)data; | 2099 | image = (u16 *) data; |
| 2082 | 2100 | ||
| 2083 | IPW_DEBUG_TRACE(">> \n"); | 2101 | IPW_DEBUG_TRACE(">> \n"); |
| 2084 | 2102 | ||
| @@ -2087,7 +2105,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, | |||
| 2087 | if (rc < 0) | 2105 | if (rc < 0) |
| 2088 | return rc; | 2106 | return rc; |
| 2089 | 2107 | ||
| 2090 | // spin_lock_irqsave(&priv->lock, flags); | 2108 | // spin_lock_irqsave(&priv->lock, flags); |
| 2091 | 2109 | ||
| 2092 | for (addr = CX2_SHARED_LOWER_BOUND; | 2110 | for (addr = CX2_SHARED_LOWER_BOUND; |
| 2093 | addr < CX2_REGISTER_DOMAIN1_END; addr += 4) { | 2111 | addr < CX2_REGISTER_DOMAIN1_END; addr += 4) { |
| @@ -2099,7 +2117,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, | |||
| 2099 | /* destroy DMA queues */ | 2117 | /* destroy DMA queues */ |
| 2100 | /* reset sequence */ | 2118 | /* reset sequence */ |
| 2101 | 2119 | ||
| 2102 | ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET ,CX2_BIT_HALT_RESET_ON); | 2120 | ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_ON); |
| 2103 | ipw_arc_release(priv); | 2121 | ipw_arc_release(priv); |
| 2104 | ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF); | 2122 | ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF); |
| 2105 | mdelay(1); | 2123 | mdelay(1); |
| @@ -2128,13 +2146,11 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, | |||
| 2128 | for (i = 0; i < len / 2; i++) | 2146 | for (i = 0; i < len / 2; i++) |
| 2129 | ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); | 2147 | ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); |
| 2130 | 2148 | ||
| 2131 | |||
| 2132 | /* enable DINO */ | 2149 | /* enable DINO */ |
| 2133 | ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); | 2150 | ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); |
| 2134 | ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, | 2151 | ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM); |
| 2135 | DINO_ENABLE_SYSTEM ); | ||
| 2136 | 2152 | ||
| 2137 | /* this is where the igx / win driver deveates from the VAP driver.*/ | 2153 | /* this is where the igx / win driver deveates from the VAP driver. */ |
| 2138 | 2154 | ||
| 2139 | /* wait for alive response */ | 2155 | /* wait for alive response */ |
| 2140 | for (i = 0; i < 100; i++) { | 2156 | for (i = 0; i < 100; i++) { |
| @@ -2151,25 +2167,24 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, | |||
| 2151 | 2167 | ||
| 2152 | for (i = 0; i < ARRAY_SIZE(response_buffer); i++) | 2168 | for (i = 0; i < ARRAY_SIZE(response_buffer); i++) |
| 2153 | response_buffer[i] = | 2169 | response_buffer[i] = |
| 2154 | ipw_read_reg32(priv, | 2170 | ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ); |
| 2155 | CX2_BASEBAND_RX_FIFO_READ); | ||
| 2156 | memcpy(&priv->dino_alive, response_buffer, | 2171 | memcpy(&priv->dino_alive, response_buffer, |
| 2157 | sizeof(priv->dino_alive)); | 2172 | sizeof(priv->dino_alive)); |
| 2158 | if (priv->dino_alive.alive_command == 1 | 2173 | if (priv->dino_alive.alive_command == 1 |
| 2159 | && priv->dino_alive.ucode_valid == 1) { | 2174 | && priv->dino_alive.ucode_valid == 1) { |
| 2160 | rc = 0; | 2175 | rc = 0; |
| 2161 | IPW_DEBUG_INFO( | 2176 | IPW_DEBUG_INFO |
| 2162 | "Microcode OK, rev. %d (0x%x) dev. %d (0x%x) " | 2177 | ("Microcode OK, rev. %d (0x%x) dev. %d (0x%x) " |
| 2163 | "of %02d/%02d/%02d %02d:%02d\n", | 2178 | "of %02d/%02d/%02d %02d:%02d\n", |
| 2164 | priv->dino_alive.software_revision, | 2179 | priv->dino_alive.software_revision, |
| 2165 | priv->dino_alive.software_revision, | 2180 | priv->dino_alive.software_revision, |
| 2166 | priv->dino_alive.device_identifier, | 2181 | priv->dino_alive.device_identifier, |
| 2167 | priv->dino_alive.device_identifier, | 2182 | priv->dino_alive.device_identifier, |
| 2168 | priv->dino_alive.time_stamp[0], | 2183 | priv->dino_alive.time_stamp[0], |
| 2169 | priv->dino_alive.time_stamp[1], | 2184 | priv->dino_alive.time_stamp[1], |
| 2170 | priv->dino_alive.time_stamp[2], | 2185 | priv->dino_alive.time_stamp[2], |
| 2171 | priv->dino_alive.time_stamp[3], | 2186 | priv->dino_alive.time_stamp[3], |
| 2172 | priv->dino_alive.time_stamp[4]); | 2187 | priv->dino_alive.time_stamp[4]); |
| 2173 | } else { | 2188 | } else { |
| 2174 | IPW_DEBUG_INFO("Microcode is not alive\n"); | 2189 | IPW_DEBUG_INFO("Microcode is not alive\n"); |
| 2175 | rc = -EINVAL; | 2190 | rc = -EINVAL; |
| @@ -2183,13 +2198,12 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, | |||
| 2183 | firmware have problem getting alive resp. */ | 2198 | firmware have problem getting alive resp. */ |
| 2184 | ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); | 2199 | ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); |
| 2185 | 2200 | ||
| 2186 | // spin_unlock_irqrestore(&priv->lock, flags); | 2201 | // spin_unlock_irqrestore(&priv->lock, flags); |
| 2187 | 2202 | ||
| 2188 | return rc; | 2203 | return rc; |
| 2189 | } | 2204 | } |
| 2190 | 2205 | ||
| 2191 | static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, | 2206 | static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) |
| 2192 | size_t len) | ||
| 2193 | { | 2207 | { |
| 2194 | int rc = -1; | 2208 | int rc = -1; |
| 2195 | int offset = 0; | 2209 | int offset = 0; |
| @@ -2231,7 +2245,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, | |||
| 2231 | offset += chunk->length; | 2245 | offset += chunk->length; |
| 2232 | } while (offset < len); | 2246 | } while (offset < len); |
| 2233 | 2247 | ||
| 2234 | /* Run the DMA and wait for the answer*/ | 2248 | /* Run the DMA and wait for the answer */ |
| 2235 | rc = ipw_fw_dma_kick(priv); | 2249 | rc = ipw_fw_dma_kick(priv); |
| 2236 | if (rc) { | 2250 | if (rc) { |
| 2237 | IPW_ERROR("dmaKick Failed\n"); | 2251 | IPW_ERROR("dmaKick Failed\n"); |
| @@ -2243,8 +2257,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, | |||
| 2243 | IPW_ERROR("dmaWaitSync Failed\n"); | 2257 | IPW_ERROR("dmaWaitSync Failed\n"); |
| 2244 | goto out; | 2258 | goto out; |
| 2245 | } | 2259 | } |
| 2246 | out: | 2260 | out: |
| 2247 | pci_free_consistent( priv->pci_dev, len, shared_virt, shared_phys); | 2261 | pci_free_consistent(priv->pci_dev, len, shared_virt, shared_phys); |
| 2248 | return rc; | 2262 | return rc; |
| 2249 | } | 2263 | } |
| 2250 | 2264 | ||
| @@ -2253,7 +2267,7 @@ static int ipw_stop_nic(struct ipw_priv *priv) | |||
| 2253 | { | 2267 | { |
| 2254 | int rc = 0; | 2268 | int rc = 0; |
| 2255 | 2269 | ||
| 2256 | /* stop*/ | 2270 | /* stop */ |
| 2257 | ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); | 2271 | ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); |
| 2258 | 2272 | ||
| 2259 | rc = ipw_poll_bit(priv, CX2_RESET_REG, | 2273 | rc = ipw_poll_bit(priv, CX2_RESET_REG, |
| @@ -2272,14 +2286,15 @@ static void ipw_start_nic(struct ipw_priv *priv) | |||
| 2272 | { | 2286 | { |
| 2273 | IPW_DEBUG_TRACE(">>\n"); | 2287 | IPW_DEBUG_TRACE(">>\n"); |
| 2274 | 2288 | ||
| 2275 | /* prvHwStartNic release ARC*/ | 2289 | /* prvHwStartNic release ARC */ |
| 2276 | ipw_clear_bit(priv, CX2_RESET_REG, | 2290 | ipw_clear_bit(priv, CX2_RESET_REG, |
| 2277 | CX2_RESET_REG_MASTER_DISABLED | | 2291 | CX2_RESET_REG_MASTER_DISABLED | |
| 2278 | CX2_RESET_REG_STOP_MASTER | | 2292 | CX2_RESET_REG_STOP_MASTER | |
| 2279 | CBD_RESET_REG_PRINCETON_RESET); | 2293 | CBD_RESET_REG_PRINCETON_RESET); |
| 2280 | 2294 | ||
| 2281 | /* enable power management */ | 2295 | /* enable power management */ |
| 2282 | ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY); | 2296 | ipw_set_bit(priv, CX2_GP_CNTRL_RW, |
| 2297 | CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY); | ||
| 2283 | 2298 | ||
| 2284 | IPW_DEBUG_TRACE("<<\n"); | 2299 | IPW_DEBUG_TRACE("<<\n"); |
| 2285 | } | 2300 | } |
| @@ -2295,12 +2310,13 @@ static int ipw_init_nic(struct ipw_priv *priv) | |||
| 2295 | ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); | 2310 | ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); |
| 2296 | 2311 | ||
| 2297 | /* low-level PLL activation */ | 2312 | /* low-level PLL activation */ |
| 2298 | ipw_write32(priv, CX2_READ_INT_REGISTER, CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER); | 2313 | ipw_write32(priv, CX2_READ_INT_REGISTER, |
| 2314 | CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER); | ||
| 2299 | 2315 | ||
| 2300 | /* wait for clock stabilization */ | 2316 | /* wait for clock stabilization */ |
| 2301 | rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, | 2317 | rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, |
| 2302 | CX2_GP_CNTRL_BIT_CLOCK_READY, 250); | 2318 | CX2_GP_CNTRL_BIT_CLOCK_READY, 250); |
| 2303 | if (rc < 0 ) | 2319 | if (rc < 0) |
| 2304 | IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); | 2320 | IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); |
| 2305 | 2321 | ||
| 2306 | /* assert SW reset */ | 2322 | /* assert SW reset */ |
| @@ -2315,7 +2331,6 @@ static int ipw_init_nic(struct ipw_priv *priv) | |||
| 2315 | return 0; | 2331 | return 0; |
| 2316 | } | 2332 | } |
| 2317 | 2333 | ||
| 2318 | |||
| 2319 | /* Call this function from process context, it will sleep in request_firmware. | 2334 | /* Call this function from process context, it will sleep in request_firmware. |
| 2320 | * Probe is an ok place to call this from. | 2335 | * Probe is an ok place to call this from. |
| 2321 | */ | 2336 | */ |
| @@ -2383,8 +2398,7 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv, | |||
| 2383 | * to an SKB, so we need to unmap and free potential storage */ | 2398 | * to an SKB, so we need to unmap and free potential storage */ |
| 2384 | if (rxq->pool[i].skb != NULL) { | 2399 | if (rxq->pool[i].skb != NULL) { |
| 2385 | pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, | 2400 | pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, |
| 2386 | CX2_RX_BUF_SIZE, | 2401 | CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
| 2387 | PCI_DMA_FROMDEVICE); | ||
| 2388 | dev_kfree_skb(rxq->pool[i].skb); | 2402 | dev_kfree_skb(rxq->pool[i].skb); |
| 2389 | } | 2403 | } |
| 2390 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 2404 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
| @@ -2438,12 +2452,12 @@ static int ipw_load(struct ipw_priv *priv) | |||
| 2438 | if (rc) | 2452 | if (rc) |
| 2439 | goto error; | 2453 | goto error; |
| 2440 | 2454 | ||
| 2441 | rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("sniffer")); | 2455 | rc = ipw_get_fw(priv, &firmware, |
| 2456 | IPW_FW_NAME("sniffer")); | ||
| 2442 | break; | 2457 | break; |
| 2443 | #endif | 2458 | #endif |
| 2444 | case IW_MODE_INFRA: | 2459 | case IW_MODE_INFRA: |
| 2445 | rc = ipw_get_fw(priv, &ucode, | 2460 | rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode")); |
| 2446 | IPW_FW_NAME("bss_ucode")); | ||
| 2447 | if (rc) | 2461 | if (rc) |
| 2448 | goto error; | 2462 | goto error; |
| 2449 | 2463 | ||
| @@ -2471,7 +2485,7 @@ static int ipw_load(struct ipw_priv *priv) | |||
| 2471 | goto error; | 2485 | goto error; |
| 2472 | } | 2486 | } |
| 2473 | 2487 | ||
| 2474 | retry: | 2488 | retry: |
| 2475 | /* Ensure interrupts are disabled */ | 2489 | /* Ensure interrupts are disabled */ |
| 2476 | ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); | 2490 | ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); |
| 2477 | priv->status &= ~STATUS_INT_ENABLED; | 2491 | priv->status &= ~STATUS_INT_ENABLED; |
| @@ -2528,7 +2542,7 @@ static int ipw_load(struct ipw_priv *priv) | |||
| 2528 | rc = ipw_load_firmware(priv, firmware->data + | 2542 | rc = ipw_load_firmware(priv, firmware->data + |
| 2529 | sizeof(struct fw_header), | 2543 | sizeof(struct fw_header), |
| 2530 | firmware->size - sizeof(struct fw_header)); | 2544 | firmware->size - sizeof(struct fw_header)); |
| 2531 | if (rc < 0 ) { | 2545 | if (rc < 0) { |
| 2532 | IPW_ERROR("Unable to load firmware\n"); | 2546 | IPW_ERROR("Unable to load firmware\n"); |
| 2533 | goto error; | 2547 | goto error; |
| 2534 | } | 2548 | } |
| @@ -2593,7 +2607,7 @@ static int ipw_load(struct ipw_priv *priv) | |||
| 2593 | #endif | 2607 | #endif |
| 2594 | return 0; | 2608 | return 0; |
| 2595 | 2609 | ||
| 2596 | error: | 2610 | error: |
| 2597 | if (priv->rxq) { | 2611 | if (priv->rxq) { |
| 2598 | ipw_rx_queue_free(priv, priv->rxq); | 2612 | ipw_rx_queue_free(priv, priv->rxq); |
| 2599 | priv->rxq = NULL; | 2613 | priv->rxq = NULL; |
| @@ -2671,8 +2685,7 @@ static inline int ipw_queue_inc_wrap(int index, int n_bd) | |||
| 2671 | * (not offset within BAR, full address) | 2685 | * (not offset within BAR, full address) |
| 2672 | */ | 2686 | */ |
| 2673 | static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q, | 2687 | static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q, |
| 2674 | int count, u32 read, u32 write, | 2688 | int count, u32 read, u32 write, u32 base, u32 size) |
| 2675 | u32 base, u32 size) | ||
| 2676 | { | 2689 | { |
| 2677 | q->n_bd = count; | 2690 | q->n_bd = count; |
| 2678 | 2691 | ||
| @@ -2698,8 +2711,7 @@ static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q, | |||
| 2698 | 2711 | ||
| 2699 | static int ipw_queue_tx_init(struct ipw_priv *priv, | 2712 | static int ipw_queue_tx_init(struct ipw_priv *priv, |
| 2700 | struct clx2_tx_queue *q, | 2713 | struct clx2_tx_queue *q, |
| 2701 | int count, u32 read, u32 write, | 2714 | int count, u32 read, u32 write, u32 base, u32 size) |
| 2702 | u32 base, u32 size) | ||
| 2703 | { | 2715 | { |
| 2704 | struct pci_dev *dev = priv->pci_dev; | 2716 | struct pci_dev *dev = priv->pci_dev; |
| 2705 | 2717 | ||
| @@ -2709,10 +2721,11 @@ static int ipw_queue_tx_init(struct ipw_priv *priv, | |||
| 2709 | return -ENOMEM; | 2721 | return -ENOMEM; |
| 2710 | } | 2722 | } |
| 2711 | 2723 | ||
| 2712 | q->bd = pci_alloc_consistent(dev,sizeof(q->bd[0])*count, &q->q.dma_addr); | 2724 | q->bd = |
| 2725 | pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr); | ||
| 2713 | if (!q->bd) { | 2726 | if (!q->bd) { |
| 2714 | IPW_ERROR("pci_alloc_consistent(%zd) failed\n", | 2727 | IPW_ERROR("pci_alloc_consistent(%zd) failed\n", |
| 2715 | sizeof(q->bd[0]) * count); | 2728 | sizeof(q->bd[0]) * count); |
| 2716 | kfree(q->txb); | 2729 | kfree(q->txb); |
| 2717 | q->txb = NULL; | 2730 | q->txb = NULL; |
| 2718 | return -ENOMEM; | 2731 | return -ENOMEM; |
| @@ -2768,8 +2781,7 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv, | |||
| 2768 | * @param dev | 2781 | * @param dev |
| 2769 | * @param q | 2782 | * @param q |
| 2770 | */ | 2783 | */ |
| 2771 | static void ipw_queue_tx_free(struct ipw_priv *priv, | 2784 | static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq) |
| 2772 | struct clx2_tx_queue *txq) | ||
| 2773 | { | 2785 | { |
| 2774 | struct clx2_queue *q = &txq->q; | 2786 | struct clx2_queue *q = &txq->q; |
| 2775 | struct pci_dev *dev = priv->pci_dev; | 2787 | struct pci_dev *dev = priv->pci_dev; |
| @@ -2784,7 +2796,7 @@ static void ipw_queue_tx_free(struct ipw_priv *priv, | |||
| 2784 | } | 2796 | } |
| 2785 | 2797 | ||
| 2786 | /* free buffers belonging to queue itself */ | 2798 | /* free buffers belonging to queue itself */ |
| 2787 | pci_free_consistent(dev, sizeof(txq->bd[0])*q->n_bd, txq->bd, | 2799 | pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd, |
| 2788 | q->dma_addr); | 2800 | q->dma_addr); |
| 2789 | kfree(txq->txb); | 2801 | kfree(txq->txb); |
| 2790 | 2802 | ||
| @@ -2792,7 +2804,6 @@ static void ipw_queue_tx_free(struct ipw_priv *priv, | |||
| 2792 | memset(txq, 0, sizeof(*txq)); | 2804 | memset(txq, 0, sizeof(*txq)); |
| 2793 | } | 2805 | } |
| 2794 | 2806 | ||
| 2795 | |||
| 2796 | /** | 2807 | /** |
| 2797 | * Destroy all DMA queues and structures | 2808 | * Destroy all DMA queues and structures |
| 2798 | * | 2809 | * |
| @@ -2825,7 +2836,7 @@ static void inline __maybe_wake_tx(struct ipw_priv *priv) | |||
| 2825 | 2836 | ||
| 2826 | } | 2837 | } |
| 2827 | 2838 | ||
| 2828 | static inline void ipw_create_bssid(struct ipw_priv *priv, u8 *bssid) | 2839 | static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid) |
| 2829 | { | 2840 | { |
| 2830 | /* First 3 bytes are manufacturer */ | 2841 | /* First 3 bytes are manufacturer */ |
| 2831 | bssid[0] = priv->mac_addr[0]; | 2842 | bssid[0] = priv->mac_addr[0]; |
| @@ -2833,13 +2844,13 @@ static inline void ipw_create_bssid(struct ipw_priv *priv, u8 *bssid) | |||
| 2833 | bssid[2] = priv->mac_addr[2]; | 2844 | bssid[2] = priv->mac_addr[2]; |
| 2834 | 2845 | ||
| 2835 | /* Last bytes are random */ | 2846 | /* Last bytes are random */ |
| 2836 | get_random_bytes(&bssid[3], ETH_ALEN-3); | 2847 | get_random_bytes(&bssid[3], ETH_ALEN - 3); |
| 2837 | 2848 | ||
| 2838 | bssid[0] &= 0xfe; /* clear multicast bit */ | 2849 | bssid[0] &= 0xfe; /* clear multicast bit */ |
| 2839 | bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */ | 2850 | bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */ |
| 2840 | } | 2851 | } |
| 2841 | 2852 | ||
| 2842 | static inline u8 ipw_add_station(struct ipw_priv *priv, u8 *bssid) | 2853 | static inline u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid) |
| 2843 | { | 2854 | { |
| 2844 | struct ipw_station_entry entry; | 2855 | struct ipw_station_entry entry; |
| 2845 | int i; | 2856 | int i; |
| @@ -2866,14 +2877,13 @@ static inline u8 ipw_add_station(struct ipw_priv *priv, u8 *bssid) | |||
| 2866 | memcpy(entry.mac_addr, bssid, ETH_ALEN); | 2877 | memcpy(entry.mac_addr, bssid, ETH_ALEN); |
| 2867 | memcpy(priv->stations[i], bssid, ETH_ALEN); | 2878 | memcpy(priv->stations[i], bssid, ETH_ALEN); |
| 2868 | ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry), | 2879 | ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry), |
| 2869 | &entry, | 2880 | &entry, sizeof(entry)); |
| 2870 | sizeof(entry)); | ||
| 2871 | priv->num_stations++; | 2881 | priv->num_stations++; |
| 2872 | 2882 | ||
| 2873 | return i; | 2883 | return i; |
| 2874 | } | 2884 | } |
| 2875 | 2885 | ||
| 2876 | static inline u8 ipw_find_station(struct ipw_priv *priv, u8 *bssid) | 2886 | static inline u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid) |
| 2877 | { | 2887 | { |
| 2878 | int i; | 2888 | int i; |
| 2879 | 2889 | ||
| @@ -2944,26 +2954,34 @@ static const struct ipw_status_code ipw_status_codes[] = { | |||
| 2944 | "association exists"}, | 2954 | "association exists"}, |
| 2945 | {0x0C, "Association denied due to reason outside the scope of this " | 2955 | {0x0C, "Association denied due to reason outside the scope of this " |
| 2946 | "standard"}, | 2956 | "standard"}, |
| 2947 | {0x0D, "Responding station does not support the specified authentication " | 2957 | {0x0D, |
| 2958 | "Responding station does not support the specified authentication " | ||
| 2948 | "algorithm"}, | 2959 | "algorithm"}, |
| 2949 | {0x0E, "Received an Authentication frame with authentication sequence " | 2960 | {0x0E, |
| 2961 | "Received an Authentication frame with authentication sequence " | ||
| 2950 | "transaction sequence number out of expected sequence"}, | 2962 | "transaction sequence number out of expected sequence"}, |
| 2951 | {0x0F, "Authentication rejected because of challenge failure"}, | 2963 | {0x0F, "Authentication rejected because of challenge failure"}, |
| 2952 | {0x10, "Authentication rejected due to timeout waiting for next " | 2964 | {0x10, "Authentication rejected due to timeout waiting for next " |
| 2953 | "frame in sequence"}, | 2965 | "frame in sequence"}, |
| 2954 | {0x11, "Association denied because AP is unable to handle additional " | 2966 | {0x11, "Association denied because AP is unable to handle additional " |
| 2955 | "associated stations"}, | 2967 | "associated stations"}, |
| 2956 | {0x12, "Association denied due to requesting station not supporting all " | 2968 | {0x12, |
| 2969 | "Association denied due to requesting station not supporting all " | ||
| 2957 | "of the datarates in the BSSBasicServiceSet Parameter"}, | 2970 | "of the datarates in the BSSBasicServiceSet Parameter"}, |
| 2958 | {0x13, "Association denied due to requesting station not supporting " | 2971 | {0x13, |
| 2972 | "Association denied due to requesting station not supporting " | ||
| 2959 | "short preamble operation"}, | 2973 | "short preamble operation"}, |
| 2960 | {0x14, "Association denied due to requesting station not supporting " | 2974 | {0x14, |
| 2975 | "Association denied due to requesting station not supporting " | ||
| 2961 | "PBCC encoding"}, | 2976 | "PBCC encoding"}, |
| 2962 | {0x15, "Association denied due to requesting station not supporting " | 2977 | {0x15, |
| 2978 | "Association denied due to requesting station not supporting " | ||
| 2963 | "channel agility"}, | 2979 | "channel agility"}, |
| 2964 | {0x19, "Association denied due to requesting station not supporting " | 2980 | {0x19, |
| 2981 | "Association denied due to requesting station not supporting " | ||
| 2965 | "short slot operation"}, | 2982 | "short slot operation"}, |
| 2966 | {0x1A, "Association denied due to requesting station not supporting " | 2983 | {0x1A, |
| 2984 | "Association denied due to requesting station not supporting " | ||
| 2967 | "DSSS-OFDM operation"}, | 2985 | "DSSS-OFDM operation"}, |
| 2968 | {0x28, "Invalid Information Element"}, | 2986 | {0x28, "Invalid Information Element"}, |
| 2969 | {0x29, "Group Cipher is not valid"}, | 2987 | {0x29, "Group Cipher is not valid"}, |
| @@ -3043,7 +3061,6 @@ static void ipw_reset_stats(struct ipw_priv *priv) | |||
| 3043 | 3061 | ||
| 3044 | } | 3062 | } |
| 3045 | 3063 | ||
| 3046 | |||
| 3047 | static inline u32 ipw_get_max_rate(struct ipw_priv *priv) | 3064 | static inline u32 ipw_get_max_rate(struct ipw_priv *priv) |
| 3048 | { | 3065 | { |
| 3049 | u32 i = 0x80000000; | 3066 | u32 i = 0x80000000; |
| @@ -3056,20 +3073,21 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv) | |||
| 3056 | /* TODO: Verify that the rate is supported by the current rates | 3073 | /* TODO: Verify that the rate is supported by the current rates |
| 3057 | * list. */ | 3074 | * list. */ |
| 3058 | 3075 | ||
| 3059 | while (i && !(mask & i)) i >>= 1; | 3076 | while (i && !(mask & i)) |
| 3077 | i >>= 1; | ||
| 3060 | switch (i) { | 3078 | switch (i) { |
| 3061 | case IEEE80211_CCK_RATE_1MB_MASK: return 1000000; | 3079 | case IEEE80211_CCK_RATE_1MB_MASK: return 1000000; |
| 3062 | case IEEE80211_CCK_RATE_2MB_MASK: return 2000000; | 3080 | case IEEE80211_CCK_RATE_2MB_MASK: return 2000000; |
| 3063 | case IEEE80211_CCK_RATE_5MB_MASK: return 5500000; | 3081 | case IEEE80211_CCK_RATE_5MB_MASK: return 5500000; |
| 3064 | case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000; | 3082 | case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000; |
| 3065 | case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000; | 3083 | case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000; |
| 3066 | case IEEE80211_CCK_RATE_11MB_MASK: return 11000000; | 3084 | case IEEE80211_CCK_RATE_11MB_MASK: return 11000000; |
| 3067 | case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000; | 3085 | case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000; |
| 3068 | case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000; | 3086 | case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000; |
| 3069 | case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000; | 3087 | case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000; |
| 3070 | case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000; | 3088 | case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000; |
| 3071 | case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000; | 3089 | case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000; |
| 3072 | case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; | 3090 | case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; |
| 3073 | } | 3091 | } |
| 3074 | 3092 | ||
| 3075 | if (priv->ieee->mode == IEEE_B) | 3093 | if (priv->ieee->mode == IEEE_B) |
| @@ -3097,18 +3115,18 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv) | |||
| 3097 | return ipw_get_max_rate(priv); | 3115 | return ipw_get_max_rate(priv); |
| 3098 | 3116 | ||
| 3099 | switch (rate) { | 3117 | switch (rate) { |
| 3100 | case IPW_TX_RATE_1MB: return 1000000; | 3118 | case IPW_TX_RATE_1MB: return 1000000; |
| 3101 | case IPW_TX_RATE_2MB: return 2000000; | 3119 | case IPW_TX_RATE_2MB: return 2000000; |
| 3102 | case IPW_TX_RATE_5MB: return 5500000; | 3120 | case IPW_TX_RATE_5MB: return 5500000; |
| 3103 | case IPW_TX_RATE_6MB: return 6000000; | 3121 | case IPW_TX_RATE_6MB: return 6000000; |
| 3104 | case IPW_TX_RATE_9MB: return 9000000; | 3122 | case IPW_TX_RATE_9MB: return 9000000; |
| 3105 | case IPW_TX_RATE_11MB: return 11000000; | 3123 | case IPW_TX_RATE_11MB: return 11000000; |
| 3106 | case IPW_TX_RATE_12MB: return 12000000; | 3124 | case IPW_TX_RATE_12MB: return 12000000; |
| 3107 | case IPW_TX_RATE_18MB: return 18000000; | 3125 | case IPW_TX_RATE_18MB: return 18000000; |
| 3108 | case IPW_TX_RATE_24MB: return 24000000; | 3126 | case IPW_TX_RATE_24MB: return 24000000; |
| 3109 | case IPW_TX_RATE_36MB: return 36000000; | 3127 | case IPW_TX_RATE_36MB: return 36000000; |
| 3110 | case IPW_TX_RATE_48MB: return 48000000; | 3128 | case IPW_TX_RATE_48MB: return 48000000; |
| 3111 | case IPW_TX_RATE_54MB: return 54000000; | 3129 | case IPW_TX_RATE_54MB: return 54000000; |
| 3112 | } | 3130 | } |
| 3113 | 3131 | ||
| 3114 | return 0; | 3132 | return 0; |
| @@ -3126,7 +3144,7 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
| 3126 | u32 len = sizeof(u32); | 3144 | u32 len = sizeof(u32); |
| 3127 | s16 rssi; | 3145 | s16 rssi; |
| 3128 | u32 beacon_quality, signal_quality, tx_quality, rx_quality, | 3146 | u32 beacon_quality, signal_quality, tx_quality, rx_quality, |
| 3129 | rate_quality; | 3147 | rate_quality; |
| 3130 | 3148 | ||
| 3131 | if (!(priv->status & STATUS_ASSOCIATED)) { | 3149 | if (!(priv->status & STATUS_ASSOCIATED)) { |
| 3132 | priv->quality = 0; | 3150 | priv->quality = 0; |
| @@ -3136,13 +3154,12 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
| 3136 | /* Update the statistics */ | 3154 | /* Update the statistics */ |
| 3137 | ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS, | 3155 | ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS, |
| 3138 | &priv->missed_beacons, &len); | 3156 | &priv->missed_beacons, &len); |
| 3139 | missed_beacons_delta = priv->missed_beacons - | 3157 | missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons; |
| 3140 | priv->last_missed_beacons; | ||
| 3141 | priv->last_missed_beacons = priv->missed_beacons; | 3158 | priv->last_missed_beacons = priv->missed_beacons; |
| 3142 | if (priv->assoc_request.beacon_interval) { | 3159 | if (priv->assoc_request.beacon_interval) { |
| 3143 | missed_beacons_percent = missed_beacons_delta * | 3160 | missed_beacons_percent = missed_beacons_delta * |
| 3144 | (HZ * priv->assoc_request.beacon_interval) / | 3161 | (HZ * priv->assoc_request.beacon_interval) / |
| 3145 | (IPW_STATS_INTERVAL * 10); | 3162 | (IPW_STATS_INTERVAL * 10); |
| 3146 | } else { | 3163 | } else { |
| 3147 | missed_beacons_percent = 0; | 3164 | missed_beacons_percent = 0; |
| 3148 | } | 3165 | } |
| @@ -3179,28 +3196,26 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
| 3179 | beacon_quality = 0; | 3196 | beacon_quality = 0; |
| 3180 | else | 3197 | else |
| 3181 | beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 / | 3198 | beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 / |
| 3182 | (100 - BEACON_THRESHOLD); | 3199 | (100 - BEACON_THRESHOLD); |
| 3183 | IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n", | 3200 | IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n", |
| 3184 | beacon_quality, missed_beacons_percent); | 3201 | beacon_quality, missed_beacons_percent); |
| 3185 | 3202 | ||
| 3186 | priv->last_rate = ipw_get_current_rate(priv); | 3203 | priv->last_rate = ipw_get_current_rate(priv); |
| 3187 | rate_quality = priv->last_rate * 40 / priv->last_rate + 60; | 3204 | rate_quality = priv->last_rate * 40 / priv->last_rate + 60; |
| 3188 | IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", | 3205 | IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", |
| 3189 | rate_quality, priv->last_rate / 1000000); | 3206 | rate_quality, priv->last_rate / 1000000); |
| 3190 | 3207 | ||
| 3191 | if (rx_packets_delta > 100 && | 3208 | if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta) |
| 3192 | rx_packets_delta + rx_err_delta) | ||
| 3193 | rx_quality = 100 - (rx_err_delta * 100) / | 3209 | rx_quality = 100 - (rx_err_delta * 100) / |
| 3194 | (rx_packets_delta + rx_err_delta); | 3210 | (rx_packets_delta + rx_err_delta); |
| 3195 | else | 3211 | else |
| 3196 | rx_quality = 100; | 3212 | rx_quality = 100; |
| 3197 | IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n", | 3213 | IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n", |
| 3198 | rx_quality, rx_err_delta, rx_packets_delta); | 3214 | rx_quality, rx_err_delta, rx_packets_delta); |
| 3199 | 3215 | ||
| 3200 | if (tx_packets_delta > 100 && | 3216 | if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta) |
| 3201 | tx_packets_delta + tx_failures_delta) | ||
| 3202 | tx_quality = 100 - (tx_failures_delta * 100) / | 3217 | tx_quality = 100 - (tx_failures_delta * 100) / |
| 3203 | (tx_packets_delta + tx_failures_delta); | 3218 | (tx_packets_delta + tx_failures_delta); |
| 3204 | else | 3219 | else |
| 3205 | tx_quality = 100; | 3220 | tx_quality = 100; |
| 3206 | IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n", | 3221 | IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n", |
| @@ -3213,7 +3228,7 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
| 3213 | signal_quality = 0; | 3228 | signal_quality = 0; |
| 3214 | else | 3229 | else |
| 3215 | signal_quality = (rssi - WORST_RSSI) * 100 / | 3230 | signal_quality = (rssi - WORST_RSSI) * 100 / |
| 3216 | (PERFECT_RSSI - WORST_RSSI); | 3231 | (PERFECT_RSSI - WORST_RSSI); |
| 3217 | IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", | 3232 | IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", |
| 3218 | signal_quality, rssi); | 3233 | signal_quality, rssi); |
| 3219 | 3234 | ||
| @@ -3221,25 +3236,20 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
| 3221 | min(rate_quality, | 3236 | min(rate_quality, |
| 3222 | min(tx_quality, min(rx_quality, signal_quality)))); | 3237 | min(tx_quality, min(rx_quality, signal_quality)))); |
| 3223 | if (quality == beacon_quality) | 3238 | if (quality == beacon_quality) |
| 3224 | IPW_DEBUG_STATS( | 3239 | IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n", |
| 3225 | "Quality (%d%%): Clamped to missed beacons.\n", | 3240 | quality); |
| 3226 | quality); | ||
| 3227 | if (quality == rate_quality) | 3241 | if (quality == rate_quality) |
| 3228 | IPW_DEBUG_STATS( | 3242 | IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n", |
| 3229 | "Quality (%d%%): Clamped to rate quality.\n", | 3243 | quality); |
| 3230 | quality); | ||
| 3231 | if (quality == tx_quality) | 3244 | if (quality == tx_quality) |
| 3232 | IPW_DEBUG_STATS( | 3245 | IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n", |
| 3233 | "Quality (%d%%): Clamped to Tx quality.\n", | 3246 | quality); |
| 3234 | quality); | ||
| 3235 | if (quality == rx_quality) | 3247 | if (quality == rx_quality) |
| 3236 | IPW_DEBUG_STATS( | 3248 | IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n", |
| 3237 | "Quality (%d%%): Clamped to Rx quality.\n", | 3249 | quality); |
| 3238 | quality); | ||
| 3239 | if (quality == signal_quality) | 3250 | if (quality == signal_quality) |
| 3240 | IPW_DEBUG_STATS( | 3251 | IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n", |
| 3241 | "Quality (%d%%): Clamped to signal quality.\n", | 3252 | quality); |
| 3242 | quality); | ||
| 3243 | 3253 | ||
| 3244 | priv->quality = quality; | 3254 | priv->quality = quality; |
| 3245 | 3255 | ||
| @@ -3251,402 +3261,454 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
| 3251 | * Handle host notification packet. | 3261 | * Handle host notification packet. |
| 3252 | * Called from interrupt routine | 3262 | * Called from interrupt routine |
| 3253 | */ | 3263 | */ |
| 3254 | static inline void ipw_rx_notification(struct ipw_priv* priv, | 3264 | static inline void ipw_rx_notification(struct ipw_priv *priv, |
| 3255 | struct ipw_rx_notification *notif) | 3265 | struct ipw_rx_notification *notif) |
| 3256 | { | 3266 | { |
| 3257 | IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", | 3267 | IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); |
| 3258 | notif->subtype, notif->size); | ||
| 3259 | 3268 | ||
| 3260 | switch (notif->subtype) { | 3269 | switch (notif->subtype) { |
| 3261 | case HOST_NOTIFICATION_STATUS_ASSOCIATED: { | 3270 | case HOST_NOTIFICATION_STATUS_ASSOCIATED:{ |
| 3262 | struct notif_association *assoc = ¬if->u.assoc; | 3271 | struct notif_association *assoc = ¬if->u.assoc; |
| 3263 | 3272 | ||
| 3264 | switch (assoc->state) { | 3273 | switch (assoc->state) { |
| 3265 | case CMAS_ASSOCIATED: { | 3274 | case CMAS_ASSOCIATED:{ |
| 3266 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | 3275 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
| 3267 | "associated: '%s' " MAC_FMT " \n", | 3276 | IPW_DL_ASSOC, |
| 3268 | escape_essid(priv->essid, priv->essid_len), | 3277 | "associated: '%s' " MAC_FMT |
| 3269 | MAC_ARG(priv->bssid)); | 3278 | " \n", |
| 3270 | 3279 | escape_essid(priv->essid, | |
| 3271 | switch (priv->ieee->iw_mode) { | 3280 | priv->essid_len), |
| 3272 | case IW_MODE_INFRA: | 3281 | MAC_ARG(priv->bssid)); |
| 3273 | memcpy(priv->ieee->bssid, priv->bssid, | 3282 | |
| 3274 | ETH_ALEN); | 3283 | switch (priv->ieee->iw_mode) { |
| 3275 | break; | 3284 | case IW_MODE_INFRA: |
| 3276 | 3285 | memcpy(priv->ieee->bssid, | |
| 3277 | case IW_MODE_ADHOC: | 3286 | priv->bssid, ETH_ALEN); |
| 3278 | memcpy(priv->ieee->bssid, priv->bssid, | 3287 | break; |
| 3279 | ETH_ALEN); | 3288 | |
| 3280 | 3289 | case IW_MODE_ADHOC: | |
| 3281 | /* clear out the station table */ | 3290 | memcpy(priv->ieee->bssid, |
| 3282 | priv->num_stations = 0; | 3291 | priv->bssid, ETH_ALEN); |
| 3283 | 3292 | ||
| 3284 | IPW_DEBUG_ASSOC("queueing adhoc check\n"); | 3293 | /* clear out the station table */ |
| 3285 | queue_delayed_work(priv->workqueue, | 3294 | priv->num_stations = 0; |
| 3286 | &priv->adhoc_check, | 3295 | |
| 3287 | priv->assoc_request.beacon_interval); | 3296 | IPW_DEBUG_ASSOC |
| 3288 | break; | 3297 | ("queueing adhoc check\n"); |
| 3289 | } | 3298 | queue_delayed_work(priv-> |
| 3290 | 3299 | workqueue, | |
| 3291 | priv->status &= ~STATUS_ASSOCIATING; | 3300 | &priv-> |
| 3292 | priv->status |= STATUS_ASSOCIATED; | 3301 | adhoc_check, |
| 3293 | 3302 | priv-> | |
| 3294 | netif_carrier_on(priv->net_dev); | 3303 | assoc_request. |
| 3295 | if (netif_queue_stopped(priv->net_dev)) { | 3304 | beacon_interval); |
| 3296 | IPW_DEBUG_NOTIF("waking queue\n"); | 3305 | break; |
| 3297 | netif_wake_queue(priv->net_dev); | 3306 | } |
| 3298 | } else { | 3307 | |
| 3299 | IPW_DEBUG_NOTIF("starting queue\n"); | 3308 | priv->status &= ~STATUS_ASSOCIATING; |
| 3300 | netif_start_queue(priv->net_dev); | 3309 | priv->status |= STATUS_ASSOCIATED; |
| 3301 | } | 3310 | |
| 3302 | 3311 | netif_carrier_on(priv->net_dev); | |
| 3303 | ipw_reset_stats(priv); | 3312 | if (netif_queue_stopped(priv->net_dev)) { |
| 3304 | /* Ensure the rate is updated immediately */ | 3313 | IPW_DEBUG_NOTIF |
| 3305 | priv->last_rate = ipw_get_current_rate(priv); | 3314 | ("waking queue\n"); |
| 3306 | schedule_work(&priv->gather_stats); | 3315 | netif_wake_queue(priv->net_dev); |
| 3307 | notify_wx_assoc_event(priv); | 3316 | } else { |
| 3317 | IPW_DEBUG_NOTIF | ||
| 3318 | ("starting queue\n"); | ||
| 3319 | netif_start_queue(priv-> | ||
| 3320 | net_dev); | ||
| 3321 | } | ||
| 3322 | |||
| 3323 | ipw_reset_stats(priv); | ||
| 3324 | /* Ensure the rate is updated immediately */ | ||
| 3325 | priv->last_rate = | ||
| 3326 | ipw_get_current_rate(priv); | ||
| 3327 | schedule_work(&priv->gather_stats); | ||
| 3328 | notify_wx_assoc_event(priv); | ||
| 3308 | 3329 | ||
| 3309 | /* queue_delayed_work(priv->workqueue, | 3330 | /* queue_delayed_work(priv->workqueue, |
| 3310 | &priv->request_scan, | 3331 | &priv->request_scan, |
| 3311 | SCAN_ASSOCIATED_INTERVAL); | 3332 | SCAN_ASSOCIATED_INTERVAL); |
| 3312 | */ | 3333 | */ |
| 3313 | break; | 3334 | break; |
| 3314 | } | 3335 | } |
| 3315 | 3336 | ||
| 3316 | case CMAS_AUTHENTICATED: { | 3337 | case CMAS_AUTHENTICATED:{ |
| 3317 | if (priv->status & (STATUS_ASSOCIATED | STATUS_AUTH)) { | 3338 | if (priv-> |
| 3339 | status & (STATUS_ASSOCIATED | | ||
| 3340 | STATUS_AUTH)) { | ||
| 3318 | #ifdef CONFIG_IPW_DEBUG | 3341 | #ifdef CONFIG_IPW_DEBUG |
| 3319 | struct notif_authenticate *auth = ¬if->u.auth; | 3342 | struct notif_authenticate *auth |
| 3320 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | 3343 | = ¬if->u.auth; |
| 3321 | "deauthenticated: '%s' " MAC_FMT ": (0x%04X) - %s \n", | 3344 | IPW_DEBUG(IPW_DL_NOTIF | |
| 3322 | escape_essid(priv->essid, priv->essid_len), | 3345 | IPW_DL_STATE | |
| 3323 | MAC_ARG(priv->bssid), | 3346 | IPW_DL_ASSOC, |
| 3324 | ntohs(auth->status), | 3347 | "deauthenticated: '%s' " |
| 3325 | ipw_get_status_code(ntohs(auth->status))); | 3348 | MAC_FMT |
| 3349 | ": (0x%04X) - %s \n", | ||
| 3350 | escape_essid(priv-> | ||
| 3351 | essid, | ||
| 3352 | priv-> | ||
| 3353 | essid_len), | ||
| 3354 | MAC_ARG(priv->bssid), | ||
| 3355 | ntohs(auth->status), | ||
| 3356 | ipw_get_status_code | ||
| 3357 | (ntohs | ||
| 3358 | (auth->status))); | ||
| 3326 | #endif | 3359 | #endif |
| 3327 | 3360 | ||
| 3328 | priv->status &= ~(STATUS_ASSOCIATING | | 3361 | priv->status &= |
| 3329 | STATUS_AUTH | | 3362 | ~(STATUS_ASSOCIATING | |
| 3330 | STATUS_ASSOCIATED); | 3363 | STATUS_AUTH | |
| 3364 | STATUS_ASSOCIATED); | ||
| 3365 | |||
| 3366 | netif_carrier_off(priv-> | ||
| 3367 | net_dev); | ||
| 3368 | netif_stop_queue(priv->net_dev); | ||
| 3369 | queue_work(priv->workqueue, | ||
| 3370 | &priv->request_scan); | ||
| 3371 | notify_wx_assoc_event(priv); | ||
| 3372 | break; | ||
| 3373 | } | ||
| 3374 | |||
| 3375 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3376 | IPW_DL_ASSOC, | ||
| 3377 | "authenticated: '%s' " MAC_FMT | ||
| 3378 | "\n", | ||
| 3379 | escape_essid(priv->essid, | ||
| 3380 | priv->essid_len), | ||
| 3381 | MAC_ARG(priv->bssid)); | ||
| 3382 | break; | ||
| 3383 | } | ||
| 3384 | |||
| 3385 | case CMAS_INIT:{ | ||
| 3386 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3387 | IPW_DL_ASSOC, | ||
| 3388 | "disassociated: '%s' " MAC_FMT | ||
| 3389 | " \n", | ||
| 3390 | escape_essid(priv->essid, | ||
| 3391 | priv->essid_len), | ||
| 3392 | MAC_ARG(priv->bssid)); | ||
| 3393 | |||
| 3394 | priv->status &= | ||
| 3395 | ~(STATUS_DISASSOCIATING | | ||
| 3396 | STATUS_ASSOCIATING | | ||
| 3397 | STATUS_ASSOCIATED | STATUS_AUTH); | ||
| 3398 | |||
| 3399 | netif_stop_queue(priv->net_dev); | ||
| 3400 | if (!(priv->status & STATUS_ROAMING)) { | ||
| 3401 | netif_carrier_off(priv-> | ||
| 3402 | net_dev); | ||
| 3403 | notify_wx_assoc_event(priv); | ||
| 3404 | |||
| 3405 | /* Cancel any queued work ... */ | ||
| 3406 | cancel_delayed_work(&priv-> | ||
| 3407 | request_scan); | ||
| 3408 | cancel_delayed_work(&priv-> | ||
| 3409 | adhoc_check); | ||
| 3410 | |||
| 3411 | /* Queue up another scan... */ | ||
| 3412 | queue_work(priv->workqueue, | ||
| 3413 | &priv->request_scan); | ||
| 3414 | |||
| 3415 | cancel_delayed_work(&priv-> | ||
| 3416 | gather_stats); | ||
| 3417 | } else { | ||
| 3418 | priv->status |= STATUS_ROAMING; | ||
| 3419 | queue_work(priv->workqueue, | ||
| 3420 | &priv->request_scan); | ||
| 3421 | } | ||
| 3422 | |||
| 3423 | ipw_reset_stats(priv); | ||
| 3424 | break; | ||
| 3425 | } | ||
| 3331 | 3426 | ||
| 3332 | netif_carrier_off(priv->net_dev); | 3427 | default: |
| 3333 | netif_stop_queue(priv->net_dev); | 3428 | IPW_ERROR("assoc: unknown (%d)\n", |
| 3334 | queue_work(priv->workqueue, &priv->request_scan); | 3429 | assoc->state); |
| 3335 | notify_wx_assoc_event(priv); | ||
| 3336 | break; | 3430 | break; |
| 3337 | } | 3431 | } |
| 3338 | 3432 | ||
| 3339 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3340 | "authenticated: '%s' " MAC_FMT "\n", | ||
| 3341 | escape_essid(priv->essid, priv->essid_len), | ||
| 3342 | MAC_ARG(priv->bssid)); | ||
| 3343 | break; | 3433 | break; |
| 3344 | } | 3434 | } |
| 3345 | 3435 | ||
| 3346 | case CMAS_INIT: { | 3436 | case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{ |
| 3347 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | 3437 | struct notif_authenticate *auth = ¬if->u.auth; |
| 3348 | "disassociated: '%s' " MAC_FMT " \n", | 3438 | switch (auth->state) { |
| 3349 | escape_essid(priv->essid, priv->essid_len), | 3439 | case CMAS_AUTHENTICATED: |
| 3350 | MAC_ARG(priv->bssid)); | 3440 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, |
| 3441 | "authenticated: '%s' " MAC_FMT " \n", | ||
| 3442 | escape_essid(priv->essid, | ||
| 3443 | priv->essid_len), | ||
| 3444 | MAC_ARG(priv->bssid)); | ||
| 3445 | priv->status |= STATUS_AUTH; | ||
| 3446 | break; | ||
| 3351 | 3447 | ||
| 3352 | priv->status &= ~( | 3448 | case CMAS_INIT: |
| 3353 | STATUS_DISASSOCIATING | | 3449 | if (priv->status & STATUS_AUTH) { |
| 3354 | STATUS_ASSOCIATING | | 3450 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
| 3355 | STATUS_ASSOCIATED | | 3451 | IPW_DL_ASSOC, |
| 3356 | STATUS_AUTH); | 3452 | "authentication failed (0x%04X): %s\n", |
| 3453 | ntohs(auth->status), | ||
| 3454 | ipw_get_status_code(ntohs | ||
| 3455 | (auth-> | ||
| 3456 | status))); | ||
| 3457 | } | ||
| 3458 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3459 | IPW_DL_ASSOC, | ||
| 3460 | "deauthenticated: '%s' " MAC_FMT "\n", | ||
| 3461 | escape_essid(priv->essid, | ||
| 3462 | priv->essid_len), | ||
| 3463 | MAC_ARG(priv->bssid)); | ||
| 3357 | 3464 | ||
| 3358 | netif_stop_queue(priv->net_dev); | 3465 | priv->status &= ~(STATUS_ASSOCIATING | |
| 3359 | if (!(priv->status & STATUS_ROAMING)) { | 3466 | STATUS_AUTH | |
| 3360 | netif_carrier_off(priv->net_dev); | 3467 | STATUS_ASSOCIATED); |
| 3361 | notify_wx_assoc_event(priv); | ||
| 3362 | |||
| 3363 | /* Cancel any queued work ... */ | ||
| 3364 | cancel_delayed_work(&priv->request_scan); | ||
| 3365 | cancel_delayed_work(&priv->adhoc_check); | ||
| 3366 | 3468 | ||
| 3367 | /* Queue up another scan... */ | 3469 | netif_carrier_off(priv->net_dev); |
| 3470 | netif_stop_queue(priv->net_dev); | ||
| 3368 | queue_work(priv->workqueue, | 3471 | queue_work(priv->workqueue, |
| 3369 | &priv->request_scan); | 3472 | &priv->request_scan); |
| 3473 | notify_wx_assoc_event(priv); | ||
| 3474 | break; | ||
| 3370 | 3475 | ||
| 3371 | cancel_delayed_work(&priv->gather_stats); | 3476 | case CMAS_TX_AUTH_SEQ_1: |
| 3372 | } else { | 3477 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
| 3373 | priv->status |= STATUS_ROAMING; | 3478 | IPW_DL_ASSOC, "AUTH_SEQ_1\n"); |
| 3374 | queue_work(priv->workqueue, | 3479 | break; |
| 3375 | &priv->request_scan); | 3480 | case CMAS_RX_AUTH_SEQ_2: |
| 3481 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3482 | IPW_DL_ASSOC, "AUTH_SEQ_2\n"); | ||
| 3483 | break; | ||
| 3484 | case CMAS_AUTH_SEQ_1_PASS: | ||
| 3485 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3486 | IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n"); | ||
| 3487 | break; | ||
| 3488 | case CMAS_AUTH_SEQ_1_FAIL: | ||
| 3489 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3490 | IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n"); | ||
| 3491 | break; | ||
| 3492 | case CMAS_TX_AUTH_SEQ_3: | ||
| 3493 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3494 | IPW_DL_ASSOC, "AUTH_SEQ_3\n"); | ||
| 3495 | break; | ||
| 3496 | case CMAS_RX_AUTH_SEQ_4: | ||
| 3497 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3498 | IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n"); | ||
| 3499 | break; | ||
| 3500 | case CMAS_AUTH_SEQ_2_PASS: | ||
| 3501 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3502 | IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n"); | ||
| 3503 | break; | ||
| 3504 | case CMAS_AUTH_SEQ_2_FAIL: | ||
| 3505 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3506 | IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n"); | ||
| 3507 | break; | ||
| 3508 | case CMAS_TX_ASSOC: | ||
| 3509 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3510 | IPW_DL_ASSOC, "TX_ASSOC\n"); | ||
| 3511 | break; | ||
| 3512 | case CMAS_RX_ASSOC_RESP: | ||
| 3513 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3514 | IPW_DL_ASSOC, "RX_ASSOC_RESP\n"); | ||
| 3515 | break; | ||
| 3516 | case CMAS_ASSOCIATED: | ||
| 3517 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | ||
| 3518 | IPW_DL_ASSOC, "ASSOCIATED\n"); | ||
| 3519 | break; | ||
| 3520 | default: | ||
| 3521 | IPW_DEBUG_NOTIF("auth: failure - %d\n", | ||
| 3522 | auth->state); | ||
| 3523 | break; | ||
| 3376 | } | 3524 | } |
| 3377 | |||
| 3378 | ipw_reset_stats(priv); | ||
| 3379 | break; | ||
| 3380 | } | ||
| 3381 | |||
| 3382 | default: | ||
| 3383 | IPW_ERROR("assoc: unknown (%d)\n", | ||
| 3384 | assoc->state); | ||
| 3385 | break; | 3525 | break; |
| 3386 | } | 3526 | } |
| 3387 | 3527 | ||
| 3388 | break; | 3528 | case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{ |
| 3389 | } | 3529 | struct notif_channel_result *x = |
| 3530 | ¬if->u.channel_result; | ||
| 3390 | 3531 | ||
| 3391 | case HOST_NOTIFICATION_STATUS_AUTHENTICATE: { | 3532 | if (notif->size == sizeof(*x)) { |
| 3392 | struct notif_authenticate *auth = ¬if->u.auth; | 3533 | IPW_DEBUG_SCAN("Scan result for channel %d\n", |
| 3393 | switch (auth->state) { | 3534 | x->channel_num); |
| 3394 | case CMAS_AUTHENTICATED: | 3535 | } else { |
| 3395 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, | 3536 | IPW_DEBUG_SCAN("Scan result of wrong size %d " |
| 3396 | "authenticated: '%s' " MAC_FMT " \n", | 3537 | "(should be %zd)\n", |
| 3397 | escape_essid(priv->essid, priv->essid_len), | 3538 | notif->size, sizeof(*x)); |
| 3398 | MAC_ARG(priv->bssid)); | ||
| 3399 | priv->status |= STATUS_AUTH; | ||
| 3400 | break; | ||
| 3401 | |||
| 3402 | case CMAS_INIT: | ||
| 3403 | if (priv->status & STATUS_AUTH) { | ||
| 3404 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3405 | "authentication failed (0x%04X): %s\n", | ||
| 3406 | ntohs(auth->status), | ||
| 3407 | ipw_get_status_code(ntohs(auth->status))); | ||
| 3408 | } | 3539 | } |
| 3409 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3410 | "deauthenticated: '%s' " MAC_FMT "\n", | ||
| 3411 | escape_essid(priv->essid, priv->essid_len), | ||
| 3412 | MAC_ARG(priv->bssid)); | ||
| 3413 | |||
| 3414 | priv->status &= ~(STATUS_ASSOCIATING | | ||
| 3415 | STATUS_AUTH | | ||
| 3416 | STATUS_ASSOCIATED); | ||
| 3417 | |||
| 3418 | netif_carrier_off(priv->net_dev); | ||
| 3419 | netif_stop_queue(priv->net_dev); | ||
| 3420 | queue_work(priv->workqueue, &priv->request_scan); | ||
| 3421 | notify_wx_assoc_event(priv); | ||
| 3422 | break; | ||
| 3423 | |||
| 3424 | case CMAS_TX_AUTH_SEQ_1: | ||
| 3425 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3426 | "AUTH_SEQ_1\n"); | ||
| 3427 | break; | ||
| 3428 | case CMAS_RX_AUTH_SEQ_2: | ||
| 3429 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3430 | "AUTH_SEQ_2\n"); | ||
| 3431 | break; | ||
| 3432 | case CMAS_AUTH_SEQ_1_PASS: | ||
| 3433 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3434 | "AUTH_SEQ_1_PASS\n"); | ||
| 3435 | break; | ||
| 3436 | case CMAS_AUTH_SEQ_1_FAIL: | ||
| 3437 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3438 | "AUTH_SEQ_1_FAIL\n"); | ||
| 3439 | break; | ||
| 3440 | case CMAS_TX_AUTH_SEQ_3: | ||
| 3441 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3442 | "AUTH_SEQ_3\n"); | ||
| 3443 | break; | ||
| 3444 | case CMAS_RX_AUTH_SEQ_4: | ||
| 3445 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3446 | "RX_AUTH_SEQ_4\n"); | ||
| 3447 | break; | ||
| 3448 | case CMAS_AUTH_SEQ_2_PASS: | ||
| 3449 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3450 | "AUTH_SEQ_2_PASS\n"); | ||
| 3451 | break; | ||
| 3452 | case CMAS_AUTH_SEQ_2_FAIL: | ||
| 3453 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3454 | "AUT_SEQ_2_FAIL\n"); | ||
| 3455 | break; | ||
| 3456 | case CMAS_TX_ASSOC: | ||
| 3457 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3458 | "TX_ASSOC\n"); | ||
| 3459 | break; | ||
| 3460 | case CMAS_RX_ASSOC_RESP: | ||
| 3461 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3462 | "RX_ASSOC_RESP\n"); | ||
| 3463 | break; | ||
| 3464 | case CMAS_ASSOCIATED: | ||
| 3465 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | ||
| 3466 | "ASSOCIATED\n"); | ||
| 3467 | break; | ||
| 3468 | default: | ||
| 3469 | IPW_DEBUG_NOTIF("auth: failure - %d\n", auth->state); | ||
| 3470 | break; | 3540 | break; |
| 3471 | } | 3541 | } |
| 3472 | break; | ||
| 3473 | } | ||
| 3474 | |||
| 3475 | case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT: { | ||
| 3476 | struct notif_channel_result *x = ¬if->u.channel_result; | ||
| 3477 | |||
| 3478 | if (notif->size == sizeof(*x)) { | ||
| 3479 | IPW_DEBUG_SCAN("Scan result for channel %d\n", | ||
| 3480 | x->channel_num); | ||
| 3481 | } else { | ||
| 3482 | IPW_DEBUG_SCAN("Scan result of wrong size %d " | ||
| 3483 | "(should be %zd)\n", | ||
| 3484 | notif->size, sizeof(*x)); | ||
| 3485 | } | ||
| 3486 | break; | ||
| 3487 | } | ||
| 3488 | 3542 | ||
| 3489 | case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED: { | 3543 | case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{ |
| 3490 | struct notif_scan_complete* x = ¬if->u.scan_complete; | 3544 | struct notif_scan_complete *x = ¬if->u.scan_complete; |
| 3491 | if (notif->size == sizeof(*x)) { | 3545 | if (notif->size == sizeof(*x)) { |
| 3492 | IPW_DEBUG_SCAN("Scan completed: type %d, %d channels, " | 3546 | IPW_DEBUG_SCAN |
| 3493 | "%d status\n", | 3547 | ("Scan completed: type %d, %d channels, " |
| 3494 | x->scan_type, | 3548 | "%d status\n", x->scan_type, |
| 3495 | x->num_channels, | 3549 | x->num_channels, x->status); |
| 3496 | x->status); | 3550 | } else { |
| 3497 | } else { | 3551 | IPW_ERROR("Scan completed of wrong size %d " |
| 3498 | IPW_ERROR("Scan completed of wrong size %d " | 3552 | "(should be %zd)\n", |
| 3499 | "(should be %zd)\n", | 3553 | notif->size, sizeof(*x)); |
| 3500 | notif->size, sizeof(*x)); | 3554 | } |
| 3501 | } | ||
| 3502 | |||
| 3503 | priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING); | ||
| 3504 | |||
| 3505 | cancel_delayed_work(&priv->scan_check); | ||
| 3506 | |||
| 3507 | if (!(priv->status & (STATUS_ASSOCIATED | | ||
| 3508 | STATUS_ASSOCIATING | | ||
| 3509 | STATUS_ROAMING | | ||
| 3510 | STATUS_DISASSOCIATING))) | ||
| 3511 | queue_work(priv->workqueue, &priv->associate); | ||
| 3512 | else if (priv->status & STATUS_ROAMING) { | ||
| 3513 | /* If a scan completed and we are in roam mode, then | ||
| 3514 | * the scan that completed was the one requested as a | ||
| 3515 | * result of entering roam... so, schedule the | ||
| 3516 | * roam work */ | ||
| 3517 | queue_work(priv->workqueue, &priv->roam); | ||
| 3518 | } else if (priv->status & STATUS_SCAN_PENDING) | ||
| 3519 | queue_work(priv->workqueue, &priv->request_scan); | ||
| 3520 | |||
| 3521 | priv->ieee->scans++; | ||
| 3522 | break; | ||
| 3523 | } | ||
| 3524 | 3555 | ||
| 3525 | case HOST_NOTIFICATION_STATUS_FRAG_LENGTH: { | 3556 | priv->status &= |
| 3526 | struct notif_frag_length *x = ¬if->u.frag_len; | 3557 | ~(STATUS_SCANNING | STATUS_SCAN_ABORTING); |
| 3558 | |||
| 3559 | cancel_delayed_work(&priv->scan_check); | ||
| 3560 | |||
| 3561 | if (!(priv->status & (STATUS_ASSOCIATED | | ||
| 3562 | STATUS_ASSOCIATING | | ||
| 3563 | STATUS_ROAMING | | ||
| 3564 | STATUS_DISASSOCIATING))) | ||
| 3565 | queue_work(priv->workqueue, &priv->associate); | ||
| 3566 | else if (priv->status & STATUS_ROAMING) { | ||
| 3567 | /* If a scan completed and we are in roam mode, then | ||
| 3568 | * the scan that completed was the one requested as a | ||
| 3569 | * result of entering roam... so, schedule the | ||
| 3570 | * roam work */ | ||
| 3571 | queue_work(priv->workqueue, &priv->roam); | ||
| 3572 | } else if (priv->status & STATUS_SCAN_PENDING) | ||
| 3573 | queue_work(priv->workqueue, | ||
| 3574 | &priv->request_scan); | ||
| 3527 | 3575 | ||
| 3528 | if (notif->size == sizeof(*x)) { | 3576 | priv->ieee->scans++; |
| 3529 | IPW_ERROR("Frag length: %d\n", x->frag_length); | 3577 | break; |
| 3530 | } else { | ||
| 3531 | IPW_ERROR("Frag length of wrong size %d " | ||
| 3532 | "(should be %zd)\n", | ||
| 3533 | notif->size, sizeof(*x)); | ||
| 3534 | } | 3578 | } |
| 3535 | break; | ||
| 3536 | } | ||
| 3537 | 3579 | ||
| 3538 | case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION: { | 3580 | case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{ |
| 3539 | struct notif_link_deterioration *x = | 3581 | struct notif_frag_length *x = ¬if->u.frag_len; |
| 3540 | ¬if->u.link_deterioration; | ||
| 3541 | if (notif->size==sizeof(*x)) { | ||
| 3542 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, | ||
| 3543 | "link deterioration: '%s' " MAC_FMT " \n", | ||
| 3544 | escape_essid(priv->essid, priv->essid_len), | ||
| 3545 | MAC_ARG(priv->bssid)); | ||
| 3546 | memcpy(&priv->last_link_deterioration, x, sizeof(*x)); | ||
| 3547 | } else { | ||
| 3548 | IPW_ERROR("Link Deterioration of wrong size %d " | ||
| 3549 | "(should be %zd)\n", | ||
| 3550 | notif->size, sizeof(*x)); | ||
| 3551 | } | ||
| 3552 | break; | ||
| 3553 | } | ||
| 3554 | 3582 | ||
| 3555 | case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE: { | 3583 | if (notif->size == sizeof(*x)) { |
| 3556 | IPW_ERROR("Dino config\n"); | 3584 | IPW_ERROR("Frag length: %d\n", x->frag_length); |
| 3557 | if (priv->hcmd && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) { | 3585 | } else { |
| 3558 | /* TODO: Do anything special? */ | 3586 | IPW_ERROR("Frag length of wrong size %d " |
| 3559 | } else { | 3587 | "(should be %zd)\n", |
| 3560 | IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n"); | 3588 | notif->size, sizeof(*x)); |
| 3589 | } | ||
| 3590 | break; | ||
| 3561 | } | 3591 | } |
| 3562 | break; | ||
| 3563 | } | ||
| 3564 | 3592 | ||
| 3565 | case HOST_NOTIFICATION_STATUS_BEACON_STATE: { | 3593 | case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{ |
| 3566 | struct notif_beacon_state *x = ¬if->u.beacon_state; | 3594 | struct notif_link_deterioration *x = |
| 3567 | if (notif->size != sizeof(*x)) { | 3595 | ¬if->u.link_deterioration; |
| 3568 | IPW_ERROR("Beacon state of wrong size %d (should " | 3596 | if (notif->size == sizeof(*x)) { |
| 3569 | "be %zd)\n", notif->size, sizeof(*x)); | 3597 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, |
| 3598 | "link deterioration: '%s' " MAC_FMT | ||
| 3599 | " \n", escape_essid(priv->essid, | ||
| 3600 | priv->essid_len), | ||
| 3601 | MAC_ARG(priv->bssid)); | ||
| 3602 | memcpy(&priv->last_link_deterioration, x, | ||
| 3603 | sizeof(*x)); | ||
| 3604 | } else { | ||
| 3605 | IPW_ERROR("Link Deterioration of wrong size %d " | ||
| 3606 | "(should be %zd)\n", | ||
| 3607 | notif->size, sizeof(*x)); | ||
| 3608 | } | ||
| 3570 | break; | 3609 | break; |
| 3571 | } | 3610 | } |
| 3572 | 3611 | ||
| 3573 | if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) { | 3612 | case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{ |
| 3574 | if (priv->status & STATUS_SCANNING) { | 3613 | IPW_ERROR("Dino config\n"); |
| 3575 | /* Stop scan to keep fw from getting | 3614 | if (priv->hcmd |
| 3576 | * stuck... */ | 3615 | && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) { |
| 3577 | queue_work(priv->workqueue, | 3616 | /* TODO: Do anything special? */ |
| 3578 | &priv->abort_scan); | 3617 | } else { |
| 3618 | IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n"); | ||
| 3579 | } | 3619 | } |
| 3620 | break; | ||
| 3621 | } | ||
| 3580 | 3622 | ||
| 3581 | if (x->number > priv->missed_beacon_threshold && | 3623 | case HOST_NOTIFICATION_STATUS_BEACON_STATE:{ |
| 3582 | priv->status & STATUS_ASSOCIATED) { | 3624 | struct notif_beacon_state *x = ¬if->u.beacon_state; |
| 3583 | IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | | 3625 | if (notif->size != sizeof(*x)) { |
| 3584 | IPW_DL_STATE, | 3626 | IPW_ERROR |
| 3585 | "Missed beacon: %d - disassociate\n", | 3627 | ("Beacon state of wrong size %d (should " |
| 3586 | x->number); | 3628 | "be %zd)\n", notif->size, sizeof(*x)); |
| 3587 | queue_work(priv->workqueue, | 3629 | break; |
| 3588 | &priv->disassociate); | ||
| 3589 | } else if (x->number > priv->roaming_threshold) { | ||
| 3590 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, | ||
| 3591 | "Missed beacon: %d - initiate " | ||
| 3592 | "roaming\n", | ||
| 3593 | x->number); | ||
| 3594 | queue_work(priv->workqueue, | ||
| 3595 | &priv->roam); | ||
| 3596 | } else { | ||
| 3597 | IPW_DEBUG_NOTIF("Missed beacon: %d\n", | ||
| 3598 | x->number); | ||
| 3599 | } | 3630 | } |
| 3600 | 3631 | ||
| 3601 | priv->notif_missed_beacons = x->number; | 3632 | if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) { |
| 3633 | if (priv->status & STATUS_SCANNING) { | ||
| 3634 | /* Stop scan to keep fw from getting | ||
| 3635 | * stuck... */ | ||
| 3636 | queue_work(priv->workqueue, | ||
| 3637 | &priv->abort_scan); | ||
| 3638 | } | ||
| 3639 | |||
| 3640 | if (x->number > priv->missed_beacon_threshold && | ||
| 3641 | priv->status & STATUS_ASSOCIATED) { | ||
| 3642 | IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | | ||
| 3643 | IPW_DL_STATE, | ||
| 3644 | "Missed beacon: %d - disassociate\n", | ||
| 3645 | x->number); | ||
| 3646 | queue_work(priv->workqueue, | ||
| 3647 | &priv->disassociate); | ||
| 3648 | } else if (x->number > priv->roaming_threshold) { | ||
| 3649 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, | ||
| 3650 | "Missed beacon: %d - initiate " | ||
| 3651 | "roaming\n", x->number); | ||
| 3652 | queue_work(priv->workqueue, | ||
| 3653 | &priv->roam); | ||
| 3654 | } else { | ||
| 3655 | IPW_DEBUG_NOTIF("Missed beacon: %d\n", | ||
| 3656 | x->number); | ||
| 3657 | } | ||
| 3658 | |||
| 3659 | priv->notif_missed_beacons = x->number; | ||
| 3602 | 3660 | ||
| 3603 | } | 3661 | } |
| 3604 | 3662 | ||
| 3663 | break; | ||
| 3664 | } | ||
| 3605 | 3665 | ||
| 3606 | break; | 3666 | case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{ |
| 3607 | } | 3667 | struct notif_tgi_tx_key *x = ¬if->u.tgi_tx_key; |
| 3668 | if (notif->size == sizeof(*x)) { | ||
| 3669 | IPW_ERROR("TGi Tx Key: state 0x%02x sec type " | ||
| 3670 | "0x%02x station %d\n", | ||
| 3671 | x->key_state, x->security_type, | ||
| 3672 | x->station_index); | ||
| 3673 | break; | ||
| 3674 | } | ||
| 3608 | 3675 | ||
| 3609 | case HOST_NOTIFICATION_STATUS_TGI_TX_KEY: { | 3676 | IPW_ERROR |
| 3610 | struct notif_tgi_tx_key *x = ¬if->u.tgi_tx_key; | 3677 | ("TGi Tx Key of wrong size %d (should be %zd)\n", |
| 3611 | if (notif->size==sizeof(*x)) { | 3678 | notif->size, sizeof(*x)); |
| 3612 | IPW_ERROR("TGi Tx Key: state 0x%02x sec type " | ||
| 3613 | "0x%02x station %d\n", | ||
| 3614 | x->key_state,x->security_type, | ||
| 3615 | x->station_index); | ||
| 3616 | break; | 3679 | break; |
| 3617 | } | 3680 | } |
| 3618 | 3681 | ||
| 3619 | IPW_ERROR("TGi Tx Key of wrong size %d (should be %zd)\n", | 3682 | case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{ |
| 3620 | notif->size, sizeof(*x)); | 3683 | struct notif_calibration *x = ¬if->u.calibration; |
| 3621 | break; | ||
| 3622 | } | ||
| 3623 | 3684 | ||
| 3624 | case HOST_NOTIFICATION_CALIB_KEEP_RESULTS: { | 3685 | if (notif->size == sizeof(*x)) { |
| 3625 | struct notif_calibration *x = ¬if->u.calibration; | 3686 | memcpy(&priv->calib, x, sizeof(*x)); |
| 3687 | IPW_DEBUG_INFO("TODO: Calibration\n"); | ||
| 3688 | break; | ||
| 3689 | } | ||
| 3626 | 3690 | ||
| 3627 | if (notif->size == sizeof(*x)) { | 3691 | IPW_ERROR |
| 3628 | memcpy(&priv->calib, x, sizeof(*x)); | 3692 | ("Calibration of wrong size %d (should be %zd)\n", |
| 3629 | IPW_DEBUG_INFO("TODO: Calibration\n"); | 3693 | notif->size, sizeof(*x)); |
| 3630 | break; | 3694 | break; |
| 3631 | } | 3695 | } |
| 3632 | 3696 | ||
| 3633 | IPW_ERROR("Calibration of wrong size %d (should be %zd)\n", | 3697 | case HOST_NOTIFICATION_NOISE_STATS:{ |
| 3634 | notif->size, sizeof(*x)); | 3698 | if (notif->size == sizeof(u32)) { |
| 3635 | break; | 3699 | priv->last_noise = |
| 3636 | } | 3700 | (u8) (notif->u.noise.value & 0xff); |
| 3701 | average_add(&priv->average_noise, | ||
| 3702 | priv->last_noise); | ||
| 3703 | break; | ||
| 3704 | } | ||
| 3637 | 3705 | ||
| 3638 | case HOST_NOTIFICATION_NOISE_STATS: { | 3706 | IPW_ERROR |
| 3639 | if (notif->size == sizeof(u32)) { | 3707 | ("Noise stat is wrong size %d (should be %zd)\n", |
| 3640 | priv->last_noise = (u8)(notif->u.noise.value & 0xff); | 3708 | notif->size, sizeof(u32)); |
| 3641 | average_add(&priv->average_noise, priv->last_noise); | ||
| 3642 | break; | 3709 | break; |
| 3643 | } | 3710 | } |
| 3644 | 3711 | ||
| 3645 | IPW_ERROR("Noise stat is wrong size %d (should be %zd)\n", | ||
| 3646 | notif->size, sizeof(u32)); | ||
| 3647 | break; | ||
| 3648 | } | ||
| 3649 | |||
| 3650 | default: | 3712 | default: |
| 3651 | IPW_ERROR("Unknown notification: " | 3713 | IPW_ERROR("Unknown notification: " |
| 3652 | "subtype=%d,flags=0x%2x,size=%d\n", | 3714 | "subtype=%d,flags=0x%2x,size=%d\n", |
| @@ -3680,8 +3742,7 @@ static int ipw_queue_reset(struct ipw_priv *priv) | |||
| 3680 | rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx, | 3742 | rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx, |
| 3681 | CX2_TX_QUEUE_0_READ_INDEX, | 3743 | CX2_TX_QUEUE_0_READ_INDEX, |
| 3682 | CX2_TX_QUEUE_0_WRITE_INDEX, | 3744 | CX2_TX_QUEUE_0_WRITE_INDEX, |
| 3683 | CX2_TX_QUEUE_0_BD_BASE, | 3745 | CX2_TX_QUEUE_0_BD_BASE, CX2_TX_QUEUE_0_BD_SIZE); |
| 3684 | CX2_TX_QUEUE_0_BD_SIZE); | ||
| 3685 | if (rc) { | 3746 | if (rc) { |
| 3686 | IPW_ERROR("Tx 0 queue init failed\n"); | 3747 | IPW_ERROR("Tx 0 queue init failed\n"); |
| 3687 | goto error; | 3748 | goto error; |
| @@ -3689,8 +3750,7 @@ static int ipw_queue_reset(struct ipw_priv *priv) | |||
| 3689 | rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx, | 3750 | rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx, |
| 3690 | CX2_TX_QUEUE_1_READ_INDEX, | 3751 | CX2_TX_QUEUE_1_READ_INDEX, |
| 3691 | CX2_TX_QUEUE_1_WRITE_INDEX, | 3752 | CX2_TX_QUEUE_1_WRITE_INDEX, |
| 3692 | CX2_TX_QUEUE_1_BD_BASE, | 3753 | CX2_TX_QUEUE_1_BD_BASE, CX2_TX_QUEUE_1_BD_SIZE); |
| 3693 | CX2_TX_QUEUE_1_BD_SIZE); | ||
| 3694 | if (rc) { | 3754 | if (rc) { |
| 3695 | IPW_ERROR("Tx 1 queue init failed\n"); | 3755 | IPW_ERROR("Tx 1 queue init failed\n"); |
| 3696 | goto error; | 3756 | goto error; |
| @@ -3698,8 +3758,7 @@ static int ipw_queue_reset(struct ipw_priv *priv) | |||
| 3698 | rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx, | 3758 | rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx, |
| 3699 | CX2_TX_QUEUE_2_READ_INDEX, | 3759 | CX2_TX_QUEUE_2_READ_INDEX, |
| 3700 | CX2_TX_QUEUE_2_WRITE_INDEX, | 3760 | CX2_TX_QUEUE_2_WRITE_INDEX, |
| 3701 | CX2_TX_QUEUE_2_BD_BASE, | 3761 | CX2_TX_QUEUE_2_BD_BASE, CX2_TX_QUEUE_2_BD_SIZE); |
| 3702 | CX2_TX_QUEUE_2_BD_SIZE); | ||
| 3703 | if (rc) { | 3762 | if (rc) { |
| 3704 | IPW_ERROR("Tx 2 queue init failed\n"); | 3763 | IPW_ERROR("Tx 2 queue init failed\n"); |
| 3705 | goto error; | 3764 | goto error; |
| @@ -3707,8 +3766,7 @@ static int ipw_queue_reset(struct ipw_priv *priv) | |||
| 3707 | rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx, | 3766 | rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx, |
| 3708 | CX2_TX_QUEUE_3_READ_INDEX, | 3767 | CX2_TX_QUEUE_3_READ_INDEX, |
| 3709 | CX2_TX_QUEUE_3_WRITE_INDEX, | 3768 | CX2_TX_QUEUE_3_WRITE_INDEX, |
| 3710 | CX2_TX_QUEUE_3_BD_BASE, | 3769 | CX2_TX_QUEUE_3_BD_BASE, CX2_TX_QUEUE_3_BD_SIZE); |
| 3711 | CX2_TX_QUEUE_3_BD_SIZE); | ||
| 3712 | if (rc) { | 3770 | if (rc) { |
| 3713 | IPW_ERROR("Tx 3 queue init failed\n"); | 3771 | IPW_ERROR("Tx 3 queue init failed\n"); |
| 3714 | goto error; | 3772 | goto error; |
| @@ -3718,7 +3776,7 @@ static int ipw_queue_reset(struct ipw_priv *priv) | |||
| 3718 | priv->rx_pend_max = 0; | 3776 | priv->rx_pend_max = 0; |
| 3719 | return rc; | 3777 | return rc; |
| 3720 | 3778 | ||
| 3721 | error: | 3779 | error: |
| 3722 | ipw_tx_queue_free(priv); | 3780 | ipw_tx_queue_free(priv); |
| 3723 | return rc; | 3781 | return rc; |
| 3724 | } | 3782 | } |
| @@ -3746,8 +3804,8 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv, | |||
| 3746 | hw_tail = ipw_read32(priv, q->reg_r); | 3804 | hw_tail = ipw_read32(priv, q->reg_r); |
| 3747 | if (hw_tail >= q->n_bd) { | 3805 | if (hw_tail >= q->n_bd) { |
| 3748 | IPW_ERROR | 3806 | IPW_ERROR |
| 3749 | ("Read index for DMA queue (%d) is out of range [0-%d)\n", | 3807 | ("Read index for DMA queue (%d) is out of range [0-%d)\n", |
| 3750 | hw_tail, q->n_bd); | 3808 | hw_tail, q->n_bd); |
| 3751 | goto done; | 3809 | goto done; |
| 3752 | } | 3810 | } |
| 3753 | for (; q->last_used != hw_tail; | 3811 | for (; q->last_used != hw_tail; |
| @@ -3755,7 +3813,7 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv, | |||
| 3755 | ipw_queue_tx_free_tfd(priv, txq); | 3813 | ipw_queue_tx_free_tfd(priv, txq); |
| 3756 | priv->tx_packets++; | 3814 | priv->tx_packets++; |
| 3757 | } | 3815 | } |
| 3758 | done: | 3816 | done: |
| 3759 | if (ipw_queue_space(q) > q->low_mark && qindex >= 0) { | 3817 | if (ipw_queue_space(q) > q->low_mark && qindex >= 0) { |
| 3760 | __maybe_wake_tx(priv); | 3818 | __maybe_wake_tx(priv); |
| 3761 | } | 3819 | } |
| @@ -3795,8 +3853,6 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf, | |||
| 3795 | return 0; | 3853 | return 0; |
| 3796 | } | 3854 | } |
| 3797 | 3855 | ||
| 3798 | |||
| 3799 | |||
| 3800 | /* | 3856 | /* |
| 3801 | * Rx theory of operation | 3857 | * Rx theory of operation |
| 3802 | * | 3858 | * |
| @@ -3933,9 +3989,9 @@ static void ipw_rx_queue_replenish(void *data) | |||
| 3933 | list_del(element); | 3989 | list_del(element); |
| 3934 | 3990 | ||
| 3935 | rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; | 3991 | rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; |
| 3936 | rxb->dma_addr = pci_map_single( | 3992 | rxb->dma_addr = |
| 3937 | priv->pci_dev, rxb->skb->data, CX2_RX_BUF_SIZE, | 3993 | pci_map_single(priv->pci_dev, rxb->skb->data, |
| 3938 | PCI_DMA_FROMDEVICE); | 3994 | CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
| 3939 | 3995 | ||
| 3940 | list_add_tail(&rxb->list, &rxq->rx_free); | 3996 | list_add_tail(&rxb->list, &rxq->rx_free); |
| 3941 | rxq->free_count++; | 3997 | rxq->free_count++; |
| @@ -3950,8 +4006,7 @@ static void ipw_rx_queue_replenish(void *data) | |||
| 3950 | * This free routine walks the list of POOL entries and if SKB is set to | 4006 | * This free routine walks the list of POOL entries and if SKB is set to |
| 3951 | * non NULL it is unmapped and freed | 4007 | * non NULL it is unmapped and freed |
| 3952 | */ | 4008 | */ |
| 3953 | static void ipw_rx_queue_free(struct ipw_priv *priv, | 4009 | static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq) |
| 3954 | struct ipw_rx_queue *rxq) | ||
| 3955 | { | 4010 | { |
| 3956 | int i; | 4011 | int i; |
| 3957 | 4012 | ||
| @@ -3961,8 +4016,7 @@ static void ipw_rx_queue_free(struct ipw_priv *priv, | |||
| 3961 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | 4016 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { |
| 3962 | if (rxq->pool[i].skb != NULL) { | 4017 | if (rxq->pool[i].skb != NULL) { |
| 3963 | pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, | 4018 | pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, |
| 3964 | CX2_RX_BUF_SIZE, | 4019 | CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
| 3965 | PCI_DMA_FROMDEVICE); | ||
| 3966 | dev_kfree_skb(rxq->pool[i].skb); | 4020 | dev_kfree_skb(rxq->pool[i].skb); |
| 3967 | } | 4021 | } |
| 3968 | } | 4022 | } |
| @@ -4001,28 +4055,28 @@ static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate) | |||
| 4001 | switch (rate) { | 4055 | switch (rate) { |
| 4002 | case IEEE80211_OFDM_RATE_6MB: | 4056 | case IEEE80211_OFDM_RATE_6MB: |
| 4003 | return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? | 4057 | return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? |
| 4004 | 1 : 0; | 4058 | 1 : 0; |
| 4005 | case IEEE80211_OFDM_RATE_9MB: | 4059 | case IEEE80211_OFDM_RATE_9MB: |
| 4006 | return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? | 4060 | return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? |
| 4007 | 1 : 0; | 4061 | 1 : 0; |
| 4008 | case IEEE80211_OFDM_RATE_12MB: | 4062 | case IEEE80211_OFDM_RATE_12MB: |
| 4009 | return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? | 4063 | return priv-> |
| 4010 | 1 : 0; | 4064 | rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0; |
| 4011 | case IEEE80211_OFDM_RATE_18MB: | 4065 | case IEEE80211_OFDM_RATE_18MB: |
| 4012 | return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? | 4066 | return priv-> |
| 4013 | 1 : 0; | 4067 | rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0; |
| 4014 | case IEEE80211_OFDM_RATE_24MB: | 4068 | case IEEE80211_OFDM_RATE_24MB: |
| 4015 | return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? | 4069 | return priv-> |
| 4016 | 1 : 0; | 4070 | rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0; |
| 4017 | case IEEE80211_OFDM_RATE_36MB: | 4071 | case IEEE80211_OFDM_RATE_36MB: |
| 4018 | return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? | 4072 | return priv-> |
| 4019 | 1 : 0; | 4073 | rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0; |
| 4020 | case IEEE80211_OFDM_RATE_48MB: | 4074 | case IEEE80211_OFDM_RATE_48MB: |
| 4021 | return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? | 4075 | return priv-> |
| 4022 | 1 : 0; | 4076 | rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0; |
| 4023 | case IEEE80211_OFDM_RATE_54MB: | 4077 | case IEEE80211_OFDM_RATE_54MB: |
| 4024 | return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? | 4078 | return priv-> |
| 4025 | 1 : 0; | 4079 | rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0; |
| 4026 | default: | 4080 | default: |
| 4027 | return 0; | 4081 | return 0; |
| 4028 | } | 4082 | } |
| @@ -4074,10 +4128,11 @@ static int ipw_compatible_rates(struct ipw_priv *priv, | |||
| 4074 | int num_rates, i; | 4128 | int num_rates, i; |
| 4075 | 4129 | ||
| 4076 | memset(rates, 0, sizeof(*rates)); | 4130 | memset(rates, 0, sizeof(*rates)); |
| 4077 | num_rates = min(network->rates_len, (u8)IPW_MAX_RATES); | 4131 | num_rates = min(network->rates_len, (u8) IPW_MAX_RATES); |
| 4078 | rates->num_rates = 0; | 4132 | rates->num_rates = 0; |
| 4079 | for (i = 0; i < num_rates; i++) { | 4133 | for (i = 0; i < num_rates; i++) { |
| 4080 | if (!ipw_is_rate_in_mask(priv, network->mode, network->rates[i])) { | 4134 | if (!ipw_is_rate_in_mask |
| 4135 | (priv, network->mode, network->rates[i])) { | ||
| 4081 | IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", | 4136 | IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", |
| 4082 | network->rates[i], priv->rates_mask); | 4137 | network->rates[i], priv->rates_mask); |
| 4083 | continue; | 4138 | continue; |
| @@ -4086,15 +4141,18 @@ static int ipw_compatible_rates(struct ipw_priv *priv, | |||
| 4086 | rates->supported_rates[rates->num_rates++] = network->rates[i]; | 4141 | rates->supported_rates[rates->num_rates++] = network->rates[i]; |
| 4087 | } | 4142 | } |
| 4088 | 4143 | ||
| 4089 | num_rates = min(network->rates_ex_len, (u8)(IPW_MAX_RATES - num_rates)); | 4144 | num_rates = |
| 4145 | min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates)); | ||
| 4090 | for (i = 0; i < num_rates; i++) { | 4146 | for (i = 0; i < num_rates; i++) { |
| 4091 | if (!ipw_is_rate_in_mask(priv, network->mode, network->rates_ex[i])) { | 4147 | if (!ipw_is_rate_in_mask |
| 4148 | (priv, network->mode, network->rates_ex[i])) { | ||
| 4092 | IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", | 4149 | IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", |
| 4093 | network->rates_ex[i], priv->rates_mask); | 4150 | network->rates_ex[i], priv->rates_mask); |
| 4094 | continue; | 4151 | continue; |
| 4095 | } | 4152 | } |
| 4096 | 4153 | ||
| 4097 | rates->supported_rates[rates->num_rates++] = network->rates_ex[i]; | 4154 | rates->supported_rates[rates->num_rates++] = |
| 4155 | network->rates_ex[i]; | ||
| 4098 | } | 4156 | } |
| 4099 | 4157 | ||
| 4100 | return rates->num_rates; | 4158 | return rates->num_rates; |
| @@ -4113,65 +4171,65 @@ static inline void ipw_copy_rates(struct ipw_supported_rates *dest, | |||
| 4113 | * mask should ever be used -- right now all callers to add the scan rates are | 4171 | * mask should ever be used -- right now all callers to add the scan rates are |
| 4114 | * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */ | 4172 | * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */ |
| 4115 | static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates, | 4173 | static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates, |
| 4116 | u8 modulation, u32 rate_mask) | 4174 | u8 modulation, u32 rate_mask) |
| 4117 | { | 4175 | { |
| 4118 | u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? | 4176 | u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? |
| 4119 | IEEE80211_BASIC_RATE_MASK : 0; | 4177 | IEEE80211_BASIC_RATE_MASK : 0; |
| 4120 | 4178 | ||
| 4121 | if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK) | 4179 | if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK) |
| 4122 | rates->supported_rates[rates->num_rates++] = | 4180 | rates->supported_rates[rates->num_rates++] = |
| 4123 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; | 4181 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; |
| 4124 | 4182 | ||
| 4125 | if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK) | 4183 | if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK) |
| 4126 | rates->supported_rates[rates->num_rates++] = | 4184 | rates->supported_rates[rates->num_rates++] = |
| 4127 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; | 4185 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; |
| 4128 | 4186 | ||
| 4129 | if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK) | 4187 | if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK) |
| 4130 | rates->supported_rates[rates->num_rates++] = basic_mask | | 4188 | rates->supported_rates[rates->num_rates++] = basic_mask | |
| 4131 | IEEE80211_CCK_RATE_5MB; | 4189 | IEEE80211_CCK_RATE_5MB; |
| 4132 | 4190 | ||
| 4133 | if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK) | 4191 | if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK) |
| 4134 | rates->supported_rates[rates->num_rates++] = basic_mask | | 4192 | rates->supported_rates[rates->num_rates++] = basic_mask | |
| 4135 | IEEE80211_CCK_RATE_11MB; | 4193 | IEEE80211_CCK_RATE_11MB; |
| 4136 | } | 4194 | } |
| 4137 | 4195 | ||
| 4138 | static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates, | 4196 | static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates, |
| 4139 | u8 modulation, u32 rate_mask) | 4197 | u8 modulation, u32 rate_mask) |
| 4140 | { | 4198 | { |
| 4141 | u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? | 4199 | u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? |
| 4142 | IEEE80211_BASIC_RATE_MASK : 0; | 4200 | IEEE80211_BASIC_RATE_MASK : 0; |
| 4143 | 4201 | ||
| 4144 | if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK) | 4202 | if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK) |
| 4145 | rates->supported_rates[rates->num_rates++] = basic_mask | | 4203 | rates->supported_rates[rates->num_rates++] = basic_mask | |
| 4146 | IEEE80211_OFDM_RATE_6MB; | 4204 | IEEE80211_OFDM_RATE_6MB; |
| 4147 | 4205 | ||
| 4148 | if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK) | 4206 | if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK) |
| 4149 | rates->supported_rates[rates->num_rates++] = | 4207 | rates->supported_rates[rates->num_rates++] = |
| 4150 | IEEE80211_OFDM_RATE_9MB; | 4208 | IEEE80211_OFDM_RATE_9MB; |
| 4151 | 4209 | ||
| 4152 | if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK) | 4210 | if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK) |
| 4153 | rates->supported_rates[rates->num_rates++] = basic_mask | | 4211 | rates->supported_rates[rates->num_rates++] = basic_mask | |
| 4154 | IEEE80211_OFDM_RATE_12MB; | 4212 | IEEE80211_OFDM_RATE_12MB; |
| 4155 | 4213 | ||
| 4156 | if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK) | 4214 | if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK) |
| 4157 | rates->supported_rates[rates->num_rates++] = | 4215 | rates->supported_rates[rates->num_rates++] = |
| 4158 | IEEE80211_OFDM_RATE_18MB; | 4216 | IEEE80211_OFDM_RATE_18MB; |
| 4159 | 4217 | ||
| 4160 | if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK) | 4218 | if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK) |
| 4161 | rates->supported_rates[rates->num_rates++] = basic_mask | | 4219 | rates->supported_rates[rates->num_rates++] = basic_mask | |
| 4162 | IEEE80211_OFDM_RATE_24MB; | 4220 | IEEE80211_OFDM_RATE_24MB; |
| 4163 | 4221 | ||
| 4164 | if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK) | 4222 | if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK) |
| 4165 | rates->supported_rates[rates->num_rates++] = | 4223 | rates->supported_rates[rates->num_rates++] = |
| 4166 | IEEE80211_OFDM_RATE_36MB; | 4224 | IEEE80211_OFDM_RATE_36MB; |
| 4167 | 4225 | ||
| 4168 | if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK) | 4226 | if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK) |
| 4169 | rates->supported_rates[rates->num_rates++] = | 4227 | rates->supported_rates[rates->num_rates++] = |
| 4170 | IEEE80211_OFDM_RATE_48MB; | 4228 | IEEE80211_OFDM_RATE_48MB; |
| 4171 | 4229 | ||
| 4172 | if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK) | 4230 | if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK) |
| 4173 | rates->supported_rates[rates->num_rates++] = | 4231 | rates->supported_rates[rates->num_rates++] = |
| 4174 | IEEE80211_OFDM_RATE_54MB; | 4232 | IEEE80211_OFDM_RATE_54MB; |
| 4175 | } | 4233 | } |
| 4176 | 4234 | ||
| 4177 | struct ipw_network_match { | 4235 | struct ipw_network_match { |
| @@ -4179,11 +4237,9 @@ struct ipw_network_match { | |||
| 4179 | struct ipw_supported_rates rates; | 4237 | struct ipw_supported_rates rates; |
| 4180 | }; | 4238 | }; |
| 4181 | 4239 | ||
| 4182 | static int ipw_best_network( | 4240 | static int ipw_best_network(struct ipw_priv *priv, |
| 4183 | struct ipw_priv *priv, | 4241 | struct ipw_network_match *match, |
| 4184 | struct ipw_network_match *match, | 4242 | struct ieee80211_network *network, int roaming) |
| 4185 | struct ieee80211_network *network, | ||
| 4186 | int roaming) | ||
| 4187 | { | 4243 | { |
| 4188 | struct ipw_supported_rates rates; | 4244 | struct ipw_supported_rates rates; |
| 4189 | 4245 | ||
| @@ -4231,21 +4287,21 @@ static int ipw_best_network( | |||
| 4231 | memcmp(network->ssid, priv->essid, | 4287 | memcmp(network->ssid, priv->essid, |
| 4232 | min(network->ssid_len, priv->essid_len)))) { | 4288 | min(network->ssid_len, priv->essid_len)))) { |
| 4233 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 4289 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
| 4234 | strncpy(escaped, escape_essid( | 4290 | strncpy(escaped, |
| 4235 | network->ssid, network->ssid_len), | 4291 | escape_essid(network->ssid, network->ssid_len), |
| 4236 | sizeof(escaped)); | 4292 | sizeof(escaped)); |
| 4237 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " | 4293 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " |
| 4238 | "because of ESSID mismatch: '%s'.\n", | 4294 | "because of ESSID mismatch: '%s'.\n", |
| 4239 | escaped, MAC_ARG(network->bssid), | 4295 | escaped, MAC_ARG(network->bssid), |
| 4240 | escape_essid(priv->essid, priv->essid_len)); | 4296 | escape_essid(priv->essid, |
| 4297 | priv->essid_len)); | ||
| 4241 | return 0; | 4298 | return 0; |
| 4242 | } | 4299 | } |
| 4243 | } | 4300 | } |
| 4244 | 4301 | ||
| 4245 | /* If the old network rate is better than this one, don't bother | 4302 | /* If the old network rate is better than this one, don't bother |
| 4246 | * testing everything else. */ | 4303 | * testing everything else. */ |
| 4247 | if (match->network && match->network->stats.rssi > | 4304 | if (match->network && match->network->stats.rssi > network->stats.rssi) { |
| 4248 | network->stats.rssi) { | ||
| 4249 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 4305 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
| 4250 | strncpy(escaped, | 4306 | strncpy(escaped, |
| 4251 | escape_essid(network->ssid, network->ssid_len), | 4307 | escape_essid(network->ssid, network->ssid_len), |
| @@ -4303,7 +4359,7 @@ static int ipw_best_network( | |||
| 4303 | priv->capability & CAP_PRIVACY_ON ? "on" : | 4359 | priv->capability & CAP_PRIVACY_ON ? "on" : |
| 4304 | "off", | 4360 | "off", |
| 4305 | network->capability & | 4361 | network->capability & |
| 4306 | WLAN_CAPABILITY_PRIVACY ?"on" : "off"); | 4362 | WLAN_CAPABILITY_PRIVACY ? "on" : "off"); |
| 4307 | return 0; | 4363 | return 0; |
| 4308 | } | 4364 | } |
| 4309 | 4365 | ||
| @@ -4312,8 +4368,7 @@ static int ipw_best_network( | |||
| 4312 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " | 4368 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " |
| 4313 | "because of BSSID mismatch: " MAC_FMT ".\n", | 4369 | "because of BSSID mismatch: " MAC_FMT ".\n", |
| 4314 | escape_essid(network->ssid, network->ssid_len), | 4370 | escape_essid(network->ssid, network->ssid_len), |
| 4315 | MAC_ARG(network->bssid), | 4371 | MAC_ARG(network->bssid), MAC_ARG(priv->bssid)); |
| 4316 | MAC_ARG(priv->bssid)); | ||
| 4317 | return 0; | 4372 | return 0; |
| 4318 | } | 4373 | } |
| 4319 | 4374 | ||
| @@ -4351,9 +4406,8 @@ static int ipw_best_network( | |||
| 4351 | return 1; | 4406 | return 1; |
| 4352 | } | 4407 | } |
| 4353 | 4408 | ||
| 4354 | |||
| 4355 | static void ipw_adhoc_create(struct ipw_priv *priv, | 4409 | static void ipw_adhoc_create(struct ipw_priv *priv, |
| 4356 | struct ieee80211_network *network) | 4410 | struct ieee80211_network *network) |
| 4357 | { | 4411 | { |
| 4358 | /* | 4412 | /* |
| 4359 | * For the purposes of scanning, we can set our wireless mode | 4413 | * For the purposes of scanning, we can set our wireless mode |
| @@ -4393,8 +4447,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv, | |||
| 4393 | if (priv->capability & CAP_PRIVACY_ON) | 4447 | if (priv->capability & CAP_PRIVACY_ON) |
| 4394 | network->capability |= WLAN_CAPABILITY_PRIVACY; | 4448 | network->capability |= WLAN_CAPABILITY_PRIVACY; |
| 4395 | network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); | 4449 | network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); |
| 4396 | memcpy(network->rates, priv->rates.supported_rates, | 4450 | memcpy(network->rates, priv->rates.supported_rates, network->rates_len); |
| 4397 | network->rates_len); | ||
| 4398 | network->rates_ex_len = priv->rates.num_rates - network->rates_len; | 4451 | network->rates_ex_len = priv->rates.num_rates - network->rates_len; |
| 4399 | memcpy(network->rates_ex, | 4452 | memcpy(network->rates_ex, |
| 4400 | &priv->rates.supported_rates[network->rates_len], | 4453 | &priv->rates.supported_rates[network->rates_len], |
| @@ -4404,13 +4457,13 @@ static void ipw_adhoc_create(struct ipw_priv *priv, | |||
| 4404 | network->last_associate = 0; | 4457 | network->last_associate = 0; |
| 4405 | network->time_stamp[0] = 0; | 4458 | network->time_stamp[0] = 0; |
| 4406 | network->time_stamp[1] = 0; | 4459 | network->time_stamp[1] = 0; |
| 4407 | network->beacon_interval = 100; /* Default */ | 4460 | network->beacon_interval = 100; /* Default */ |
| 4408 | network->listen_interval = 10; /* Default */ | 4461 | network->listen_interval = 10; /* Default */ |
| 4409 | network->atim_window = 0; /* Default */ | 4462 | network->atim_window = 0; /* Default */ |
| 4410 | #ifdef CONFIG_IEEE80211_WPA | 4463 | #ifdef CONFIG_IEEE80211_WPA |
| 4411 | network->wpa_ie_len = 0; | 4464 | network->wpa_ie_len = 0; |
| 4412 | network->rsn_ie_len = 0; | 4465 | network->rsn_ie_len = 0; |
| 4413 | #endif /* CONFIG_IEEE80211_WPA */ | 4466 | #endif /* CONFIG_IEEE80211_WPA */ |
| 4414 | } | 4467 | } |
| 4415 | 4468 | ||
| 4416 | static void ipw_send_wep_keys(struct ipw_priv *priv) | 4469 | static void ipw_send_wep_keys(struct ipw_priv *priv) |
| @@ -4464,14 +4517,12 @@ static void ipw_debug_config(struct ipw_priv *priv) | |||
| 4464 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " | 4517 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " |
| 4465 | "[CFG 0x%08X]\n", priv->config); | 4518 | "[CFG 0x%08X]\n", priv->config); |
| 4466 | if (priv->config & CFG_STATIC_CHANNEL) | 4519 | if (priv->config & CFG_STATIC_CHANNEL) |
| 4467 | IPW_DEBUG_INFO("Channel locked to %d\n", | 4520 | IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel); |
| 4468 | priv->channel); | ||
| 4469 | else | 4521 | else |
| 4470 | IPW_DEBUG_INFO("Channel unlocked.\n"); | 4522 | IPW_DEBUG_INFO("Channel unlocked.\n"); |
| 4471 | if (priv->config & CFG_STATIC_ESSID) | 4523 | if (priv->config & CFG_STATIC_ESSID) |
| 4472 | IPW_DEBUG_INFO("ESSID locked to '%s'\n", | 4524 | IPW_DEBUG_INFO("ESSID locked to '%s'\n", |
| 4473 | escape_essid(priv->essid, | 4525 | escape_essid(priv->essid, priv->essid_len)); |
| 4474 | priv->essid_len)); | ||
| 4475 | else | 4526 | else |
| 4476 | IPW_DEBUG_INFO("ESSID unlocked.\n"); | 4527 | IPW_DEBUG_INFO("ESSID unlocked.\n"); |
| 4477 | if (priv->config & CFG_STATIC_BSSID) | 4528 | if (priv->config & CFG_STATIC_BSSID) |
| @@ -4502,7 +4553,7 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv, | |||
| 4502 | * Tx rates */ | 4553 | * Tx rates */ |
| 4503 | 4554 | ||
| 4504 | switch (priv->ieee->freq_band) { | 4555 | switch (priv->ieee->freq_band) { |
| 4505 | case IEEE80211_52GHZ_BAND: /* A only */ | 4556 | case IEEE80211_52GHZ_BAND: /* A only */ |
| 4506 | /* IEEE_A */ | 4557 | /* IEEE_A */ |
| 4507 | if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) { | 4558 | if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) { |
| 4508 | /* Invalid fixed rate mask */ | 4559 | /* Invalid fixed rate mask */ |
| @@ -4513,7 +4564,7 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv, | |||
| 4513 | fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A; | 4564 | fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A; |
| 4514 | break; | 4565 | break; |
| 4515 | 4566 | ||
| 4516 | default: /* 2.4Ghz or Mixed */ | 4567 | default: /* 2.4Ghz or Mixed */ |
| 4517 | /* IEEE_B */ | 4568 | /* IEEE_B */ |
| 4518 | if (network->mode == IEEE_B) { | 4569 | if (network->mode == IEEE_B) { |
| 4519 | if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { | 4570 | if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { |
| @@ -4551,13 +4602,12 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv, | |||
| 4551 | } | 4602 | } |
| 4552 | 4603 | ||
| 4553 | reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE); | 4604 | reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE); |
| 4554 | ipw_write_reg32(priv, reg, *(u32*)&fr); | 4605 | ipw_write_reg32(priv, reg, *(u32 *) & fr); |
| 4555 | } | 4606 | } |
| 4556 | 4607 | ||
| 4557 | static int ipw_associate_network(struct ipw_priv *priv, | 4608 | static int ipw_associate_network(struct ipw_priv *priv, |
| 4558 | struct ieee80211_network *network, | 4609 | struct ieee80211_network *network, |
| 4559 | struct ipw_supported_rates *rates, | 4610 | struct ipw_supported_rates *rates, int roaming) |
| 4560 | int roaming) | ||
| 4561 | { | 4611 | { |
| 4562 | int err; | 4612 | int err; |
| 4563 | 4613 | ||
| @@ -4566,7 +4616,7 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
| 4566 | 4616 | ||
| 4567 | if (!(priv->config & CFG_STATIC_ESSID)) { | 4617 | if (!(priv->config & CFG_STATIC_ESSID)) { |
| 4568 | priv->essid_len = min(network->ssid_len, | 4618 | priv->essid_len = min(network->ssid_len, |
| 4569 | (u8)IW_ESSID_MAX_SIZE); | 4619 | (u8) IW_ESSID_MAX_SIZE); |
| 4570 | memcpy(priv->essid, network->ssid, priv->essid_len); | 4620 | memcpy(priv->essid, network->ssid, priv->essid_len); |
| 4571 | } | 4621 | } |
| 4572 | 4622 | ||
| @@ -4612,13 +4662,11 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
| 4612 | priv->capability & CAP_PRIVACY_ON ? " key=" : "", | 4662 | priv->capability & CAP_PRIVACY_ON ? " key=" : "", |
| 4613 | priv->capability & CAP_PRIVACY_ON ? | 4663 | priv->capability & CAP_PRIVACY_ON ? |
| 4614 | '1' + priv->sec.active_key : '.', | 4664 | '1' + priv->sec.active_key : '.', |
| 4615 | priv->capability & CAP_PRIVACY_ON ? | 4665 | priv->capability & CAP_PRIVACY_ON ? '.' : ' '); |
| 4616 | '.' : ' '); | ||
| 4617 | 4666 | ||
| 4618 | priv->assoc_request.beacon_interval = network->beacon_interval; | 4667 | priv->assoc_request.beacon_interval = network->beacon_interval; |
| 4619 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC) && | 4668 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC) && |
| 4620 | (network->time_stamp[0] == 0) && | 4669 | (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) { |
| 4621 | (network->time_stamp[1] == 0)) { | ||
| 4622 | priv->assoc_request.assoc_type = HC_IBSS_START; | 4670 | priv->assoc_request.assoc_type = HC_IBSS_START; |
| 4623 | priv->assoc_request.assoc_tsf_msw = 0; | 4671 | priv->assoc_request.assoc_tsf_msw = 0; |
| 4624 | priv->assoc_request.assoc_tsf_lsw = 0; | 4672 | priv->assoc_request.assoc_tsf_lsw = 0; |
| @@ -4637,8 +4685,7 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
| 4637 | memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN); | 4685 | memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN); |
| 4638 | priv->assoc_request.atim_window = network->atim_window; | 4686 | priv->assoc_request.atim_window = network->atim_window; |
| 4639 | } else { | 4687 | } else { |
| 4640 | memcpy(&priv->assoc_request.dest, network->bssid, | 4688 | memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN); |
| 4641 | ETH_ALEN); | ||
| 4642 | priv->assoc_request.atim_window = 0; | 4689 | priv->assoc_request.atim_window = 0; |
| 4643 | } | 4690 | } |
| 4644 | 4691 | ||
| @@ -4772,14 +4819,13 @@ static void ipw_associate(void *data) | |||
| 4772 | 4819 | ||
| 4773 | if (!(priv->config & CFG_ASSOCIATE) && | 4820 | if (!(priv->config & CFG_ASSOCIATE) && |
| 4774 | !(priv->config & (CFG_STATIC_ESSID | | 4821 | !(priv->config & (CFG_STATIC_ESSID | |
| 4775 | CFG_STATIC_CHANNEL | | 4822 | CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) { |
| 4776 | CFG_STATIC_BSSID))) { | ||
| 4777 | IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n"); | 4823 | IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n"); |
| 4778 | return; | 4824 | return; |
| 4779 | } | 4825 | } |
| 4780 | 4826 | ||
| 4781 | list_for_each_entry(network, &priv->ieee->network_list, list) | 4827 | list_for_each_entry(network, &priv->ieee->network_list, list) |
| 4782 | ipw_best_network(priv, &match, network, 0); | 4828 | ipw_best_network(priv, &match, network, 0); |
| 4783 | 4829 | ||
| 4784 | network = match.network; | 4830 | network = match.network; |
| 4785 | rates = &match.rates; | 4831 | rates = &match.rates; |
| @@ -4790,8 +4836,7 @@ static void ipw_associate(void *data) | |||
| 4790 | priv->config & CFG_STATIC_ESSID && | 4836 | priv->config & CFG_STATIC_ESSID && |
| 4791 | !list_empty(&priv->ieee->network_free_list)) { | 4837 | !list_empty(&priv->ieee->network_free_list)) { |
| 4792 | element = priv->ieee->network_free_list.next; | 4838 | element = priv->ieee->network_free_list.next; |
| 4793 | network = list_entry(element, struct ieee80211_network, | 4839 | network = list_entry(element, struct ieee80211_network, list); |
| 4794 | list); | ||
| 4795 | ipw_adhoc_create(priv, network); | 4840 | ipw_adhoc_create(priv, network); |
| 4796 | rates = &priv->rates; | 4841 | rates = &priv->rates; |
| 4797 | list_del(element); | 4842 | list_del(element); |
| @@ -4813,8 +4858,8 @@ static void ipw_associate(void *data) | |||
| 4813 | } | 4858 | } |
| 4814 | 4859 | ||
| 4815 | static inline void ipw_handle_data_packet(struct ipw_priv *priv, | 4860 | static inline void ipw_handle_data_packet(struct ipw_priv *priv, |
| 4816 | struct ipw_rx_mem_buffer *rxb, | 4861 | struct ipw_rx_mem_buffer *rxb, |
| 4817 | struct ieee80211_rx_stats *stats) | 4862 | struct ieee80211_rx_stats *stats) |
| 4818 | { | 4863 | { |
| 4819 | struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data; | 4864 | struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data; |
| 4820 | 4865 | ||
| @@ -4846,11 +4891,10 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv, | |||
| 4846 | 4891 | ||
| 4847 | if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) | 4892 | if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) |
| 4848 | priv->ieee->stats.rx_errors++; | 4893 | priv->ieee->stats.rx_errors++; |
| 4849 | else /* ieee80211_rx succeeded, so it now owns the SKB */ | 4894 | else /* ieee80211_rx succeeded, so it now owns the SKB */ |
| 4850 | rxb->skb = NULL; | 4895 | rxb->skb = NULL; |
| 4851 | } | 4896 | } |
| 4852 | 4897 | ||
| 4853 | |||
| 4854 | /* | 4898 | /* |
| 4855 | * Main entry function for recieving a packet with 80211 headers. This | 4899 | * Main entry function for recieving a packet with 80211 headers. This |
| 4856 | * should be called when ever the FW has notified us that there is a new | 4900 | * should be called when ever the FW has notified us that there is a new |
| @@ -4885,125 +4929,152 @@ static void ipw_rx(struct ipw_priv *priv) | |||
| 4885 | pkt = (struct ipw_rx_packet *)rxb->skb->data; | 4929 | pkt = (struct ipw_rx_packet *)rxb->skb->data; |
| 4886 | IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n", | 4930 | IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n", |
| 4887 | pkt->header.message_type, | 4931 | pkt->header.message_type, |
| 4888 | pkt->header.rx_seq_num, | 4932 | pkt->header.rx_seq_num, pkt->header.control_bits); |
| 4889 | pkt->header.control_bits); | ||
| 4890 | 4933 | ||
| 4891 | switch (pkt->header.message_type) { | 4934 | switch (pkt->header.message_type) { |
| 4892 | case RX_FRAME_TYPE: /* 802.11 frame */ { | 4935 | case RX_FRAME_TYPE: /* 802.11 frame */ { |
| 4893 | struct ieee80211_rx_stats stats = { | 4936 | struct ieee80211_rx_stats stats = { |
| 4894 | .rssi = pkt->u.frame.rssi_dbm - | 4937 | .rssi = pkt->u.frame.rssi_dbm - |
| 4895 | IPW_RSSI_TO_DBM, | 4938 | IPW_RSSI_TO_DBM, |
| 4896 | .signal = pkt->u.frame.signal, | 4939 | .signal = pkt->u.frame.signal, |
| 4897 | .rate = pkt->u.frame.rate, | 4940 | .rate = pkt->u.frame.rate, |
| 4898 | .mac_time = jiffies, | 4941 | .mac_time = jiffies, |
| 4899 | .received_channel = | 4942 | .received_channel = |
| 4900 | pkt->u.frame.received_channel, | 4943 | pkt->u.frame.received_channel, |
| 4901 | .freq = (pkt->u.frame.control & (1<<0)) ? | 4944 | .freq = |
| 4902 | IEEE80211_24GHZ_BAND : IEEE80211_52GHZ_BAND, | 4945 | (pkt->u.frame. |
| 4903 | .len = pkt->u.frame.length, | 4946 | control & (1 << 0)) ? |
| 4904 | }; | 4947 | IEEE80211_24GHZ_BAND : |
| 4905 | 4948 | IEEE80211_52GHZ_BAND, | |
| 4906 | if (stats.rssi != 0) | 4949 | .len = pkt->u.frame.length, |
| 4907 | stats.mask |= IEEE80211_STATMASK_RSSI; | 4950 | }; |
| 4908 | if (stats.signal != 0) | 4951 | |
| 4909 | stats.mask |= IEEE80211_STATMASK_SIGNAL; | 4952 | if (stats.rssi != 0) |
| 4910 | if (stats.rate != 0) | 4953 | stats.mask |= IEEE80211_STATMASK_RSSI; |
| 4911 | stats.mask |= IEEE80211_STATMASK_RATE; | 4954 | if (stats.signal != 0) |
| 4912 | 4955 | stats.mask |= IEEE80211_STATMASK_SIGNAL; | |
| 4913 | priv->rx_packets++; | 4956 | if (stats.rate != 0) |
| 4957 | stats.mask |= IEEE80211_STATMASK_RATE; | ||
| 4958 | |||
| 4959 | priv->rx_packets++; | ||
| 4914 | 4960 | ||
| 4915 | #ifdef CONFIG_IPW_PROMISC | 4961 | #ifdef CONFIG_IPW_PROMISC |
| 4916 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 4962 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
| 4917 | ipw_handle_data_packet(priv, rxb, &stats); | 4963 | ipw_handle_data_packet(priv, rxb, |
| 4918 | break; | 4964 | &stats); |
| 4919 | } | 4965 | break; |
| 4966 | } | ||
| 4920 | #endif | 4967 | #endif |
| 4921 | 4968 | ||
| 4922 | header = (struct ieee80211_hdr *)(rxb->skb->data + | 4969 | header = |
| 4923 | IPW_RX_FRAME_SIZE); | 4970 | (struct ieee80211_hdr *)(rxb->skb->data + |
| 4971 | IPW_RX_FRAME_SIZE); | ||
| 4924 | /* TODO: Check Ad-Hoc dest/source and make sure | 4972 | /* TODO: Check Ad-Hoc dest/source and make sure |
| 4925 | * that we are actually parsing these packets | 4973 | * that we are actually parsing these packets |
| 4926 | * correctly -- we should probably use the | 4974 | * correctly -- we should probably use the |
| 4927 | * frame control of the packet and disregard | 4975 | * frame control of the packet and disregard |
| 4928 | * the current iw_mode */ | 4976 | * the current iw_mode */ |
| 4929 | switch (priv->ieee->iw_mode) { | 4977 | switch (priv->ieee->iw_mode) { |
| 4930 | case IW_MODE_ADHOC: | 4978 | case IW_MODE_ADHOC: |
| 4931 | network_packet = | 4979 | network_packet = |
| 4932 | !memcmp(header->addr1, | 4980 | !memcmp(header->addr1, |
| 4933 | priv->net_dev->dev_addr, | 4981 | priv->net_dev->dev_addr, |
| 4934 | ETH_ALEN) || | 4982 | ETH_ALEN) || |
| 4935 | !memcmp(header->addr3, | 4983 | !memcmp(header->addr3, |
| 4936 | priv->bssid, ETH_ALEN) || | 4984 | priv->bssid, ETH_ALEN) || |
| 4937 | is_broadcast_ether_addr(header->addr1) || | 4985 | is_broadcast_ether_addr(header-> |
| 4938 | is_multicast_ether_addr(header->addr1); | 4986 | addr1) |
| 4939 | break; | 4987 | || is_multicast_ether_addr(header-> |
| 4940 | 4988 | addr1); | |
| 4941 | case IW_MODE_INFRA: | 4989 | break; |
| 4942 | default: | 4990 | |
| 4943 | network_packet = | 4991 | case IW_MODE_INFRA: |
| 4944 | !memcmp(header->addr3, | 4992 | default: |
| 4945 | priv->bssid, ETH_ALEN) || | 4993 | network_packet = |
| 4946 | !memcmp(header->addr1, | 4994 | !memcmp(header->addr3, |
| 4947 | priv->net_dev->dev_addr, | 4995 | priv->bssid, ETH_ALEN) || |
| 4948 | ETH_ALEN) || | 4996 | !memcmp(header->addr1, |
| 4949 | is_broadcast_ether_addr(header->addr1) || | 4997 | priv->net_dev->dev_addr, |
| 4950 | is_multicast_ether_addr(header->addr1); | 4998 | ETH_ALEN) || |
| 4999 | is_broadcast_ether_addr(header-> | ||
| 5000 | addr1) | ||
| 5001 | || is_multicast_ether_addr(header-> | ||
| 5002 | addr1); | ||
| 5003 | break; | ||
| 5004 | } | ||
| 5005 | |||
| 5006 | if (network_packet && priv->assoc_network) { | ||
| 5007 | priv->assoc_network->stats.rssi = | ||
| 5008 | stats.rssi; | ||
| 5009 | average_add(&priv->average_rssi, | ||
| 5010 | stats.rssi); | ||
| 5011 | priv->last_rx_rssi = stats.rssi; | ||
| 5012 | } | ||
| 5013 | |||
| 5014 | IPW_DEBUG_RX("Frame: len=%u\n", | ||
| 5015 | pkt->u.frame.length); | ||
| 5016 | |||
| 5017 | if (pkt->u.frame.length < frame_hdr_len(header)) { | ||
| 5018 | IPW_DEBUG_DROP | ||
| 5019 | ("Received packet is too small. " | ||
| 5020 | "Dropping.\n"); | ||
| 5021 | priv->ieee->stats.rx_errors++; | ||
| 5022 | priv->wstats.discard.misc++; | ||
| 5023 | break; | ||
| 5024 | } | ||
| 5025 | |||
| 5026 | switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { | ||
| 5027 | case IEEE80211_FTYPE_MGMT: | ||
| 5028 | ieee80211_rx_mgt(priv->ieee, header, | ||
| 5029 | &stats); | ||
| 5030 | if (priv->ieee->iw_mode == IW_MODE_ADHOC | ||
| 5031 | && | ||
| 5032 | ((WLAN_FC_GET_STYPE | ||
| 5033 | (header->frame_ctl) == | ||
| 5034 | IEEE80211_STYPE_PROBE_RESP) | ||
| 5035 | || | ||
| 5036 | (WLAN_FC_GET_STYPE | ||
| 5037 | (header->frame_ctl) == | ||
| 5038 | IEEE80211_STYPE_BEACON)) | ||
| 5039 | && !memcmp(header->addr3, | ||
| 5040 | priv->bssid, ETH_ALEN)) | ||
| 5041 | ipw_add_station(priv, | ||
| 5042 | header->addr2); | ||
| 5043 | break; | ||
| 5044 | |||
| 5045 | case IEEE80211_FTYPE_CTL: | ||
| 5046 | break; | ||
| 5047 | |||
| 5048 | case IEEE80211_FTYPE_DATA: | ||
| 5049 | if (network_packet) | ||
| 5050 | ipw_handle_data_packet(priv, | ||
| 5051 | rxb, | ||
| 5052 | &stats); | ||
| 5053 | else | ||
| 5054 | IPW_DEBUG_DROP("Dropping: " | ||
| 5055 | MAC_FMT ", " | ||
| 5056 | MAC_FMT ", " | ||
| 5057 | MAC_FMT "\n", | ||
| 5058 | MAC_ARG(header-> | ||
| 5059 | addr1), | ||
| 5060 | MAC_ARG(header-> | ||
| 5061 | addr2), | ||
| 5062 | MAC_ARG(header-> | ||
| 5063 | addr3)); | ||
| 5064 | break; | ||
| 5065 | } | ||
| 4951 | break; | 5066 | break; |
| 4952 | } | 5067 | } |
| 4953 | 5068 | ||
| 4954 | if (network_packet && priv->assoc_network) { | 5069 | case RX_HOST_NOTIFICATION_TYPE:{ |
| 4955 | priv->assoc_network->stats.rssi = stats.rssi; | 5070 | IPW_DEBUG_RX |
| 4956 | average_add(&priv->average_rssi, | 5071 | ("Notification: subtype=%02X flags=%02X size=%d\n", |
| 4957 | stats.rssi); | ||
| 4958 | priv->last_rx_rssi = stats.rssi; | ||
| 4959 | } | ||
| 4960 | |||
| 4961 | IPW_DEBUG_RX("Frame: len=%u\n", pkt->u.frame.length); | ||
| 4962 | |||
| 4963 | if (pkt->u.frame.length < frame_hdr_len(header)) { | ||
| 4964 | IPW_DEBUG_DROP("Received packet is too small. " | ||
| 4965 | "Dropping.\n"); | ||
| 4966 | priv->ieee->stats.rx_errors++; | ||
| 4967 | priv->wstats.discard.misc++; | ||
| 4968 | break; | ||
| 4969 | } | ||
| 4970 | |||
| 4971 | switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { | ||
| 4972 | case IEEE80211_FTYPE_MGMT: | ||
| 4973 | ieee80211_rx_mgt(priv->ieee, header, &stats); | ||
| 4974 | if (priv->ieee->iw_mode == IW_MODE_ADHOC && | ||
| 4975 | ((WLAN_FC_GET_STYPE(header->frame_ctl) == | ||
| 4976 | IEEE80211_STYPE_PROBE_RESP) || | ||
| 4977 | (WLAN_FC_GET_STYPE(header->frame_ctl) == | ||
| 4978 | IEEE80211_STYPE_BEACON)) && | ||
| 4979 | !memcmp(header->addr3, priv->bssid, ETH_ALEN)) | ||
| 4980 | ipw_add_station(priv, header->addr2); | ||
| 4981 | break; | ||
| 4982 | |||
| 4983 | case IEEE80211_FTYPE_CTL: | ||
| 4984 | break; | ||
| 4985 | |||
| 4986 | case IEEE80211_FTYPE_DATA: | ||
| 4987 | if (network_packet) | ||
| 4988 | ipw_handle_data_packet(priv, rxb, &stats); | ||
| 4989 | else | ||
| 4990 | IPW_DEBUG_DROP("Dropping: " MAC_FMT | ||
| 4991 | ", " MAC_FMT ", " MAC_FMT "\n", | ||
| 4992 | MAC_ARG(header->addr1), MAC_ARG(header->addr2), | ||
| 4993 | MAC_ARG(header->addr3)); | ||
| 4994 | break; | ||
| 4995 | } | ||
| 4996 | break; | ||
| 4997 | } | ||
| 4998 | |||
| 4999 | case RX_HOST_NOTIFICATION_TYPE: { | ||
| 5000 | IPW_DEBUG_RX("Notification: subtype=%02X flags=%02X size=%d\n", | ||
| 5001 | pkt->u.notification.subtype, | 5072 | pkt->u.notification.subtype, |
| 5002 | pkt->u.notification.flags, | 5073 | pkt->u.notification.flags, |
| 5003 | pkt->u.notification.size); | 5074 | pkt->u.notification.size); |
| 5004 | ipw_rx_notification(priv, &pkt->u.notification); | 5075 | ipw_rx_notification(priv, &pkt->u.notification); |
| 5005 | break; | 5076 | break; |
| 5006 | } | 5077 | } |
| 5007 | 5078 | ||
| 5008 | default: | 5079 | default: |
| 5009 | IPW_DEBUG_RX("Bad Rx packet of type %d\n", | 5080 | IPW_DEBUG_RX("Bad Rx packet of type %d\n", |
| @@ -5088,10 +5159,10 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
| 5088 | /* If we are roaming, then make this a directed scan for the current | 5159 | /* If we are roaming, then make this a directed scan for the current |
| 5089 | * network. Otherwise, ensure that every other scan is a fast | 5160 | * network. Otherwise, ensure that every other scan is a fast |
| 5090 | * channel hop scan */ | 5161 | * channel hop scan */ |
| 5091 | if ((priv->status & STATUS_ROAMING) || ( | 5162 | if ((priv->status & STATUS_ROAMING) |
| 5092 | !(priv->status & STATUS_ASSOCIATED) && | 5163 | || (!(priv->status & STATUS_ASSOCIATED) |
| 5093 | (priv->config & CFG_STATIC_ESSID) && | 5164 | && (priv->config & CFG_STATIC_ESSID) |
| 5094 | (scan.full_scan_index % 2))) { | 5165 | && (scan.full_scan_index % 2))) { |
| 5095 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); | 5166 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); |
| 5096 | if (err) { | 5167 | if (err) { |
| 5097 | IPW_DEBUG_HC("Attempt to send SSID command failed.\n"); | 5168 | IPW_DEBUG_HC("Attempt to send SSID command failed.\n"); |
| @@ -5103,7 +5174,7 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
| 5103 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN; | 5174 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN; |
| 5104 | } | 5175 | } |
| 5105 | 5176 | ||
| 5106 | if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { | 5177 | if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { |
| 5107 | int start = channel_index; | 5178 | int start = channel_index; |
| 5108 | for (i = 0; i < MAX_A_CHANNELS; i++) { | 5179 | for (i = 0; i < MAX_A_CHANNELS; i++) { |
| 5109 | if (band_a_active_channel[i] == 0) | 5180 | if (band_a_active_channel[i] == 0) |
| @@ -5113,18 +5184,18 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
| 5113 | continue; | 5184 | continue; |
| 5114 | channel_index++; | 5185 | channel_index++; |
| 5115 | scan.channels_list[channel_index] = | 5186 | scan.channels_list[channel_index] = |
| 5116 | band_a_active_channel[i]; | 5187 | band_a_active_channel[i]; |
| 5117 | ipw_set_scan_type(&scan, channel_index, scan_type); | 5188 | ipw_set_scan_type(&scan, channel_index, scan_type); |
| 5118 | } | 5189 | } |
| 5119 | 5190 | ||
| 5120 | if (start != channel_index) { | 5191 | if (start != channel_index) { |
| 5121 | scan.channels_list[start] = (u8)(IPW_A_MODE << 6) | | 5192 | scan.channels_list[start] = (u8) (IPW_A_MODE << 6) | |
| 5122 | (channel_index - start); | 5193 | (channel_index - start); |
| 5123 | channel_index++; | 5194 | channel_index++; |
| 5124 | } | 5195 | } |
| 5125 | } | 5196 | } |
| 5126 | 5197 | ||
| 5127 | if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) { | 5198 | if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) { |
| 5128 | int start = channel_index; | 5199 | int start = channel_index; |
| 5129 | for (i = 0; i < MAX_B_CHANNELS; i++) { | 5200 | for (i = 0; i < MAX_B_CHANNELS; i++) { |
| 5130 | if (band_b_active_channel[i] == 0) | 5201 | if (band_b_active_channel[i] == 0) |
| @@ -5134,20 +5205,19 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
| 5134 | continue; | 5205 | continue; |
| 5135 | channel_index++; | 5206 | channel_index++; |
| 5136 | scan.channels_list[channel_index] = | 5207 | scan.channels_list[channel_index] = |
| 5137 | band_b_active_channel[i]; | 5208 | band_b_active_channel[i]; |
| 5138 | ipw_set_scan_type(&scan, channel_index, scan_type); | 5209 | ipw_set_scan_type(&scan, channel_index, scan_type); |
| 5139 | } | 5210 | } |
| 5140 | 5211 | ||
| 5141 | if (start != channel_index) { | 5212 | if (start != channel_index) { |
| 5142 | scan.channels_list[start] = (u8)(IPW_B_MODE << 6) | | 5213 | scan.channels_list[start] = (u8) (IPW_B_MODE << 6) | |
| 5143 | (channel_index - start); | 5214 | (channel_index - start); |
| 5144 | } | 5215 | } |
| 5145 | } | 5216 | } |
| 5146 | 5217 | ||
| 5147 | err = ipw_send_scan_request_ext(priv, &scan); | 5218 | err = ipw_send_scan_request_ext(priv, &scan); |
| 5148 | if (err) { | 5219 | if (err) { |
| 5149 | IPW_DEBUG_HC("Sending scan command failed: %08X\n", | 5220 | IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); |
| 5150 | err); | ||
| 5151 | return -EIO; | 5221 | return -EIO; |
| 5152 | } | 5222 | } |
| 5153 | 5223 | ||
| @@ -5199,9 +5269,8 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel) | |||
| 5199 | priv->config |= CFG_STATIC_CHANNEL; | 5269 | priv->config |= CFG_STATIC_CHANNEL; |
| 5200 | 5270 | ||
| 5201 | if (priv->channel == channel) { | 5271 | if (priv->channel == channel) { |
| 5202 | IPW_DEBUG_INFO( | 5272 | IPW_DEBUG_INFO("Request to set channel to current value (%d)\n", |
| 5203 | "Request to set channel to current value (%d)\n", | 5273 | channel); |
| 5204 | channel); | ||
| 5205 | return 0; | 5274 | return 0; |
| 5206 | } | 5275 | } |
| 5207 | 5276 | ||
| @@ -5229,8 +5298,7 @@ static int ipw_wx_set_freq(struct net_device *dev, | |||
| 5229 | 5298 | ||
| 5230 | /* if setting by freq convert to channel */ | 5299 | /* if setting by freq convert to channel */ |
| 5231 | if (fwrq->e == 1) { | 5300 | if (fwrq->e == 1) { |
| 5232 | if ((fwrq->m >= (int) 2.412e8 && | 5301 | if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) { |
| 5233 | fwrq->m <= (int) 2.487e8)) { | ||
| 5234 | int f = fwrq->m / 100000; | 5302 | int f = fwrq->m / 100000; |
| 5235 | int c = 0; | 5303 | int c = 0; |
| 5236 | 5304 | ||
| @@ -5248,12 +5316,11 @@ static int ipw_wx_set_freq(struct net_device *dev, | |||
| 5248 | return -EOPNOTSUPP; | 5316 | return -EOPNOTSUPP; |
| 5249 | 5317 | ||
| 5250 | IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); | 5318 | IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); |
| 5251 | return ipw_set_channel(priv, (u8)fwrq->m); | 5319 | return ipw_set_channel(priv, (u8) fwrq->m); |
| 5252 | 5320 | ||
| 5253 | return 0; | 5321 | return 0; |
| 5254 | } | 5322 | } |
| 5255 | 5323 | ||
| 5256 | |||
| 5257 | static int ipw_wx_get_freq(struct net_device *dev, | 5324 | static int ipw_wx_get_freq(struct net_device *dev, |
| 5258 | struct iw_request_info *info, | 5325 | struct iw_request_info *info, |
| 5259 | union iwreq_data *wrqu, char *extra) | 5326 | union iwreq_data *wrqu, char *extra) |
| @@ -5306,7 +5373,7 @@ static int ipw_wx_set_mode(struct net_device *dev, | |||
| 5306 | 5373 | ||
| 5307 | if (wrqu->mode == IW_MODE_MONITOR) | 5374 | if (wrqu->mode == IW_MODE_MONITOR) |
| 5308 | priv->net_dev->type = ARPHRD_IEEE80211; | 5375 | priv->net_dev->type = ARPHRD_IEEE80211; |
| 5309 | #endif /* CONFIG_IPW_PROMISC */ | 5376 | #endif /* CONFIG_IPW_PROMISC */ |
| 5310 | 5377 | ||
| 5311 | #ifdef CONFIG_PM | 5378 | #ifdef CONFIG_PM |
| 5312 | /* Free the existing firmware and reset the fw_loaded | 5379 | /* Free the existing firmware and reset the fw_loaded |
| @@ -5324,12 +5391,12 @@ static int ipw_wx_set_mode(struct net_device *dev, | |||
| 5324 | priv->ieee->iw_mode = wrqu->mode; | 5391 | priv->ieee->iw_mode = wrqu->mode; |
| 5325 | ipw_adapter_restart(priv); | 5392 | ipw_adapter_restart(priv); |
| 5326 | 5393 | ||
| 5327 | return err; | 5394 | return err; |
| 5328 | } | 5395 | } |
| 5329 | 5396 | ||
| 5330 | static int ipw_wx_get_mode(struct net_device *dev, | 5397 | static int ipw_wx_get_mode(struct net_device *dev, |
| 5331 | struct iw_request_info *info, | 5398 | struct iw_request_info *info, |
| 5332 | union iwreq_data *wrqu, char *extra) | 5399 | union iwreq_data *wrqu, char *extra) |
| 5333 | { | 5400 | { |
| 5334 | struct ipw_priv *priv = ieee80211_priv(dev); | 5401 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5335 | 5402 | ||
| @@ -5339,7 +5406,6 @@ static int ipw_wx_get_mode(struct net_device *dev, | |||
| 5339 | return 0; | 5406 | return 0; |
| 5340 | } | 5407 | } |
| 5341 | 5408 | ||
| 5342 | |||
| 5343 | #define DEFAULT_RTS_THRESHOLD 2304U | 5409 | #define DEFAULT_RTS_THRESHOLD 2304U |
| 5344 | #define MIN_RTS_THRESHOLD 1U | 5410 | #define MIN_RTS_THRESHOLD 1U |
| 5345 | #define MAX_RTS_THRESHOLD 2304U | 5411 | #define MAX_RTS_THRESHOLD 2304U |
| @@ -5383,19 +5449,19 @@ static int ipw_wx_get_range(struct net_device *dev, | |||
| 5383 | /* TODO: Find real max RSSI and stick here */ | 5449 | /* TODO: Find real max RSSI and stick here */ |
| 5384 | range->max_qual.level = 0; | 5450 | range->max_qual.level = 0; |
| 5385 | range->max_qual.noise = 0; | 5451 | range->max_qual.noise = 0; |
| 5386 | range->max_qual.updated = 7; /* Updated all three */ | 5452 | range->max_qual.updated = 7; /* Updated all three */ |
| 5387 | 5453 | ||
| 5388 | range->avg_qual.qual = 70; | 5454 | range->avg_qual.qual = 70; |
| 5389 | /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ | 5455 | /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ |
| 5390 | range->avg_qual.level = 0; /* FIXME to real average level */ | 5456 | range->avg_qual.level = 0; /* FIXME to real average level */ |
| 5391 | range->avg_qual.noise = 0; | 5457 | range->avg_qual.noise = 0; |
| 5392 | range->avg_qual.updated = 7; /* Updated all three */ | 5458 | range->avg_qual.updated = 7; /* Updated all three */ |
| 5393 | 5459 | ||
| 5394 | range->num_bitrates = min(priv->rates.num_rates, (u8)IW_MAX_BITRATES); | 5460 | range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); |
| 5395 | 5461 | ||
| 5396 | for (i = 0; i < range->num_bitrates; i++) | 5462 | for (i = 0; i < range->num_bitrates; i++) |
| 5397 | range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) * | 5463 | range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) * |
| 5398 | 500000; | 5464 | 500000; |
| 5399 | 5465 | ||
| 5400 | range->max_rts = DEFAULT_RTS_THRESHOLD; | 5466 | range->max_rts = DEFAULT_RTS_THRESHOLD; |
| 5401 | range->min_frag = MIN_FRAG_THRESHOLD; | 5467 | range->min_frag = MIN_FRAG_THRESHOLD; |
| @@ -5410,7 +5476,7 @@ static int ipw_wx_get_range(struct net_device *dev, | |||
| 5410 | range->we_version_compiled = WIRELESS_EXT; | 5476 | range->we_version_compiled = WIRELESS_EXT; |
| 5411 | range->we_version_source = 16; | 5477 | range->we_version_source = 16; |
| 5412 | 5478 | ||
| 5413 | range->num_channels = FREQ_COUNT; | 5479 | range->num_channels = FREQ_COUNT; |
| 5414 | 5480 | ||
| 5415 | val = 0; | 5481 | val = 0; |
| 5416 | for (i = 0; i < FREQ_COUNT; i++) { | 5482 | for (i = 0; i < FREQ_COUNT; i++) { |
| @@ -5506,7 +5572,7 @@ static int ipw_wx_set_essid(struct net_device *dev, | |||
| 5506 | union iwreq_data *wrqu, char *extra) | 5572 | union iwreq_data *wrqu, char *extra) |
| 5507 | { | 5573 | { |
| 5508 | struct ipw_priv *priv = ieee80211_priv(dev); | 5574 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5509 | char *essid = ""; /* ANY */ | 5575 | char *essid = ""; /* ANY */ |
| 5510 | int length = 0; | 5576 | int length = 0; |
| 5511 | 5577 | ||
| 5512 | if (wrqu->essid.flags && wrqu->essid.length) { | 5578 | if (wrqu->essid.flags && wrqu->essid.length) { |
| @@ -5567,11 +5633,11 @@ static int ipw_wx_get_essid(struct net_device *dev, | |||
| 5567 | escape_essid(priv->essid, priv->essid_len)); | 5633 | escape_essid(priv->essid, priv->essid_len)); |
| 5568 | memcpy(extra, priv->essid, priv->essid_len); | 5634 | memcpy(extra, priv->essid, priv->essid_len); |
| 5569 | wrqu->essid.length = priv->essid_len; | 5635 | wrqu->essid.length = priv->essid_len; |
| 5570 | wrqu->essid.flags = 1; /* active */ | 5636 | wrqu->essid.flags = 1; /* active */ |
| 5571 | } else { | 5637 | } else { |
| 5572 | IPW_DEBUG_WX("Getting essid: ANY\n"); | 5638 | IPW_DEBUG_WX("Getting essid: ANY\n"); |
| 5573 | wrqu->essid.length = 0; | 5639 | wrqu->essid.length = 0; |
| 5574 | wrqu->essid.flags = 0; /* active */ | 5640 | wrqu->essid.flags = 0; /* active */ |
| 5575 | } | 5641 | } |
| 5576 | 5642 | ||
| 5577 | return 0; | 5643 | return 0; |
| @@ -5587,15 +5653,14 @@ static int ipw_wx_set_nick(struct net_device *dev, | |||
| 5587 | if (wrqu->data.length > IW_ESSID_MAX_SIZE) | 5653 | if (wrqu->data.length > IW_ESSID_MAX_SIZE) |
| 5588 | return -E2BIG; | 5654 | return -E2BIG; |
| 5589 | 5655 | ||
| 5590 | wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick)); | 5656 | wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); |
| 5591 | memset(priv->nick, 0, sizeof(priv->nick)); | 5657 | memset(priv->nick, 0, sizeof(priv->nick)); |
| 5592 | memcpy(priv->nick, extra, wrqu->data.length); | 5658 | memcpy(priv->nick, extra, wrqu->data.length); |
| 5593 | IPW_DEBUG_TRACE("<<\n"); | 5659 | IPW_DEBUG_TRACE("<<\n"); |
| 5594 | return 0; | 5660 | return 0; |
| 5595 | 5661 | ||
| 5596 | } | 5662 | } |
| 5597 | 5663 | ||
| 5598 | |||
| 5599 | static int ipw_wx_get_nick(struct net_device *dev, | 5664 | static int ipw_wx_get_nick(struct net_device *dev, |
| 5600 | struct iw_request_info *info, | 5665 | struct iw_request_info *info, |
| 5601 | union iwreq_data *wrqu, char *extra) | 5666 | union iwreq_data *wrqu, char *extra) |
| @@ -5604,11 +5669,10 @@ static int ipw_wx_get_nick(struct net_device *dev, | |||
| 5604 | IPW_DEBUG_WX("Getting nick\n"); | 5669 | IPW_DEBUG_WX("Getting nick\n"); |
| 5605 | wrqu->data.length = strlen(priv->nick) + 1; | 5670 | wrqu->data.length = strlen(priv->nick) + 1; |
| 5606 | memcpy(extra, priv->nick, wrqu->data.length); | 5671 | memcpy(extra, priv->nick, wrqu->data.length); |
| 5607 | wrqu->data.flags = 1; /* active */ | 5672 | wrqu->data.flags = 1; /* active */ |
| 5608 | return 0; | 5673 | return 0; |
| 5609 | } | 5674 | } |
| 5610 | 5675 | ||
| 5611 | |||
| 5612 | static int ipw_wx_set_rate(struct net_device *dev, | 5676 | static int ipw_wx_set_rate(struct net_device *dev, |
| 5613 | struct iw_request_info *info, | 5677 | struct iw_request_info *info, |
| 5614 | union iwreq_data *wrqu, char *extra) | 5678 | union iwreq_data *wrqu, char *extra) |
| @@ -5621,14 +5685,13 @@ static int ipw_wx_get_rate(struct net_device *dev, | |||
| 5621 | struct iw_request_info *info, | 5685 | struct iw_request_info *info, |
| 5622 | union iwreq_data *wrqu, char *extra) | 5686 | union iwreq_data *wrqu, char *extra) |
| 5623 | { | 5687 | { |
| 5624 | struct ipw_priv * priv = ieee80211_priv(dev); | 5688 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5625 | wrqu->bitrate.value = priv->last_rate; | 5689 | wrqu->bitrate.value = priv->last_rate; |
| 5626 | 5690 | ||
| 5627 | IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); | 5691 | IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); |
| 5628 | return 0; | 5692 | return 0; |
| 5629 | } | 5693 | } |
| 5630 | 5694 | ||
| 5631 | |||
| 5632 | static int ipw_wx_set_rts(struct net_device *dev, | 5695 | static int ipw_wx_set_rts(struct net_device *dev, |
| 5633 | struct iw_request_info *info, | 5696 | struct iw_request_info *info, |
| 5634 | union iwreq_data *wrqu, char *extra) | 5697 | union iwreq_data *wrqu, char *extra) |
| @@ -5657,14 +5720,12 @@ static int ipw_wx_get_rts(struct net_device *dev, | |||
| 5657 | struct ipw_priv *priv = ieee80211_priv(dev); | 5720 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5658 | wrqu->rts.value = priv->rts_threshold; | 5721 | wrqu->rts.value = priv->rts_threshold; |
| 5659 | wrqu->rts.fixed = 0; /* no auto select */ | 5722 | wrqu->rts.fixed = 0; /* no auto select */ |
| 5660 | wrqu->rts.disabled = | 5723 | wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); |
| 5661 | (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); | ||
| 5662 | 5724 | ||
| 5663 | IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); | 5725 | IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); |
| 5664 | return 0; | 5726 | return 0; |
| 5665 | } | 5727 | } |
| 5666 | 5728 | ||
| 5667 | |||
| 5668 | static int ipw_wx_set_txpow(struct net_device *dev, | 5729 | static int ipw_wx_set_txpow(struct net_device *dev, |
| 5669 | struct iw_request_info *info, | 5730 | struct iw_request_info *info, |
| 5670 | union iwreq_data *wrqu, char *extra) | 5731 | union iwreq_data *wrqu, char *extra) |
| @@ -5679,8 +5740,7 @@ static int ipw_wx_set_txpow(struct net_device *dev, | |||
| 5679 | if (wrqu->power.flags != IW_TXPOW_DBM) | 5740 | if (wrqu->power.flags != IW_TXPOW_DBM) |
| 5680 | return -EINVAL; | 5741 | return -EINVAL; |
| 5681 | 5742 | ||
| 5682 | if ((wrqu->power.value > 20) || | 5743 | if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) |
| 5683 | (wrqu->power.value < -12)) | ||
| 5684 | return -EINVAL; | 5744 | return -EINVAL; |
| 5685 | 5745 | ||
| 5686 | priv->tx_power = wrqu->power.value; | 5746 | priv->tx_power = wrqu->power.value; |
| @@ -5704,11 +5764,10 @@ static int ipw_wx_set_txpow(struct net_device *dev, | |||
| 5704 | 5764 | ||
| 5705 | return 0; | 5765 | return 0; |
| 5706 | 5766 | ||
| 5707 | error: | 5767 | error: |
| 5708 | return -EIO; | 5768 | return -EIO; |
| 5709 | } | 5769 | } |
| 5710 | 5770 | ||
| 5711 | |||
| 5712 | static int ipw_wx_get_txpow(struct net_device *dev, | 5771 | static int ipw_wx_get_txpow(struct net_device *dev, |
| 5713 | struct iw_request_info *info, | 5772 | struct iw_request_info *info, |
| 5714 | union iwreq_data *wrqu, char *extra) | 5773 | union iwreq_data *wrqu, char *extra) |
| @@ -5721,15 +5780,14 @@ static int ipw_wx_get_txpow(struct net_device *dev, | |||
| 5721 | wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; | 5780 | wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; |
| 5722 | 5781 | ||
| 5723 | IPW_DEBUG_WX("GET TX Power -> %s %d \n", | 5782 | IPW_DEBUG_WX("GET TX Power -> %s %d \n", |
| 5724 | wrqu->power.disabled ? "ON" : "OFF", | 5783 | wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value); |
| 5725 | wrqu->power.value); | ||
| 5726 | 5784 | ||
| 5727 | return 0; | 5785 | return 0; |
| 5728 | } | 5786 | } |
| 5729 | 5787 | ||
| 5730 | static int ipw_wx_set_frag(struct net_device *dev, | 5788 | static int ipw_wx_set_frag(struct net_device *dev, |
| 5731 | struct iw_request_info *info, | 5789 | struct iw_request_info *info, |
| 5732 | union iwreq_data *wrqu, char *extra) | 5790 | union iwreq_data *wrqu, char *extra) |
| 5733 | { | 5791 | { |
| 5734 | struct ipw_priv *priv = ieee80211_priv(dev); | 5792 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5735 | 5793 | ||
| @@ -5749,14 +5807,13 @@ static int ipw_wx_set_frag(struct net_device *dev, | |||
| 5749 | } | 5807 | } |
| 5750 | 5808 | ||
| 5751 | static int ipw_wx_get_frag(struct net_device *dev, | 5809 | static int ipw_wx_get_frag(struct net_device *dev, |
| 5752 | struct iw_request_info *info, | 5810 | struct iw_request_info *info, |
| 5753 | union iwreq_data *wrqu, char *extra) | 5811 | union iwreq_data *wrqu, char *extra) |
| 5754 | { | 5812 | { |
| 5755 | struct ipw_priv *priv = ieee80211_priv(dev); | 5813 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5756 | wrqu->frag.value = priv->ieee->fts; | 5814 | wrqu->frag.value = priv->ieee->fts; |
| 5757 | wrqu->frag.fixed = 0; /* no auto select */ | 5815 | wrqu->frag.fixed = 0; /* no auto select */ |
| 5758 | wrqu->frag.disabled = | 5816 | wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); |
| 5759 | (wrqu->frag.value == DEFAULT_FTS); | ||
| 5760 | 5817 | ||
| 5761 | IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); | 5818 | IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); |
| 5762 | 5819 | ||
| @@ -5771,7 +5828,6 @@ static int ipw_wx_set_retry(struct net_device *dev, | |||
| 5771 | return -EOPNOTSUPP; | 5828 | return -EOPNOTSUPP; |
| 5772 | } | 5829 | } |
| 5773 | 5830 | ||
| 5774 | |||
| 5775 | static int ipw_wx_get_retry(struct net_device *dev, | 5831 | static int ipw_wx_get_retry(struct net_device *dev, |
| 5776 | struct iw_request_info *info, | 5832 | struct iw_request_info *info, |
| 5777 | union iwreq_data *wrqu, char *extra) | 5833 | union iwreq_data *wrqu, char *extra) |
| @@ -5780,7 +5836,6 @@ static int ipw_wx_get_retry(struct net_device *dev, | |||
| 5780 | return -EOPNOTSUPP; | 5836 | return -EOPNOTSUPP; |
| 5781 | } | 5837 | } |
| 5782 | 5838 | ||
| 5783 | |||
| 5784 | static int ipw_wx_set_scan(struct net_device *dev, | 5839 | static int ipw_wx_set_scan(struct net_device *dev, |
| 5785 | struct iw_request_info *info, | 5840 | struct iw_request_info *info, |
| 5786 | union iwreq_data *wrqu, char *extra) | 5841 | union iwreq_data *wrqu, char *extra) |
| @@ -5801,24 +5856,24 @@ static int ipw_wx_get_scan(struct net_device *dev, | |||
| 5801 | } | 5856 | } |
| 5802 | 5857 | ||
| 5803 | static int ipw_wx_set_encode(struct net_device *dev, | 5858 | static int ipw_wx_set_encode(struct net_device *dev, |
| 5804 | struct iw_request_info *info, | 5859 | struct iw_request_info *info, |
| 5805 | union iwreq_data *wrqu, char *key) | 5860 | union iwreq_data *wrqu, char *key) |
| 5806 | { | 5861 | { |
| 5807 | struct ipw_priv *priv = ieee80211_priv(dev); | 5862 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5808 | return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); | 5863 | return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); |
| 5809 | } | 5864 | } |
| 5810 | 5865 | ||
| 5811 | static int ipw_wx_get_encode(struct net_device *dev, | 5866 | static int ipw_wx_get_encode(struct net_device *dev, |
| 5812 | struct iw_request_info *info, | 5867 | struct iw_request_info *info, |
| 5813 | union iwreq_data *wrqu, char *key) | 5868 | union iwreq_data *wrqu, char *key) |
| 5814 | { | 5869 | { |
| 5815 | struct ipw_priv *priv = ieee80211_priv(dev); | 5870 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5816 | return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key); | 5871 | return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key); |
| 5817 | } | 5872 | } |
| 5818 | 5873 | ||
| 5819 | static int ipw_wx_set_power(struct net_device *dev, | 5874 | static int ipw_wx_set_power(struct net_device *dev, |
| 5820 | struct iw_request_info *info, | 5875 | struct iw_request_info *info, |
| 5821 | union iwreq_data *wrqu, char *extra) | 5876 | union iwreq_data *wrqu, char *extra) |
| 5822 | { | 5877 | { |
| 5823 | struct ipw_priv *priv = ieee80211_priv(dev); | 5878 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5824 | int err; | 5879 | int err; |
| @@ -5837,11 +5892,11 @@ static int ipw_wx_set_power(struct net_device *dev, | |||
| 5837 | } | 5892 | } |
| 5838 | 5893 | ||
| 5839 | switch (wrqu->power.flags & IW_POWER_MODE) { | 5894 | switch (wrqu->power.flags & IW_POWER_MODE) { |
| 5840 | case IW_POWER_ON: /* If not specified */ | 5895 | case IW_POWER_ON: /* If not specified */ |
| 5841 | case IW_POWER_MODE: /* If set all mask */ | 5896 | case IW_POWER_MODE: /* If set all mask */ |
| 5842 | case IW_POWER_ALL_R: /* If explicitely state all */ | 5897 | case IW_POWER_ALL_R: /* If explicitely state all */ |
| 5843 | break; | 5898 | break; |
| 5844 | default: /* Otherwise we don't support it */ | 5899 | default: /* Otherwise we don't support it */ |
| 5845 | IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", | 5900 | IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", |
| 5846 | wrqu->power.flags); | 5901 | wrqu->power.flags); |
| 5847 | return -EOPNOTSUPP; | 5902 | return -EOPNOTSUPP; |
| @@ -5849,7 +5904,7 @@ static int ipw_wx_set_power(struct net_device *dev, | |||
| 5849 | 5904 | ||
| 5850 | /* If the user hasn't specified a power management mode yet, default | 5905 | /* If the user hasn't specified a power management mode yet, default |
| 5851 | * to BATTERY */ | 5906 | * to BATTERY */ |
| 5852 | if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC) | 5907 | if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC) |
| 5853 | priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY; | 5908 | priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY; |
| 5854 | else | 5909 | else |
| 5855 | priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; | 5910 | priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; |
| @@ -5859,15 +5914,14 @@ static int ipw_wx_set_power(struct net_device *dev, | |||
| 5859 | return err; | 5914 | return err; |
| 5860 | } | 5915 | } |
| 5861 | 5916 | ||
| 5862 | IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", | 5917 | IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); |
| 5863 | priv->power_mode); | ||
| 5864 | 5918 | ||
| 5865 | return 0; | 5919 | return 0; |
| 5866 | } | 5920 | } |
| 5867 | 5921 | ||
| 5868 | static int ipw_wx_get_power(struct net_device *dev, | 5922 | static int ipw_wx_get_power(struct net_device *dev, |
| 5869 | struct iw_request_info *info, | 5923 | struct iw_request_info *info, |
| 5870 | union iwreq_data *wrqu, char *extra) | 5924 | union iwreq_data *wrqu, char *extra) |
| 5871 | { | 5925 | { |
| 5872 | struct ipw_priv *priv = ieee80211_priv(dev); | 5926 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5873 | 5927 | ||
| @@ -5883,8 +5937,8 @@ static int ipw_wx_get_power(struct net_device *dev, | |||
| 5883 | } | 5937 | } |
| 5884 | 5938 | ||
| 5885 | static int ipw_wx_set_powermode(struct net_device *dev, | 5939 | static int ipw_wx_set_powermode(struct net_device *dev, |
| 5886 | struct iw_request_info *info, | 5940 | struct iw_request_info *info, |
| 5887 | union iwreq_data *wrqu, char *extra) | 5941 | union iwreq_data *wrqu, char *extra) |
| 5888 | { | 5942 | { |
| 5889 | struct ipw_priv *priv = ieee80211_priv(dev); | 5943 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5890 | int mode = *(int *)extra; | 5944 | int mode = *(int *)extra; |
| @@ -5911,8 +5965,8 @@ static int ipw_wx_set_powermode(struct net_device *dev, | |||
| 5911 | 5965 | ||
| 5912 | #define MAX_WX_STRING 80 | 5966 | #define MAX_WX_STRING 80 |
| 5913 | static int ipw_wx_get_powermode(struct net_device *dev, | 5967 | static int ipw_wx_get_powermode(struct net_device *dev, |
| 5914 | struct iw_request_info *info, | 5968 | struct iw_request_info *info, |
| 5915 | union iwreq_data *wrqu, char *extra) | 5969 | union iwreq_data *wrqu, char *extra) |
| 5916 | { | 5970 | { |
| 5917 | struct ipw_priv *priv = ieee80211_priv(dev); | 5971 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5918 | int level = IPW_POWER_LEVEL(priv->power_mode); | 5972 | int level = IPW_POWER_LEVEL(priv->power_mode); |
| @@ -5935,7 +5989,7 @@ static int ipw_wx_get_powermode(struct net_device *dev, | |||
| 5935 | } | 5989 | } |
| 5936 | 5990 | ||
| 5937 | if (!(priv->power_mode & IPW_POWER_ENABLED)) | 5991 | if (!(priv->power_mode & IPW_POWER_ENABLED)) |
| 5938 | p += snprintf(p, MAX_WX_STRING - (p - extra)," OFF"); | 5992 | p += snprintf(p, MAX_WX_STRING - (p - extra), " OFF"); |
| 5939 | 5993 | ||
| 5940 | wrqu->data.length = p - extra + 1; | 5994 | wrqu->data.length = p - extra + 1; |
| 5941 | 5995 | ||
| @@ -5943,16 +5997,15 @@ static int ipw_wx_get_powermode(struct net_device *dev, | |||
| 5943 | } | 5997 | } |
| 5944 | 5998 | ||
| 5945 | static int ipw_wx_set_wireless_mode(struct net_device *dev, | 5999 | static int ipw_wx_set_wireless_mode(struct net_device *dev, |
| 5946 | struct iw_request_info *info, | 6000 | struct iw_request_info *info, |
| 5947 | union iwreq_data *wrqu, char *extra) | 6001 | union iwreq_data *wrqu, char *extra) |
| 5948 | { | 6002 | { |
| 5949 | struct ipw_priv *priv = ieee80211_priv(dev); | 6003 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 5950 | int mode = *(int *)extra; | 6004 | int mode = *(int *)extra; |
| 5951 | u8 band = 0, modulation = 0; | 6005 | u8 band = 0, modulation = 0; |
| 5952 | 6006 | ||
| 5953 | if (mode == 0 || mode & ~IEEE_MODE_MASK) { | 6007 | if (mode == 0 || mode & ~IEEE_MODE_MASK) { |
| 5954 | IPW_WARNING("Attempt to set invalid wireless mode: %d\n", | 6008 | IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); |
| 5955 | mode); | ||
| 5956 | return -EINVAL; | 6009 | return -EINVAL; |
| 5957 | } | 6010 | } |
| 5958 | 6011 | ||
| @@ -5988,31 +6041,30 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, | |||
| 5988 | priv->ieee->mode = mode; | 6041 | priv->ieee->mode = mode; |
| 5989 | priv->ieee->freq_band = band; | 6042 | priv->ieee->freq_band = band; |
| 5990 | priv->ieee->modulation = modulation; | 6043 | priv->ieee->modulation = modulation; |
| 5991 | init_supported_rates(priv, &priv->rates); | 6044 | init_supported_rates(priv, &priv->rates); |
| 5992 | 6045 | ||
| 5993 | /* If we are currently associated, or trying to associate | 6046 | /* If we are currently associated, or trying to associate |
| 5994 | * then see if this is a new configuration (causing us to | 6047 | * then see if this is a new configuration (causing us to |
| 5995 | * disassociate) */ | 6048 | * disassociate) */ |
| 5996 | if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { | 6049 | if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { |
| 5997 | /* The resulting association will trigger | 6050 | /* The resulting association will trigger |
| 5998 | * the new rates to be sent to the device */ | 6051 | * the new rates to be sent to the device */ |
| 5999 | IPW_DEBUG_ASSOC("Disassociating due to mode change.\n"); | 6052 | IPW_DEBUG_ASSOC("Disassociating due to mode change.\n"); |
| 6000 | ipw_disassociate(priv); | 6053 | ipw_disassociate(priv); |
| 6001 | } else | 6054 | } else |
| 6002 | ipw_send_supported_rates(priv, &priv->rates); | 6055 | ipw_send_supported_rates(priv, &priv->rates); |
| 6003 | 6056 | ||
| 6004 | IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", | 6057 | IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", |
| 6005 | mode & IEEE_A ? 'a' : '.', | 6058 | mode & IEEE_A ? 'a' : '.', |
| 6006 | mode & IEEE_B ? 'b' : '.', | 6059 | mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); |
| 6007 | mode & IEEE_G ? 'g' : '.'); | ||
| 6008 | return 0; | 6060 | return 0; |
| 6009 | } | 6061 | } |
| 6010 | 6062 | ||
| 6011 | static int ipw_wx_get_wireless_mode(struct net_device *dev, | 6063 | static int ipw_wx_get_wireless_mode(struct net_device *dev, |
| 6012 | struct iw_request_info *info, | 6064 | struct iw_request_info *info, |
| 6013 | union iwreq_data *wrqu, char *extra) | 6065 | union iwreq_data *wrqu, char *extra) |
| 6014 | { | 6066 | { |
| 6015 | struct ipw_priv *priv = ieee80211_priv(dev); | 6067 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 6016 | 6068 | ||
| 6017 | switch (priv->ieee->freq_band) { | 6069 | switch (priv->ieee->freq_band) { |
| 6018 | case IEEE80211_24GHZ_BAND: | 6070 | case IEEE80211_24GHZ_BAND: |
| @@ -6033,7 +6085,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, | |||
| 6033 | strncpy(extra, "802.11a (1)", MAX_WX_STRING); | 6085 | strncpy(extra, "802.11a (1)", MAX_WX_STRING); |
| 6034 | break; | 6086 | break; |
| 6035 | 6087 | ||
| 6036 | default: /* Mixed Band */ | 6088 | default: /* Mixed Band */ |
| 6037 | switch (priv->ieee->modulation) { | 6089 | switch (priv->ieee->modulation) { |
| 6038 | case IEEE80211_CCK_MODULATION: | 6090 | case IEEE80211_CCK_MODULATION: |
| 6039 | strncpy(extra, "802.11ab (3)", MAX_WX_STRING); | 6091 | strncpy(extra, "802.11ab (3)", MAX_WX_STRING); |
| @@ -6050,9 +6102,9 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, | |||
| 6050 | 6102 | ||
| 6051 | IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); | 6103 | IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); |
| 6052 | 6104 | ||
| 6053 | wrqu->data.length = strlen(extra) + 1; | 6105 | wrqu->data.length = strlen(extra) + 1; |
| 6054 | 6106 | ||
| 6055 | return 0; | 6107 | return 0; |
| 6056 | } | 6108 | } |
| 6057 | 6109 | ||
| 6058 | #ifdef CONFIG_IPW_PROMISC | 6110 | #ifdef CONFIG_IPW_PROMISC |
| @@ -6081,7 +6133,6 @@ static int ipw_wx_set_promisc(struct net_device *dev, | |||
| 6081 | return 0; | 6133 | return 0; |
| 6082 | } | 6134 | } |
| 6083 | 6135 | ||
| 6084 | |||
| 6085 | static int ipw_wx_reset(struct net_device *dev, | 6136 | static int ipw_wx_reset(struct net_device *dev, |
| 6086 | struct iw_request_info *info, | 6137 | struct iw_request_info *info, |
| 6087 | union iwreq_data *wrqu, char *extra) | 6138 | union iwreq_data *wrqu, char *extra) |
| @@ -6091,40 +6142,39 @@ static int ipw_wx_reset(struct net_device *dev, | |||
| 6091 | ipw_adapter_restart(priv); | 6142 | ipw_adapter_restart(priv); |
| 6092 | return 0; | 6143 | return 0; |
| 6093 | } | 6144 | } |
| 6094 | #endif // CONFIG_IPW_PROMISC | 6145 | #endif // CONFIG_IPW_PROMISC |
| 6095 | 6146 | ||
| 6096 | /* Rebase the WE IOCTLs to zero for the handler array */ | 6147 | /* Rebase the WE IOCTLs to zero for the handler array */ |
| 6097 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] | 6148 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] |
| 6098 | static iw_handler ipw_wx_handlers[] = | 6149 | static iw_handler ipw_wx_handlers[] = { |
| 6099 | { | 6150 | IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, |
| 6100 | IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, | 6151 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, |
| 6101 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, | 6152 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, |
| 6102 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, | 6153 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, |
| 6103 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, | 6154 | IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, |
| 6104 | IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, | 6155 | IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, |
| 6105 | IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, | 6156 | IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, |
| 6106 | IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, | 6157 | IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, |
| 6107 | IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, | 6158 | IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, |
| 6108 | IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, | 6159 | IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, |
| 6109 | IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, | 6160 | IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, |
| 6110 | IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, | 6161 | IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, |
| 6111 | IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, | 6162 | IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, |
| 6112 | IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, | 6163 | IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, |
| 6113 | IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, | 6164 | IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, |
| 6114 | IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, | 6165 | IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, |
| 6115 | IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, | 6166 | IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, |
| 6116 | IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, | 6167 | IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, |
| 6117 | IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, | 6168 | IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, |
| 6118 | IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, | 6169 | IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, |
| 6119 | IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, | 6170 | IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, |
| 6120 | IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, | 6171 | IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, |
| 6121 | IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, | 6172 | IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, |
| 6122 | IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, | 6173 | IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, |
| 6123 | IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, | 6174 | IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, |
| 6124 | IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, | 6175 | IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, |
| 6125 | IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, | 6176 | IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, |
| 6126 | IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, | 6177 | IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, |
| 6127 | IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, | ||
| 6128 | }; | 6178 | }; |
| 6129 | 6179 | ||
| 6130 | #define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV | 6180 | #define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV |
| @@ -6134,38 +6184,31 @@ static iw_handler ipw_wx_handlers[] = | |||
| 6134 | #define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4 | 6184 | #define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4 |
| 6135 | #define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 | 6185 | #define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 |
| 6136 | 6186 | ||
| 6137 | |||
| 6138 | static struct iw_priv_args ipw_priv_args[] = { | 6187 | static struct iw_priv_args ipw_priv_args[] = { |
| 6139 | { | 6188 | { |
| 6140 | .cmd = IPW_PRIV_SET_POWER, | 6189 | .cmd = IPW_PRIV_SET_POWER, |
| 6141 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 6190 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
| 6142 | .name = "set_power" | 6191 | .name = "set_power"}, |
| 6143 | }, | ||
| 6144 | { | 6192 | { |
| 6145 | .cmd = IPW_PRIV_GET_POWER, | 6193 | .cmd = IPW_PRIV_GET_POWER, |
| 6146 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, | 6194 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, |
| 6147 | .name = "get_power" | 6195 | .name = "get_power"}, |
| 6148 | }, | ||
| 6149 | { | 6196 | { |
| 6150 | .cmd = IPW_PRIV_SET_MODE, | 6197 | .cmd = IPW_PRIV_SET_MODE, |
| 6151 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 6198 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
| 6152 | .name = "set_mode" | 6199 | .name = "set_mode"}, |
| 6153 | }, | ||
| 6154 | { | 6200 | { |
| 6155 | .cmd = IPW_PRIV_GET_MODE, | 6201 | .cmd = IPW_PRIV_GET_MODE, |
| 6156 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, | 6202 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, |
| 6157 | .name = "get_mode" | 6203 | .name = "get_mode"}, |
| 6158 | }, | ||
| 6159 | #ifdef CONFIG_IPW_PROMISC | 6204 | #ifdef CONFIG_IPW_PROMISC |
| 6160 | { | 6205 | { |
| 6161 | IPW_PRIV_SET_PROMISC, | 6206 | IPW_PRIV_SET_PROMISC, |
| 6162 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor" | 6207 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"}, |
| 6163 | }, | ||
| 6164 | { | 6208 | { |
| 6165 | IPW_PRIV_RESET, | 6209 | IPW_PRIV_RESET, |
| 6166 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset" | 6210 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"}, |
| 6167 | }, | 6211 | #endif /* CONFIG_IPW_PROMISC */ |
| 6168 | #endif /* CONFIG_IPW_PROMISC */ | ||
| 6169 | }; | 6212 | }; |
| 6170 | 6213 | ||
| 6171 | static iw_handler ipw_priv_handler[] = { | 6214 | static iw_handler ipw_priv_handler[] = { |
| @@ -6179,25 +6222,21 @@ static iw_handler ipw_priv_handler[] = { | |||
| 6179 | #endif | 6222 | #endif |
| 6180 | }; | 6223 | }; |
| 6181 | 6224 | ||
| 6182 | static struct iw_handler_def ipw_wx_handler_def = | 6225 | static struct iw_handler_def ipw_wx_handler_def = { |
| 6183 | { | 6226 | .standard = ipw_wx_handlers, |
| 6184 | .standard = ipw_wx_handlers, | 6227 | .num_standard = ARRAY_SIZE(ipw_wx_handlers), |
| 6185 | .num_standard = ARRAY_SIZE(ipw_wx_handlers), | 6228 | .num_private = ARRAY_SIZE(ipw_priv_handler), |
| 6186 | .num_private = ARRAY_SIZE(ipw_priv_handler), | 6229 | .num_private_args = ARRAY_SIZE(ipw_priv_args), |
| 6187 | .num_private_args = ARRAY_SIZE(ipw_priv_args), | 6230 | .private = ipw_priv_handler, |
| 6188 | .private = ipw_priv_handler, | 6231 | .private_args = ipw_priv_args, |
| 6189 | .private_args = ipw_priv_args, | ||
| 6190 | }; | 6232 | }; |
| 6191 | 6233 | ||
| 6192 | |||
| 6193 | |||
| 6194 | |||
| 6195 | /* | 6234 | /* |
| 6196 | * Get wireless statistics. | 6235 | * Get wireless statistics. |
| 6197 | * Called by /proc/net/wireless | 6236 | * Called by /proc/net/wireless |
| 6198 | * Also called by SIOCGIWSTATS | 6237 | * Also called by SIOCGIWSTATS |
| 6199 | */ | 6238 | */ |
| 6200 | static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev) | 6239 | static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev) |
| 6201 | { | 6240 | { |
| 6202 | struct ipw_priv *priv = ieee80211_priv(dev); | 6241 | struct ipw_priv *priv = ieee80211_priv(dev); |
| 6203 | struct iw_statistics *wstats; | 6242 | struct iw_statistics *wstats; |
| @@ -6217,7 +6256,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev) | |||
| 6217 | wstats->qual.noise = 0; | 6256 | wstats->qual.noise = 0; |
| 6218 | wstats->qual.updated = 7; | 6257 | wstats->qual.updated = 7; |
| 6219 | wstats->qual.updated |= IW_QUAL_NOISE_INVALID | | 6258 | wstats->qual.updated |= IW_QUAL_NOISE_INVALID | |
| 6220 | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; | 6259 | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; |
| 6221 | return wstats; | 6260 | return wstats; |
| 6222 | } | 6261 | } |
| 6223 | 6262 | ||
| @@ -6225,7 +6264,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev) | |||
| 6225 | wstats->qual.level = average_value(&priv->average_rssi); | 6264 | wstats->qual.level = average_value(&priv->average_rssi); |
| 6226 | wstats->qual.noise = average_value(&priv->average_noise); | 6265 | wstats->qual.noise = average_value(&priv->average_noise); |
| 6227 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | | 6266 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | |
| 6228 | IW_QUAL_NOISE_UPDATED; | 6267 | IW_QUAL_NOISE_UPDATED; |
| 6229 | 6268 | ||
| 6230 | wstats->miss.beacon = average_value(&priv->average_missed_beacons); | 6269 | wstats->miss.beacon = average_value(&priv->average_missed_beacons); |
| 6231 | wstats->discard.retries = priv->last_tx_failures; | 6270 | wstats->discard.retries = priv->last_tx_failures; |
| @@ -6238,13 +6277,12 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev) | |||
| 6238 | return wstats; | 6277 | return wstats; |
| 6239 | } | 6278 | } |
| 6240 | 6279 | ||
| 6241 | |||
| 6242 | /* net device stuff */ | 6280 | /* net device stuff */ |
| 6243 | 6281 | ||
| 6244 | static inline void init_sys_config(struct ipw_sys_config *sys_config) | 6282 | static inline void init_sys_config(struct ipw_sys_config *sys_config) |
| 6245 | { | 6283 | { |
| 6246 | memset(sys_config, 0, sizeof(struct ipw_sys_config)); | 6284 | memset(sys_config, 0, sizeof(struct ipw_sys_config)); |
| 6247 | sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */ | 6285 | sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */ |
| 6248 | sys_config->answer_broadcast_ssid_probe = 0; | 6286 | sys_config->answer_broadcast_ssid_probe = 0; |
| 6249 | sys_config->accept_all_data_frames = 0; | 6287 | sys_config->accept_all_data_frames = 0; |
| 6250 | sys_config->accept_non_directed_frames = 1; | 6288 | sys_config->accept_non_directed_frames = 1; |
| @@ -6253,7 +6291,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config) | |||
| 6253 | sys_config->exclude_multicast_unencrypted = 0; | 6291 | sys_config->exclude_multicast_unencrypted = 0; |
| 6254 | sys_config->disable_multicast_decryption = 1; | 6292 | sys_config->disable_multicast_decryption = 1; |
| 6255 | sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH; | 6293 | sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH; |
| 6256 | sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */ | 6294 | sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */ |
| 6257 | sys_config->dot11g_auto_detection = 0; | 6295 | sys_config->dot11g_auto_detection = 0; |
| 6258 | sys_config->enable_cts_to_self = 0; | 6296 | sys_config->enable_cts_to_self = 0; |
| 6259 | sys_config->bt_coexist_collision_thr = 0; | 6297 | sys_config->bt_coexist_collision_thr = 0; |
| @@ -6288,7 +6326,7 @@ we need to heavily modify the ieee80211_skb_to_txb. | |||
| 6288 | static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) | 6326 | static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) |
| 6289 | { | 6327 | { |
| 6290 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) | 6328 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) |
| 6291 | txb->fragments[0]->data; | 6329 | txb->fragments[0]->data; |
| 6292 | int i = 0; | 6330 | int i = 0; |
| 6293 | struct tfd_frame *tfd; | 6331 | struct tfd_frame *tfd; |
| 6294 | struct clx2_tx_queue *txq = &priv->txq[0]; | 6332 | struct clx2_tx_queue *txq = &priv->txq[0]; |
| @@ -6300,7 +6338,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) | |||
| 6300 | case IW_MODE_ADHOC: | 6338 | case IW_MODE_ADHOC: |
| 6301 | hdr_len = IEEE80211_3ADDR_LEN; | 6339 | hdr_len = IEEE80211_3ADDR_LEN; |
| 6302 | unicast = !is_broadcast_ether_addr(hdr->addr1) && | 6340 | unicast = !is_broadcast_ether_addr(hdr->addr1) && |
| 6303 | !is_multicast_ether_addr(hdr->addr1); | 6341 | !is_multicast_ether_addr(hdr->addr1); |
| 6304 | id = ipw_find_station(priv, hdr->addr1); | 6342 | id = ipw_find_station(priv, hdr->addr1); |
| 6305 | if (id == IPW_INVALID_STATION) { | 6343 | if (id == IPW_INVALID_STATION) { |
| 6306 | id = ipw_add_station(priv, hdr->addr1); | 6344 | id = ipw_add_station(priv, hdr->addr1); |
| @@ -6316,7 +6354,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) | |||
| 6316 | case IW_MODE_INFRA: | 6354 | case IW_MODE_INFRA: |
| 6317 | default: | 6355 | default: |
| 6318 | unicast = !is_broadcast_ether_addr(hdr->addr3) && | 6356 | unicast = !is_broadcast_ether_addr(hdr->addr3) && |
| 6319 | !is_multicast_ether_addr(hdr->addr3); | 6357 | !is_multicast_ether_addr(hdr->addr3); |
| 6320 | hdr_len = IEEE80211_3ADDR_LEN; | 6358 | hdr_len = IEEE80211_3ADDR_LEN; |
| 6321 | id = 0; | 6359 | id = 0; |
| 6322 | break; | 6360 | break; |
| @@ -6349,7 +6387,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) | |||
| 6349 | memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); | 6387 | memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); |
| 6350 | 6388 | ||
| 6351 | /* payload */ | 6389 | /* payload */ |
| 6352 | tfd->u.data.num_chunks = min((u8)(NUM_TFD_CHUNKS - 2), txb->nr_frags); | 6390 | tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags); |
| 6353 | for (i = 0; i < tfd->u.data.num_chunks; i++) { | 6391 | for (i = 0; i < tfd->u.data.num_chunks; i++) { |
| 6354 | IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", | 6392 | IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", |
| 6355 | i, tfd->u.data.num_chunks, | 6393 | i, tfd->u.data.num_chunks, |
| @@ -6357,9 +6395,11 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) | |||
| 6357 | printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len, | 6395 | printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len, |
| 6358 | txb->fragments[i]->len - hdr_len); | 6396 | txb->fragments[i]->len - hdr_len); |
| 6359 | 6397 | ||
| 6360 | tfd->u.data.chunk_ptr[i] = pci_map_single( | 6398 | tfd->u.data.chunk_ptr[i] = |
| 6361 | priv->pci_dev, txb->fragments[i]->data + hdr_len, | 6399 | pci_map_single(priv->pci_dev, |
| 6362 | txb->fragments[i]->len - hdr_len, PCI_DMA_TODEVICE); | 6400 | txb->fragments[i]->data + hdr_len, |
| 6401 | txb->fragments[i]->len - hdr_len, | ||
| 6402 | PCI_DMA_TODEVICE); | ||
| 6363 | tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len; | 6403 | tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len; |
| 6364 | } | 6404 | } |
| 6365 | 6405 | ||
| @@ -6379,16 +6419,16 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) | |||
| 6379 | for (j = i; j < txb->nr_frags; j++) { | 6419 | for (j = i; j < txb->nr_frags; j++) { |
| 6380 | int size = txb->fragments[j]->len - hdr_len; | 6420 | int size = txb->fragments[j]->len - hdr_len; |
| 6381 | printk(KERN_INFO "Adding frag %d %d...\n", | 6421 | printk(KERN_INFO "Adding frag %d %d...\n", |
| 6382 | j, size); | 6422 | j, size); |
| 6383 | memcpy(skb_put(skb, size), | 6423 | memcpy(skb_put(skb, size), |
| 6384 | txb->fragments[j]->data + hdr_len, | 6424 | txb->fragments[j]->data + hdr_len, size); |
| 6385 | size); | ||
| 6386 | } | 6425 | } |
| 6387 | dev_kfree_skb_any(txb->fragments[i]); | 6426 | dev_kfree_skb_any(txb->fragments[i]); |
| 6388 | txb->fragments[i] = skb; | 6427 | txb->fragments[i] = skb; |
| 6389 | tfd->u.data.chunk_ptr[i] = pci_map_single( | 6428 | tfd->u.data.chunk_ptr[i] = |
| 6390 | priv->pci_dev, skb->data, | 6429 | pci_map_single(priv->pci_dev, skb->data, |
| 6391 | tfd->u.data.chunk_len[i], PCI_DMA_TODEVICE); | 6430 | tfd->u.data.chunk_len[i], |
| 6431 | PCI_DMA_TODEVICE); | ||
| 6392 | tfd->u.data.num_chunks++; | 6432 | tfd->u.data.num_chunks++; |
| 6393 | } | 6433 | } |
| 6394 | } | 6434 | } |
| @@ -6402,7 +6442,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) | |||
| 6402 | 6442 | ||
| 6403 | return; | 6443 | return; |
| 6404 | 6444 | ||
| 6405 | drop: | 6445 | drop: |
| 6406 | IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); | 6446 | IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); |
| 6407 | ieee80211_txb_free(txb); | 6447 | ieee80211_txb_free(txb); |
| 6408 | } | 6448 | } |
| @@ -6429,7 +6469,7 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, | |||
| 6429 | spin_unlock_irqrestore(&priv->lock, flags); | 6469 | spin_unlock_irqrestore(&priv->lock, flags); |
| 6430 | return 0; | 6470 | return 0; |
| 6431 | 6471 | ||
| 6432 | fail_unlock: | 6472 | fail_unlock: |
| 6433 | spin_unlock_irqrestore(&priv->lock, flags); | 6473 | spin_unlock_irqrestore(&priv->lock, flags); |
| 6434 | return 1; | 6474 | return 1; |
| 6435 | } | 6475 | } |
| @@ -6478,7 +6518,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev, | |||
| 6478 | len = sizeof(date); | 6518 | len = sizeof(date); |
| 6479 | ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len); | 6519 | ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len); |
| 6480 | 6520 | ||
| 6481 | snprintf(info->fw_version, sizeof(info->fw_version),"%s (%s)", | 6521 | snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)", |
| 6482 | vers, date); | 6522 | vers, date); |
| 6483 | strcpy(info->bus_info, pci_name(p->pci_dev)); | 6523 | strcpy(info->bus_info, pci_name(p->pci_dev)); |
| 6484 | info->eedump_len = CX2_EEPROM_IMAGE_SIZE; | 6524 | info->eedump_len = CX2_EEPROM_IMAGE_SIZE; |
| @@ -6496,19 +6536,19 @@ static int ipw_ethtool_get_eeprom_len(struct net_device *dev) | |||
| 6496 | } | 6536 | } |
| 6497 | 6537 | ||
| 6498 | static int ipw_ethtool_get_eeprom(struct net_device *dev, | 6538 | static int ipw_ethtool_get_eeprom(struct net_device *dev, |
| 6499 | struct ethtool_eeprom *eeprom, u8 *bytes) | 6539 | struct ethtool_eeprom *eeprom, u8 * bytes) |
| 6500 | { | 6540 | { |
| 6501 | struct ipw_priv *p = ieee80211_priv(dev); | 6541 | struct ipw_priv *p = ieee80211_priv(dev); |
| 6502 | 6542 | ||
| 6503 | if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) | 6543 | if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) |
| 6504 | return -EINVAL; | 6544 | return -EINVAL; |
| 6505 | 6545 | ||
| 6506 | memcpy(bytes, &((u8 *)p->eeprom)[eeprom->offset], eeprom->len); | 6546 | memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len); |
| 6507 | return 0; | 6547 | return 0; |
| 6508 | } | 6548 | } |
| 6509 | 6549 | ||
| 6510 | static int ipw_ethtool_set_eeprom(struct net_device *dev, | 6550 | static int ipw_ethtool_set_eeprom(struct net_device *dev, |
| 6511 | struct ethtool_eeprom *eeprom, u8 *bytes) | 6551 | struct ethtool_eeprom *eeprom, u8 * bytes) |
| 6512 | { | 6552 | { |
| 6513 | struct ipw_priv *p = ieee80211_priv(dev); | 6553 | struct ipw_priv *p = ieee80211_priv(dev); |
| 6514 | int i; | 6554 | int i; |
| @@ -6516,21 +6556,20 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev, | |||
| 6516 | if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) | 6556 | if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) |
| 6517 | return -EINVAL; | 6557 | return -EINVAL; |
| 6518 | 6558 | ||
| 6519 | memcpy(&((u8 *)p->eeprom)[eeprom->offset], bytes, eeprom->len); | 6559 | memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len); |
| 6520 | for (i = IPW_EEPROM_DATA; | 6560 | for (i = IPW_EEPROM_DATA; |
| 6521 | i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; | 6561 | i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++) |
| 6522 | i++) | ||
| 6523 | ipw_write8(p, i, p->eeprom[i]); | 6562 | ipw_write8(p, i, p->eeprom[i]); |
| 6524 | 6563 | ||
| 6525 | return 0; | 6564 | return 0; |
| 6526 | } | 6565 | } |
| 6527 | 6566 | ||
| 6528 | static struct ethtool_ops ipw_ethtool_ops = { | 6567 | static struct ethtool_ops ipw_ethtool_ops = { |
| 6529 | .get_link = ipw_ethtool_get_link, | 6568 | .get_link = ipw_ethtool_get_link, |
| 6530 | .get_drvinfo = ipw_ethtool_get_drvinfo, | 6569 | .get_drvinfo = ipw_ethtool_get_drvinfo, |
| 6531 | .get_eeprom_len = ipw_ethtool_get_eeprom_len, | 6570 | .get_eeprom_len = ipw_ethtool_get_eeprom_len, |
| 6532 | .get_eeprom = ipw_ethtool_get_eeprom, | 6571 | .get_eeprom = ipw_ethtool_get_eeprom, |
| 6533 | .set_eeprom = ipw_ethtool_set_eeprom, | 6572 | .set_eeprom = ipw_ethtool_set_eeprom, |
| 6534 | }; | 6573 | }; |
| 6535 | 6574 | ||
| 6536 | static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) | 6575 | static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) |
| @@ -6574,10 +6613,10 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) | |||
| 6574 | 6613 | ||
| 6575 | tasklet_schedule(&priv->irq_tasklet); | 6614 | tasklet_schedule(&priv->irq_tasklet); |
| 6576 | 6615 | ||
| 6577 | spin_unlock(&priv->lock); | 6616 | spin_unlock(&priv->lock); |
| 6578 | 6617 | ||
| 6579 | return IRQ_HANDLED; | 6618 | return IRQ_HANDLED; |
| 6580 | none: | 6619 | none: |
| 6581 | spin_unlock(&priv->lock); | 6620 | spin_unlock(&priv->lock); |
| 6582 | return IRQ_NONE; | 6621 | return IRQ_NONE; |
| 6583 | } | 6622 | } |
| @@ -6609,7 +6648,7 @@ static void ipw_rf_kill(void *adapter) | |||
| 6609 | IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " | 6648 | IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " |
| 6610 | "enabled\n"); | 6649 | "enabled\n"); |
| 6611 | 6650 | ||
| 6612 | exit_unlock: | 6651 | exit_unlock: |
| 6613 | spin_unlock_irqrestore(&priv->lock, flags); | 6652 | spin_unlock_irqrestore(&priv->lock, flags); |
| 6614 | } | 6653 | } |
| 6615 | 6654 | ||
| @@ -6642,7 +6681,6 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) | |||
| 6642 | return ret; | 6681 | return ret; |
| 6643 | } | 6682 | } |
| 6644 | 6683 | ||
| 6645 | |||
| 6646 | static void shim__set_security(struct net_device *dev, | 6684 | static void shim__set_security(struct net_device *dev, |
| 6647 | struct ieee80211_security *sec) | 6685 | struct ieee80211_security *sec) |
| 6648 | { | 6686 | { |
| @@ -6683,8 +6721,7 @@ static void shim__set_security(struct net_device *dev, | |||
| 6683 | priv->status |= STATUS_SECURITY_UPDATED; | 6721 | priv->status |= STATUS_SECURITY_UPDATED; |
| 6684 | } | 6722 | } |
| 6685 | 6723 | ||
| 6686 | if (sec->flags & SEC_ENABLED && | 6724 | if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) { |
| 6687 | priv->sec.enabled != sec->enabled) { | ||
| 6688 | priv->sec.flags |= SEC_ENABLED; | 6725 | priv->sec.flags |= SEC_ENABLED; |
| 6689 | priv->sec.enabled = sec->enabled; | 6726 | priv->sec.enabled = sec->enabled; |
| 6690 | priv->status |= STATUS_SECURITY_UPDATED; | 6727 | priv->status |= STATUS_SECURITY_UPDATED; |
| @@ -6694,8 +6731,7 @@ static void shim__set_security(struct net_device *dev, | |||
| 6694 | priv->capability &= ~CAP_PRIVACY_ON; | 6731 | priv->capability &= ~CAP_PRIVACY_ON; |
| 6695 | } | 6732 | } |
| 6696 | 6733 | ||
| 6697 | if (sec->flags & SEC_LEVEL && | 6734 | if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) { |
| 6698 | priv->sec.level != sec->level) { | ||
| 6699 | priv->sec.level = sec->level; | 6735 | priv->sec.level = sec->level; |
| 6700 | priv->sec.flags |= SEC_LEVEL; | 6736 | priv->sec.flags |= SEC_LEVEL; |
| 6701 | priv->status |= STATUS_SECURITY_UPDATED; | 6737 | priv->status |= STATUS_SECURITY_UPDATED; |
| @@ -6709,7 +6745,7 @@ static void shim__set_security(struct net_device *dev, | |||
| 6709 | (((priv->assoc_request.capability & | 6745 | (((priv->assoc_request.capability & |
| 6710 | WLAN_CAPABILITY_PRIVACY) && !sec->enabled) || | 6746 | WLAN_CAPABILITY_PRIVACY) && !sec->enabled) || |
| 6711 | (!(priv->assoc_request.capability & | 6747 | (!(priv->assoc_request.capability & |
| 6712 | WLAN_CAPABILITY_PRIVACY) && sec->enabled))) { | 6748 | WLAN_CAPABILITY_PRIVACY) && sec->enabled))) { |
| 6713 | IPW_DEBUG_ASSOC("Disassociating due to capability " | 6749 | IPW_DEBUG_ASSOC("Disassociating due to capability " |
| 6714 | "change.\n"); | 6750 | "change.\n"); |
| 6715 | ipw_disassociate(priv); | 6751 | ipw_disassociate(priv); |
| @@ -6723,7 +6759,7 @@ static int init_supported_rates(struct ipw_priv *priv, | |||
| 6723 | /* TODO: Mask out rates based on priv->rates_mask */ | 6759 | /* TODO: Mask out rates based on priv->rates_mask */ |
| 6724 | 6760 | ||
| 6725 | memset(rates, 0, sizeof(*rates)); | 6761 | memset(rates, 0, sizeof(*rates)); |
| 6726 | /* configure supported rates */ | 6762 | /* configure supported rates */ |
| 6727 | switch (priv->ieee->freq_band) { | 6763 | switch (priv->ieee->freq_band) { |
| 6728 | case IEEE80211_52GHZ_BAND: | 6764 | case IEEE80211_52GHZ_BAND: |
| 6729 | rates->ieee_mode = IPW_A_MODE; | 6765 | rates->ieee_mode = IPW_A_MODE; |
| @@ -6732,7 +6768,7 @@ static int init_supported_rates(struct ipw_priv *priv, | |||
| 6732 | IEEE80211_OFDM_DEFAULT_RATES_MASK); | 6768 | IEEE80211_OFDM_DEFAULT_RATES_MASK); |
| 6733 | break; | 6769 | break; |
| 6734 | 6770 | ||
| 6735 | default: /* Mixed or 2.4Ghz */ | 6771 | default: /* Mixed or 2.4Ghz */ |
| 6736 | rates->ieee_mode = IPW_G_MODE; | 6772 | rates->ieee_mode = IPW_G_MODE; |
| 6737 | rates->purpose = IPW_RATE_CAPABILITIES; | 6773 | rates->purpose = IPW_RATE_CAPABILITIES; |
| 6738 | ipw_add_cck_scan_rates(rates, IEEE80211_CCK_MODULATION, | 6774 | ipw_add_cck_scan_rates(rates, IEEE80211_CCK_MODULATION, |
| @@ -6783,8 +6819,8 @@ static int ipw_config(struct ipw_priv *priv) | |||
| 6783 | if (ipw_send_system_config(priv, &priv->sys_config)) | 6819 | if (ipw_send_system_config(priv, &priv->sys_config)) |
| 6784 | goto error; | 6820 | goto error; |
| 6785 | 6821 | ||
| 6786 | init_supported_rates(priv, &priv->rates); | 6822 | init_supported_rates(priv, &priv->rates); |
| 6787 | if (ipw_send_supported_rates(priv, &priv->rates)) | 6823 | if (ipw_send_supported_rates(priv, &priv->rates)) |
| 6788 | goto error; | 6824 | goto error; |
| 6789 | 6825 | ||
| 6790 | /* Set request-to-send threshold */ | 6826 | /* Set request-to-send threshold */ |
| @@ -6806,7 +6842,7 @@ static int ipw_config(struct ipw_priv *priv) | |||
| 6806 | 6842 | ||
| 6807 | return 0; | 6843 | return 0; |
| 6808 | 6844 | ||
| 6809 | error: | 6845 | error: |
| 6810 | return -EIO; | 6846 | return -EIO; |
| 6811 | } | 6847 | } |
| 6812 | 6848 | ||
| @@ -6818,13 +6854,12 @@ static int ipw_up(struct ipw_priv *priv) | |||
| 6818 | if (priv->status & STATUS_EXIT_PENDING) | 6854 | if (priv->status & STATUS_EXIT_PENDING) |
| 6819 | return -EIO; | 6855 | return -EIO; |
| 6820 | 6856 | ||
| 6821 | for (i = 0; i < MAX_HW_RESTARTS; i++ ) { | 6857 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
| 6822 | /* Load the microcode, firmware, and eeprom. | 6858 | /* Load the microcode, firmware, and eeprom. |
| 6823 | * Also start the clocks. */ | 6859 | * Also start the clocks. */ |
| 6824 | rc = ipw_load(priv); | 6860 | rc = ipw_load(priv); |
| 6825 | if (rc) { | 6861 | if (rc) { |
| 6826 | IPW_ERROR("Unable to load firmware: 0x%08X\n", | 6862 | IPW_ERROR("Unable to load firmware: 0x%08X\n", rc); |
| 6827 | rc); | ||
| 6828 | return rc; | 6863 | return rc; |
| 6829 | } | 6864 | } |
| 6830 | 6865 | ||
| @@ -6857,8 +6892,7 @@ static int ipw_up(struct ipw_priv *priv) | |||
| 6857 | 6892 | ||
| 6858 | /* tried to restart and config the device for as long as our | 6893 | /* tried to restart and config the device for as long as our |
| 6859 | * patience could withstand */ | 6894 | * patience could withstand */ |
| 6860 | IPW_ERROR("Unable to initialize device after %d attempts.\n", | 6895 | IPW_ERROR("Unable to initialize device after %d attempts.\n", i); |
| 6861 | i); | ||
| 6862 | return -EIO; | 6896 | return -EIO; |
| 6863 | } | 6897 | } |
| 6864 | 6898 | ||
| @@ -6923,10 +6957,10 @@ static struct pci_device_id card_ids[] = { | |||
| 6923 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0}, | 6957 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0}, |
| 6924 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, | 6958 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, |
| 6925 | {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 6959 | {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
| 6926 | {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */ | 6960 | {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */ |
| 6927 | {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ | 6961 | {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ |
| 6928 | {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ | 6962 | {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ |
| 6929 | {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ | 6963 | {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ |
| 6930 | 6964 | ||
| 6931 | /* required last entry */ | 6965 | /* required last entry */ |
| 6932 | {0,} | 6966 | {0,} |
| @@ -6954,11 +6988,10 @@ static struct attribute *ipw_sysfs_entries[] = { | |||
| 6954 | 6988 | ||
| 6955 | static struct attribute_group ipw_attribute_group = { | 6989 | static struct attribute_group ipw_attribute_group = { |
| 6956 | .name = NULL, /* put in device directory */ | 6990 | .name = NULL, /* put in device directory */ |
| 6957 | .attrs = ipw_sysfs_entries, | 6991 | .attrs = ipw_sysfs_entries, |
| 6958 | }; | 6992 | }; |
| 6959 | 6993 | ||
| 6960 | static int ipw_pci_probe(struct pci_dev *pdev, | 6994 | static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 6961 | const struct pci_device_id *ent) | ||
| 6962 | { | 6995 | { |
| 6963 | int err = 0; | 6996 | int err = 0; |
| 6964 | struct net_device *net_dev; | 6997 | struct net_device *net_dev; |
| @@ -7051,7 +7084,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, | |||
| 7051 | priv->config |= CFG_STATIC_CHANNEL; | 7084 | priv->config |= CFG_STATIC_CHANNEL; |
| 7052 | priv->channel = channel; | 7085 | priv->channel = channel; |
| 7053 | IPW_DEBUG_INFO("Bind to static channel %d\n", channel); | 7086 | IPW_DEBUG_INFO("Bind to static channel %d\n", channel); |
| 7054 | IPW_DEBUG_INFO("Bind to static channel %d\n", channel); | 7087 | IPW_DEBUG_INFO("Bind to static channel %d\n", channel); |
| 7055 | /* TODO: Validate that provided channel is in range */ | 7088 | /* TODO: Validate that provided channel is in range */ |
| 7056 | } | 7089 | } |
| 7057 | 7090 | ||
| @@ -7078,9 +7111,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, | |||
| 7078 | priv->ieee->abg_ture = 1; | 7111 | priv->ieee->abg_ture = 1; |
| 7079 | band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND; | 7112 | band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND; |
| 7080 | modulation = IEEE80211_OFDM_MODULATION | | 7113 | modulation = IEEE80211_OFDM_MODULATION | |
| 7081 | IEEE80211_CCK_MODULATION; | 7114 | IEEE80211_CCK_MODULATION; |
| 7082 | priv->adapter = IPW_2915ABG; | 7115 | priv->adapter = IPW_2915ABG; |
| 7083 | priv->ieee->mode = IEEE_A|IEEE_G|IEEE_B; | 7116 | priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B; |
| 7084 | } else { | 7117 | } else { |
| 7085 | if (priv->pci_dev->device == 0x4221) | 7118 | if (priv->pci_dev->device == 0x4221) |
| 7086 | printk(KERN_INFO DRV_NAME | 7119 | printk(KERN_INFO DRV_NAME |
| @@ -7094,9 +7127,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, | |||
| 7094 | priv->ieee->abg_ture = 0; | 7127 | priv->ieee->abg_ture = 0; |
| 7095 | band = IEEE80211_24GHZ_BAND; | 7128 | band = IEEE80211_24GHZ_BAND; |
| 7096 | modulation = IEEE80211_OFDM_MODULATION | | 7129 | modulation = IEEE80211_OFDM_MODULATION | |
| 7097 | IEEE80211_CCK_MODULATION; | 7130 | IEEE80211_CCK_MODULATION; |
| 7098 | priv->adapter = IPW_2200BG; | 7131 | priv->adapter = IPW_2200BG; |
| 7099 | priv->ieee->mode = IEEE_G|IEEE_B; | 7132 | priv->ieee->mode = IEEE_G | IEEE_B; |
| 7100 | } | 7133 | } |
| 7101 | 7134 | ||
| 7102 | priv->ieee->freq_band = band; | 7135 | priv->ieee->freq_band = band; |
| @@ -7110,11 +7143,10 @@ static int ipw_pci_probe(struct pci_dev *pdev, | |||
| 7110 | priv->rts_threshold = DEFAULT_RTS_THRESHOLD; | 7143 | priv->rts_threshold = DEFAULT_RTS_THRESHOLD; |
| 7111 | 7144 | ||
| 7112 | /* If power management is turned on, default to AC mode */ | 7145 | /* If power management is turned on, default to AC mode */ |
| 7113 | priv->power_mode = IPW_POWER_AC; | 7146 | priv->power_mode = IPW_POWER_AC; |
| 7114 | priv->tx_power = IPW_DEFAULT_TX_POWER; | 7147 | priv->tx_power = IPW_DEFAULT_TX_POWER; |
| 7115 | 7148 | ||
| 7116 | err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, | 7149 | err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv); |
| 7117 | priv); | ||
| 7118 | if (err) { | 7150 | if (err) { |
| 7119 | IPW_ERROR("Error allocating IRQ %d\n", pdev->irq); | 7151 | IPW_ERROR("Error allocating IRQ %d\n", pdev->irq); |
| 7120 | goto out_destroy_workqueue; | 7152 | goto out_destroy_workqueue; |
| @@ -7136,7 +7168,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, | |||
| 7136 | net_dev->wireless_handlers = &ipw_wx_handler_def; | 7168 | net_dev->wireless_handlers = &ipw_wx_handler_def; |
| 7137 | net_dev->ethtool_ops = &ipw_ethtool_ops; | 7169 | net_dev->ethtool_ops = &ipw_ethtool_ops; |
| 7138 | net_dev->irq = pdev->irq; | 7170 | net_dev->irq = pdev->irq; |
| 7139 | net_dev->base_addr = (unsigned long )priv->hw_base; | 7171 | net_dev->base_addr = (unsigned long)priv->hw_base; |
| 7140 | net_dev->mem_start = pci_resource_start(pdev, 0); | 7172 | net_dev->mem_start = pci_resource_start(pdev, 0); |
| 7141 | net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1; | 7173 | net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1; |
| 7142 | 7174 | ||
| @@ -7154,23 +7186,23 @@ static int ipw_pci_probe(struct pci_dev *pdev, | |||
| 7154 | 7186 | ||
| 7155 | return 0; | 7187 | return 0; |
| 7156 | 7188 | ||
| 7157 | out_remove_group: | 7189 | out_remove_group: |
| 7158 | sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); | 7190 | sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); |
| 7159 | out_release_irq: | 7191 | out_release_irq: |
| 7160 | free_irq(pdev->irq, priv); | 7192 | free_irq(pdev->irq, priv); |
| 7161 | out_destroy_workqueue: | 7193 | out_destroy_workqueue: |
| 7162 | destroy_workqueue(priv->workqueue); | 7194 | destroy_workqueue(priv->workqueue); |
| 7163 | priv->workqueue = NULL; | 7195 | priv->workqueue = NULL; |
| 7164 | out_iounmap: | 7196 | out_iounmap: |
| 7165 | iounmap(priv->hw_base); | 7197 | iounmap(priv->hw_base); |
| 7166 | out_pci_release_regions: | 7198 | out_pci_release_regions: |
| 7167 | pci_release_regions(pdev); | 7199 | pci_release_regions(pdev); |
| 7168 | out_pci_disable_device: | 7200 | out_pci_disable_device: |
| 7169 | pci_disable_device(pdev); | 7201 | pci_disable_device(pdev); |
| 7170 | pci_set_drvdata(pdev, NULL); | 7202 | pci_set_drvdata(pdev, NULL); |
| 7171 | out_free_ieee80211: | 7203 | out_free_ieee80211: |
| 7172 | free_ieee80211(priv->net_dev); | 7204 | free_ieee80211(priv->net_dev); |
| 7173 | out: | 7205 | out: |
| 7174 | return err; | 7206 | return err; |
| 7175 | } | 7207 | } |
| 7176 | 7208 | ||
| @@ -7223,7 +7255,6 @@ static void ipw_pci_remove(struct pci_dev *pdev) | |||
| 7223 | #endif | 7255 | #endif |
| 7224 | } | 7256 | } |
| 7225 | 7257 | ||
| 7226 | |||
| 7227 | #ifdef CONFIG_PM | 7258 | #ifdef CONFIG_PM |
| 7228 | static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 7259 | static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
| 7229 | { | 7260 | { |
| @@ -7232,7 +7263,7 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 7232 | 7263 | ||
| 7233 | printk(KERN_INFO "%s: Going into suspend...\n", dev->name); | 7264 | printk(KERN_INFO "%s: Going into suspend...\n", dev->name); |
| 7234 | 7265 | ||
| 7235 | /* Take down the device; powers it off, etc. */ | 7266 | /* Take down the device; powers it off, etc. */ |
| 7236 | ipw_down(priv); | 7267 | ipw_down(priv); |
| 7237 | 7268 | ||
| 7238 | /* Remove the PRESENT state of the device */ | 7269 | /* Remove the PRESENT state of the device */ |
| @@ -7306,8 +7337,7 @@ static int __init ipw_init(void) | |||
| 7306 | return ret; | 7337 | return ret; |
| 7307 | } | 7338 | } |
| 7308 | 7339 | ||
| 7309 | ret = driver_create_file(&ipw_driver.driver, | 7340 | ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level); |
| 7310 | &driver_attr_debug_level); | ||
| 7311 | if (ret) { | 7341 | if (ret) { |
| 7312 | IPW_ERROR("Unable to create driver sysfs file\n"); | 7342 | IPW_ERROR("Unable to create driver sysfs file\n"); |
| 7313 | pci_unregister_driver(&ipw_driver); | 7343 | pci_unregister_driver(&ipw_driver); |
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index 66bb5903537f..5b00882133f9 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h | |||
| @@ -56,8 +56,7 @@ | |||
| 56 | #include <linux/workqueue.h> | 56 | #include <linux/workqueue.h> |
| 57 | 57 | ||
| 58 | /* Authentication and Association States */ | 58 | /* Authentication and Association States */ |
| 59 | enum connection_manager_assoc_states | 59 | enum connection_manager_assoc_states { |
| 60 | { | ||
| 61 | CMAS_INIT = 0, | 60 | CMAS_INIT = 0, |
| 62 | CMAS_TX_AUTH_SEQ_1, | 61 | CMAS_TX_AUTH_SEQ_1, |
| 63 | CMAS_RX_AUTH_SEQ_2, | 62 | CMAS_RX_AUTH_SEQ_2, |
| @@ -74,7 +73,6 @@ enum connection_manager_assoc_states | |||
| 74 | CMAS_LAST | 73 | CMAS_LAST |
| 75 | }; | 74 | }; |
| 76 | 75 | ||
| 77 | |||
| 78 | #define IPW_WAIT (1<<0) | 76 | #define IPW_WAIT (1<<0) |
| 79 | #define IPW_QUIET (1<<1) | 77 | #define IPW_QUIET (1<<1) |
| 80 | #define IPW_ROAMING (1<<2) | 78 | #define IPW_ROAMING (1<<2) |
| @@ -190,7 +188,6 @@ enum connection_manager_assoc_states | |||
| 190 | #define DCT_FLAG_EXT_MODE_CCK 0x01 | 188 | #define DCT_FLAG_EXT_MODE_CCK 0x01 |
| 191 | #define DCT_FLAG_EXT_MODE_OFDM 0x00 | 189 | #define DCT_FLAG_EXT_MODE_OFDM 0x00 |
| 192 | 190 | ||
| 193 | |||
| 194 | #define TX_RX_TYPE_MASK 0xFF | 191 | #define TX_RX_TYPE_MASK 0xFF |
| 195 | #define TX_FRAME_TYPE 0x00 | 192 | #define TX_FRAME_TYPE 0x00 |
| 196 | #define TX_HOST_COMMAND_TYPE 0x01 | 193 | #define TX_HOST_COMMAND_TYPE 0x01 |
| @@ -242,107 +239,97 @@ enum connection_manager_assoc_states | |||
| 242 | * Contains common data for Rx and Tx queues | 239 | * Contains common data for Rx and Tx queues |
| 243 | */ | 240 | */ |
| 244 | struct clx2_queue { | 241 | struct clx2_queue { |
| 245 | int n_bd; /**< number of BDs in this queue */ | 242 | int n_bd; /**< number of BDs in this queue */ |
| 246 | int first_empty; /**< 1-st empty entry (index) */ | 243 | int first_empty; /**< 1-st empty entry (index) */ |
| 247 | int last_used; /**< last used entry (index) */ | 244 | int last_used; /**< last used entry (index) */ |
| 248 | u32 reg_w; /**< 'write' reg (queue head), addr in domain 1 */ | 245 | u32 reg_w; /**< 'write' reg (queue head), addr in domain 1 */ |
| 249 | u32 reg_r; /**< 'read' reg (queue tail), addr in domain 1 */ | 246 | u32 reg_r; /**< 'read' reg (queue tail), addr in domain 1 */ |
| 250 | dma_addr_t dma_addr; /**< physical addr for BD's */ | 247 | dma_addr_t dma_addr; /**< physical addr for BD's */ |
| 251 | int low_mark; /**< low watermark, resume queue if free space more than this */ | 248 | int low_mark; /**< low watermark, resume queue if free space more than this */ |
| 252 | int high_mark; /**< high watermark, stop queue if free space less than this */ | 249 | int high_mark; /**< high watermark, stop queue if free space less than this */ |
| 253 | } __attribute__ ((packed)); | 250 | } __attribute__ ((packed)); |
| 254 | 251 | ||
| 255 | struct machdr32 | 252 | struct machdr32 { |
| 256 | { | ||
| 257 | u16 frame_ctl; | 253 | u16 frame_ctl; |
| 258 | u16 duration; // watch out for endians! | 254 | u16 duration; // watch out for endians! |
| 259 | u8 addr1[ MACADRR_BYTE_LEN ]; | 255 | u8 addr1[MACADRR_BYTE_LEN]; |
| 260 | u8 addr2[ MACADRR_BYTE_LEN ]; | 256 | u8 addr2[MACADRR_BYTE_LEN]; |
| 261 | u8 addr3[ MACADRR_BYTE_LEN ]; | 257 | u8 addr3[MACADRR_BYTE_LEN]; |
| 262 | u16 seq_ctrl; // more endians! | 258 | u16 seq_ctrl; // more endians! |
| 263 | u8 addr4[ MACADRR_BYTE_LEN ]; | 259 | u8 addr4[MACADRR_BYTE_LEN]; |
| 264 | u16 qos_ctrl; | 260 | u16 qos_ctrl; |
| 265 | } __attribute__ ((packed)) ; | 261 | } __attribute__ ((packed)); |
| 266 | 262 | ||
| 267 | struct machdr30 | 263 | struct machdr30 { |
| 268 | { | ||
| 269 | u16 frame_ctl; | 264 | u16 frame_ctl; |
| 270 | u16 duration; // watch out for endians! | 265 | u16 duration; // watch out for endians! |
| 271 | u8 addr1[ MACADRR_BYTE_LEN ]; | 266 | u8 addr1[MACADRR_BYTE_LEN]; |
| 272 | u8 addr2[ MACADRR_BYTE_LEN ]; | 267 | u8 addr2[MACADRR_BYTE_LEN]; |
| 273 | u8 addr3[ MACADRR_BYTE_LEN ]; | 268 | u8 addr3[MACADRR_BYTE_LEN]; |
| 274 | u16 seq_ctrl; // more endians! | 269 | u16 seq_ctrl; // more endians! |
| 275 | u8 addr4[ MACADRR_BYTE_LEN ]; | 270 | u8 addr4[MACADRR_BYTE_LEN]; |
| 276 | } __attribute__ ((packed)) ; | 271 | } __attribute__ ((packed)); |
| 277 | 272 | ||
| 278 | struct machdr26 | 273 | struct machdr26 { |
| 279 | { | ||
| 280 | u16 frame_ctl; | 274 | u16 frame_ctl; |
| 281 | u16 duration; // watch out for endians! | 275 | u16 duration; // watch out for endians! |
| 282 | u8 addr1[ MACADRR_BYTE_LEN ]; | 276 | u8 addr1[MACADRR_BYTE_LEN]; |
| 283 | u8 addr2[ MACADRR_BYTE_LEN ]; | 277 | u8 addr2[MACADRR_BYTE_LEN]; |
| 284 | u8 addr3[ MACADRR_BYTE_LEN ]; | 278 | u8 addr3[MACADRR_BYTE_LEN]; |
| 285 | u16 seq_ctrl; // more endians! | 279 | u16 seq_ctrl; // more endians! |
| 286 | u16 qos_ctrl; | 280 | u16 qos_ctrl; |
| 287 | } __attribute__ ((packed)) ; | 281 | } __attribute__ ((packed)); |
| 288 | 282 | ||
| 289 | struct machdr24 | 283 | struct machdr24 { |
| 290 | { | ||
| 291 | u16 frame_ctl; | 284 | u16 frame_ctl; |
| 292 | u16 duration; // watch out for endians! | 285 | u16 duration; // watch out for endians! |
| 293 | u8 addr1[ MACADRR_BYTE_LEN ]; | 286 | u8 addr1[MACADRR_BYTE_LEN]; |
| 294 | u8 addr2[ MACADRR_BYTE_LEN ]; | 287 | u8 addr2[MACADRR_BYTE_LEN]; |
| 295 | u8 addr3[ MACADRR_BYTE_LEN ]; | 288 | u8 addr3[MACADRR_BYTE_LEN]; |
| 296 | u16 seq_ctrl; // more endians! | 289 | u16 seq_ctrl; // more endians! |
| 297 | } __attribute__ ((packed)) ; | 290 | } __attribute__ ((packed)); |
| 298 | 291 | ||
| 299 | // TX TFD with 32 byte MAC Header | 292 | // TX TFD with 32 byte MAC Header |
| 300 | struct tx_tfd_32 | 293 | struct tx_tfd_32 { |
| 301 | { | 294 | struct machdr32 mchdr; // 32 |
| 302 | struct machdr32 mchdr; // 32 | 295 | u32 uivplaceholder[2]; // 8 |
| 303 | u32 uivplaceholder[2]; // 8 | 296 | } __attribute__ ((packed)); |
| 304 | } __attribute__ ((packed)) ; | ||
| 305 | 297 | ||
| 306 | // TX TFD with 30 byte MAC Header | 298 | // TX TFD with 30 byte MAC Header |
| 307 | struct tx_tfd_30 | 299 | struct tx_tfd_30 { |
| 308 | { | 300 | struct machdr30 mchdr; // 30 |
| 309 | struct machdr30 mchdr; // 30 | 301 | u8 reserved[2]; // 2 |
| 310 | u8 reserved[2]; // 2 | 302 | u32 uivplaceholder[2]; // 8 |
| 311 | u32 uivplaceholder[2]; // 8 | 303 | } __attribute__ ((packed)); |
| 312 | } __attribute__ ((packed)) ; | ||
| 313 | 304 | ||
| 314 | // tx tfd with 26 byte mac header | 305 | // tx tfd with 26 byte mac header |
| 315 | struct tx_tfd_26 | 306 | struct tx_tfd_26 { |
| 316 | { | 307 | struct machdr26 mchdr; // 26 |
| 317 | struct machdr26 mchdr; // 26 | 308 | u8 reserved1[2]; // 2 |
| 318 | u8 reserved1[2]; // 2 | 309 | u32 uivplaceholder[2]; // 8 |
| 319 | u32 uivplaceholder[2]; // 8 | 310 | u8 reserved2[4]; // 4 |
| 320 | u8 reserved2[4]; // 4 | 311 | } __attribute__ ((packed)); |
| 321 | } __attribute__ ((packed)) ; | ||
| 322 | 312 | ||
| 323 | // tx tfd with 24 byte mac header | 313 | // tx tfd with 24 byte mac header |
| 324 | struct tx_tfd_24 | 314 | struct tx_tfd_24 { |
| 325 | { | 315 | struct machdr24 mchdr; // 24 |
| 326 | struct machdr24 mchdr; // 24 | 316 | u32 uivplaceholder[2]; // 8 |
| 327 | u32 uivplaceholder[2]; // 8 | 317 | u8 reserved[8]; // 8 |
| 328 | u8 reserved[8]; // 8 | 318 | } __attribute__ ((packed)); |
| 329 | } __attribute__ ((packed)) ; | ||
| 330 | |||
| 331 | 319 | ||
| 332 | #define DCT_WEP_KEY_FIELD_LENGTH 16 | 320 | #define DCT_WEP_KEY_FIELD_LENGTH 16 |
| 333 | 321 | ||
| 334 | struct tfd_command | 322 | struct tfd_command { |
| 335 | { | ||
| 336 | u8 index; | 323 | u8 index; |
| 337 | u8 length; | 324 | u8 length; |
| 338 | u16 reserved; | 325 | u16 reserved; |
| 339 | u8 payload[0]; | 326 | u8 payload[0]; |
| 340 | } __attribute__ ((packed)) ; | 327 | } __attribute__ ((packed)); |
| 341 | 328 | ||
| 342 | struct tfd_data { | 329 | struct tfd_data { |
| 343 | /* Header */ | 330 | /* Header */ |
| 344 | u32 work_area_ptr; | 331 | u32 work_area_ptr; |
| 345 | u8 station_number; /* 0 for BSS */ | 332 | u8 station_number; /* 0 for BSS */ |
| 346 | u8 reserved1; | 333 | u8 reserved1; |
| 347 | u16 reserved2; | 334 | u16 reserved2; |
| 348 | 335 | ||
| @@ -359,14 +346,13 @@ struct tfd_data { | |||
| 359 | u8 antenna; | 346 | u8 antenna; |
| 360 | u16 next_packet_duration; | 347 | u16 next_packet_duration; |
| 361 | u16 next_frag_len; | 348 | u16 next_frag_len; |
| 362 | u16 back_off_counter; //////txop; | 349 | u16 back_off_counter; //////txop; |
| 363 | u8 retrylimit; | 350 | u8 retrylimit; |
| 364 | u16 cwcurrent; | 351 | u16 cwcurrent; |
| 365 | u8 reserved3; | 352 | u8 reserved3; |
| 366 | 353 | ||
| 367 | /* 802.11 MAC Header */ | 354 | /* 802.11 MAC Header */ |
| 368 | union | 355 | union { |
| 369 | { | ||
| 370 | struct tx_tfd_24 tfd_24; | 356 | struct tx_tfd_24 tfd_24; |
| 371 | struct tx_tfd_26 tfd_26; | 357 | struct tx_tfd_26 tfd_26; |
| 372 | struct tx_tfd_30 tfd_30; | 358 | struct tx_tfd_30 tfd_30; |
| @@ -379,8 +365,7 @@ struct tfd_data { | |||
| 379 | u16 chunk_len[NUM_TFD_CHUNKS]; | 365 | u16 chunk_len[NUM_TFD_CHUNKS]; |
| 380 | } __attribute__ ((packed)); | 366 | } __attribute__ ((packed)); |
| 381 | 367 | ||
| 382 | struct txrx_control_flags | 368 | struct txrx_control_flags { |
| 383 | { | ||
| 384 | u8 message_type; | 369 | u8 message_type; |
| 385 | u8 rx_seq_num; | 370 | u8 rx_seq_num; |
| 386 | u8 control_bits; | 371 | u8 control_bits; |
| @@ -390,17 +375,16 @@ struct txrx_control_flags | |||
| 390 | #define TFD_SIZE 128 | 375 | #define TFD_SIZE 128 |
| 391 | #define TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH (TFD_SIZE - sizeof(struct txrx_control_flags)) | 376 | #define TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH (TFD_SIZE - sizeof(struct txrx_control_flags)) |
| 392 | 377 | ||
| 393 | struct tfd_frame | 378 | struct tfd_frame { |
| 394 | { | ||
| 395 | struct txrx_control_flags control_flags; | 379 | struct txrx_control_flags control_flags; |
| 396 | union { | 380 | union { |
| 397 | struct tfd_data data; | 381 | struct tfd_data data; |
| 398 | struct tfd_command cmd; | 382 | struct tfd_command cmd; |
| 399 | u8 raw[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; | 383 | u8 raw[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; |
| 400 | } u; | 384 | } u; |
| 401 | } __attribute__ ((packed)) ; | 385 | } __attribute__ ((packed)); |
| 402 | 386 | ||
| 403 | typedef void destructor_func(const void*); | 387 | typedef void destructor_func(const void *); |
| 404 | 388 | ||
| 405 | /** | 389 | /** |
| 406 | * Tx Queue for DMA. Queue consists of circular buffer of | 390 | * Tx Queue for DMA. Queue consists of circular buffer of |
| @@ -408,7 +392,7 @@ typedef void destructor_func(const void*); | |||
| 408 | */ | 392 | */ |
| 409 | struct clx2_tx_queue { | 393 | struct clx2_tx_queue { |
| 410 | struct clx2_queue q; | 394 | struct clx2_queue q; |
| 411 | struct tfd_frame* bd; | 395 | struct tfd_frame *bd; |
| 412 | struct ieee80211_txb **txb; | 396 | struct ieee80211_txb **txb; |
| 413 | }; | 397 | }; |
| 414 | 398 | ||
| @@ -423,8 +407,7 @@ struct clx2_tx_queue { | |||
| 423 | #define SUP_RATE_11G_MAX_NUM_CHANNELS (12) | 407 | #define SUP_RATE_11G_MAX_NUM_CHANNELS (12) |
| 424 | 408 | ||
| 425 | // Used for passing to driver number of successes and failures per rate | 409 | // Used for passing to driver number of successes and failures per rate |
| 426 | struct rate_histogram | 410 | struct rate_histogram { |
| 427 | { | ||
| 428 | union { | 411 | union { |
| 429 | u32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; | 412 | u32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; |
| 430 | u32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; | 413 | u32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; |
| @@ -475,12 +458,12 @@ struct notif_scan_complete { | |||
| 475 | u8 num_channels; | 458 | u8 num_channels; |
| 476 | u8 status; | 459 | u8 status; |
| 477 | u8 reserved; | 460 | u8 reserved; |
| 478 | } __attribute__ ((packed)); | 461 | } __attribute__ ((packed)); |
| 479 | 462 | ||
| 480 | struct notif_frag_length { | 463 | struct notif_frag_length { |
| 481 | u16 frag_length; | 464 | u16 frag_length; |
| 482 | u16 reserved; | 465 | u16 reserved; |
| 483 | } __attribute__ ((packed)); | 466 | } __attribute__ ((packed)); |
| 484 | 467 | ||
| 485 | struct notif_beacon_state { | 468 | struct notif_beacon_state { |
| 486 | u32 state; | 469 | u32 state; |
| @@ -543,11 +526,11 @@ struct ipw_rx_notification { | |||
| 543 | 526 | ||
| 544 | struct ipw_rx_frame { | 527 | struct ipw_rx_frame { |
| 545 | u32 reserved1; | 528 | u32 reserved1; |
| 546 | u8 parent_tsf[4]; // fw_use[0] is boolean for OUR_TSF_IS_GREATER | 529 | u8 parent_tsf[4]; // fw_use[0] is boolean for OUR_TSF_IS_GREATER |
| 547 | u8 received_channel; // The channel that this frame was received on. | 530 | u8 received_channel; // The channel that this frame was received on. |
| 548 | // Note that for .11b this does not have to be | 531 | // Note that for .11b this does not have to be |
| 549 | // the same as the channel that it was sent. | 532 | // the same as the channel that it was sent. |
| 550 | // Filled by LMAC | 533 | // Filled by LMAC |
| 551 | u8 frameStatus; | 534 | u8 frameStatus; |
| 552 | u8 rate; | 535 | u8 rate; |
| 553 | u8 rssi; | 536 | u8 rssi; |
| @@ -556,10 +539,10 @@ struct ipw_rx_frame { | |||
| 556 | u16 signal; | 539 | u16 signal; |
| 557 | u16 noise; | 540 | u16 noise; |
| 558 | u8 antennaAndPhy; | 541 | u8 antennaAndPhy; |
| 559 | u8 control; // control bit should be on in bg | 542 | u8 control; // control bit should be on in bg |
| 560 | u8 rtscts_rate; // rate of rts or cts (in rts cts sequence rate | 543 | u8 rtscts_rate; // rate of rts or cts (in rts cts sequence rate |
| 561 | // is identical) | 544 | // is identical) |
| 562 | u8 rtscts_seen; // 0x1 RTS seen ; 0x2 CTS seen | 545 | u8 rtscts_seen; // 0x1 RTS seen ; 0x2 CTS seen |
| 563 | u16 length; | 546 | u16 length; |
| 564 | u8 data[0]; | 547 | u8 data[0]; |
| 565 | } __attribute__ ((packed)); | 548 | } __attribute__ ((packed)); |
| @@ -571,8 +554,7 @@ struct ipw_rx_header { | |||
| 571 | u8 reserved; | 554 | u8 reserved; |
| 572 | } __attribute__ ((packed)); | 555 | } __attribute__ ((packed)); |
| 573 | 556 | ||
| 574 | struct ipw_rx_packet | 557 | struct ipw_rx_packet { |
| 575 | { | ||
| 576 | struct ipw_rx_header header; | 558 | struct ipw_rx_header header; |
| 577 | union { | 559 | union { |
| 578 | struct ipw_rx_frame frame; | 560 | struct ipw_rx_frame frame; |
| @@ -589,21 +571,20 @@ struct ipw_rx_mem_buffer { | |||
| 589 | struct ipw_rx_buffer *rxb; | 571 | struct ipw_rx_buffer *rxb; |
| 590 | struct sk_buff *skb; | 572 | struct sk_buff *skb; |
| 591 | struct list_head list; | 573 | struct list_head list; |
| 592 | }; /* Not transferred over network, so not __attribute__ ((packed)) */ | 574 | }; /* Not transferred over network, so not __attribute__ ((packed)) */ |
| 593 | 575 | ||
| 594 | struct ipw_rx_queue { | 576 | struct ipw_rx_queue { |
| 595 | struct ipw_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; | 577 | struct ipw_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; |
| 596 | struct ipw_rx_mem_buffer *queue[RX_QUEUE_SIZE]; | 578 | struct ipw_rx_mem_buffer *queue[RX_QUEUE_SIZE]; |
| 597 | u32 processed; /* Internal index to last handled Rx packet */ | 579 | u32 processed; /* Internal index to last handled Rx packet */ |
| 598 | u32 read; /* Shared index to newest available Rx buffer */ | 580 | u32 read; /* Shared index to newest available Rx buffer */ |
| 599 | u32 write; /* Shared index to oldest written Rx packet */ | 581 | u32 write; /* Shared index to oldest written Rx packet */ |
| 600 | u32 free_count;/* Number of pre-allocated buffers in rx_free */ | 582 | u32 free_count; /* Number of pre-allocated buffers in rx_free */ |
| 601 | /* Each of these lists is used as a FIFO for ipw_rx_mem_buffers */ | 583 | /* Each of these lists is used as a FIFO for ipw_rx_mem_buffers */ |
| 602 | struct list_head rx_free; /* Own an SKBs */ | 584 | struct list_head rx_free; /* Own an SKBs */ |
| 603 | struct list_head rx_used; /* No SKB allocated */ | 585 | struct list_head rx_used; /* No SKB allocated */ |
| 604 | spinlock_t lock; | 586 | spinlock_t lock; |
| 605 | }; /* Not transferred over network, so not __attribute__ ((packed)) */ | 587 | }; /* Not transferred over network, so not __attribute__ ((packed)) */ |
| 606 | |||
| 607 | 588 | ||
| 608 | struct alive_command_responce { | 589 | struct alive_command_responce { |
| 609 | u8 alive_command; | 590 | u8 alive_command; |
| @@ -627,8 +608,7 @@ struct ipw_rates { | |||
| 627 | u8 rates[IPW_MAX_RATES]; | 608 | u8 rates[IPW_MAX_RATES]; |
| 628 | } __attribute__ ((packed)); | 609 | } __attribute__ ((packed)); |
| 629 | 610 | ||
| 630 | struct command_block | 611 | struct command_block { |
| 631 | { | ||
| 632 | unsigned int control; | 612 | unsigned int control; |
| 633 | u32 source_addr; | 613 | u32 source_addr; |
| 634 | u32 dest_addr; | 614 | u32 dest_addr; |
| @@ -636,18 +616,16 @@ struct command_block | |||
| 636 | } __attribute__ ((packed)); | 616 | } __attribute__ ((packed)); |
| 637 | 617 | ||
| 638 | #define CB_NUMBER_OF_ELEMENTS_SMALL 64 | 618 | #define CB_NUMBER_OF_ELEMENTS_SMALL 64 |
| 639 | struct fw_image_desc | 619 | struct fw_image_desc { |
| 640 | { | ||
| 641 | unsigned long last_cb_index; | 620 | unsigned long last_cb_index; |
| 642 | unsigned long current_cb_index; | 621 | unsigned long current_cb_index; |
| 643 | struct command_block cb_list[CB_NUMBER_OF_ELEMENTS_SMALL]; | 622 | struct command_block cb_list[CB_NUMBER_OF_ELEMENTS_SMALL]; |
| 644 | void * v_addr; | 623 | void *v_addr; |
| 645 | unsigned long p_addr; | 624 | unsigned long p_addr; |
| 646 | unsigned long len; | 625 | unsigned long len; |
| 647 | }; | 626 | }; |
| 648 | 627 | ||
| 649 | struct ipw_sys_config | 628 | struct ipw_sys_config { |
| 650 | { | ||
| 651 | u8 bt_coexistence; | 629 | u8 bt_coexistence; |
| 652 | u8 reserved1; | 630 | u8 reserved1; |
| 653 | u8 answer_broadcast_ssid_probe; | 631 | u8 answer_broadcast_ssid_probe; |
| @@ -670,8 +648,7 @@ struct ipw_sys_config | |||
| 670 | u8 reserved3; | 648 | u8 reserved3; |
| 671 | } __attribute__ ((packed)); | 649 | } __attribute__ ((packed)); |
| 672 | 650 | ||
| 673 | struct ipw_multicast_addr | 651 | struct ipw_multicast_addr { |
| 674 | { | ||
| 675 | u8 num_of_multicast_addresses; | 652 | u8 num_of_multicast_addresses; |
| 676 | u8 reserved[3]; | 653 | u8 reserved[3]; |
| 677 | u8 mac1[6]; | 654 | u8 mac1[6]; |
| @@ -680,8 +657,7 @@ struct ipw_multicast_addr | |||
| 680 | u8 mac4[6]; | 657 | u8 mac4[6]; |
| 681 | } __attribute__ ((packed)); | 658 | } __attribute__ ((packed)); |
| 682 | 659 | ||
| 683 | struct ipw_wep_key | 660 | struct ipw_wep_key { |
| 684 | { | ||
| 685 | u8 cmd_id; | 661 | u8 cmd_id; |
| 686 | u8 seq_num; | 662 | u8 seq_num; |
| 687 | u8 key_index; | 663 | u8 key_index; |
| @@ -689,8 +665,7 @@ struct ipw_wep_key | |||
| 689 | u8 key[16]; | 665 | u8 key[16]; |
| 690 | } __attribute__ ((packed)); | 666 | } __attribute__ ((packed)); |
| 691 | 667 | ||
| 692 | struct ipw_tgi_tx_key | 668 | struct ipw_tgi_tx_key { |
| 693 | { | ||
| 694 | u8 key_id; | 669 | u8 key_id; |
| 695 | u8 security_type; | 670 | u8 security_type; |
| 696 | u8 station_index; | 671 | u8 station_index; |
| @@ -701,8 +676,7 @@ struct ipw_tgi_tx_key | |||
| 701 | 676 | ||
| 702 | #define IPW_SCAN_CHANNELS 54 | 677 | #define IPW_SCAN_CHANNELS 54 |
| 703 | 678 | ||
| 704 | struct ipw_scan_request | 679 | struct ipw_scan_request { |
| 705 | { | ||
| 706 | u8 scan_type; | 680 | u8 scan_type; |
| 707 | u16 dwell_time; | 681 | u16 dwell_time; |
| 708 | u8 channels_list[IPW_SCAN_CHANNELS]; | 682 | u8 channels_list[IPW_SCAN_CHANNELS]; |
| @@ -718,8 +692,7 @@ enum { | |||
| 718 | IPW_SCAN_TYPES | 692 | IPW_SCAN_TYPES |
| 719 | }; | 693 | }; |
| 720 | 694 | ||
| 721 | struct ipw_scan_request_ext | 695 | struct ipw_scan_request_ext { |
| 722 | { | ||
| 723 | u32 full_scan_index; | 696 | u32 full_scan_index; |
| 724 | u8 channels_list[IPW_SCAN_CHANNELS]; | 697 | u8 channels_list[IPW_SCAN_CHANNELS]; |
| 725 | u8 scan_type[IPW_SCAN_CHANNELS / 2]; | 698 | u8 scan_type[IPW_SCAN_CHANNELS / 2]; |
| @@ -740,19 +713,16 @@ extern inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan, | |||
| 740 | { | 713 | { |
| 741 | if (index % 2) | 714 | if (index % 2) |
| 742 | scan->scan_type[index / 2] = | 715 | scan->scan_type[index / 2] = |
| 743 | (scan->scan_type[index / 2] & 0xF0) | | 716 | (scan->scan_type[index / 2] & 0xF0) | (scan_type & 0x0F); |
| 744 | (scan_type & 0x0F); | ||
| 745 | else | 717 | else |
| 746 | scan->scan_type[index / 2] = | 718 | scan->scan_type[index / 2] = |
| 747 | (scan->scan_type[index / 2] & 0x0F) | | 719 | (scan->scan_type[index / 2] & 0x0F) | |
| 748 | ((scan_type & 0x0F) << 4); | 720 | ((scan_type & 0x0F) << 4); |
| 749 | } | 721 | } |
| 750 | 722 | ||
| 751 | struct ipw_associate | 723 | struct ipw_associate { |
| 752 | { | ||
| 753 | u8 channel; | 724 | u8 channel; |
| 754 | u8 auth_type:4, | 725 | u8 auth_type:4, auth_key:4; |
| 755 | auth_key:4; | ||
| 756 | u8 assoc_type; | 726 | u8 assoc_type; |
| 757 | u8 reserved; | 727 | u8 reserved; |
| 758 | u16 policy_support; | 728 | u16 policy_support; |
| @@ -771,8 +741,7 @@ struct ipw_associate | |||
| 771 | u16 reserved2; | 741 | u16 reserved2; |
| 772 | } __attribute__ ((packed)); | 742 | } __attribute__ ((packed)); |
| 773 | 743 | ||
| 774 | struct ipw_supported_rates | 744 | struct ipw_supported_rates { |
| 775 | { | ||
| 776 | u8 ieee_mode; | 745 | u8 ieee_mode; |
| 777 | u8 num_rates; | 746 | u8 num_rates; |
| 778 | u8 purpose; | 747 | u8 purpose; |
| @@ -780,42 +749,36 @@ struct ipw_supported_rates | |||
| 780 | u8 supported_rates[IPW_MAX_RATES]; | 749 | u8 supported_rates[IPW_MAX_RATES]; |
| 781 | } __attribute__ ((packed)); | 750 | } __attribute__ ((packed)); |
| 782 | 751 | ||
| 783 | struct ipw_rts_threshold | 752 | struct ipw_rts_threshold { |
| 784 | { | ||
| 785 | u16 rts_threshold; | 753 | u16 rts_threshold; |
| 786 | u16 reserved; | 754 | u16 reserved; |
| 787 | } __attribute__ ((packed)); | 755 | } __attribute__ ((packed)); |
| 788 | 756 | ||
| 789 | struct ipw_frag_threshold | 757 | struct ipw_frag_threshold { |
| 790 | { | ||
| 791 | u16 frag_threshold; | 758 | u16 frag_threshold; |
| 792 | u16 reserved; | 759 | u16 reserved; |
| 793 | } __attribute__ ((packed)); | 760 | } __attribute__ ((packed)); |
| 794 | 761 | ||
| 795 | struct ipw_retry_limit | 762 | struct ipw_retry_limit { |
| 796 | { | ||
| 797 | u8 short_retry_limit; | 763 | u8 short_retry_limit; |
| 798 | u8 long_retry_limit; | 764 | u8 long_retry_limit; |
| 799 | u16 reserved; | 765 | u16 reserved; |
| 800 | } __attribute__ ((packed)); | 766 | } __attribute__ ((packed)); |
| 801 | 767 | ||
| 802 | struct ipw_dino_config | 768 | struct ipw_dino_config { |
| 803 | { | ||
| 804 | u32 dino_config_addr; | 769 | u32 dino_config_addr; |
| 805 | u16 dino_config_size; | 770 | u16 dino_config_size; |
| 806 | u8 dino_response; | 771 | u8 dino_response; |
| 807 | u8 reserved; | 772 | u8 reserved; |
| 808 | } __attribute__ ((packed)); | 773 | } __attribute__ ((packed)); |
| 809 | 774 | ||
| 810 | struct ipw_aironet_info | 775 | struct ipw_aironet_info { |
| 811 | { | ||
| 812 | u8 id; | 776 | u8 id; |
| 813 | u8 length; | 777 | u8 length; |
| 814 | u16 reserved; | 778 | u16 reserved; |
| 815 | } __attribute__ ((packed)); | 779 | } __attribute__ ((packed)); |
| 816 | 780 | ||
| 817 | struct ipw_rx_key | 781 | struct ipw_rx_key { |
| 818 | { | ||
| 819 | u8 station_index; | 782 | u8 station_index; |
| 820 | u8 key_type; | 783 | u8 key_type; |
| 821 | u8 key_id; | 784 | u8 key_id; |
| @@ -826,23 +789,20 @@ struct ipw_rx_key | |||
| 826 | u8 reserved; | 789 | u8 reserved; |
| 827 | } __attribute__ ((packed)); | 790 | } __attribute__ ((packed)); |
| 828 | 791 | ||
| 829 | struct ipw_country_channel_info | 792 | struct ipw_country_channel_info { |
| 830 | { | ||
| 831 | u8 first_channel; | 793 | u8 first_channel; |
| 832 | u8 no_channels; | 794 | u8 no_channels; |
| 833 | s8 max_tx_power; | 795 | s8 max_tx_power; |
| 834 | } __attribute__ ((packed)); | 796 | } __attribute__ ((packed)); |
| 835 | 797 | ||
| 836 | struct ipw_country_info | 798 | struct ipw_country_info { |
| 837 | { | ||
| 838 | u8 id; | 799 | u8 id; |
| 839 | u8 length; | 800 | u8 length; |
| 840 | u8 country_str[3]; | 801 | u8 country_str[3]; |
| 841 | struct ipw_country_channel_info groups[7]; | 802 | struct ipw_country_channel_info groups[7]; |
| 842 | } __attribute__ ((packed)); | 803 | } __attribute__ ((packed)); |
| 843 | 804 | ||
| 844 | struct ipw_channel_tx_power | 805 | struct ipw_channel_tx_power { |
| 845 | { | ||
| 846 | u8 channel_number; | 806 | u8 channel_number; |
| 847 | s8 tx_power; | 807 | s8 tx_power; |
| 848 | } __attribute__ ((packed)); | 808 | } __attribute__ ((packed)); |
| @@ -852,15 +812,13 @@ struct ipw_channel_tx_power | |||
| 852 | #define MAX_A_CHANNELS 37 | 812 | #define MAX_A_CHANNELS 37 |
| 853 | #define MAX_B_CHANNELS 14 | 813 | #define MAX_B_CHANNELS 14 |
| 854 | 814 | ||
| 855 | struct ipw_tx_power | 815 | struct ipw_tx_power { |
| 856 | { | ||
| 857 | u8 num_channels; | 816 | u8 num_channels; |
| 858 | u8 ieee_mode; | 817 | u8 ieee_mode; |
| 859 | struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS]; | 818 | struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS]; |
| 860 | } __attribute__ ((packed)); | 819 | } __attribute__ ((packed)); |
| 861 | 820 | ||
| 862 | struct ipw_qos_parameters | 821 | struct ipw_qos_parameters { |
| 863 | { | ||
| 864 | u16 cw_min[4]; | 822 | u16 cw_min[4]; |
| 865 | u16 cw_max[4]; | 823 | u16 cw_max[4]; |
| 866 | u8 aifs[4]; | 824 | u8 aifs[4]; |
| @@ -868,15 +826,13 @@ struct ipw_qos_parameters | |||
| 868 | u16 tx_op_limit[4]; | 826 | u16 tx_op_limit[4]; |
| 869 | } __attribute__ ((packed)); | 827 | } __attribute__ ((packed)); |
| 870 | 828 | ||
| 871 | struct ipw_rsn_capabilities | 829 | struct ipw_rsn_capabilities { |
| 872 | { | ||
| 873 | u8 id; | 830 | u8 id; |
| 874 | u8 length; | 831 | u8 length; |
| 875 | u16 version; | 832 | u16 version; |
| 876 | } __attribute__ ((packed)); | 833 | } __attribute__ ((packed)); |
| 877 | 834 | ||
| 878 | struct ipw_sensitivity_calib | 835 | struct ipw_sensitivity_calib { |
| 879 | { | ||
| 880 | u16 beacon_rssi_raw; | 836 | u16 beacon_rssi_raw; |
| 881 | u16 reserved; | 837 | u16 reserved; |
| 882 | } __attribute__ ((packed)); | 838 | } __attribute__ ((packed)); |
| @@ -895,10 +851,11 @@ struct ipw_sensitivity_calib | |||
| 895 | * - \a param filled with status parameters. | 851 | * - \a param filled with status parameters. |
| 896 | */ | 852 | */ |
| 897 | struct ipw_cmd { | 853 | struct ipw_cmd { |
| 898 | u32 cmd; /**< Host command */ | 854 | u32 cmd; /**< Host command */ |
| 899 | u32 status; /**< Status */ | 855 | u32 status;/**< Status */ |
| 900 | u32 status_len; /**< How many 32 bit parameters in the status */ | 856 | u32 status_len; |
| 901 | u32 len; /**< incoming parameters length, bytes */ | 857 | /**< How many 32 bit parameters in the status */ |
| 858 | u32 len; /**< incoming parameters length, bytes */ | ||
| 902 | /** | 859 | /** |
| 903 | * command parameters. | 860 | * command parameters. |
| 904 | * There should be enough space for incoming and | 861 | * There should be enough space for incoming and |
| @@ -906,10 +863,10 @@ struct ipw_cmd { | |||
| 906 | * Incoming parameters listed 1-st, followed by outcoming params. | 863 | * Incoming parameters listed 1-st, followed by outcoming params. |
| 907 | * nParams=(len+3)/4+status_len | 864 | * nParams=(len+3)/4+status_len |
| 908 | */ | 865 | */ |
| 909 | u32 param[0]; | 866 | u32 param[0]; |
| 910 | } __attribute__ ((packed)); | 867 | } __attribute__ ((packed)); |
| 911 | 868 | ||
| 912 | #define STATUS_HCMD_ACTIVE (1<<0) /**< host command in progress */ | 869 | #define STATUS_HCMD_ACTIVE (1<<0) /**< host command in progress */ |
| 913 | 870 | ||
| 914 | #define STATUS_INT_ENABLED (1<<1) | 871 | #define STATUS_INT_ENABLED (1<<1) |
| 915 | #define STATUS_RF_KILL_HW (1<<2) | 872 | #define STATUS_RF_KILL_HW (1<<2) |
| @@ -932,15 +889,15 @@ struct ipw_cmd { | |||
| 932 | #define STATUS_SCANNING (1<<21) | 889 | #define STATUS_SCANNING (1<<21) |
| 933 | #define STATUS_SCAN_ABORTING (1<<22) | 890 | #define STATUS_SCAN_ABORTING (1<<22) |
| 934 | 891 | ||
| 935 | #define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ | 892 | #define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ |
| 936 | #define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ | 893 | #define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ |
| 937 | #define STATUS_DIRECT_DWORD (1<<30) /* sysfs entry configured for access */ | 894 | #define STATUS_DIRECT_DWORD (1<<30) /* sysfs entry configured for access */ |
| 938 | 895 | ||
| 939 | #define STATUS_SECURITY_UPDATED (1<<31) /* Security sync needed */ | 896 | #define STATUS_SECURITY_UPDATED (1<<31) /* Security sync needed */ |
| 940 | 897 | ||
| 941 | #define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */ | 898 | #define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */ |
| 942 | #define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */ | 899 | #define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */ |
| 943 | #define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */ | 900 | #define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */ |
| 944 | #define CFG_CUSTOM_MAC (1<<3) | 901 | #define CFG_CUSTOM_MAC (1<<3) |
| 945 | #define CFG_PREAMBLE (1<<4) | 902 | #define CFG_PREAMBLE (1<<4) |
| 946 | #define CFG_ADHOC_PERSIST (1<<5) | 903 | #define CFG_ADHOC_PERSIST (1<<5) |
| @@ -948,8 +905,8 @@ struct ipw_cmd { | |||
| 948 | #define CFG_FIXED_RATE (1<<7) | 905 | #define CFG_FIXED_RATE (1<<7) |
| 949 | #define CFG_ADHOC_CREATE (1<<8) | 906 | #define CFG_ADHOC_CREATE (1<<8) |
| 950 | 907 | ||
| 951 | #define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ | 908 | #define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ |
| 952 | #define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ | 909 | #define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ |
| 953 | 910 | ||
| 954 | #define MAX_STATIONS 32 | 911 | #define MAX_STATIONS 32 |
| 955 | #define IPW_INVALID_STATION (0xff) | 912 | #define IPW_INVALID_STATION (0xff) |
| @@ -989,8 +946,8 @@ struct ipw_priv { | |||
| 989 | /* result of ucode download */ | 946 | /* result of ucode download */ |
| 990 | struct alive_command_responce dino_alive; | 947 | struct alive_command_responce dino_alive; |
| 991 | 948 | ||
| 992 | wait_queue_head_t wait_command_queue; | 949 | wait_queue_head_t wait_command_queue; |
| 993 | wait_queue_head_t wait_state; | 950 | wait_queue_head_t wait_state; |
| 994 | 951 | ||
| 995 | /* Rx and Tx DMA processing queues */ | 952 | /* Rx and Tx DMA processing queues */ |
| 996 | struct ipw_rx_queue *rxq; | 953 | struct ipw_rx_queue *rxq; |
| @@ -1006,9 +963,9 @@ struct ipw_priv { | |||
| 1006 | struct average average_rssi; | 963 | struct average average_rssi; |
| 1007 | struct average average_noise; | 964 | struct average average_noise; |
| 1008 | u32 port_type; | 965 | u32 port_type; |
| 1009 | int rx_bufs_min; /**< minimum number of bufs in Rx queue */ | 966 | int rx_bufs_min; /**< minimum number of bufs in Rx queue */ |
| 1010 | int rx_pend_max; /**< maximum pending buffers for one IRQ */ | 967 | int rx_pend_max; /**< maximum pending buffers for one IRQ */ |
| 1011 | u32 hcmd_seq; /**< sequence number for hcmd */ | 968 | u32 hcmd_seq; /**< sequence number for hcmd */ |
| 1012 | u32 missed_beacon_threshold; | 969 | u32 missed_beacon_threshold; |
| 1013 | u32 roaming_threshold; | 970 | u32 roaming_threshold; |
| 1014 | 971 | ||
| @@ -1017,17 +974,17 @@ struct ipw_priv { | |||
| 1017 | 974 | ||
| 1018 | unsigned long ts_scan_abort; | 975 | unsigned long ts_scan_abort; |
| 1019 | struct ipw_supported_rates rates; | 976 | struct ipw_supported_rates rates; |
| 1020 | struct ipw_rates phy[3]; /**< PHY restrictions, per band */ | 977 | struct ipw_rates phy[3]; /**< PHY restrictions, per band */ |
| 1021 | struct ipw_rates supp; /**< software defined */ | 978 | struct ipw_rates supp; /**< software defined */ |
| 1022 | struct ipw_rates extended; /**< use for corresp. IE, AP only */ | 979 | struct ipw_rates extended; /**< use for corresp. IE, AP only */ |
| 1023 | 980 | ||
| 1024 | struct notif_link_deterioration last_link_deterioration; /** for statistics */ | 981 | struct notif_link_deterioration last_link_deterioration; /** for statistics */ |
| 1025 | struct ipw_cmd* hcmd; /**< host command currently executed */ | 982 | struct ipw_cmd *hcmd; /**< host command currently executed */ |
| 1026 | 983 | ||
| 1027 | wait_queue_head_t hcmd_wq; /**< host command waits for execution */ | 984 | wait_queue_head_t hcmd_wq; /**< host command waits for execution */ |
| 1028 | u32 tsf_bcn[2]; /**< TSF from latest beacon */ | 985 | u32 tsf_bcn[2]; /**< TSF from latest beacon */ |
| 1029 | 986 | ||
| 1030 | struct notif_calibration calib; /**< last calibration */ | 987 | struct notif_calibration calib; /**< last calibration */ |
| 1031 | 988 | ||
| 1032 | /* ordinal interface with firmware */ | 989 | /* ordinal interface with firmware */ |
| 1033 | u32 table0_addr; | 990 | u32 table0_addr; |
| @@ -1067,8 +1024,8 @@ struct ipw_priv { | |||
| 1067 | u32 tx_packets; | 1024 | u32 tx_packets; |
| 1068 | u32 quality; | 1025 | u32 quality; |
| 1069 | 1026 | ||
| 1070 | /* eeprom */ | 1027 | /* eeprom */ |
| 1071 | u8 eeprom[0x100]; /* 256 bytes of eeprom */ | 1028 | u8 eeprom[0x100]; /* 256 bytes of eeprom */ |
| 1072 | int eeprom_delay; | 1029 | int eeprom_delay; |
| 1073 | 1030 | ||
| 1074 | struct iw_statistics wstats; | 1031 | struct iw_statistics wstats; |
| @@ -1091,7 +1048,6 @@ struct ipw_priv { | |||
| 1091 | 1048 | ||
| 1092 | struct tasklet_struct irq_tasklet; | 1049 | struct tasklet_struct irq_tasklet; |
| 1093 | 1050 | ||
| 1094 | |||
| 1095 | #define IPW_2200BG 1 | 1051 | #define IPW_2200BG 1 |
| 1096 | #define IPW_2915ABG 2 | 1052 | #define IPW_2915ABG 2 |
| 1097 | u8 adapter; | 1053 | u8 adapter; |
| @@ -1114,7 +1070,6 @@ struct ipw_priv { | |||
| 1114 | u32 indirect_byte; | 1070 | u32 indirect_byte; |
| 1115 | }; /*ipw_priv */ | 1071 | }; /*ipw_priv */ |
| 1116 | 1072 | ||
| 1117 | |||
| 1118 | /* debug macros */ | 1073 | /* debug macros */ |
| 1119 | 1074 | ||
| 1120 | #ifdef CONFIG_IPW_DEBUG | 1075 | #ifdef CONFIG_IPW_DEBUG |
| @@ -1170,7 +1125,6 @@ do { if (ipw_debug_level & (level)) \ | |||
| 1170 | #define IPW_DL_RF_KILL (1<<17) | 1125 | #define IPW_DL_RF_KILL (1<<17) |
| 1171 | #define IPW_DL_FW_ERRORS (1<<18) | 1126 | #define IPW_DL_FW_ERRORS (1<<18) |
| 1172 | 1127 | ||
| 1173 | |||
| 1174 | #define IPW_DL_ORD (1<<20) | 1128 | #define IPW_DL_ORD (1<<20) |
| 1175 | 1129 | ||
| 1176 | #define IPW_DL_FRAG (1<<21) | 1130 | #define IPW_DL_FRAG (1<<21) |
| @@ -1184,7 +1138,6 @@ do { if (ipw_debug_level & (level)) \ | |||
| 1184 | 1138 | ||
| 1185 | #define IPW_DL_STATS (1<<29) | 1139 | #define IPW_DL_STATS (1<<29) |
| 1186 | 1140 | ||
| 1187 | |||
| 1188 | #define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) | 1141 | #define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) |
| 1189 | #define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) | 1142 | #define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) |
| 1190 | #define IPW_DEBUG_INFO(f, a...) IPW_DEBUG(IPW_DL_INFO, f, ## a) | 1143 | #define IPW_DEBUG_INFO(f, a...) IPW_DEBUG(IPW_DL_INFO, f, ## a) |
| @@ -1253,12 +1206,12 @@ do { if (ipw_debug_level & (level)) \ | |||
| 1253 | /* | 1206 | /* |
| 1254 | * RESET Register Bit Indexes | 1207 | * RESET Register Bit Indexes |
| 1255 | */ | 1208 | */ |
| 1256 | #define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */ | 1209 | #define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */ |
| 1257 | #define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */ | 1210 | #define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */ |
| 1258 | #define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */ | 1211 | #define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */ |
| 1259 | #define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */ | 1212 | #define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */ |
| 1260 | #define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */ | 1213 | #define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */ |
| 1261 | #define CX2_START_STANDBY 0x00000004 /* Bit 2 */ | 1214 | #define CX2_START_STANDBY 0x00000004 /* Bit 2 */ |
| 1262 | 1215 | ||
| 1263 | #define CX2_CSR_CIS_UPPER_BOUND 0x00000200 | 1216 | #define CX2_CSR_CIS_UPPER_BOUND 0x00000200 |
| 1264 | #define CX2_DOMAIN_0_END 0x1000 | 1217 | #define CX2_DOMAIN_0_END 0x1000 |
| @@ -1289,14 +1242,12 @@ do { if (ipw_debug_level & (level)) \ | |||
| 1289 | #define CB_SRC_SIZE_LONG 0x00200000 | 1242 | #define CB_SRC_SIZE_LONG 0x00200000 |
| 1290 | #define CB_DEST_SIZE_LONG 0x00020000 | 1243 | #define CB_DEST_SIZE_LONG 0x00020000 |
| 1291 | 1244 | ||
| 1292 | |||
| 1293 | /* DMA DEFINES */ | 1245 | /* DMA DEFINES */ |
| 1294 | 1246 | ||
| 1295 | #define DMA_CONTROL_SMALL_CB_CONST_VALUE 0x00540000 | 1247 | #define DMA_CONTROL_SMALL_CB_CONST_VALUE 0x00540000 |
| 1296 | #define DMA_CB_STOP_AND_ABORT 0x00000C00 | 1248 | #define DMA_CB_STOP_AND_ABORT 0x00000C00 |
| 1297 | #define DMA_CB_START 0x00000100 | 1249 | #define DMA_CB_START 0x00000100 |
| 1298 | 1250 | ||
| 1299 | |||
| 1300 | #define CX2_SHARED_SRAM_SIZE 0x00030000 | 1251 | #define CX2_SHARED_SRAM_SIZE 0x00030000 |
| 1301 | #define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000 | 1252 | #define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000 |
| 1302 | #define CB_MAX_LENGTH 0x1FFF | 1253 | #define CB_MAX_LENGTH 0x1FFF |
| @@ -1304,7 +1255,6 @@ do { if (ipw_debug_level & (level)) \ | |||
| 1304 | #define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18 | 1255 | #define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18 |
| 1305 | #define CX2_EEPROM_IMAGE_SIZE 0x100 | 1256 | #define CX2_EEPROM_IMAGE_SIZE 0x100 |
| 1306 | 1257 | ||
| 1307 | |||
| 1308 | /* DMA defs */ | 1258 | /* DMA defs */ |
| 1309 | #define CX2_DMA_I_CURRENT_CB 0x003000D0 | 1259 | #define CX2_DMA_I_CURRENT_CB 0x003000D0 |
| 1310 | #define CX2_DMA_O_CURRENT_CB 0x003000D4 | 1260 | #define CX2_DMA_O_CURRENT_CB 0x003000D4 |
| @@ -1356,7 +1306,6 @@ do { if (ipw_debug_level & (level)) \ | |||
| 1356 | #define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14) | 1306 | #define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14) |
| 1357 | #define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18) | 1307 | #define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18) |
| 1358 | 1308 | ||
| 1359 | |||
| 1360 | #define MSB 1 | 1309 | #define MSB 1 |
| 1361 | #define LSB 0 | 1310 | #define LSB 0 |
| 1362 | #define WORD_TO_BYTE(_word) ((_word) * sizeof(u16)) | 1311 | #define WORD_TO_BYTE(_word) ((_word) * sizeof(u16)) |
| @@ -1365,16 +1314,16 @@ do { if (ipw_debug_level & (level)) \ | |||
| 1365 | ( WORD_TO_BYTE(_wordoffset) + (_byteoffset) ) | 1314 | ( WORD_TO_BYTE(_wordoffset) + (_byteoffset) ) |
| 1366 | 1315 | ||
| 1367 | /* EEPROM access by BYTE */ | 1316 | /* EEPROM access by BYTE */ |
| 1368 | #define EEPROM_PME_CAPABILITY (GET_EEPROM_ADDR(0x09,MSB)) /* 1 byte */ | 1317 | #define EEPROM_PME_CAPABILITY (GET_EEPROM_ADDR(0x09,MSB)) /* 1 byte */ |
| 1369 | #define EEPROM_MAC_ADDRESS (GET_EEPROM_ADDR(0x21,LSB)) /* 6 byte */ | 1318 | #define EEPROM_MAC_ADDRESS (GET_EEPROM_ADDR(0x21,LSB)) /* 6 byte */ |
| 1370 | #define EEPROM_VERSION (GET_EEPROM_ADDR(0x24,MSB)) /* 1 byte */ | 1319 | #define EEPROM_VERSION (GET_EEPROM_ADDR(0x24,MSB)) /* 1 byte */ |
| 1371 | #define EEPROM_NIC_TYPE (GET_EEPROM_ADDR(0x25,LSB)) /* 1 byte */ | 1320 | #define EEPROM_NIC_TYPE (GET_EEPROM_ADDR(0x25,LSB)) /* 1 byte */ |
| 1372 | #define EEPROM_SKU_CAPABILITY (GET_EEPROM_ADDR(0x25,MSB)) /* 1 byte */ | 1321 | #define EEPROM_SKU_CAPABILITY (GET_EEPROM_ADDR(0x25,MSB)) /* 1 byte */ |
| 1373 | #define EEPROM_COUNTRY_CODE (GET_EEPROM_ADDR(0x26,LSB)) /* 3 bytes */ | 1322 | #define EEPROM_COUNTRY_CODE (GET_EEPROM_ADDR(0x26,LSB)) /* 3 bytes */ |
| 1374 | #define EEPROM_IBSS_CHANNELS_BG (GET_EEPROM_ADDR(0x28,LSB)) /* 2 bytes */ | 1323 | #define EEPROM_IBSS_CHANNELS_BG (GET_EEPROM_ADDR(0x28,LSB)) /* 2 bytes */ |
| 1375 | #define EEPROM_IBSS_CHANNELS_A (GET_EEPROM_ADDR(0x29,MSB)) /* 5 bytes */ | 1324 | #define EEPROM_IBSS_CHANNELS_A (GET_EEPROM_ADDR(0x29,MSB)) /* 5 bytes */ |
| 1376 | #define EEPROM_BSS_CHANNELS_BG (GET_EEPROM_ADDR(0x2c,LSB)) /* 2 bytes */ | 1325 | #define EEPROM_BSS_CHANNELS_BG (GET_EEPROM_ADDR(0x2c,LSB)) /* 2 bytes */ |
| 1377 | #define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ | 1326 | #define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ |
| 1378 | 1327 | ||
| 1379 | /* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ | 1328 | /* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ |
| 1380 | #define EEPROM_NIC_TYPE_STANDARD 0 | 1329 | #define EEPROM_NIC_TYPE_STANDARD 0 |
| @@ -1479,7 +1428,6 @@ enum { | |||
| 1479 | #define IPW_RATE_CAPABILITIES 1 | 1428 | #define IPW_RATE_CAPABILITIES 1 |
| 1480 | #define IPW_RATE_CONNECT 0 | 1429 | #define IPW_RATE_CONNECT 0 |
| 1481 | 1430 | ||
| 1482 | |||
| 1483 | /* | 1431 | /* |
| 1484 | * Rate values and masks | 1432 | * Rate values and masks |
| 1485 | */ | 1433 | */ |
| @@ -1524,12 +1472,6 @@ enum { | |||
| 1524 | IPW_ORD_STAT_TX_DIR_DATA_B_11, | 1472 | IPW_ORD_STAT_TX_DIR_DATA_B_11, |
| 1525 | /* Hole */ | 1473 | /* Hole */ |
| 1526 | 1474 | ||
| 1527 | |||
| 1528 | |||
| 1529 | |||
| 1530 | |||
| 1531 | |||
| 1532 | |||
| 1533 | IPW_ORD_STAT_TX_DIR_DATA_G_1 = IPW_ORD_TABLE_0_MASK + 19, | 1475 | IPW_ORD_STAT_TX_DIR_DATA_G_1 = IPW_ORD_TABLE_0_MASK + 19, |
| 1534 | IPW_ORD_STAT_TX_DIR_DATA_G_2, | 1476 | IPW_ORD_STAT_TX_DIR_DATA_G_2, |
| 1535 | IPW_ORD_STAT_TX_DIR_DATA_G_5_5, | 1477 | IPW_ORD_STAT_TX_DIR_DATA_G_5_5, |
| @@ -1549,12 +1491,6 @@ enum { | |||
| 1549 | IPW_ORD_STAT_TX_NON_DIR_DATA_B_11, | 1491 | IPW_ORD_STAT_TX_NON_DIR_DATA_B_11, |
| 1550 | /* Hole */ | 1492 | /* Hole */ |
| 1551 | 1493 | ||
| 1552 | |||
| 1553 | |||
| 1554 | |||
| 1555 | |||
| 1556 | |||
| 1557 | |||
| 1558 | IPW_ORD_STAT_TX_NON_DIR_DATA_G_1 = IPW_ORD_TABLE_0_MASK + 44, | 1494 | IPW_ORD_STAT_TX_NON_DIR_DATA_G_1 = IPW_ORD_TABLE_0_MASK + 44, |
| 1559 | IPW_ORD_STAT_TX_NON_DIR_DATA_G_2, | 1495 | IPW_ORD_STAT_TX_NON_DIR_DATA_G_2, |
| 1560 | IPW_ORD_STAT_TX_NON_DIR_DATA_G_5_5, | 1496 | IPW_ORD_STAT_TX_NON_DIR_DATA_G_5_5, |
| @@ -1685,7 +1621,7 @@ struct host_cmd { | |||
| 1685 | #define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08 | 1621 | #define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08 |
| 1686 | #define CFG_BT_COEXISTENCE_OOB 0x10 | 1622 | #define CFG_BT_COEXISTENCE_OOB 0x10 |
| 1687 | #define CFG_BT_COEXISTENCE_MAX 0xFF | 1623 | #define CFG_BT_COEXISTENCE_MAX 0xFF |
| 1688 | #define CFG_BT_COEXISTENCE_DEF 0x80 /* read Bt from EEPROM*/ | 1624 | #define CFG_BT_COEXISTENCE_DEF 0x80 /* read Bt from EEPROM */ |
| 1689 | 1625 | ||
| 1690 | #define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x0 | 1626 | #define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x0 |
| 1691 | #define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x1 | 1627 | #define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x1 |
| @@ -1727,11 +1663,11 @@ static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr) | |||
| 1727 | fc = le16_to_cpu(hdr->frame_ctl); | 1663 | fc = le16_to_cpu(hdr->frame_ctl); |
| 1728 | 1664 | ||
| 1729 | /* | 1665 | /* |
| 1730 | * Function ToDS FromDS | 1666 | * Function ToDS FromDS |
| 1731 | * IBSS 0 0 | 1667 | * IBSS 0 0 |
| 1732 | * To AP 1 0 | 1668 | * To AP 1 0 |
| 1733 | * From AP 0 1 | 1669 | * From AP 0 1 |
| 1734 | * WDS (bridge) 1 1 | 1670 | * WDS (bridge) 1 1 |
| 1735 | * | 1671 | * |
| 1736 | * Only WDS frames use Address4 among them. --YZ | 1672 | * Only WDS frames use Address4 among them. --YZ |
| 1737 | */ | 1673 | */ |
| @@ -1741,4 +1677,4 @@ static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr) | |||
| 1741 | return retval; | 1677 | return retval; |
| 1742 | } | 1678 | } |
| 1743 | 1679 | ||
| 1744 | #endif /* __ipw2200_h__ */ | 1680 | #endif /* __ipw2200_h__ */ |
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 5f507c49907b..ca6c03c89926 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c | |||
| @@ -471,12 +471,12 @@ static dev_link_t *netwave_attach(void) | |||
| 471 | dev->get_stats = &netwave_get_stats; | 471 | dev->get_stats = &netwave_get_stats; |
| 472 | dev->set_multicast_list = &set_multicast_list; | 472 | dev->set_multicast_list = &set_multicast_list; |
| 473 | /* wireless extensions */ | 473 | /* wireless extensions */ |
| 474 | #ifdef WIRELESS_EXT | 474 | #if WIRELESS_EXT <= 16 |
| 475 | dev->get_wireless_stats = &netwave_get_wireless_stats; | 475 | dev->get_wireless_stats = &netwave_get_wireless_stats; |
| 476 | #endif /* WIRELESS_EXT <= 16 */ | ||
| 476 | #if WIRELESS_EXT > 12 | 477 | #if WIRELESS_EXT > 12 |
| 477 | dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def; | 478 | dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def; |
| 478 | #endif /* WIRELESS_EXT > 12 */ | 479 | #endif /* WIRELESS_EXT > 12 */ |
| 479 | #endif /* WIRELESS_EXT */ | ||
| 480 | dev->do_ioctl = &netwave_ioctl; | 480 | dev->do_ioctl = &netwave_ioctl; |
| 481 | 481 | ||
| 482 | dev->tx_timeout = &netwave_watchdog; | 482 | dev->tx_timeout = &netwave_watchdog; |
| @@ -839,6 +839,9 @@ static const struct iw_handler_def netwave_handler_def = | |||
| 839 | .standard = (iw_handler *) netwave_handler, | 839 | .standard = (iw_handler *) netwave_handler, |
| 840 | .private = (iw_handler *) netwave_private_handler, | 840 | .private = (iw_handler *) netwave_private_handler, |
| 841 | .private_args = (struct iw_priv_args *) netwave_private_args, | 841 | .private_args = (struct iw_priv_args *) netwave_private_args, |
| 842 | #if WIRELESS_EXT > 16 | ||
| 843 | .get_wireless_stats = netwave_get_wireless_stats, | ||
| 844 | #endif /* WIRELESS_EXT > 16 */ | ||
| 842 | }; | 845 | }; |
| 843 | #endif /* WIRELESS_EXT > 12 */ | 846 | #endif /* WIRELESS_EXT > 12 */ |
| 844 | 847 | ||
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 0f29a9c7bc2c..9a8790e3580c 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
| @@ -2727,6 +2727,9 @@ const struct iw_handler_def prism54_handler_def = { | |||
| 2727 | .standard = (iw_handler *) prism54_handler, | 2727 | .standard = (iw_handler *) prism54_handler, |
| 2728 | .private = (iw_handler *) prism54_private_handler, | 2728 | .private = (iw_handler *) prism54_private_handler, |
| 2729 | .private_args = (struct iw_priv_args *) prism54_private_args, | 2729 | .private_args = (struct iw_priv_args *) prism54_private_args, |
| 2730 | #if WIRELESS_EXT > 16 | ||
| 2731 | .get_wireless_stats = prism54_get_wireless_stats, | ||
| 2732 | #endif /* WIRELESS_EXT > 16 */ | ||
| 2730 | #if WIRELESS_EXT == 16 | 2733 | #if WIRELESS_EXT == 16 |
| 2731 | .spy_offset = offsetof(islpci_private, spy_data), | 2734 | .spy_offset = offsetof(islpci_private, spy_data), |
| 2732 | #endif /* WIRELESS_EXT == 16 */ | 2735 | #endif /* WIRELESS_EXT == 16 */ |
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index efab07e9e24e..6f13d4a8e2d3 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
| @@ -815,7 +815,6 @@ islpci_setup(struct pci_dev *pdev) | |||
| 815 | ndev->open = &islpci_open; | 815 | ndev->open = &islpci_open; |
| 816 | ndev->stop = &islpci_close; | 816 | ndev->stop = &islpci_close; |
| 817 | ndev->get_stats = &islpci_statistics; | 817 | ndev->get_stats = &islpci_statistics; |
| 818 | ndev->get_wireless_stats = &prism54_get_wireless_stats; | ||
| 819 | ndev->do_ioctl = &prism54_ioctl; | 818 | ndev->do_ioctl = &prism54_ioctl; |
| 820 | ndev->wireless_handlers = | 819 | ndev->wireless_handlers = |
| 821 | (struct iw_handler_def *) &prism54_handler_def; | 820 | (struct iw_handler_def *) &prism54_handler_def; |
| @@ -844,6 +843,8 @@ islpci_setup(struct pci_dev *pdev) | |||
| 844 | /* Add pointers to enable iwspy support. */ | 843 | /* Add pointers to enable iwspy support. */ |
| 845 | priv->wireless_data.spy_data = &priv->spy_data; | 844 | priv->wireless_data.spy_data = &priv->spy_data; |
| 846 | ndev->wireless_data = &priv->wireless_data; | 845 | ndev->wireless_data = &priv->wireless_data; |
| 846 | #else /* WIRELESS_EXT > 16 */ | ||
| 847 | ndev->get_wireless_stats = &prism54_get_wireless_stats; | ||
| 847 | #endif /* WIRELESS_EXT > 16 */ | 848 | #endif /* WIRELESS_EXT > 16 */ |
| 848 | 849 | ||
| 849 | /* save the start and end address of the PCI memory area */ | 850 | /* save the start and end address of the PCI memory area */ |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 0e0ba614259a..e9c5ea0f5535 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | #include <pcmcia/ds.h> | 53 | #include <pcmcia/ds.h> |
| 54 | #include <pcmcia/mem_op.h> | 54 | #include <pcmcia/mem_op.h> |
| 55 | 55 | ||
| 56 | #include <net/ieee80211.h> | ||
| 56 | #include <linux/wireless.h> | 57 | #include <linux/wireless.h> |
| 57 | 58 | ||
| 58 | #include <asm/io.h> | 59 | #include <asm/io.h> |
| @@ -64,7 +65,6 @@ | |||
| 64 | #define WIRELESS_SPY /* Enable spying addresses */ | 65 | #define WIRELESS_SPY /* Enable spying addresses */ |
| 65 | /* Definitions we need for spy */ | 66 | /* Definitions we need for spy */ |
| 66 | typedef struct iw_statistics iw_stats; | 67 | typedef struct iw_statistics iw_stats; |
| 67 | typedef struct iw_quality iw_qual; | ||
| 68 | typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ | 68 | typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ |
| 69 | 69 | ||
| 70 | #include "rayctl.h" | 70 | #include "rayctl.h" |
| @@ -101,7 +101,6 @@ static int ray_dev_close(struct net_device *dev); | |||
| 101 | static int ray_dev_config(struct net_device *dev, struct ifmap *map); | 101 | static int ray_dev_config(struct net_device *dev, struct ifmap *map); |
| 102 | static struct net_device_stats *ray_get_stats(struct net_device *dev); | 102 | static struct net_device_stats *ray_get_stats(struct net_device *dev); |
| 103 | static int ray_dev_init(struct net_device *dev); | 103 | static int ray_dev_init(struct net_device *dev); |
| 104 | static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); | ||
| 105 | 104 | ||
| 106 | static struct ethtool_ops netdev_ethtool_ops; | 105 | static struct ethtool_ops netdev_ethtool_ops; |
| 107 | 106 | ||
| @@ -114,9 +113,8 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, | |||
| 114 | static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type, | 113 | static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type, |
| 115 | unsigned char *data); | 114 | unsigned char *data); |
| 116 | static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); | 115 | static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); |
| 117 | #if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ | ||
| 118 | static iw_stats * ray_get_wireless_stats(struct net_device * dev); | 116 | static iw_stats * ray_get_wireless_stats(struct net_device * dev); |
| 119 | #endif /* WIRELESS_EXT > 7 */ | 117 | static const struct iw_handler_def ray_handler_def; |
| 120 | 118 | ||
| 121 | /***** Prototypes for raylink functions **************************************/ | 119 | /***** Prototypes for raylink functions **************************************/ |
| 122 | static int asc_to_int(char a); | 120 | static int asc_to_int(char a); |
| @@ -373,11 +371,12 @@ static dev_link_t *ray_attach(void) | |||
| 373 | dev->hard_start_xmit = &ray_dev_start_xmit; | 371 | dev->hard_start_xmit = &ray_dev_start_xmit; |
| 374 | dev->set_config = &ray_dev_config; | 372 | dev->set_config = &ray_dev_config; |
| 375 | dev->get_stats = &ray_get_stats; | 373 | dev->get_stats = &ray_get_stats; |
| 376 | dev->do_ioctl = &ray_dev_ioctl; | ||
| 377 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); | 374 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); |
| 378 | #if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ | 375 | dev->wireless_handlers = &ray_handler_def; |
| 379 | dev->get_wireless_stats = ray_get_wireless_stats; | 376 | #ifdef WIRELESS_SPY |
| 380 | #endif | 377 | local->wireless_data.spy_data = &local->spy_data; |
| 378 | dev->wireless_data = &local->wireless_data; | ||
| 379 | #endif /* WIRELESS_SPY */ | ||
| 381 | 380 | ||
| 382 | dev->set_multicast_list = &set_multicast_list; | 381 | dev->set_multicast_list = &set_multicast_list; |
| 383 | 382 | ||
| @@ -1201,436 +1200,420 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
| 1201 | 1200 | ||
| 1202 | /*====================================================================*/ | 1201 | /*====================================================================*/ |
| 1203 | 1202 | ||
| 1204 | static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 1203 | /*------------------------------------------------------------------*/ |
| 1204 | /* | ||
| 1205 | * Wireless Handler : get protocol name | ||
| 1206 | */ | ||
| 1207 | static int ray_get_name(struct net_device *dev, | ||
| 1208 | struct iw_request_info *info, | ||
| 1209 | char *cwrq, | ||
| 1210 | char *extra) | ||
| 1205 | { | 1211 | { |
| 1206 | ray_dev_t *local = (ray_dev_t *)dev->priv; | 1212 | strcpy(cwrq, "IEEE 802.11-FH"); |
| 1207 | dev_link_t *link = local->finder; | 1213 | return 0; |
| 1208 | int err = 0; | 1214 | } |
| 1209 | #if WIRELESS_EXT > 7 | ||
| 1210 | struct iwreq *wrq = (struct iwreq *) ifr; | ||
| 1211 | #endif /* WIRELESS_EXT > 7 */ | ||
| 1212 | #ifdef WIRELESS_SPY | ||
| 1213 | struct sockaddr address[IW_MAX_SPY]; | ||
| 1214 | #endif /* WIRELESS_SPY */ | ||
| 1215 | 1215 | ||
| 1216 | if (!(link->state & DEV_PRESENT)) { | 1216 | /*------------------------------------------------------------------*/ |
| 1217 | DEBUG(2,"ray_dev_ioctl - device not present\n"); | 1217 | /* |
| 1218 | return -1; | 1218 | * Wireless Handler : set frequency |
| 1219 | } | 1219 | */ |
| 1220 | DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd); | 1220 | static int ray_set_freq(struct net_device *dev, |
| 1221 | /* Validate the command */ | 1221 | struct iw_request_info *info, |
| 1222 | switch (cmd) | 1222 | struct iw_freq *fwrq, |
| 1223 | { | 1223 | char *extra) |
| 1224 | #if WIRELESS_EXT > 7 | 1224 | { |
| 1225 | /* --------------- WIRELESS EXTENSIONS --------------- */ | 1225 | ray_dev_t *local = (ray_dev_t *)dev->priv; |
| 1226 | /* Get name */ | 1226 | int err = -EINPROGRESS; /* Call commit handler */ |
| 1227 | case SIOCGIWNAME: | ||
| 1228 | strcpy(wrq->u.name, "IEEE 802.11-FH"); | ||
| 1229 | break; | ||
| 1230 | |||
| 1231 | /* Get frequency/channel */ | ||
| 1232 | case SIOCGIWFREQ: | ||
| 1233 | wrq->u.freq.m = local->sparm.b5.a_hop_pattern; | ||
| 1234 | wrq->u.freq.e = 0; | ||
| 1235 | break; | ||
| 1236 | |||
| 1237 | /* Set frequency/channel */ | ||
| 1238 | case SIOCSIWFREQ: | ||
| 1239 | /* Reject if card is already initialised */ | ||
| 1240 | if(local->card_status != CARD_AWAITING_PARAM) | ||
| 1241 | { | ||
| 1242 | err = -EBUSY; | ||
| 1243 | break; | ||
| 1244 | } | ||
| 1245 | 1227 | ||
| 1246 | /* Setting by channel number */ | 1228 | /* Reject if card is already initialised */ |
| 1247 | if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0)) | 1229 | if(local->card_status != CARD_AWAITING_PARAM) |
| 1248 | err = -EOPNOTSUPP; | 1230 | return -EBUSY; |
| 1249 | else | ||
| 1250 | local->sparm.b5.a_hop_pattern = wrq->u.freq.m; | ||
| 1251 | break; | ||
| 1252 | 1231 | ||
| 1253 | /* Get current network name (ESSID) */ | 1232 | /* Setting by channel number */ |
| 1254 | case SIOCGIWESSID: | 1233 | if ((fwrq->m > USA_HOP_MOD) || (fwrq->e > 0)) |
| 1255 | if (wrq->u.data.pointer) | 1234 | err = -EOPNOTSUPP; |
| 1256 | { | 1235 | else |
| 1257 | char essid[IW_ESSID_MAX_SIZE + 1]; | 1236 | local->sparm.b5.a_hop_pattern = fwrq->m; |
| 1258 | /* Get the essid that was set */ | ||
| 1259 | memcpy(essid, local->sparm.b5.a_current_ess_id, | ||
| 1260 | IW_ESSID_MAX_SIZE); | ||
| 1261 | essid[IW_ESSID_MAX_SIZE] = '\0'; | ||
| 1262 | |||
| 1263 | /* Push it out ! */ | ||
| 1264 | wrq->u.data.length = strlen(essid) + 1; | ||
| 1265 | wrq->u.data.flags = 1; /* active */ | ||
| 1266 | if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid))) | ||
| 1267 | err = -EFAULT; | ||
| 1268 | } | ||
| 1269 | break; | ||
| 1270 | 1237 | ||
| 1271 | /* Set desired network name (ESSID) */ | 1238 | return err; |
| 1272 | case SIOCSIWESSID: | 1239 | } |
| 1273 | /* Reject if card is already initialised */ | 1240 | |
| 1274 | if(local->card_status != CARD_AWAITING_PARAM) | 1241 | /*------------------------------------------------------------------*/ |
| 1275 | { | 1242 | /* |
| 1276 | err = -EBUSY; | 1243 | * Wireless Handler : get frequency |
| 1277 | break; | 1244 | */ |
| 1278 | } | 1245 | static int ray_get_freq(struct net_device *dev, |
| 1246 | struct iw_request_info *info, | ||
| 1247 | struct iw_freq *fwrq, | ||
| 1248 | char *extra) | ||
| 1249 | { | ||
| 1250 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1279 | 1251 | ||
| 1280 | if (wrq->u.data.pointer) | 1252 | fwrq->m = local->sparm.b5.a_hop_pattern; |
| 1281 | { | 1253 | fwrq->e = 0; |
| 1282 | char card_essid[IW_ESSID_MAX_SIZE + 1]; | 1254 | return 0; |
| 1283 | 1255 | } | |
| 1284 | /* Check if we asked for `any' */ | 1256 | |
| 1285 | if(wrq->u.data.flags == 0) | 1257 | /*------------------------------------------------------------------*/ |
| 1286 | { | 1258 | /* |
| 1259 | * Wireless Handler : set ESSID | ||
| 1260 | */ | ||
| 1261 | static int ray_set_essid(struct net_device *dev, | ||
| 1262 | struct iw_request_info *info, | ||
| 1263 | struct iw_point *dwrq, | ||
| 1264 | char *extra) | ||
| 1265 | { | ||
| 1266 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1267 | |||
| 1268 | /* Reject if card is already initialised */ | ||
| 1269 | if(local->card_status != CARD_AWAITING_PARAM) | ||
| 1270 | return -EBUSY; | ||
| 1271 | |||
| 1272 | /* Check if we asked for `any' */ | ||
| 1273 | if(dwrq->flags == 0) { | ||
| 1287 | /* Corey : can you do that ? */ | 1274 | /* Corey : can you do that ? */ |
| 1288 | err = -EOPNOTSUPP; | 1275 | return -EOPNOTSUPP; |
| 1289 | } | 1276 | } else { |
| 1290 | else | ||
| 1291 | { | ||
| 1292 | /* Check the size of the string */ | 1277 | /* Check the size of the string */ |
| 1293 | if(wrq->u.data.length > | 1278 | if(dwrq->length > IW_ESSID_MAX_SIZE + 1) { |
| 1294 | IW_ESSID_MAX_SIZE + 1) | 1279 | return -E2BIG; |
| 1295 | { | ||
| 1296 | err = -E2BIG; | ||
| 1297 | break; | ||
| 1298 | } | ||
| 1299 | if (copy_from_user(card_essid, | ||
| 1300 | wrq->u.data.pointer, | ||
| 1301 | wrq->u.data.length)) { | ||
| 1302 | err = -EFAULT; | ||
| 1303 | break; | ||
| 1304 | } | 1280 | } |
| 1305 | card_essid[IW_ESSID_MAX_SIZE] = '\0'; | ||
| 1306 | 1281 | ||
| 1307 | /* Set the ESSID in the card */ | 1282 | /* Set the ESSID in the card */ |
| 1308 | memcpy(local->sparm.b5.a_current_ess_id, card_essid, | 1283 | memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE); |
| 1309 | IW_ESSID_MAX_SIZE); | 1284 | memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length); |
| 1310 | } | ||
| 1311 | } | 1285 | } |
| 1312 | break; | ||
| 1313 | |||
| 1314 | /* Get current Access Point (BSSID in our case) */ | ||
| 1315 | case SIOCGIWAP: | ||
| 1316 | memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN); | ||
| 1317 | wrq->u.ap_addr.sa_family = ARPHRD_ETHER; | ||
| 1318 | break; | ||
| 1319 | |||
| 1320 | /* Get the current bit-rate */ | ||
| 1321 | case SIOCGIWRATE: | ||
| 1322 | if(local->net_default_tx_rate == 3) | ||
| 1323 | wrq->u.bitrate.value = 2000000; /* Hum... */ | ||
| 1324 | else | ||
| 1325 | wrq->u.bitrate.value = local->net_default_tx_rate * 500000; | ||
| 1326 | wrq->u.bitrate.fixed = 0; /* We are in auto mode */ | ||
| 1327 | break; | ||
| 1328 | |||
| 1329 | /* Set the desired bit-rate */ | ||
| 1330 | case SIOCSIWRATE: | ||
| 1331 | /* Check if rate is in range */ | ||
| 1332 | if((wrq->u.bitrate.value != 1000000) && | ||
| 1333 | (wrq->u.bitrate.value != 2000000)) | ||
| 1334 | { | ||
| 1335 | err = -EINVAL; | ||
| 1336 | break; | ||
| 1337 | } | ||
| 1338 | /* Hack for 1.5 Mb/s instead of 2 Mb/s */ | ||
| 1339 | if((local->fw_ver == 0x55) && /* Please check */ | ||
| 1340 | (wrq->u.bitrate.value == 2000000)) | ||
| 1341 | local->net_default_tx_rate = 3; | ||
| 1342 | else | ||
| 1343 | local->net_default_tx_rate = wrq->u.bitrate.value/500000; | ||
| 1344 | break; | ||
| 1345 | |||
| 1346 | /* Get the current RTS threshold */ | ||
| 1347 | case SIOCGIWRTS: | ||
| 1348 | wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8) | ||
| 1349 | + local->sparm.b5.a_rts_threshold[1]; | ||
| 1350 | #if WIRELESS_EXT > 8 | ||
| 1351 | wrq->u.rts.disabled = (wrq->u.rts.value == 32767); | ||
| 1352 | #endif /* WIRELESS_EXT > 8 */ | ||
| 1353 | wrq->u.rts.fixed = 1; | ||
| 1354 | break; | ||
| 1355 | |||
| 1356 | /* Set the desired RTS threshold */ | ||
| 1357 | case SIOCSIWRTS: | ||
| 1358 | { | ||
| 1359 | int rthr = wrq->u.rts.value; | ||
| 1360 | 1286 | ||
| 1361 | /* Reject if card is already initialised */ | 1287 | return -EINPROGRESS; /* Call commit handler */ |
| 1362 | if(local->card_status != CARD_AWAITING_PARAM) | 1288 | } |
| 1363 | { | ||
| 1364 | err = -EBUSY; | ||
| 1365 | break; | ||
| 1366 | } | ||
| 1367 | 1289 | ||
| 1368 | /* if(wrq->u.rts.fixed == 0) we should complain */ | 1290 | /*------------------------------------------------------------------*/ |
| 1369 | #if WIRELESS_EXT > 8 | 1291 | /* |
| 1370 | if(wrq->u.rts.disabled) | 1292 | * Wireless Handler : get ESSID |
| 1371 | rthr = 32767; | 1293 | */ |
| 1294 | static int ray_get_essid(struct net_device *dev, | ||
| 1295 | struct iw_request_info *info, | ||
| 1296 | struct iw_point *dwrq, | ||
| 1297 | char *extra) | ||
| 1298 | { | ||
| 1299 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1300 | |||
| 1301 | /* Get the essid that was set */ | ||
| 1302 | memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); | ||
| 1303 | extra[IW_ESSID_MAX_SIZE] = '\0'; | ||
| 1304 | |||
| 1305 | /* Push it out ! */ | ||
| 1306 | dwrq->length = strlen(extra) + 1; | ||
| 1307 | dwrq->flags = 1; /* active */ | ||
| 1308 | |||
| 1309 | return 0; | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | /*------------------------------------------------------------------*/ | ||
| 1313 | /* | ||
| 1314 | * Wireless Handler : get AP address | ||
| 1315 | */ | ||
| 1316 | static int ray_get_wap(struct net_device *dev, | ||
| 1317 | struct iw_request_info *info, | ||
| 1318 | struct sockaddr *awrq, | ||
| 1319 | char *extra) | ||
| 1320 | { | ||
| 1321 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1322 | |||
| 1323 | memcpy(awrq->sa_data, local->bss_id, ETH_ALEN); | ||
| 1324 | awrq->sa_family = ARPHRD_ETHER; | ||
| 1325 | |||
| 1326 | return 0; | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | /*------------------------------------------------------------------*/ | ||
| 1330 | /* | ||
| 1331 | * Wireless Handler : set Bit-Rate | ||
| 1332 | */ | ||
| 1333 | static int ray_set_rate(struct net_device *dev, | ||
| 1334 | struct iw_request_info *info, | ||
| 1335 | struct iw_param *vwrq, | ||
| 1336 | char *extra) | ||
| 1337 | { | ||
| 1338 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1339 | |||
| 1340 | /* Reject if card is already initialised */ | ||
| 1341 | if(local->card_status != CARD_AWAITING_PARAM) | ||
| 1342 | return -EBUSY; | ||
| 1343 | |||
| 1344 | /* Check if rate is in range */ | ||
| 1345 | if((vwrq->value != 1000000) && (vwrq->value != 2000000)) | ||
| 1346 | return -EINVAL; | ||
| 1347 | |||
| 1348 | /* Hack for 1.5 Mb/s instead of 2 Mb/s */ | ||
| 1349 | if((local->fw_ver == 0x55) && /* Please check */ | ||
| 1350 | (vwrq->value == 2000000)) | ||
| 1351 | local->net_default_tx_rate = 3; | ||
| 1372 | else | 1352 | else |
| 1373 | #endif /* WIRELESS_EXT > 8 */ | 1353 | local->net_default_tx_rate = vwrq->value/500000; |
| 1374 | if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ | 1354 | |
| 1375 | { | 1355 | return 0; |
| 1376 | err = -EINVAL; | 1356 | } |
| 1377 | break; | 1357 | |
| 1378 | } | 1358 | /*------------------------------------------------------------------*/ |
| 1359 | /* | ||
| 1360 | * Wireless Handler : get Bit-Rate | ||
| 1361 | */ | ||
| 1362 | static int ray_get_rate(struct net_device *dev, | ||
| 1363 | struct iw_request_info *info, | ||
| 1364 | struct iw_param *vwrq, | ||
| 1365 | char *extra) | ||
| 1366 | { | ||
| 1367 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1368 | |||
| 1369 | if(local->net_default_tx_rate == 3) | ||
| 1370 | vwrq->value = 2000000; /* Hum... */ | ||
| 1371 | else | ||
| 1372 | vwrq->value = local->net_default_tx_rate * 500000; | ||
| 1373 | vwrq->fixed = 0; /* We are in auto mode */ | ||
| 1374 | |||
| 1375 | return 0; | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | /*------------------------------------------------------------------*/ | ||
| 1379 | /* | ||
| 1380 | * Wireless Handler : set RTS threshold | ||
| 1381 | */ | ||
| 1382 | static int ray_set_rts(struct net_device *dev, | ||
| 1383 | struct iw_request_info *info, | ||
| 1384 | struct iw_param *vwrq, | ||
| 1385 | char *extra) | ||
| 1386 | { | ||
| 1387 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1388 | int rthr = vwrq->value; | ||
| 1389 | |||
| 1390 | /* Reject if card is already initialised */ | ||
| 1391 | if(local->card_status != CARD_AWAITING_PARAM) | ||
| 1392 | return -EBUSY; | ||
| 1393 | |||
| 1394 | /* if(wrq->u.rts.fixed == 0) we should complain */ | ||
| 1395 | if(vwrq->disabled) | ||
| 1396 | rthr = 32767; | ||
| 1397 | else { | ||
| 1398 | if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ | ||
| 1399 | return -EINVAL; | ||
| 1400 | } | ||
| 1379 | local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF; | 1401 | local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF; |
| 1380 | local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF; | 1402 | local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF; |
| 1381 | } | ||
| 1382 | break; | ||
| 1383 | 1403 | ||
| 1384 | /* Get the current fragmentation threshold */ | 1404 | return -EINPROGRESS; /* Call commit handler */ |
| 1385 | case SIOCGIWFRAG: | 1405 | } |
| 1386 | wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8) | ||
| 1387 | + local->sparm.b5.a_frag_threshold[1]; | ||
| 1388 | #if WIRELESS_EXT > 8 | ||
| 1389 | wrq->u.frag.disabled = (wrq->u.frag.value == 32767); | ||
| 1390 | #endif /* WIRELESS_EXT > 8 */ | ||
| 1391 | wrq->u.frag.fixed = 1; | ||
| 1392 | break; | ||
| 1393 | 1406 | ||
| 1394 | /* Set the desired fragmentation threshold */ | ||
| 1395 | case SIOCSIWFRAG: | ||
| 1396 | { | ||
| 1397 | int fthr = wrq->u.frag.value; | ||
| 1398 | 1407 | ||
| 1399 | /* Reject if card is already initialised */ | 1408 | /*------------------------------------------------------------------*/ |
| 1400 | if(local->card_status != CARD_AWAITING_PARAM) | 1409 | /* |
| 1401 | { | 1410 | * Wireless Handler : get RTS threshold |
| 1402 | err = -EBUSY; | 1411 | */ |
| 1403 | break; | 1412 | static int ray_get_rts(struct net_device *dev, |
| 1404 | } | 1413 | struct iw_request_info *info, |
| 1414 | struct iw_param *vwrq, | ||
| 1415 | char *extra) | ||
| 1416 | { | ||
| 1417 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1418 | |||
| 1419 | vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8) | ||
| 1420 | + local->sparm.b5.a_rts_threshold[1]; | ||
| 1421 | vwrq->disabled = (vwrq->value == 32767); | ||
| 1422 | vwrq->fixed = 1; | ||
| 1423 | |||
| 1424 | return 0; | ||
| 1425 | } | ||
| 1426 | |||
| 1427 | /*------------------------------------------------------------------*/ | ||
| 1428 | /* | ||
| 1429 | * Wireless Handler : set Fragmentation threshold | ||
| 1430 | */ | ||
| 1431 | static int ray_set_frag(struct net_device *dev, | ||
| 1432 | struct iw_request_info *info, | ||
| 1433 | struct iw_param *vwrq, | ||
| 1434 | char *extra) | ||
| 1435 | { | ||
| 1436 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1437 | int fthr = vwrq->value; | ||
| 1438 | |||
| 1439 | /* Reject if card is already initialised */ | ||
| 1440 | if(local->card_status != CARD_AWAITING_PARAM) | ||
| 1441 | return -EBUSY; | ||
| 1405 | 1442 | ||
| 1406 | /* if(wrq->u.frag.fixed == 0) should complain */ | 1443 | /* if(wrq->u.frag.fixed == 0) should complain */ |
| 1407 | #if WIRELESS_EXT > 8 | 1444 | if(vwrq->disabled) |
| 1408 | if(wrq->u.frag.disabled) | 1445 | fthr = 32767; |
| 1409 | fthr = 32767; | 1446 | else { |
| 1410 | else | 1447 | if((fthr < 256) || (fthr > 2347)) /* To check out ! */ |
| 1411 | #endif /* WIRELESS_EXT > 8 */ | 1448 | return -EINVAL; |
| 1412 | if((fthr < 256) || (fthr > 2347)) /* To check out ! */ | 1449 | } |
| 1413 | { | ||
| 1414 | err = -EINVAL; | ||
| 1415 | break; | ||
| 1416 | } | ||
| 1417 | local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF; | 1450 | local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF; |
| 1418 | local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF; | 1451 | local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF; |
| 1419 | } | ||
| 1420 | break; | ||
| 1421 | 1452 | ||
| 1422 | #endif /* WIRELESS_EXT > 7 */ | 1453 | return -EINPROGRESS; /* Call commit handler */ |
| 1423 | #if WIRELESS_EXT > 8 | 1454 | } |
| 1424 | 1455 | ||
| 1425 | /* Get the current mode of operation */ | 1456 | /*------------------------------------------------------------------*/ |
| 1426 | case SIOCGIWMODE: | 1457 | /* |
| 1427 | if(local->sparm.b5.a_network_type) | 1458 | * Wireless Handler : get Fragmentation threshold |
| 1428 | wrq->u.mode = IW_MODE_INFRA; | 1459 | */ |
| 1429 | else | 1460 | static int ray_get_frag(struct net_device *dev, |
| 1430 | wrq->u.mode = IW_MODE_ADHOC; | 1461 | struct iw_request_info *info, |
| 1431 | break; | 1462 | struct iw_param *vwrq, |
| 1463 | char *extra) | ||
| 1464 | { | ||
| 1465 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1432 | 1466 | ||
| 1433 | /* Set the current mode of operation */ | 1467 | vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8) |
| 1434 | case SIOCSIWMODE: | 1468 | + local->sparm.b5.a_frag_threshold[1]; |
| 1435 | { | 1469 | vwrq->disabled = (vwrq->value == 32767); |
| 1470 | vwrq->fixed = 1; | ||
| 1471 | |||
| 1472 | return 0; | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | /*------------------------------------------------------------------*/ | ||
| 1476 | /* | ||
| 1477 | * Wireless Handler : set Mode of Operation | ||
| 1478 | */ | ||
| 1479 | static int ray_set_mode(struct net_device *dev, | ||
| 1480 | struct iw_request_info *info, | ||
| 1481 | __u32 *uwrq, | ||
| 1482 | char *extra) | ||
| 1483 | { | ||
| 1484 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
| 1485 | int err = -EINPROGRESS; /* Call commit handler */ | ||
| 1436 | char card_mode = 1; | 1486 | char card_mode = 1; |
| 1437 | |||
| 1438 | /* Reject if card is already initialised */ | ||
| 1439 | if(local->card_status != CARD_AWAITING_PARAM) | ||
| 1440 | { | ||
| 1441 | err = -EBUSY; | ||
| 1442 | break; | ||
| 1443 | } | ||
| 1444 | 1487 | ||
| 1445 | switch (wrq->u.mode) | 1488 | /* Reject if card is already initialised */ |
| 1489 | if(local->card_status != CARD_AWAITING_PARAM) | ||
| 1490 | return -EBUSY; | ||
| 1491 | |||
| 1492 | switch (*uwrq) | ||
| 1446 | { | 1493 | { |
| 1447 | case IW_MODE_ADHOC: | 1494 | case IW_MODE_ADHOC: |
| 1448 | card_mode = 0; | 1495 | card_mode = 0; |
| 1449 | // Fall through | 1496 | // Fall through |
| 1450 | case IW_MODE_INFRA: | 1497 | case IW_MODE_INFRA: |
| 1451 | local->sparm.b5.a_network_type = card_mode; | 1498 | local->sparm.b5.a_network_type = card_mode; |
| 1452 | break; | 1499 | break; |
| 1453 | default: | 1500 | default: |
| 1454 | err = -EINVAL; | 1501 | err = -EINVAL; |
| 1455 | } | 1502 | } |
| 1456 | } | ||
| 1457 | break; | ||
| 1458 | 1503 | ||
| 1459 | #endif /* WIRELESS_EXT > 8 */ | 1504 | return err; |
| 1460 | #if WIRELESS_EXT > 7 | 1505 | } |
| 1461 | /* ------------------ IWSPY SUPPORT ------------------ */ | ||
| 1462 | /* Define the range (variations) of above parameters */ | ||
| 1463 | case SIOCGIWRANGE: | ||
| 1464 | /* Basic checking... */ | ||
| 1465 | if(wrq->u.data.pointer != (caddr_t) 0) | ||
| 1466 | { | ||
| 1467 | struct iw_range range; | ||
| 1468 | memset((char *) &range, 0, sizeof(struct iw_range)); | ||
| 1469 | |||
| 1470 | /* Set the length (very important for backward compatibility) */ | ||
| 1471 | wrq->u.data.length = sizeof(struct iw_range); | ||
| 1472 | |||
| 1473 | #if WIRELESS_EXT > 10 | ||
| 1474 | /* Set the Wireless Extension versions */ | ||
| 1475 | range.we_version_compiled = WIRELESS_EXT; | ||
| 1476 | range.we_version_source = 9; | ||
| 1477 | #endif /* WIRELESS_EXT > 10 */ | ||
| 1478 | |||
| 1479 | /* Set information in the range struct */ | ||
| 1480 | range.throughput = 1.1 * 1000 * 1000; /* Put the right number here */ | ||
| 1481 | range.num_channels = hop_pattern_length[(int)country]; | ||
| 1482 | range.num_frequency = 0; | ||
| 1483 | range.max_qual.qual = 0; | ||
| 1484 | range.max_qual.level = 255; /* What's the correct value ? */ | ||
| 1485 | range.max_qual.noise = 255; /* Idem */ | ||
| 1486 | range.num_bitrates = 2; | ||
| 1487 | range.bitrate[0] = 1000000; /* 1 Mb/s */ | ||
| 1488 | range.bitrate[1] = 2000000; /* 2 Mb/s */ | ||
| 1489 | |||
| 1490 | /* Copy structure to the user buffer */ | ||
| 1491 | if(copy_to_user(wrq->u.data.pointer, &range, | ||
| 1492 | sizeof(struct iw_range))) | ||
| 1493 | err = -EFAULT; | ||
| 1494 | } | ||
| 1495 | break; | ||
| 1496 | 1506 | ||
| 1497 | #ifdef WIRELESS_SPY | 1507 | /*------------------------------------------------------------------*/ |
| 1498 | /* Set addresses to spy */ | 1508 | /* |
| 1499 | case SIOCSIWSPY: | 1509 | * Wireless Handler : get Mode of Operation |
| 1500 | /* Check the number of addresses */ | 1510 | */ |
| 1501 | if(wrq->u.data.length > IW_MAX_SPY) | 1511 | static int ray_get_mode(struct net_device *dev, |
| 1502 | { | 1512 | struct iw_request_info *info, |
| 1503 | err = -E2BIG; | 1513 | __u32 *uwrq, |
| 1504 | break; | 1514 | char *extra) |
| 1505 | } | 1515 | { |
| 1506 | local->spy_number = wrq->u.data.length; | 1516 | ray_dev_t *local = (ray_dev_t *)dev->priv; |
| 1507 | 1517 | ||
| 1508 | /* If there is some addresses to copy */ | 1518 | if(local->sparm.b5.a_network_type) |
| 1509 | if(local->spy_number > 0) | 1519 | *uwrq = IW_MODE_INFRA; |
| 1510 | { | 1520 | else |
| 1511 | int i; | 1521 | *uwrq = IW_MODE_ADHOC; |
| 1512 | |||
| 1513 | /* Copy addresses to the driver */ | ||
| 1514 | if(copy_from_user(address, wrq->u.data.pointer, | ||
| 1515 | sizeof(struct sockaddr) * local->spy_number)) | ||
| 1516 | { | ||
| 1517 | err = -EFAULT; | ||
| 1518 | break; | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | /* Copy addresses to the lp structure */ | ||
| 1522 | for(i = 0; i < local->spy_number; i++) | ||
| 1523 | memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN); | ||
| 1524 | |||
| 1525 | /* Reset structure... */ | ||
| 1526 | memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY); | ||
| 1527 | |||
| 1528 | #ifdef DEBUG_IOCTL_INFO | ||
| 1529 | printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n"); | ||
| 1530 | for(i = 0; i < local->spy_number; i++) | ||
| 1531 | printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n", | ||
| 1532 | local->spy_address[i][0], | ||
| 1533 | local->spy_address[i][1], | ||
| 1534 | local->spy_address[i][2], | ||
| 1535 | local->spy_address[i][3], | ||
| 1536 | local->spy_address[i][4], | ||
| 1537 | local->spy_address[i][5]); | ||
| 1538 | #endif /* DEBUG_IOCTL_INFO */ | ||
| 1539 | } | ||
| 1540 | break; | ||
| 1541 | 1522 | ||
| 1542 | /* Get the spy list and spy stats */ | 1523 | return 0; |
| 1543 | case SIOCGIWSPY: | 1524 | } |
| 1544 | /* Set the number of addresses */ | ||
| 1545 | wrq->u.data.length = local->spy_number; | ||
| 1546 | 1525 | ||
| 1547 | /* If the user want to have the addresses back... */ | 1526 | /*------------------------------------------------------------------*/ |
| 1548 | if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0)) | 1527 | /* |
| 1549 | { | 1528 | * Wireless Handler : get range info |
| 1550 | int i; | 1529 | */ |
| 1551 | 1530 | static int ray_get_range(struct net_device *dev, | |
| 1552 | /* Copy addresses from the lp structure */ | 1531 | struct iw_request_info *info, |
| 1553 | for(i = 0; i < local->spy_number; i++) | 1532 | struct iw_point *dwrq, |
| 1554 | { | 1533 | char *extra) |
| 1555 | memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN); | 1534 | { |
| 1556 | address[i].sa_family = ARPHRD_ETHER; | 1535 | struct iw_range *range = (struct iw_range *) extra; |
| 1557 | } | 1536 | |
| 1558 | 1537 | memset((char *) range, 0, sizeof(struct iw_range)); | |
| 1559 | /* Copy addresses to the user buffer */ | 1538 | |
| 1560 | if(copy_to_user(wrq->u.data.pointer, address, | 1539 | /* Set the length (very important for backward compatibility) */ |
| 1561 | sizeof(struct sockaddr) * local->spy_number)) | 1540 | dwrq->length = sizeof(struct iw_range); |
| 1562 | { | 1541 | |
| 1563 | err = -EFAULT; | 1542 | /* Set the Wireless Extension versions */ |
| 1564 | break; | 1543 | range->we_version_compiled = WIRELESS_EXT; |
| 1565 | } | 1544 | range->we_version_source = 9; |
| 1566 | 1545 | ||
| 1567 | /* Copy stats to the user buffer (just after) */ | 1546 | /* Set information in the range struct */ |
| 1568 | if(copy_to_user(wrq->u.data.pointer + | 1547 | range->throughput = 1.1 * 1000 * 1000; /* Put the right number here */ |
| 1569 | (sizeof(struct sockaddr) * local->spy_number), | 1548 | range->num_channels = hop_pattern_length[(int)country]; |
| 1570 | local->spy_stat, sizeof(iw_qual) * local->spy_number)) | 1549 | range->num_frequency = 0; |
| 1571 | { | 1550 | range->max_qual.qual = 0; |
| 1572 | err = -EFAULT; | 1551 | range->max_qual.level = 255; /* What's the correct value ? */ |
| 1573 | break; | 1552 | range->max_qual.noise = 255; /* Idem */ |
| 1574 | } | 1553 | range->num_bitrates = 2; |
| 1575 | 1554 | range->bitrate[0] = 1000000; /* 1 Mb/s */ | |
| 1576 | /* Reset updated flags */ | 1555 | range->bitrate[1] = 2000000; /* 2 Mb/s */ |
| 1577 | for(i = 0; i < local->spy_number; i++) | 1556 | return 0; |
| 1578 | local->spy_stat[i].updated = 0x0; | 1557 | } |
| 1579 | } /* if(pointer != NULL) */ | ||
| 1580 | |||
| 1581 | break; | ||
| 1582 | #endif /* WIRELESS_SPY */ | ||
| 1583 | 1558 | ||
| 1584 | /* ------------------ PRIVATE IOCTL ------------------ */ | 1559 | /*------------------------------------------------------------------*/ |
| 1585 | #ifndef SIOCIWFIRSTPRIV | 1560 | /* |
| 1586 | #define SIOCIWFIRSTPRIV SIOCDEVPRIVATE | 1561 | * Wireless Private Handler : set framing mode |
| 1587 | #endif /* SIOCIWFIRSTPRIV */ | 1562 | */ |
| 1588 | #define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ | 1563 | static int ray_set_framing(struct net_device *dev, |
| 1589 | #define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */ | 1564 | struct iw_request_info *info, |
| 1590 | #define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ | 1565 | union iwreq_data *wrqu, |
| 1591 | case SIOCSIPFRAMING: | 1566 | char *extra) |
| 1592 | if(!capable(CAP_NET_ADMIN)) /* For private IOCTLs, we need to check permissions */ | 1567 | { |
| 1593 | { | 1568 | translate = *(extra); /* Set framing mode */ |
| 1594 | err = -EPERM; | ||
| 1595 | break; | ||
| 1596 | } | ||
| 1597 | translate = *(wrq->u.name); /* Set framing mode */ | ||
| 1598 | break; | ||
| 1599 | case SIOCGIPFRAMING: | ||
| 1600 | *(wrq->u.name) = translate; | ||
| 1601 | break; | ||
| 1602 | case SIOCGIPCOUNTRY: | ||
| 1603 | *(wrq->u.name) = country; | ||
| 1604 | break; | ||
| 1605 | case SIOCGIWPRIV: | ||
| 1606 | /* Export our "private" intercace */ | ||
| 1607 | if(wrq->u.data.pointer != (caddr_t) 0) | ||
| 1608 | { | ||
| 1609 | struct iw_priv_args priv[] = | ||
| 1610 | { /* cmd, set_args, get_args, name */ | ||
| 1611 | { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, | ||
| 1612 | { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, | ||
| 1613 | { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, | ||
| 1614 | }; | ||
| 1615 | /* Set the number of ioctl available */ | ||
| 1616 | wrq->u.data.length = 3; | ||
| 1617 | /* Copy structure to the user buffer */ | ||
| 1618 | if(copy_to_user(wrq->u.data.pointer, (u_char *) priv, | ||
| 1619 | sizeof(priv))) | ||
| 1620 | err = -EFAULT; | ||
| 1621 | } | ||
| 1622 | break; | ||
| 1623 | #endif /* WIRELESS_EXT > 7 */ | ||
| 1624 | 1569 | ||
| 1570 | return 0; | ||
| 1571 | } | ||
| 1625 | 1572 | ||
| 1626 | default: | 1573 | /*------------------------------------------------------------------*/ |
| 1627 | DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd); | 1574 | /* |
| 1628 | err = -EOPNOTSUPP; | 1575 | * Wireless Private Handler : get framing mode |
| 1629 | } | 1576 | */ |
| 1630 | return err; | 1577 | static int ray_get_framing(struct net_device *dev, |
| 1631 | } /* end ray_dev_ioctl */ | 1578 | struct iw_request_info *info, |
| 1632 | /*===========================================================================*/ | 1579 | union iwreq_data *wrqu, |
| 1633 | #if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ | 1580 | char *extra) |
| 1581 | { | ||
| 1582 | *(extra) = translate; | ||
| 1583 | |||
| 1584 | return 0; | ||
| 1585 | } | ||
| 1586 | |||
| 1587 | /*------------------------------------------------------------------*/ | ||
| 1588 | /* | ||
| 1589 | * Wireless Private Handler : get country | ||
| 1590 | */ | ||
| 1591 | static int ray_get_country(struct net_device *dev, | ||
| 1592 | struct iw_request_info *info, | ||
| 1593 | union iwreq_data *wrqu, | ||
| 1594 | char *extra) | ||
| 1595 | { | ||
| 1596 | *(extra) = country; | ||
| 1597 | |||
| 1598 | return 0; | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | /*------------------------------------------------------------------*/ | ||
| 1602 | /* | ||
| 1603 | * Commit handler : called after a bunch of SET operations | ||
| 1604 | */ | ||
| 1605 | static int ray_commit(struct net_device *dev, | ||
| 1606 | struct iw_request_info *info, /* NULL */ | ||
| 1607 | void *zwrq, /* NULL */ | ||
| 1608 | char *extra) /* NULL */ | ||
| 1609 | { | ||
| 1610 | return 0; | ||
| 1611 | } | ||
| 1612 | |||
| 1613 | /*------------------------------------------------------------------*/ | ||
| 1614 | /* | ||
| 1615 | * Stats handler : return Wireless Stats | ||
| 1616 | */ | ||
| 1634 | static iw_stats * ray_get_wireless_stats(struct net_device * dev) | 1617 | static iw_stats * ray_get_wireless_stats(struct net_device * dev) |
| 1635 | { | 1618 | { |
| 1636 | ray_dev_t * local = (ray_dev_t *) dev->priv; | 1619 | ray_dev_t * local = (ray_dev_t *) dev->priv; |
| @@ -1642,13 +1625,13 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev) | |||
| 1642 | 1625 | ||
| 1643 | local->wstats.status = local->card_status; | 1626 | local->wstats.status = local->card_status; |
| 1644 | #ifdef WIRELESS_SPY | 1627 | #ifdef WIRELESS_SPY |
| 1645 | if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0)) | 1628 | if((local->spy_data.spy_number > 0) && (local->sparm.b5.a_network_type == 0)) |
| 1646 | { | 1629 | { |
| 1647 | /* Get it from the first node in spy list */ | 1630 | /* Get it from the first node in spy list */ |
| 1648 | local->wstats.qual.qual = local->spy_stat[0].qual; | 1631 | local->wstats.qual.qual = local->spy_data.spy_stat[0].qual; |
| 1649 | local->wstats.qual.level = local->spy_stat[0].level; | 1632 | local->wstats.qual.level = local->spy_data.spy_stat[0].level; |
| 1650 | local->wstats.qual.noise = local->spy_stat[0].noise; | 1633 | local->wstats.qual.noise = local->spy_data.spy_stat[0].noise; |
| 1651 | local->wstats.qual.updated = local->spy_stat[0].updated; | 1634 | local->wstats.qual.updated = local->spy_data.spy_stat[0].updated; |
| 1652 | } | 1635 | } |
| 1653 | #endif /* WIRELESS_SPY */ | 1636 | #endif /* WIRELESS_SPY */ |
| 1654 | 1637 | ||
| @@ -1659,7 +1642,65 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev) | |||
| 1659 | 1642 | ||
| 1660 | return &local->wstats; | 1643 | return &local->wstats; |
| 1661 | } /* end ray_get_wireless_stats */ | 1644 | } /* end ray_get_wireless_stats */ |
| 1662 | #endif /* WIRELESS_EXT > 7 */ | 1645 | |
| 1646 | /*------------------------------------------------------------------*/ | ||
| 1647 | /* | ||
| 1648 | * Structures to export the Wireless Handlers | ||
| 1649 | */ | ||
| 1650 | |||
| 1651 | static const iw_handler ray_handler[] = { | ||
| 1652 | [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit, | ||
| 1653 | [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) ray_get_name, | ||
| 1654 | [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) ray_set_freq, | ||
| 1655 | [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) ray_get_freq, | ||
| 1656 | [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) ray_set_mode, | ||
| 1657 | [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) ray_get_mode, | ||
| 1658 | [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range, | ||
| 1659 | #ifdef WIRELESS_SPY | ||
| 1660 | [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_set_spy, | ||
| 1661 | [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_get_spy, | ||
| 1662 | [SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy, | ||
| 1663 | [SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy, | ||
| 1664 | #endif /* WIRELESS_SPY */ | ||
| 1665 | [SIOCGIWAP -SIOCIWFIRST] (iw_handler) ray_get_wap, | ||
| 1666 | [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid, | ||
| 1667 | [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid, | ||
| 1668 | [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) ray_set_rate, | ||
| 1669 | [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) ray_get_rate, | ||
| 1670 | [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) ray_set_rts, | ||
| 1671 | [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) ray_get_rts, | ||
| 1672 | [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) ray_set_frag, | ||
| 1673 | [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) ray_get_frag, | ||
| 1674 | }; | ||
| 1675 | |||
| 1676 | #define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ | ||
| 1677 | #define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */ | ||
| 1678 | #define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ | ||
| 1679 | |||
| 1680 | static const iw_handler ray_private_handler[] = { | ||
| 1681 | [0] (iw_handler) ray_set_framing, | ||
| 1682 | [1] (iw_handler) ray_get_framing, | ||
| 1683 | [3] (iw_handler) ray_get_country, | ||
| 1684 | }; | ||
| 1685 | |||
| 1686 | static const struct iw_priv_args ray_private_args[] = { | ||
| 1687 | /* cmd, set_args, get_args, name */ | ||
| 1688 | { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, | ||
| 1689 | { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, | ||
| 1690 | { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, | ||
| 1691 | }; | ||
| 1692 | |||
| 1693 | static const struct iw_handler_def ray_handler_def = | ||
| 1694 | { | ||
| 1695 | .num_standard = sizeof(ray_handler)/sizeof(iw_handler), | ||
| 1696 | .num_private = sizeof(ray_private_handler)/sizeof(iw_handler), | ||
| 1697 | .num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args), | ||
| 1698 | .standard = ray_handler, | ||
| 1699 | .private = ray_private_handler, | ||
| 1700 | .private_args = ray_private_args, | ||
| 1701 | .get_wireless_stats = ray_get_wireless_stats, | ||
| 1702 | }; | ||
| 1703 | |||
| 1663 | /*===========================================================================*/ | 1704 | /*===========================================================================*/ |
| 1664 | static int ray_open(struct net_device *dev) | 1705 | static int ray_open(struct net_device *dev) |
| 1665 | { | 1706 | { |
| @@ -2392,20 +2433,15 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i | |||
| 2392 | /*local->wstats.qual.noise = none ? */ | 2433 | /*local->wstats.qual.noise = none ? */ |
| 2393 | local->wstats.qual.updated = 0x2; | 2434 | local->wstats.qual.updated = 0x2; |
| 2394 | } | 2435 | } |
| 2395 | /* Now, for the addresses in the spy list */ | 2436 | /* Now, update the spy stuff */ |
| 2396 | { | 2437 | { |
| 2397 | int i; | 2438 | struct iw_quality wstats; |
| 2398 | /* Look all addresses */ | 2439 | wstats.level = siglev; |
| 2399 | for(i = 0; i < local->spy_number; i++) | 2440 | /* wstats.noise = none ? */ |
| 2400 | /* If match */ | 2441 | /* wstats.qual = none ? */ |
| 2401 | if(!memcmp(linksrcaddr, local->spy_address[i], ETH_ALEN)) | 2442 | wstats.updated = 0x2; |
| 2402 | { | 2443 | /* Update spy records */ |
| 2403 | /* Update statistics */ | 2444 | wireless_spy_update(dev, linksrcaddr, &wstats); |
| 2404 | /*local->spy_stat[i].qual = none ? */ | ||
| 2405 | local->spy_stat[i].level = siglev; | ||
| 2406 | /*local->spy_stat[i].noise = none ? */ | ||
| 2407 | local->spy_stat[i].updated = 0x2; | ||
| 2408 | } | ||
| 2409 | } | 2445 | } |
| 2410 | #endif /* WIRELESS_SPY */ | 2446 | #endif /* WIRELESS_SPY */ |
| 2411 | } /* end rx_data */ | 2447 | } /* end rx_data */ |
diff --git a/drivers/net/wireless/ray_cs.h b/drivers/net/wireless/ray_cs.h index c77afa14fa86..42660fe64bfd 100644 --- a/drivers/net/wireless/ray_cs.h +++ b/drivers/net/wireless/ray_cs.h | |||
| @@ -63,13 +63,10 @@ typedef struct ray_dev_t { | |||
| 63 | UCHAR last_rsl; | 63 | UCHAR last_rsl; |
| 64 | int beacon_rxed; | 64 | int beacon_rxed; |
| 65 | struct beacon_rx last_bcn; | 65 | struct beacon_rx last_bcn; |
| 66 | #ifdef WIRELESS_EXT | ||
| 67 | iw_stats wstats; /* Wireless specific stats */ | 66 | iw_stats wstats; /* Wireless specific stats */ |
| 68 | #endif | ||
| 69 | #ifdef WIRELESS_SPY | 67 | #ifdef WIRELESS_SPY |
| 70 | int spy_number; /* Number of addresses to spy */ | 68 | struct iw_spy_data spy_data; |
| 71 | mac_addr spy_address[IW_MAX_SPY + 1]; /* The addresses to spy */ | 69 | struct iw_public_data wireless_data; |
| 72 | iw_qual spy_stat[IW_MAX_SPY + 1]; /* Statistics gathered */ | ||
| 73 | #endif /* WIRELESS_SPY */ | 70 | #endif /* WIRELESS_SPY */ |
| 74 | 71 | ||
| 75 | } ray_dev_t; | 72 | } ray_dev_t; |
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h index b5719437e981..7fcbe589c3f2 100644 --- a/drivers/net/wireless/wl3501.h +++ b/drivers/net/wireless/wl3501.h | |||
| @@ -609,6 +609,7 @@ struct wl3501_card { | |||
| 609 | struct net_device_stats stats; | 609 | struct net_device_stats stats; |
| 610 | struct iw_statistics wstats; | 610 | struct iw_statistics wstats; |
| 611 | struct iw_spy_data spy_data; | 611 | struct iw_spy_data spy_data; |
| 612 | struct iw_public_data wireless_data; | ||
| 612 | struct dev_node_t node; | 613 | struct dev_node_t node; |
| 613 | }; | 614 | }; |
| 614 | #endif | 615 | #endif |
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 7cc5edbf6ede..3f8c27f0871b 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
| @@ -1944,7 +1944,7 @@ static const iw_handler wl3501_handler[] = { | |||
| 1944 | static const struct iw_handler_def wl3501_handler_def = { | 1944 | static const struct iw_handler_def wl3501_handler_def = { |
| 1945 | .num_standard = sizeof(wl3501_handler) / sizeof(iw_handler), | 1945 | .num_standard = sizeof(wl3501_handler) / sizeof(iw_handler), |
| 1946 | .standard = (iw_handler *)wl3501_handler, | 1946 | .standard = (iw_handler *)wl3501_handler, |
| 1947 | .spy_offset = offsetof(struct wl3501_card, spy_data), | 1947 | .get_wireless_stats = wl3501_get_wireless_stats, |
| 1948 | }; | 1948 | }; |
| 1949 | 1949 | ||
| 1950 | /** | 1950 | /** |
| @@ -1961,6 +1961,7 @@ static dev_link_t *wl3501_attach(void) | |||
| 1961 | client_reg_t client_reg; | 1961 | client_reg_t client_reg; |
| 1962 | dev_link_t *link; | 1962 | dev_link_t *link; |
| 1963 | struct net_device *dev; | 1963 | struct net_device *dev; |
| 1964 | struct wl3501_card *this; | ||
| 1964 | int ret; | 1965 | int ret; |
| 1965 | 1966 | ||
| 1966 | /* Initialize the dev_link_t structure */ | 1967 | /* Initialize the dev_link_t structure */ |
| @@ -1995,7 +1996,9 @@ static dev_link_t *wl3501_attach(void) | |||
| 1995 | dev->tx_timeout = wl3501_tx_timeout; | 1996 | dev->tx_timeout = wl3501_tx_timeout; |
| 1996 | dev->watchdog_timeo = 5 * HZ; | 1997 | dev->watchdog_timeo = 5 * HZ; |
| 1997 | dev->get_stats = wl3501_get_stats; | 1998 | dev->get_stats = wl3501_get_stats; |
| 1998 | dev->get_wireless_stats = wl3501_get_wireless_stats; | 1999 | this = dev->priv; |
| 2000 | this->wireless_data.spy_data = &this->spy_data; | ||
| 2001 | dev->wireless_data = &this->wireless_data; | ||
| 1999 | dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def; | 2002 | dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def; |
| 2000 | SET_ETHTOOL_OPS(dev, &ops); | 2003 | SET_ETHTOOL_OPS(dev, &ops); |
| 2001 | netif_stop_queue(dev); | 2004 | netif_stop_queue(dev); |
