diff --git a/[refs] b/[refs] index fbf239e6a0a8..68956f274245 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9ed6eda4fad9ea95e99f1e3cc546bcde049695cf +refs/heads/master: c23f3445e68e1db0e74099f264bc5ff5d55ebdeb diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index b04b97fe3217..aa73c9a2c11b 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1365,7 +1365,7 @@ BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER M: Eilon Greenstein L: netdev@vger.kernel.org S: Supported -F: drivers/net/bnx2x/ +F: drivers/net/bnx2x* BROADCOM TG3 GIGABIT ETHERNET DRIVER M: Matt Carlson @@ -3671,7 +3671,7 @@ F: include/linux/mv643xx.h MARVELL MWL8K WIRELESS DRIVER M: Lennert Buytenhek L: linux-wireless@vger.kernel.org -S: Odd Fixes +S: Maintained F: drivers/net/wireless/mwl8k.c MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER @@ -4522,7 +4522,7 @@ PRISM54 WIRELESS DRIVER M: "Luis R. Rodriguez" L: linux-wireless@vger.kernel.org W: http://prism54.org -S: Obsolete +S: Maintained F: drivers/net/wireless/prism54/ PROMISE DC4030 CACHING DISK CONTROLLER DRIVER @@ -4712,8 +4712,9 @@ S: Maintained F: drivers/rapidio/ RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER +M: Corey Thomas L: linux-wireless@vger.kernel.org -S: Orphan +S: Maintained F: drivers/net/wireless/ray* RCUTORTURE MODULE @@ -6036,9 +6037,10 @@ F: Documentation/video4linux/zc0301.txt F: drivers/media/video/zc0301/ USB ZD1201 DRIVER -L: linux-wireless@vger.kernel.org +M: Jeroen Vreeken +L: linux-usb@vger.kernel.org W: http://linux-lc100020.sourceforge.net -S: Orphan +S: Maintained F: drivers/net/wireless/zd1201.* USB ZR364XX DRIVER @@ -6224,6 +6226,14 @@ F: Documentation/watchdog/ F: drivers/watchdog/ F: include/linux/watchdog.h +WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS +M: Jean Tourrilhes +L: linux-wireless@vger.kernel.org +W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ +S: Maintained +F: Documentation/networking/wavelan.txt +F: drivers/staging/wavelan/ + WD7000 SCSI DRIVER M: Miroslav Zagorac L: linux-scsi@vger.kernel.org diff --git a/trunk/drivers/atm/nicstar.c b/trunk/drivers/atm/nicstar.c index 2f3516b7f118..729a149b6b2b 100644 --- a/trunk/drivers/atm/nicstar.c +++ b/trunk/drivers/atm/nicstar.c @@ -154,6 +154,7 @@ static void which_list(ns_dev * card, struct sk_buff *skb); #endif static void ns_poll(unsigned long arg); static int ns_parse_mac(char *mac, unsigned char *esi); +static short ns_h2i(char c); static void ns_phy_put(struct atm_dev *dev, unsigned char value, unsigned long addr); static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr); @@ -2823,9 +2824,9 @@ static int ns_parse_mac(char *mac, unsigned char *esi) return -1; j = 0; for (i = 0; i < 6; i++) { - if ((byte1 = hex_to_bin(mac[j++])) < 0) + if ((byte1 = ns_h2i(mac[j++])) < 0) return -1; - if ((byte0 = hex_to_bin(mac[j++])) < 0) + if ((byte0 = ns_h2i(mac[j++])) < 0) return -1; esi[i] = (unsigned char)(byte1 * 16 + byte0); if (i < 5) { @@ -2836,6 +2837,16 @@ static int ns_parse_mac(char *mac, unsigned char *esi) return 0; } +static short ns_h2i(char c) +{ + if (c >= '0' && c <= '9') + return (short)(c - '0'); + if (c >= 'A' && c <= 'F') + return (short)(c - 'A' + 10); + if (c >= 'a' && c <= 'f') + return (short)(c - 'a' + 10); + return -1; +} static void ns_phy_put(struct atm_dev *dev, unsigned char value, unsigned long addr) diff --git a/trunk/drivers/bluetooth/Kconfig b/trunk/drivers/bluetooth/Kconfig index 02deef424926..058fbccf2f52 100644 --- a/trunk/drivers/bluetooth/Kconfig +++ b/trunk/drivers/bluetooth/Kconfig @@ -58,18 +58,6 @@ config BT_HCIUART_BCSP Say Y here to compile support for HCI BCSP protocol. -config BT_HCIUART_ATH3K - bool "Atheros AR300x serial support" - depends on BT_HCIUART - help - HCIATH3K (HCI Atheros AR300x) is a serial protocol for - communication between host and Atheros AR300x Bluetooth devices. - This protocol enables AR300x chips to be enabled with - power management support. - Enable this if you have Atheros AR300x serial Bluetooth device. - - Say Y here to compile support for HCI UART ATH3K protocol. - config BT_HCIUART_LL bool "HCILL protocol support" depends on BT_HCIUART diff --git a/trunk/drivers/bluetooth/Makefile b/trunk/drivers/bluetooth/Makefile index 71bdf13287c4..7e5aed598121 100644 --- a/trunk/drivers/bluetooth/Makefile +++ b/trunk/drivers/bluetooth/Makefile @@ -26,5 +26,4 @@ hci_uart-y := hci_ldisc.o hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o -hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o hci_uart-objs := $(hci_uart-y) diff --git a/trunk/drivers/bluetooth/bcm203x.c b/trunk/drivers/bluetooth/bcm203x.c index 8b1b643a519b..b0c84c19f442 100644 --- a/trunk/drivers/bluetooth/bcm203x.c +++ b/trunk/drivers/bluetooth/bcm203x.c @@ -224,7 +224,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); - data->fw_data = kmemdup(firmware->data, firmware->size, GFP_KERNEL); + data->fw_data = kmalloc(firmware->size, GFP_KERNEL); if (!data->fw_data) { BT_ERR("Can't allocate memory for firmware image"); release_firmware(firmware); @@ -234,6 +234,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id return -ENOMEM; } + memcpy(data->fw_data, firmware->data, firmware->size); data->fw_size = firmware->size; data->fw_sent = 0; diff --git a/trunk/drivers/bluetooth/bpa10x.c b/trunk/drivers/bluetooth/bpa10x.c index 751b338d904a..d945cd12433a 100644 --- a/trunk/drivers/bluetooth/bpa10x.c +++ b/trunk/drivers/bluetooth/bpa10x.c @@ -62,7 +62,7 @@ struct hci_vendor_hdr { __u8 type; __le16 snum; __le16 dlen; -} __packed; +} __attribute__ ((packed)); static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count) { diff --git a/trunk/drivers/bluetooth/btmrvl_debugfs.c b/trunk/drivers/bluetooth/btmrvl_debugfs.c index 54739b08c308..b50b41d97a7f 100644 --- a/trunk/drivers/bluetooth/btmrvl_debugfs.c +++ b/trunk/drivers/bluetooth/btmrvl_debugfs.c @@ -216,7 +216,7 @@ static const struct file_operations btmrvl_gpiogap_fops = { static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { - struct btmrvl_private *priv = file->private_data; + struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data; char buf[16]; long result, ret; diff --git a/trunk/drivers/bluetooth/btmrvl_drv.h b/trunk/drivers/bluetooth/btmrvl_drv.h index 90bda50dc446..bed0ba630235 100644 --- a/trunk/drivers/bluetooth/btmrvl_drv.h +++ b/trunk/drivers/bluetooth/btmrvl_drv.h @@ -76,7 +76,6 @@ struct btmrvl_private { int (*hw_host_to_card) (struct btmrvl_private *priv, u8 *payload, u16 nb); int (*hw_wakeup_firmware) (struct btmrvl_private *priv); - int (*hw_process_int_status) (struct btmrvl_private *priv); spinlock_t driver_lock; /* spinlock used by driver */ #ifdef CONFIG_DEBUG_FS void *debugfs_data; @@ -119,13 +118,13 @@ struct btmrvl_cmd { __le16 ocf_ogf; u8 length; u8 data[4]; -} __packed; +} __attribute__ ((packed)); struct btmrvl_event { u8 ec; /* event counter */ u8 length; u8 data[4]; -} __packed; +} __attribute__ ((packed)); /* Prototype of global function */ diff --git a/trunk/drivers/bluetooth/btmrvl_main.c b/trunk/drivers/bluetooth/btmrvl_main.c index 0d32ec82e9bf..ee37ef0caee2 100644 --- a/trunk/drivers/bluetooth/btmrvl_main.c +++ b/trunk/drivers/bluetooth/btmrvl_main.c @@ -502,17 +502,14 @@ static int btmrvl_service_main_thread(void *data) spin_lock_irqsave(&priv->driver_lock, flags); if (adapter->int_count) { adapter->int_count = 0; - spin_unlock_irqrestore(&priv->driver_lock, flags); - priv->hw_process_int_status(priv); } else if (adapter->ps_state == PS_SLEEP && !skb_queue_empty(&adapter->tx_queue)) { spin_unlock_irqrestore(&priv->driver_lock, flags); adapter->wakeup_tries++; priv->hw_wakeup_firmware(priv); continue; - } else { - spin_unlock_irqrestore(&priv->driver_lock, flags); } + spin_unlock_irqrestore(&priv->driver_lock, flags); if (adapter->ps_state == PS_SLEEP) continue; diff --git a/trunk/drivers/bluetooth/btmrvl_sdio.c b/trunk/drivers/bluetooth/btmrvl_sdio.c index dcc2a6ec23f0..df0773ebd9e4 100644 --- a/trunk/drivers/bluetooth/btmrvl_sdio.c +++ b/trunk/drivers/bluetooth/btmrvl_sdio.c @@ -47,7 +47,6 @@ * module_exit function is called. */ static u8 user_rmmod; -static u8 sdio_ireg; static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { .helper = "sd8688_helper.bin", @@ -84,10 +83,10 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat) *dat = 0; fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); - if (ret) - return -EIO; - fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); + if (!ret) + fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); + if (ret) return -EIO; @@ -217,7 +216,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); - tmphlprbuf = kzalloc(tmphlprbufsz, GFP_KERNEL); + tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL); if (!tmphlprbuf) { BT_ERR("Unable to allocate buffer for helper." " Terminating download"); @@ -225,6 +224,8 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card) goto done; } + memset(tmphlprbuf, 0, tmphlprbufsz); + helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN); /* Perform helper data transfer */ @@ -317,7 +318,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) BT_DBG("Downloading FW image (%d bytes)", firmwarelen); tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN); - tmpfwbuf = kzalloc(tmpfwbufsz, GFP_KERNEL); + tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL); if (!tmpfwbuf) { BT_ERR("Unable to allocate buffer for firmware." " Terminating download"); @@ -325,6 +326,8 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) goto done; } + memset(tmpfwbuf, 0, tmpfwbufsz); + /* Ensure aligned firmware buffer */ fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN); @@ -552,79 +555,78 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) return ret; } -static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv) +static int btmrvl_sdio_get_int_status(struct btmrvl_private *priv, u8 * ireg) { - ulong flags; - u8 ireg; + int ret; + u8 sdio_ireg = 0; struct btmrvl_sdio_card *card = priv->btmrvl_dev.card; - spin_lock_irqsave(&priv->driver_lock, flags); - ireg = sdio_ireg; - sdio_ireg = 0; - spin_unlock_irqrestore(&priv->driver_lock, flags); + *ireg = 0; - sdio_claim_host(card->func); - if (ireg & DN_LD_HOST_INT_STATUS) { + sdio_ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); + if (ret) { + BT_ERR("sdio_readb: read int status register failed"); + ret = -EIO; + goto done; + } + + if (sdio_ireg != 0) { + /* + * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS + * Clear the interrupt status register and re-enable the + * interrupt. + */ + BT_DBG("sdio_ireg = 0x%x", sdio_ireg); + + sdio_writeb(card->func, ~(sdio_ireg) & (DN_LD_HOST_INT_STATUS | + UP_LD_HOST_INT_STATUS), + HOST_INTSTATUS_REG, &ret); + if (ret) { + BT_ERR("sdio_writeb: clear int status register " + "failed"); + ret = -EIO; + goto done; + } + } + + if (sdio_ireg & DN_LD_HOST_INT_STATUS) { if (priv->btmrvl_dev.tx_dnld_rdy) BT_DBG("tx_done already received: " - " int_status=0x%x", ireg); + " int_status=0x%x", sdio_ireg); else priv->btmrvl_dev.tx_dnld_rdy = true; } - if (ireg & UP_LD_HOST_INT_STATUS) + if (sdio_ireg & UP_LD_HOST_INT_STATUS) btmrvl_sdio_card_to_host(priv); - sdio_release_host(card->func); + *ireg = sdio_ireg; - return 0; + ret = 0; + +done: + return ret; } static void btmrvl_sdio_interrupt(struct sdio_func *func) { struct btmrvl_private *priv; + struct hci_dev *hcidev; struct btmrvl_sdio_card *card; - ulong flags; u8 ireg = 0; - int ret; card = sdio_get_drvdata(func); - if (!card || !card->priv) { - BT_ERR("sbi_interrupt(%p) card or priv is " - "NULL, card=%p\n", func, card); - return; - } - - priv = card->priv; - - ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); - if (ret) { - BT_ERR("sdio_readb: read int status register failed"); - return; - } + if (card && card->priv) { + priv = card->priv; + hcidev = priv->btmrvl_dev.hcidev; - if (ireg != 0) { - /* - * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS - * Clear the interrupt status register and re-enable the - * interrupt. - */ - BT_DBG("ireg = 0x%x", ireg); + if (btmrvl_sdio_get_int_status(priv, &ireg)) + BT_ERR("reading HOST_INT_STATUS_REG failed"); + else + BT_DBG("HOST_INT_STATUS_REG %#x", ireg); - sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | - UP_LD_HOST_INT_STATUS), - HOST_INTSTATUS_REG, &ret); - if (ret) { - BT_ERR("sdio_writeb: clear int status register failed"); - return; - } + btmrvl_interrupt(priv); } - - spin_lock_irqsave(&priv->driver_lock, flags); - sdio_ireg |= ireg; - spin_unlock_irqrestore(&priv->driver_lock, flags); - - btmrvl_interrupt(priv); } static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) @@ -928,7 +930,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func, /* Initialize the interface specific function pointers */ priv->hw_host_to_card = btmrvl_sdio_host_to_card; priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw; - priv->hw_process_int_status = btmrvl_sdio_process_int_status; if (btmrvl_register_hdev(priv)) { BT_ERR("Register hdev failed!"); diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index d22ce3cc611e..5d9cc53bd643 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -59,9 +59,6 @@ static struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, - /* Apple iMac11,1 */ - { USB_DEVICE(0x05ac, 0x8215) }, - /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, @@ -149,7 +146,6 @@ static struct usb_device_id blacklist_table[] = { #define BTUSB_BULK_RUNNING 1 #define BTUSB_ISOC_RUNNING 2 #define BTUSB_SUSPENDING 3 -#define BTUSB_DID_ISO_RESUME 4 struct btusb_data { struct hci_dev *hdev; @@ -183,6 +179,7 @@ struct btusb_data { unsigned int sco_num; int isoc_altsetting; int suspend_count; + int did_iso_resume:1; }; static int inc_tx(struct btusb_data *data) @@ -810,7 +807,7 @@ static void btusb_work(struct work_struct *work) int err; if (hdev->conn_hash.sco_num > 0) { - if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { + if (!data->did_iso_resume) { err = usb_autopm_get_interface(data->isoc); if (err < 0) { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); @@ -818,7 +815,7 @@ static void btusb_work(struct work_struct *work) return; } - set_bit(BTUSB_DID_ISO_RESUME, &data->flags); + data->did_iso_resume = 1; } if (data->isoc_altsetting != 2) { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); @@ -839,8 +836,10 @@ static void btusb_work(struct work_struct *work) usb_kill_anchored_urbs(&data->isoc_anchor); __set_isoc_interface(hdev, 0); - if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) + if (data->did_iso_resume) { + data->did_iso_resume = 0; usb_autopm_put_interface(data->isoc); + } } } diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index cbe9e44a42e9..ef044d55cb25 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -104,7 +104,7 @@ typedef struct { u8 type; u8 zero; u16 len; -} __packed nsh_t; /* Nokia Specific Header */ +} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */ #define NSHL 4 /* Nokia Specific Header Length */ diff --git a/trunk/drivers/bluetooth/hci_ath.c b/trunk/drivers/bluetooth/hci_ath.c deleted file mode 100644 index 6a160c17ea94..000000000000 --- a/trunk/drivers/bluetooth/hci_ath.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Atheros Communication Bluetooth HCIATH3K UART protocol - * - * HCIATH3K (HCI Atheros AR300x Protocol) is a Atheros Communication's - * power management protocol extension to H4 to support AR300x Bluetooth Chip. - * - * Copyright (c) 2009-2010 Atheros Communications Inc. - * - * Acknowledgements: - * This file is based on hci_h4.c, which was written - * by Maxim Krasnyansky and Marcel Holtmann. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "hci_uart.h" - -struct ath_struct { - struct hci_uart *hu; - unsigned int cur_sleep; - - struct sk_buff_head txq; - struct work_struct ctxtsw; -}; - -static int ath_wakeup_ar3k(struct tty_struct *tty) -{ - struct termios settings; - int status = tty->driver->ops->tiocmget(tty, NULL); - - if (status & TIOCM_CTS) - return status; - - /* Disable Automatic RTSCTS */ - n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); - settings.c_cflag &= ~CRTSCTS; - n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); - - /* Clear RTS first */ - status = tty->driver->ops->tiocmget(tty, NULL); - tty->driver->ops->tiocmset(tty, NULL, 0x00, TIOCM_RTS); - mdelay(20); - - /* Set RTS, wake up board */ - status = tty->driver->ops->tiocmget(tty, NULL); - tty->driver->ops->tiocmset(tty, NULL, TIOCM_RTS, 0x00); - mdelay(20); - - status = tty->driver->ops->tiocmget(tty, NULL); - - n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); - settings.c_cflag |= CRTSCTS; - n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); - - return status; -} - -static void ath_hci_uart_work(struct work_struct *work) -{ - int status; - struct ath_struct *ath; - struct hci_uart *hu; - struct tty_struct *tty; - - ath = container_of(work, struct ath_struct, ctxtsw); - - hu = ath->hu; - tty = hu->tty; - - /* verify and wake up controller */ - if (ath->cur_sleep) { - status = ath_wakeup_ar3k(tty); - if (!(status & TIOCM_CTS)) - return; - } - - /* Ready to send Data */ - clear_bit(HCI_UART_SENDING, &hu->tx_state); - hci_uart_tx_wakeup(hu); -} - -/* Initialize protocol */ -static int ath_open(struct hci_uart *hu) -{ - struct ath_struct *ath; - - BT_DBG("hu %p", hu); - - ath = kzalloc(sizeof(*ath), GFP_ATOMIC); - if (!ath) - return -ENOMEM; - - skb_queue_head_init(&ath->txq); - - hu->priv = ath; - ath->hu = hu; - - INIT_WORK(&ath->ctxtsw, ath_hci_uart_work); - - return 0; -} - -/* Flush protocol data */ -static int ath_flush(struct hci_uart *hu) -{ - struct ath_struct *ath = hu->priv; - - BT_DBG("hu %p", hu); - - skb_queue_purge(&ath->txq); - - return 0; -} - -/* Close protocol */ -static int ath_close(struct hci_uart *hu) -{ - struct ath_struct *ath = hu->priv; - - BT_DBG("hu %p", hu); - - skb_queue_purge(&ath->txq); - - cancel_work_sync(&ath->ctxtsw); - - hu->priv = NULL; - kfree(ath); - - return 0; -} - -#define HCI_OP_ATH_SLEEP 0xFC04 - -/* Enqueue frame for transmittion */ -static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb) -{ - struct ath_struct *ath = hu->priv; - - if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) { - kfree_skb(skb); - return 0; - } - - /* - * Update power management enable flag with parameters of - * HCI sleep enable vendor specific HCI command. - */ - if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { - struct hci_command_hdr *hdr = (void *)skb->data; - - if (__le16_to_cpu(hdr->opcode) == HCI_OP_ATH_SLEEP) - ath->cur_sleep = skb->data[HCI_COMMAND_HDR_SIZE]; - } - - BT_DBG("hu %p skb %p", hu, skb); - - /* Prepend skb with frame type */ - memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); - - skb_queue_tail(&ath->txq, skb); - set_bit(HCI_UART_SENDING, &hu->tx_state); - - schedule_work(&ath->ctxtsw); - - return 0; -} - -static struct sk_buff *ath_dequeue(struct hci_uart *hu) -{ - struct ath_struct *ath = hu->priv; - - return skb_dequeue(&ath->txq); -} - -/* Recv data */ -static int ath_recv(struct hci_uart *hu, void *data, int count) -{ - if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) - BT_ERR("Frame Reassembly Failed"); - - return count; -} - -static struct hci_uart_proto athp = { - .id = HCI_UART_ATH3K, - .open = ath_open, - .close = ath_close, - .recv = ath_recv, - .enqueue = ath_enqueue, - .dequeue = ath_dequeue, - .flush = ath_flush, -}; - -int __init ath_init(void) -{ - int err = hci_uart_register_proto(&athp); - - if (!err) - BT_INFO("HCIATH3K protocol initialized"); - else - BT_ERR("HCIATH3K protocol registration failed"); - - return err; -} - -int __exit ath_deinit(void) -{ - return hci_uart_unregister_proto(&athp); -} diff --git a/trunk/drivers/bluetooth/hci_bcsp.c b/trunk/drivers/bluetooth/hci_bcsp.c index 9c5b2dc38e29..42d69d4de05c 100644 --- a/trunk/drivers/bluetooth/hci_bcsp.c +++ b/trunk/drivers/bluetooth/hci_bcsp.c @@ -739,7 +739,7 @@ static struct hci_uart_proto bcsp = { .flush = bcsp_flush }; -int __init bcsp_init(void) +int bcsp_init(void) { int err = hci_uart_register_proto(&bcsp); @@ -751,7 +751,7 @@ int __init bcsp_init(void) return err; } -int __exit bcsp_deinit(void) +int bcsp_deinit(void) { return hci_uart_unregister_proto(&bcsp); } diff --git a/trunk/drivers/bluetooth/hci_h4.c b/trunk/drivers/bluetooth/hci_h4.c index 7b8ad93e2c36..3f038f5308a4 100644 --- a/trunk/drivers/bluetooth/hci_h4.c +++ b/trunk/drivers/bluetooth/hci_h4.c @@ -151,8 +151,107 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) /* Recv data */ static int h4_recv(struct hci_uart *hu, void *data, int count) { - if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) - BT_ERR("Frame Reassembly Failed"); + struct h4_struct *h4 = hu->priv; + register char *ptr; + struct hci_event_hdr *eh; + struct hci_acl_hdr *ah; + struct hci_sco_hdr *sh; + register int len, type, dlen; + + BT_DBG("hu %p count %d rx_state %ld rx_count %ld", + hu, count, h4->rx_state, h4->rx_count); + + ptr = data; + while (count) { + if (h4->rx_count) { + len = min_t(unsigned int, h4->rx_count, count); + memcpy(skb_put(h4->rx_skb, len), ptr, len); + h4->rx_count -= len; count -= len; ptr += len; + + if (h4->rx_count) + continue; + + switch (h4->rx_state) { + case H4_W4_DATA: + BT_DBG("Complete data"); + + hci_recv_frame(h4->rx_skb); + + h4->rx_state = H4_W4_PACKET_TYPE; + h4->rx_skb = NULL; + continue; + + case H4_W4_EVENT_HDR: + eh = hci_event_hdr(h4->rx_skb); + + BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen); + + h4_check_data_len(h4, eh->plen); + continue; + + case H4_W4_ACL_HDR: + ah = hci_acl_hdr(h4->rx_skb); + dlen = __le16_to_cpu(ah->dlen); + + BT_DBG("ACL header: dlen %d", dlen); + + h4_check_data_len(h4, dlen); + continue; + + case H4_W4_SCO_HDR: + sh = hci_sco_hdr(h4->rx_skb); + + BT_DBG("SCO header: dlen %d", sh->dlen); + + h4_check_data_len(h4, sh->dlen); + continue; + } + } + + /* H4_W4_PACKET_TYPE */ + switch (*ptr) { + case HCI_EVENT_PKT: + BT_DBG("Event packet"); + h4->rx_state = H4_W4_EVENT_HDR; + h4->rx_count = HCI_EVENT_HDR_SIZE; + type = HCI_EVENT_PKT; + break; + + case HCI_ACLDATA_PKT: + BT_DBG("ACL packet"); + h4->rx_state = H4_W4_ACL_HDR; + h4->rx_count = HCI_ACL_HDR_SIZE; + type = HCI_ACLDATA_PKT; + break; + + case HCI_SCODATA_PKT: + BT_DBG("SCO packet"); + h4->rx_state = H4_W4_SCO_HDR; + h4->rx_count = HCI_SCO_HDR_SIZE; + type = HCI_SCODATA_PKT; + break; + + default: + BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr); + hu->hdev->stat.err_rx++; + ptr++; count--; + continue; + }; + + ptr++; count--; + + /* Allocate packet */ + h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); + if (!h4->rx_skb) { + BT_ERR("Can't allocate mem for new packet"); + h4->rx_state = H4_W4_PACKET_TYPE; + h4->rx_count = 0; + return -ENOMEM; + } + + h4->rx_skb->dev = (void *) hu->hdev; + bt_cb(h4->rx_skb)->pkt_type = type; + } return count; } @@ -173,7 +272,7 @@ static struct hci_uart_proto h4p = { .flush = h4_flush, }; -int __init h4_init(void) +int h4_init(void) { int err = hci_uart_register_proto(&h4p); @@ -185,7 +284,7 @@ int __init h4_init(void) return err; } -int __exit h4_deinit(void) +int h4_deinit(void) { return hci_uart_unregister_proto(&h4p); } diff --git a/trunk/drivers/bluetooth/hci_ldisc.c b/trunk/drivers/bluetooth/hci_ldisc.c index 998833d93c13..76a1abb8f214 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -210,6 +210,7 @@ static int hci_uart_close(struct hci_dev *hdev) static int hci_uart_send_frame(struct sk_buff *skb) { struct hci_dev* hdev = (struct hci_dev *) skb->dev; + struct tty_struct *tty; struct hci_uart *hu; if (!hdev) { @@ -221,6 +222,7 @@ static int hci_uart_send_frame(struct sk_buff *skb) return -EBUSY; hu = (struct hci_uart *) hdev->driver_data; + tty = hu->tty; BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); @@ -395,9 +397,6 @@ static int hci_uart_register_dev(struct hci_uart *hu) if (!reset) set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); - if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags)) - set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); - if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); hci_free_dev(hdev); @@ -478,15 +477,6 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file, return hu->hdev->id; return -EUNATCH; - case HCIUARTSETFLAGS: - if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) - return -EBUSY; - hu->hdev_flags = arg; - break; - - case HCIUARTGETFLAGS: - return hu->hdev_flags; - default: err = n_tty_ioctl_helper(tty, file, cmd, arg); break; @@ -552,9 +542,6 @@ static int __init hci_uart_init(void) #ifdef CONFIG_BT_HCIUART_LL ll_init(); #endif -#ifdef CONFIG_BT_HCIUART_ATH3K - ath_init(); -#endif return 0; } @@ -572,9 +559,6 @@ static void __exit hci_uart_exit(void) #ifdef CONFIG_BT_HCIUART_LL ll_deinit(); #endif -#ifdef CONFIG_BT_HCIUART_ATH3K - ath_deinit(); -#endif /* Release tty registration of line discipline */ if ((err = tty_unregister_ldisc(N_HCI))) diff --git a/trunk/drivers/bluetooth/hci_ll.c b/trunk/drivers/bluetooth/hci_ll.c index 38595e782d02..fb8445c7365e 100644 --- a/trunk/drivers/bluetooth/hci_ll.c +++ b/trunk/drivers/bluetooth/hci_ll.c @@ -74,7 +74,7 @@ enum hcill_states_e { struct hcill_cmd { u8 cmd; -} __packed; +} __attribute__((packed)); struct ll_struct { unsigned long rx_state; @@ -517,7 +517,7 @@ static struct hci_uart_proto llp = { .flush = ll_flush, }; -int __init ll_init(void) +int ll_init(void) { int err = hci_uart_register_proto(&llp); @@ -529,7 +529,7 @@ int __init ll_init(void) return err; } -int __exit ll_deinit(void) +int ll_deinit(void) { return hci_uart_unregister_proto(&llp); } diff --git a/trunk/drivers/bluetooth/hci_uart.h b/trunk/drivers/bluetooth/hci_uart.h index 99fb35239d1f..50113db06b9f 100644 --- a/trunk/drivers/bluetooth/hci_uart.h +++ b/trunk/drivers/bluetooth/hci_uart.h @@ -31,20 +31,15 @@ #define HCIUARTSETPROTO _IOW('U', 200, int) #define HCIUARTGETPROTO _IOR('U', 201, int) #define HCIUARTGETDEVICE _IOR('U', 202, int) -#define HCIUARTSETFLAGS _IOW('U', 203, int) -#define HCIUARTGETFLAGS _IOR('U', 204, int) /* UART protocols */ -#define HCI_UART_MAX_PROTO 6 +#define HCI_UART_MAX_PROTO 5 #define HCI_UART_H4 0 #define HCI_UART_BCSP 1 #define HCI_UART_3WIRE 2 #define HCI_UART_H4DS 3 #define HCI_UART_LL 4 -#define HCI_UART_ATH3K 5 - -#define HCI_UART_RAW_DEVICE 0 struct hci_uart; @@ -62,7 +57,6 @@ struct hci_uart { struct tty_struct *tty; struct hci_dev *hdev; unsigned long flags; - unsigned long hdev_flags; struct hci_uart_proto *proto; void *priv; @@ -72,7 +66,7 @@ struct hci_uart { spinlock_t rx_lock; }; -/* HCI_UART proto flag bits */ +/* HCI_UART flag bits */ #define HCI_UART_PROTO_SET 0 /* TX states */ @@ -97,8 +91,3 @@ int bcsp_deinit(void); int ll_init(void); int ll_deinit(void); #endif - -#ifdef CONFIG_BT_HCIUART_ATH3K -int ath_init(void); -int ath_deinit(void); -#endif diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index c754d88e5ec9..069a03f717d3 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -1020,16 +1020,10 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, ioaddr = pci_iomap(pdev, pci_bar, 0); if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */ ioaddr = pci_iomap(pdev, 0, 0); - if (!ioaddr) { - pci_disable_device(pdev); - rc = -ENOMEM; - goto out; - } rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq, ent->driver_data, unit); if (rc < 0) { - pci_iounmap(pdev, ioaddr); pci_disable_device(pdev); goto out; } @@ -1393,7 +1387,7 @@ static int __devinit vortex_probe1(struct device *gendev, mii_preamble_required++; if (vp->drv_flags & EXTRA_PREAMBLE) mii_preamble_required++; - mdio_sync(vp, 32); + mdio_sync(ioaddr, 32); mdio_read(dev, 24, MII_BMSR); for (phy = 0; phy < 32 && phy_idx < 1; phy++) { int mii_status, phyx; @@ -2918,36 +2912,6 @@ static void vortex_get_drvinfo(struct net_device *dev, } } -static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct vortex_private *vp = netdev_priv(dev); - - spin_lock_irq(&vp->lock); - wol->supported = WAKE_MAGIC; - - wol->wolopts = 0; - if (vp->enable_wol) - wol->wolopts |= WAKE_MAGIC; - spin_unlock_irq(&vp->lock); -} - -static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct vortex_private *vp = netdev_priv(dev); - if (wol->wolopts & ~WAKE_MAGIC) - return -EINVAL; - - spin_lock_irq(&vp->lock); - if (wol->wolopts & WAKE_MAGIC) - vp->enable_wol = 1; - else - vp->enable_wol = 0; - acpi_set_WOL(dev); - spin_unlock_irq(&vp->lock); - - return 0; -} - static const struct ethtool_ops vortex_ethtool_ops = { .get_drvinfo = vortex_get_drvinfo, .get_strings = vortex_get_strings, @@ -2959,8 +2923,6 @@ static const struct ethtool_ops vortex_ethtool_ops = { .set_settings = vortex_set_settings, .get_link = ethtool_op_get_link, .nway_reset = vortex_nway_reset, - .get_wol = vortex_get_wol, - .set_wol = vortex_set_wol, }; #ifdef CONFIG_PCI diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index ebe68395ecf8..8c13df7fdc16 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1751,7 +1751,7 @@ config TLAN config KS8842 tristate "Micrel KSZ8841/42 with generic bus interface" - depends on HAS_IOMEM && DMA_ENGINE + depends on HAS_IOMEM help This platform driver is for KSZ8841(1-port) / KS8842(2-port) ethernet switch chip (managed, VLAN, QoS) from Micrel or diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 56e8c27f77ce..ce555819c8fc 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -84,7 +84,8 @@ obj-$(CONFIG_FEALNX) += fealnx.o obj-$(CONFIG_TIGON3) += tg3.o obj-$(CONFIG_BNX2) += bnx2.o obj-$(CONFIG_CNIC) += cnic.o -obj-$(CONFIG_BNX2X) += bnx2x/ +obj-$(CONFIG_BNX2X) += bnx2x.o +bnx2x-objs := bnx2x_main.o bnx2x_link.o spidernet-y += spider_net.o spider_net_ethtool.o obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o obj-$(CONFIG_GELIC_NET) += ps3_gelic.o diff --git a/trunk/drivers/net/benet/be.h b/trunk/drivers/net/benet/be.h index 99197bd54da5..f17428caecf1 100644 --- a/trunk/drivers/net/benet/be.h +++ b/trunk/drivers/net/benet/be.h @@ -33,7 +33,7 @@ #include "be_hw.h" -#define DRV_VER "2.103.175u" +#define DRV_VER "2.102.147u" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" @@ -220,16 +220,7 @@ struct be_rx_obj { struct be_rx_page_info page_info_tbl[RX_Q_LEN]; }; -struct be_vf_cfg { - unsigned char vf_mac_addr[ETH_ALEN]; - u32 vf_if_handle; - u32 vf_pmac_id; - u16 vf_vlan_tag; - u32 vf_tx_rate; -}; - #define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ -#define BE_INVALID_PMAC_ID 0xffffffff struct be_adapter { struct pci_dev *pdev; struct net_device *netdev; @@ -285,11 +276,9 @@ struct be_adapter { u32 port_num; bool promiscuous; bool wol; - u32 function_mode; + u32 cap; u32 rx_fc; /* Rx flow control */ u32 tx_fc; /* Tx flow control */ - bool ue_detected; - bool stats_ioctl_sent; int link_speed; u8 port_type; u8 transceiver; @@ -299,7 +288,8 @@ struct be_adapter { struct completion flash_compl; bool sriov_enabled; - struct be_vf_cfg vf_cfg[BE_MAX_VF]; + u32 vf_if_handle[BE_MAX_VF]; + u32 vf_pmac_id[BE_MAX_VF]; u8 base_eq_id; u8 is_virtfn; }; diff --git a/trunk/drivers/net/benet/be_cmds.c b/trunk/drivers/net/benet/be_cmds.c index 3d305494a606..344e062b7f25 100644 --- a/trunk/drivers/net/benet/be_cmds.c +++ b/trunk/drivers/net/benet/be_cmds.c @@ -75,10 +75,8 @@ static int be_mcc_compl_process(struct be_adapter *adapter, be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); netdev_stats_update(adapter); - adapter->stats_ioctl_sent = false; } - } else if ((compl_status != MCC_STATUS_NOT_SUPPORTED) && - (compl->tag0 != OPCODE_COMMON_NTWK_MAC_QUERY)) { + } else if (compl_status != MCC_STATUS_NOT_SUPPORTED) { extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & CQE_STATUS_EXTD_MASK; dev_warn(&adapter->pdev->dev, @@ -207,7 +205,6 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) if (msecs > 4000) { dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); - be_dump_ue(adapter); return -1; } @@ -952,7 +949,6 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) sge->len = cpu_to_le32(nonemb_cmd->size); be_mcc_notify(adapter); - adapter->stats_ioctl_sent = true; err: spin_unlock_bh(&adapter->mcc_lock); @@ -1261,7 +1257,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) } /* Uses mbox */ -int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) +int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap) { struct be_mcc_wrb *wrb; struct be_cmd_req_query_fw_cfg *req; @@ -1282,7 +1278,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) if (!status) { struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); *port_num = le32_to_cpu(resp->phys_port); - *mode = le32_to_cpu(resp->function_mode); + *cap = le32_to_cpu(resp->function_cap); } spin_unlock(&adapter->mbox_lock); @@ -1734,36 +1730,3 @@ int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd) spin_unlock_bh(&adapter->mcc_lock); return status; } - -int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain) -{ - struct be_mcc_wrb *wrb; - struct be_cmd_req_set_qos *req; - int status; - - spin_lock_bh(&adapter->mcc_lock); - - wrb = wrb_from_mccq(adapter); - if (!wrb) { - status = -EBUSY; - goto err; - } - - req = embedded_payload(wrb); - - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, - OPCODE_COMMON_SET_QOS); - - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_SET_QOS, sizeof(*req)); - - req->hdr.domain = domain; - req->valid_bits = BE_QOS_BITS_NIC; - req->max_bps_nic = bps; - - status = be_mcc_notify_wait(adapter); - -err: - spin_unlock_bh(&adapter->mcc_lock); - return status; -} diff --git a/trunk/drivers/net/benet/be_cmds.h b/trunk/drivers/net/benet/be_cmds.h index bdc10a28cfda..912a0586f060 100644 --- a/trunk/drivers/net/benet/be_cmds.h +++ b/trunk/drivers/net/benet/be_cmds.h @@ -124,7 +124,6 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_CQ_CREATE 12 #define OPCODE_COMMON_EQ_CREATE 13 #define OPCODE_COMMON_MCC_CREATE 21 -#define OPCODE_COMMON_SET_QOS 28 #define OPCODE_COMMON_SEEPROM_READ 30 #define OPCODE_COMMON_NTWK_RX_FILTER 34 #define OPCODE_COMMON_GET_FW_VERSION 35 @@ -749,7 +748,7 @@ struct be_cmd_resp_query_fw_cfg { u32 be_config_number; u32 asic_revision; u32 phys_port; - u32 function_mode; + u32 function_cap; u32 rsvd[26]; }; @@ -895,22 +894,6 @@ struct be_cmd_resp_get_phy_info { u32 future_use[4]; }; -/*********************** Set QOS ***********************/ - -#define BE_QOS_BITS_NIC 1 - -struct be_cmd_req_set_qos { - struct be_cmd_req_hdr hdr; - u32 valid_bits; - u32 max_bps_nic; - u32 rsvd[7]; -}; - -struct be_cmd_resp_set_qos { - struct be_cmd_resp_hdr hdr; - u32 rsvd; -}; - extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, @@ -991,6 +974,4 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, u8 loopback_type, u8 enable); extern int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd); -extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); -extern void be_dump_ue(struct be_adapter *adapter); diff --git a/trunk/drivers/net/benet/be_ethtool.c b/trunk/drivers/net/benet/be_ethtool.c index cd16243c7c36..c0ade242895d 100644 --- a/trunk/drivers/net/benet/be_ethtool.c +++ b/trunk/drivers/net/benet/be_ethtool.c @@ -322,11 +322,10 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) int status; u16 intf_type; - if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { + if (adapter->link_speed < 0) { status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, &link_speed); - be_link_status_update(adapter, link_up); /* link_speed is in units of 10 Mbps */ if (link_speed) { ecmd->speed = link_speed*10; diff --git a/trunk/drivers/net/benet/be_hw.h b/trunk/drivers/net/benet/be_hw.h index 6c8f9bb8bfe6..06839676e3c4 100644 --- a/trunk/drivers/net/benet/be_hw.h +++ b/trunk/drivers/net/benet/be_hw.h @@ -56,16 +56,6 @@ #define PCICFG_PM_CONTROL_OFFSET 0x44 #define PCICFG_PM_CONTROL_MASK 0x108 /* bits 3 & 8 */ -/********* Online Control Registers *******/ -#define PCICFG_ONLINE0 0xB0 -#define PCICFG_ONLINE1 0xB4 - -/********* UE Status and Mask Registers ***/ -#define PCICFG_UE_STATUS_LOW 0xA0 -#define PCICFG_UE_STATUS_HIGH 0xA4 -#define PCICFG_UE_STATUS_LOW_MASK 0xA8 -#define PCICFG_UE_STATUS_HI_MASK 0xAC - /********* ISR0 Register offset **********/ #define CEV_ISR0_OFFSET 0xC18 #define CEV_ISR_SIZE 4 diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 74e146f470c6..e6ca92334d6d 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -40,76 +40,6 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { 0 } }; MODULE_DEVICE_TABLE(pci, be_dev_ids); -/* UE Status Low CSR */ -static char *ue_status_low_desc[] = { - "CEV", - "CTX", - "DBUF", - "ERX", - "Host", - "MPU", - "NDMA", - "PTC ", - "RDMA ", - "RXF ", - "RXIPS ", - "RXULP0 ", - "RXULP1 ", - "RXULP2 ", - "TIM ", - "TPOST ", - "TPRE ", - "TXIPS ", - "TXULP0 ", - "TXULP1 ", - "UC ", - "WDMA ", - "TXULP2 ", - "HOST1 ", - "P0_OB_LINK ", - "P1_OB_LINK ", - "HOST_GPIO ", - "MBOX ", - "AXGMAC0", - "AXGMAC1", - "JTAG", - "MPU_INTPEND" -}; -/* UE Status High CSR */ -static char *ue_status_hi_desc[] = { - "LPCMEMHOST", - "MGMT_MAC", - "PCS0ONLINE", - "MPU_IRAM", - "PCS1ONLINE", - "PCTL0", - "PCTL1", - "PMEM", - "RR", - "TXPB", - "RXPP", - "XAUI", - "TXP", - "ARM", - "IPC", - "HOST2", - "HOST3", - "HOST4", - "HOST5", - "HOST6", - "HOST7", - "HOST8", - "HOST9", - "NETC" - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown" -}; static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) { @@ -622,18 +552,11 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu) * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE. * If the user configures more, place BE in vlan promiscuous mode. */ -static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) +static int be_vid_config(struct be_adapter *adapter) { u16 vtag[BE_NUM_VLANS_SUPPORTED]; u16 ntags = 0, i; int status = 0; - u32 if_handle; - - if (vf) { - if_handle = adapter->vf_cfg[vf_num].vf_if_handle; - vtag[0] = cpu_to_le16(adapter->vf_cfg[vf_num].vf_vlan_tag); - status = be_cmd_vlan_config(adapter, if_handle, vtag, 1, 1, 0); - } if (adapter->vlans_added <= adapter->max_vlans) { /* Construct VLAN Table to give to HW */ @@ -649,7 +572,6 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) status = be_cmd_vlan_config(adapter, adapter->if_handle, NULL, 0, 1, 1); } - return status; } @@ -670,28 +592,27 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid) { struct be_adapter *adapter = netdev_priv(netdev); - adapter->vlans_added++; if (!be_physfn(adapter)) return; adapter->vlan_tag[vid] = 1; + adapter->vlans_added++; if (adapter->vlans_added <= (adapter->max_vlans + 1)) - be_vid_config(adapter, false, 0); + be_vid_config(adapter); } static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) { struct be_adapter *adapter = netdev_priv(netdev); - adapter->vlans_added--; - vlan_group_set_device(adapter->vlan_grp, vid, NULL); - if (!be_physfn(adapter)) return; adapter->vlan_tag[vid] = 0; + vlan_group_set_device(adapter->vlan_grp, vid, NULL); + adapter->vlans_added--; if (adapter->vlans_added <= adapter->max_vlans) - be_vid_config(adapter, false, 0); + be_vid_config(adapter); } static void be_set_multicast_list(struct net_device *netdev) @@ -735,93 +656,14 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) if (!is_valid_ether_addr(mac) || (vf >= num_vfs)) return -EINVAL; - if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) - status = be_cmd_pmac_del(adapter, - adapter->vf_cfg[vf].vf_if_handle, - adapter->vf_cfg[vf].vf_pmac_id); + status = be_cmd_pmac_del(adapter, adapter->vf_if_handle[vf], + adapter->vf_pmac_id[vf]); - status = be_cmd_pmac_add(adapter, mac, - adapter->vf_cfg[vf].vf_if_handle, - &adapter->vf_cfg[vf].vf_pmac_id); - - if (status) + status = be_cmd_pmac_add(adapter, mac, adapter->vf_if_handle[vf], + &adapter->vf_pmac_id[vf]); + if (!status) dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", mac, vf); - else - memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN); - - return status; -} - -static int be_get_vf_config(struct net_device *netdev, int vf, - struct ifla_vf_info *vi) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - if (!adapter->sriov_enabled) - return -EPERM; - - if (vf >= num_vfs) - return -EINVAL; - - vi->vf = vf; - vi->tx_rate = adapter->vf_cfg[vf].vf_tx_rate; - vi->vlan = adapter->vf_cfg[vf].vf_vlan_tag; - vi->qos = 0; - memcpy(&vi->mac, adapter->vf_cfg[vf].vf_mac_addr, ETH_ALEN); - - return 0; -} - -static int be_set_vf_vlan(struct net_device *netdev, - int vf, u16 vlan, u8 qos) -{ - struct be_adapter *adapter = netdev_priv(netdev); - int status = 0; - - if (!adapter->sriov_enabled) - return -EPERM; - - if ((vf >= num_vfs) || (vlan > 4095)) - return -EINVAL; - - if (vlan) { - adapter->vf_cfg[vf].vf_vlan_tag = vlan; - adapter->vlans_added++; - } else { - adapter->vf_cfg[vf].vf_vlan_tag = 0; - adapter->vlans_added--; - } - - status = be_vid_config(adapter, true, vf); - - if (status) - dev_info(&adapter->pdev->dev, - "VLAN %d config on VF %d failed\n", vlan, vf); - return status; -} - -static int be_set_vf_tx_rate(struct net_device *netdev, - int vf, int rate) -{ - struct be_adapter *adapter = netdev_priv(netdev); - int status = 0; - - if (!adapter->sriov_enabled) - return -EPERM; - - if ((vf >= num_vfs) || (rate < 0)) - return -EINVAL; - - if (rate > 10000) - rate = 10000; - - adapter->vf_cfg[vf].vf_tx_rate = rate; - status = be_cmd_set_qos(adapter, rate / 10, vf); - - if (status) - dev_info(&adapter->pdev->dev, - "tx rate %d on VF %d failed\n", rate, vf); return status; } @@ -1033,7 +875,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, /* vlanf could be wrongly set in some cards. * ignore if vtm is not set */ - if ((adapter->function_mode & 0x400) && !vtm) + if ((adapter->cap & 0x400) && !vtm) vlanf = 0; if (unlikely(vlanf)) { @@ -1073,7 +915,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, /* vlanf could be wrongly set in some cards. * ignore if vtm is not set */ - if ((adapter->function_mode & 0x400) && !vtm) + if ((adapter->cap & 0x400) && !vtm) vlanf = 0; skb = napi_get_frags(&eq_obj->napi); @@ -1743,66 +1585,12 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) return 1; } -static inline bool be_detect_ue(struct be_adapter *adapter) -{ - u32 online0 = 0, online1 = 0; - - pci_read_config_dword(adapter->pdev, PCICFG_ONLINE0, &online0); - - pci_read_config_dword(adapter->pdev, PCICFG_ONLINE1, &online1); - - if (!online0 || !online1) { - adapter->ue_detected = true; - dev_err(&adapter->pdev->dev, - "UE Detected!! online0=%d online1=%d\n", - online0, online1); - return true; - } - - return false; -} - -void be_dump_ue(struct be_adapter *adapter) -{ - u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask; - u32 i; - - pci_read_config_dword(adapter->pdev, - PCICFG_UE_STATUS_LOW, &ue_status_lo); - pci_read_config_dword(adapter->pdev, - PCICFG_UE_STATUS_HIGH, &ue_status_hi); - pci_read_config_dword(adapter->pdev, - PCICFG_UE_STATUS_LOW_MASK, &ue_status_lo_mask); - pci_read_config_dword(adapter->pdev, - PCICFG_UE_STATUS_HI_MASK, &ue_status_hi_mask); - - ue_status_lo = (ue_status_lo & (~ue_status_lo_mask)); - ue_status_hi = (ue_status_hi & (~ue_status_hi_mask)); - - if (ue_status_lo) { - for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) { - if (ue_status_lo & 1) - dev_err(&adapter->pdev->dev, - "UE: %s bit set\n", ue_status_low_desc[i]); - } - } - if (ue_status_hi) { - for (i = 0; ue_status_hi; ue_status_hi >>= 1, i++) { - if (ue_status_hi & 1) - dev_err(&adapter->pdev->dev, - "UE: %s bit set\n", ue_status_hi_desc[i]); - } - } - -} - static void be_worker(struct work_struct *work) { struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); - if (!adapter->stats_ioctl_sent) - be_cmd_get_stats(adapter, &adapter->stats.cmd); + be_cmd_get_stats(adapter, &adapter->stats.cmd); /* Set EQ delay */ be_rx_eqd_update(adapter); @@ -1814,10 +1602,6 @@ static void be_worker(struct work_struct *work) adapter->rx_post_starved = false; be_post_rx_frags(adapter); } - if (!adapter->ue_detected) { - if (be_detect_ue(adapter)) - be_dump_ue(adapter); - } schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); } @@ -1845,11 +1629,10 @@ static void be_msix_enable(struct be_adapter *adapter) static void be_sriov_enable(struct be_adapter *adapter) { - be_check_sriov_fn_type(adapter); #ifdef CONFIG_PCI_IOV + int status; + be_check_sriov_fn_type(adapter); if (be_physfn(adapter) && num_vfs) { - int status; - status = pci_enable_sriov(adapter->pdev, num_vfs); adapter->sriov_enabled = status ? false : true; } @@ -2039,7 +1822,7 @@ static int be_open(struct net_device *netdev) be_link_status_update(adapter, link_up); if (be_physfn(adapter)) { - status = be_vid_config(adapter, false, 0); + status = be_vid_config(adapter); if (status) goto err; @@ -2120,15 +1903,13 @@ static int be_setup(struct be_adapter *adapter) cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; status = be_cmd_if_create(adapter, cap_flags, en_flags, - mac, true, - &adapter->vf_cfg[vf].vf_if_handle, + mac, true, &adapter->vf_if_handle[vf], NULL, vf+1); if (status) { dev_err(&adapter->pdev->dev, "Interface Create failed for VF %d\n", vf); goto if_destroy; } - adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID; vf++; } } else if (!be_physfn(adapter)) { @@ -2162,9 +1943,8 @@ static int be_setup(struct be_adapter *adapter) be_tx_queues_destroy(adapter); if_destroy: for (vf = 0; vf < num_vfs; vf++) - if (adapter->vf_cfg[vf].vf_if_handle) - be_cmd_if_destroy(adapter, - adapter->vf_cfg[vf].vf_if_handle); + if (adapter->vf_if_handle[vf]) + be_cmd_if_destroy(adapter, adapter->vf_if_handle[vf]); be_cmd_if_destroy(adapter, adapter->if_handle); do_none: return status; @@ -2407,10 +2187,7 @@ static struct net_device_ops be_netdev_ops = { .ndo_vlan_rx_register = be_vlan_register, .ndo_vlan_rx_add_vid = be_vlan_add_vid, .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, - .ndo_set_vf_mac = be_set_vf_mac, - .ndo_set_vf_vlan = be_set_vf_vlan, - .ndo_set_vf_tx_rate = be_set_vf_tx_rate, - .ndo_get_vf_config = be_get_vf_config + .ndo_set_vf_mac = be_set_vf_mac }; static void be_netdev_init(struct net_device *netdev) @@ -2629,7 +2406,7 @@ static int be_get_config(struct be_adapter *adapter) return status; status = be_cmd_query_fw_cfg(adapter, - &adapter->port_num, &adapter->function_mode); + &adapter->port_num, &adapter->cap); if (status) return status; @@ -2649,7 +2426,7 @@ static int be_get_config(struct be_adapter *adapter) memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); } - if (adapter->function_mode & 0x400) + if (adapter->cap & 0x400) adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; else adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; diff --git a/trunk/drivers/net/bnx2x/bnx2x.h b/trunk/drivers/net/bnx2x.h similarity index 84% rename from trunk/drivers/net/bnx2x/bnx2x.h rename to trunk/drivers/net/bnx2x.h index 53af9c93e75c..8bd23687c530 100644 --- a/trunk/drivers/net/bnx2x/bnx2x.h +++ b/trunk/drivers/net/bnx2x.h @@ -20,10 +20,6 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.52.53-3" -#define DRV_MODULE_RELDATE "2010/18/04" -#define BNX2X_BC_VER 0x040200 - #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define BCM_VLAN 1 #endif @@ -36,7 +32,7 @@ #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 -#include "../cnic_if.h" +#include "cnic_if.h" #endif @@ -49,12 +45,10 @@ #endif #include -#include #include "bnx2x_reg.h" #include "bnx2x_fw_defs.h" #include "bnx2x_hsi.h" #include "bnx2x_link.h" -#include "bnx2x_stats.h" /* error/debug prints */ @@ -112,7 +106,6 @@ do { \ dev_info(&bp->pdev->dev, __fmt, ##__args); \ } while (0) -void bnx2x_panic_dump(struct bnx2x *bp); #ifdef BNX2X_STOP_ON_ERROR #define bnx2x_panic() do { \ @@ -255,6 +248,43 @@ union db_prod { #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) +struct bnx2x_eth_q_stats { + u32 total_bytes_received_hi; + u32 total_bytes_received_lo; + u32 total_bytes_transmitted_hi; + u32 total_bytes_transmitted_lo; + u32 total_unicast_packets_received_hi; + u32 total_unicast_packets_received_lo; + u32 total_multicast_packets_received_hi; + u32 total_multicast_packets_received_lo; + u32 total_broadcast_packets_received_hi; + u32 total_broadcast_packets_received_lo; + u32 total_unicast_packets_transmitted_hi; + u32 total_unicast_packets_transmitted_lo; + u32 total_multicast_packets_transmitted_hi; + u32 total_multicast_packets_transmitted_lo; + u32 total_broadcast_packets_transmitted_hi; + u32 total_broadcast_packets_transmitted_lo; + u32 valid_bytes_received_hi; + u32 valid_bytes_received_lo; + + u32 error_bytes_received_hi; + u32 error_bytes_received_lo; + u32 etherstatsoverrsizepkts_hi; + u32 etherstatsoverrsizepkts_lo; + u32 no_buff_discard_hi; + u32 no_buff_discard_lo; + + u32 driver_xoff; + u32 rx_err_discard_pkt; + u32 rx_skb_alloc_failed; + u32 hw_csum_err; +}; + +#define BNX2X_NUM_Q_STATS 13 +#define Q_STATS_OFFSET32(stat_name) \ + (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) + struct bnx2x_fastpath { struct napi_struct napi; @@ -563,6 +593,27 @@ struct bnx2x_common { /* port */ +struct nig_stats { + u32 brb_discard; + u32 brb_packet; + u32 brb_truncate; + u32 flow_ctrl_discard; + u32 flow_ctrl_octets; + u32 flow_ctrl_packet; + u32 mng_discard; + u32 mng_octet_inp; + u32 mng_octet_out; + u32 mng_packet_inp; + u32 mng_packet_out; + u32 pbf_octets; + u32 pbf_packet; + u32 safc_inp; + u32 egress_mac_pkt0_lo; + u32 egress_mac_pkt0_hi; + u32 egress_mac_pkt1_lo; + u32 egress_mac_pkt1_hi; +}; + struct bnx2x_port { u32 pmf; @@ -590,6 +641,156 @@ struct bnx2x_port { /* end of port */ +enum bnx2x_stats_event { + STATS_EVENT_PMF = 0, + STATS_EVENT_LINK_UP, + STATS_EVENT_UPDATE, + STATS_EVENT_STOP, + STATS_EVENT_MAX +}; + +enum bnx2x_stats_state { + STATS_STATE_DISABLED = 0, + STATS_STATE_ENABLED, + STATS_STATE_MAX +}; + +struct bnx2x_eth_stats { + u32 total_bytes_received_hi; + u32 total_bytes_received_lo; + u32 total_bytes_transmitted_hi; + u32 total_bytes_transmitted_lo; + u32 total_unicast_packets_received_hi; + u32 total_unicast_packets_received_lo; + u32 total_multicast_packets_received_hi; + u32 total_multicast_packets_received_lo; + u32 total_broadcast_packets_received_hi; + u32 total_broadcast_packets_received_lo; + u32 total_unicast_packets_transmitted_hi; + u32 total_unicast_packets_transmitted_lo; + u32 total_multicast_packets_transmitted_hi; + u32 total_multicast_packets_transmitted_lo; + u32 total_broadcast_packets_transmitted_hi; + u32 total_broadcast_packets_transmitted_lo; + u32 valid_bytes_received_hi; + u32 valid_bytes_received_lo; + + u32 error_bytes_received_hi; + u32 error_bytes_received_lo; + u32 etherstatsoverrsizepkts_hi; + u32 etherstatsoverrsizepkts_lo; + u32 no_buff_discard_hi; + u32 no_buff_discard_lo; + + u32 rx_stat_ifhcinbadoctets_hi; + u32 rx_stat_ifhcinbadoctets_lo; + u32 tx_stat_ifhcoutbadoctets_hi; + u32 tx_stat_ifhcoutbadoctets_lo; + u32 rx_stat_dot3statsfcserrors_hi; + u32 rx_stat_dot3statsfcserrors_lo; + u32 rx_stat_dot3statsalignmenterrors_hi; + u32 rx_stat_dot3statsalignmenterrors_lo; + u32 rx_stat_dot3statscarriersenseerrors_hi; + u32 rx_stat_dot3statscarriersenseerrors_lo; + u32 rx_stat_falsecarriererrors_hi; + u32 rx_stat_falsecarriererrors_lo; + u32 rx_stat_etherstatsundersizepkts_hi; + u32 rx_stat_etherstatsundersizepkts_lo; + u32 rx_stat_dot3statsframestoolong_hi; + u32 rx_stat_dot3statsframestoolong_lo; + u32 rx_stat_etherstatsfragments_hi; + u32 rx_stat_etherstatsfragments_lo; + u32 rx_stat_etherstatsjabbers_hi; + u32 rx_stat_etherstatsjabbers_lo; + u32 rx_stat_maccontrolframesreceived_hi; + u32 rx_stat_maccontrolframesreceived_lo; + u32 rx_stat_bmac_xpf_hi; + u32 rx_stat_bmac_xpf_lo; + u32 rx_stat_bmac_xcf_hi; + u32 rx_stat_bmac_xcf_lo; + u32 rx_stat_xoffstateentered_hi; + u32 rx_stat_xoffstateentered_lo; + u32 rx_stat_xonpauseframesreceived_hi; + u32 rx_stat_xonpauseframesreceived_lo; + u32 rx_stat_xoffpauseframesreceived_hi; + u32 rx_stat_xoffpauseframesreceived_lo; + u32 tx_stat_outxonsent_hi; + u32 tx_stat_outxonsent_lo; + u32 tx_stat_outxoffsent_hi; + u32 tx_stat_outxoffsent_lo; + u32 tx_stat_flowcontroldone_hi; + u32 tx_stat_flowcontroldone_lo; + u32 tx_stat_etherstatscollisions_hi; + u32 tx_stat_etherstatscollisions_lo; + u32 tx_stat_dot3statssinglecollisionframes_hi; + u32 tx_stat_dot3statssinglecollisionframes_lo; + u32 tx_stat_dot3statsmultiplecollisionframes_hi; + u32 tx_stat_dot3statsmultiplecollisionframes_lo; + u32 tx_stat_dot3statsdeferredtransmissions_hi; + u32 tx_stat_dot3statsdeferredtransmissions_lo; + u32 tx_stat_dot3statsexcessivecollisions_hi; + u32 tx_stat_dot3statsexcessivecollisions_lo; + u32 tx_stat_dot3statslatecollisions_hi; + u32 tx_stat_dot3statslatecollisions_lo; + u32 tx_stat_etherstatspkts64octets_hi; + u32 tx_stat_etherstatspkts64octets_lo; + u32 tx_stat_etherstatspkts65octetsto127octets_hi; + u32 tx_stat_etherstatspkts65octetsto127octets_lo; + u32 tx_stat_etherstatspkts128octetsto255octets_hi; + u32 tx_stat_etherstatspkts128octetsto255octets_lo; + u32 tx_stat_etherstatspkts256octetsto511octets_hi; + u32 tx_stat_etherstatspkts256octetsto511octets_lo; + u32 tx_stat_etherstatspkts512octetsto1023octets_hi; + u32 tx_stat_etherstatspkts512octetsto1023octets_lo; + u32 tx_stat_etherstatspkts1024octetsto1522octets_hi; + u32 tx_stat_etherstatspkts1024octetsto1522octets_lo; + u32 tx_stat_etherstatspktsover1522octets_hi; + u32 tx_stat_etherstatspktsover1522octets_lo; + u32 tx_stat_bmac_2047_hi; + u32 tx_stat_bmac_2047_lo; + u32 tx_stat_bmac_4095_hi; + u32 tx_stat_bmac_4095_lo; + u32 tx_stat_bmac_9216_hi; + u32 tx_stat_bmac_9216_lo; + u32 tx_stat_bmac_16383_hi; + u32 tx_stat_bmac_16383_lo; + u32 tx_stat_dot3statsinternalmactransmiterrors_hi; + u32 tx_stat_dot3statsinternalmactransmiterrors_lo; + u32 tx_stat_bmac_ufl_hi; + u32 tx_stat_bmac_ufl_lo; + + u32 pause_frames_received_hi; + u32 pause_frames_received_lo; + u32 pause_frames_sent_hi; + u32 pause_frames_sent_lo; + + u32 etherstatspkts1024octetsto1522octets_hi; + u32 etherstatspkts1024octetsto1522octets_lo; + u32 etherstatspktsover1522octets_hi; + u32 etherstatspktsover1522octets_lo; + + u32 brb_drop_hi; + u32 brb_drop_lo; + u32 brb_truncate_hi; + u32 brb_truncate_lo; + + u32 mac_filter_discard; + u32 xxoverflow_discard; + u32 brb_truncate_discard; + u32 mac_discard; + + u32 driver_xoff; + u32 rx_err_discard_pkt; + u32 rx_skb_alloc_failed; + u32 hw_csum_err; + + u32 nig_timer_max; +}; + +#define BNX2X_NUM_STATS 43 +#define STATS_OFFSET32(stat_name) \ + (offsetof(struct bnx2x_eth_stats, stat_name) / 4) + #ifdef BCM_CNIC #define MAX_CONTEXT 15 @@ -805,8 +1006,6 @@ struct bnx2x { int multi_mode; int num_queues; - int disable_tpa; - int int_mode; u32 rx_mode; #define BNX2X_RX_MODE_NONE 0 @@ -863,10 +1062,6 @@ struct bnx2x { /* used to synchronize stats collecting */ int stats_state; - - /* used for synchronization of concurrent threads statistics handling */ - spinlock_t stats_lock; - /* used by dmae command loader */ struct dmae_command stats_dmae; int executer_idx; @@ -935,10 +1130,6 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command); void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, u32 addr, u32 len); -void bnx2x_calc_fc_adv(struct bnx2x *bp); -int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common); -void bnx2x_update_coalesce(struct bnx2x *bp); static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int wait) @@ -1180,18 +1371,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 -#ifdef BNX2X_MAIN -#define BNX2X_EXTERN -#else -#define BNX2X_EXTERN extern -#endif - -BNX2X_EXTERN int load_count[3]; /* 0-common, 1-port0, 2-port1 */ - /* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */ -extern void bnx2x_set_ethtool_ops(struct net_device *netdev); - -void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); - #endif /* bnx2x.h */ diff --git a/trunk/drivers/net/bnx2x/Makefile b/trunk/drivers/net/bnx2x/Makefile deleted file mode 100644 index 084afce89ae9..000000000000 --- a/trunk/drivers/net/bnx2x/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for Broadcom 10-Gigabit ethernet driver -# - -obj-$(CONFIG_BNX2X) += bnx2x.o - -bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o diff --git a/trunk/drivers/net/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/bnx2x/bnx2x_cmn.c deleted file mode 100644 index 02bf710629a3..000000000000 --- a/trunk/drivers/net/bnx2x/bnx2x_cmn.c +++ /dev/null @@ -1,2252 +0,0 @@ -/* bnx2x_cmn.c: Broadcom Everest network driver. - * - * Copyright (c) 2007-2010 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation. - * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir - * Based on code from Michael Chan's bnx2 driver - * UDP CSUM errata workaround by Arik Gendelman - * Slowpath and fastpath rework by Vladislav Zolotarov - * Statistics and Link management by Yitchak Gertner - * - */ - - -#include -#include -#include -#include -#include "bnx2x_cmn.h" - -#ifdef BCM_VLAN -#include -#endif - -static int bnx2x_poll(struct napi_struct *napi, int budget); - -/* free skb in the packet ring at pos idx - * return idx of last bd freed - */ -static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, - u16 idx) -{ - struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx]; - struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_bd *tx_data_bd; - struct sk_buff *skb = tx_buf->skb; - u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons; - int nbd; - - /* prefetch skb end pointer to speedup dev_kfree_skb() */ - prefetch(&skb->end); - - DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n", - idx, tx_buf, skb); - - /* unmap first bd */ - DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); - tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd; - dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), - BD_UNMAP_LEN(tx_start_bd), PCI_DMA_TODEVICE); - - nbd = le16_to_cpu(tx_start_bd->nbd) - 1; -#ifdef BNX2X_STOP_ON_ERROR - if ((nbd - 1) > (MAX_SKB_FRAGS + 2)) { - BNX2X_ERR("BAD nbd!\n"); - bnx2x_panic(); - } -#endif - new_cons = nbd + tx_buf->first_bd; - - /* Get the next bd */ - bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); - - /* Skip a parse bd... */ - --nbd; - bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); - - /* ...and the TSO split header bd since they have no mapping */ - if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) { - --nbd; - bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); - } - - /* now free frags */ - while (nbd > 0) { - - DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx); - tx_data_bd = &fp->tx_desc_ring[bd_idx].reg_bd; - dma_unmap_page(&bp->pdev->dev, BD_UNMAP_ADDR(tx_data_bd), - BD_UNMAP_LEN(tx_data_bd), DMA_TO_DEVICE); - if (--nbd) - bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); - } - - /* release skb */ - WARN_ON(!skb); - dev_kfree_skb(skb); - tx_buf->first_bd = 0; - tx_buf->skb = NULL; - - return new_cons; -} - -int bnx2x_tx_int(struct bnx2x_fastpath *fp) -{ - struct bnx2x *bp = fp->bp; - struct netdev_queue *txq; - u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons; - -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return -1; -#endif - - txq = netdev_get_tx_queue(bp->dev, fp->index); - hw_cons = le16_to_cpu(*fp->tx_cons_sb); - sw_cons = fp->tx_pkt_cons; - - while (sw_cons != hw_cons) { - u16 pkt_cons; - - pkt_cons = TX_BD(sw_cons); - - /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */ - - DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n", - hw_cons, sw_cons, pkt_cons); - -/* if (NEXT_TX_IDX(sw_cons) != hw_cons) { - rmb(); - prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb); - } -*/ - bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons); - sw_cons++; - } - - fp->tx_pkt_cons = sw_cons; - fp->tx_bd_cons = bd_cons; - - /* Need to make the tx_bd_cons update visible to start_xmit() - * before checking for netif_tx_queue_stopped(). Without the - * memory barrier, there is a small possibility that - * start_xmit() will miss it and cause the queue to be stopped - * forever. - */ - smp_mb(); - - /* TBD need a thresh? */ - if (unlikely(netif_tx_queue_stopped(txq))) { - /* Taking tx_lock() is needed to prevent reenabling the queue - * while it's empty. This could have happen if rx_action() gets - * suspended in bnx2x_tx_int() after the condition before - * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()): - * - * stops the queue->sees fresh tx_bd_cons->releases the queue-> - * sends some packets consuming the whole queue again-> - * stops the queue - */ - - __netif_tx_lock(txq, smp_processor_id()); - - if ((netif_tx_queue_stopped(txq)) && - (bp->state == BNX2X_STATE_OPEN) && - (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)) - netif_tx_wake_queue(txq); - - __netif_tx_unlock(txq); - } - return 0; -} - -static inline void bnx2x_update_last_max_sge(struct bnx2x_fastpath *fp, - u16 idx) -{ - u16 last_max = fp->last_max_sge; - - if (SUB_S16(idx, last_max) > 0) - fp->last_max_sge = idx; -} - -static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, - struct eth_fast_path_rx_cqe *fp_cqe) -{ - struct bnx2x *bp = fp->bp; - u16 sge_len = SGE_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) - - le16_to_cpu(fp_cqe->len_on_bd)) >> - SGE_PAGE_SHIFT; - u16 last_max, last_elem, first_elem; - u16 delta = 0; - u16 i; - - if (!sge_len) - return; - - /* First mark all used pages */ - for (i = 0; i < sge_len; i++) - SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i]))); - - DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n", - sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); - - /* Here we assume that the last SGE index is the biggest */ - prefetch((void *)(fp->sge_mask)); - bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); - - last_max = RX_SGE(fp->last_max_sge); - last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT; - first_elem = RX_SGE(fp->rx_sge_prod) >> RX_SGE_MASK_ELEM_SHIFT; - - /* If ring is not full */ - if (last_elem + 1 != first_elem) - last_elem++; - - /* Now update the prod */ - for (i = first_elem; i != last_elem; i = NEXT_SGE_MASK_ELEM(i)) { - if (likely(fp->sge_mask[i])) - break; - - fp->sge_mask[i] = RX_SGE_MASK_ELEM_ONE_MASK; - delta += RX_SGE_MASK_ELEM_SZ; - } - - if (delta > 0) { - fp->rx_sge_prod += delta; - /* clear page-end entries */ - bnx2x_clear_sge_mask_next_elems(fp); - } - - DP(NETIF_MSG_RX_STATUS, - "fp->last_max_sge = %d fp->rx_sge_prod = %d\n", - fp->last_max_sge, fp->rx_sge_prod); -} - -static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, - struct sk_buff *skb, u16 cons, u16 prod) -{ - struct bnx2x *bp = fp->bp; - struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; - struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; - struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; - dma_addr_t mapping; - - /* move empty skb from pool to prod and map it */ - prod_rx_buf->skb = fp->tpa_pool[queue].skb; - mapping = dma_map_single(&bp->pdev->dev, fp->tpa_pool[queue].skb->data, - bp->rx_buf_size, DMA_FROM_DEVICE); - dma_unmap_addr_set(prod_rx_buf, mapping, mapping); - - /* move partial skb from cons to pool (don't unmap yet) */ - fp->tpa_pool[queue] = *cons_rx_buf; - - /* mark bin state as start - print error if current state != stop */ - if (fp->tpa_state[queue] != BNX2X_TPA_STOP) - BNX2X_ERR("start of bin not in stop [%d]\n", queue); - - fp->tpa_state[queue] = BNX2X_TPA_START; - - /* point prod_bd to new skb */ - prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); - prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - -#ifdef BNX2X_STOP_ON_ERROR - fp->tpa_queue_used |= (1 << queue); -#ifdef _ASM_GENERIC_INT_L64_H - DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n", -#else - DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n", -#endif - fp->tpa_queue_used); -#endif -} - -static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, - struct sk_buff *skb, - struct eth_fast_path_rx_cqe *fp_cqe, - u16 cqe_idx) -{ - struct sw_rx_page *rx_pg, old_rx_pg; - u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); - u32 i, frag_len, frag_size, pages; - int err; - int j; - - frag_size = le16_to_cpu(fp_cqe->pkt_len) - len_on_bd; - pages = SGE_PAGE_ALIGN(frag_size) >> SGE_PAGE_SHIFT; - - /* This is needed in order to enable forwarding support */ - if (frag_size) - skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, - max(frag_size, (u32)len_on_bd)); - -#ifdef BNX2X_STOP_ON_ERROR - if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { - BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n", - pages, cqe_idx); - BNX2X_ERR("fp_cqe->pkt_len = %d fp_cqe->len_on_bd = %d\n", - fp_cqe->pkt_len, len_on_bd); - bnx2x_panic(); - return -EINVAL; - } -#endif - - /* Run through the SGL and compose the fragmented skb */ - for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) { - u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j])); - - /* FW gives the indices of the SGE as if the ring is an array - (meaning that "next" element will consume 2 indices) */ - frag_len = min(frag_size, (u32)(SGE_PAGE_SIZE*PAGES_PER_SGE)); - rx_pg = &fp->rx_page_ring[sge_idx]; - old_rx_pg = *rx_pg; - - /* If we fail to allocate a substitute page, we simply stop - where we are and drop the whole packet */ - err = bnx2x_alloc_rx_sge(bp, fp, sge_idx); - if (unlikely(err)) { - fp->eth_q_stats.rx_skb_alloc_failed++; - return err; - } - - /* Unmap the page as we r going to pass it to the stack */ - dma_unmap_page(&bp->pdev->dev, - dma_unmap_addr(&old_rx_pg, mapping), - SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE); - - /* Add one frag and update the appropriate fields in the skb */ - skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len); - - skb->data_len += frag_len; - skb->truesize += frag_len; - skb->len += frag_len; - - frag_size -= frag_len; - } - - return 0; -} - -static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, - u16 queue, int pad, int len, union eth_rx_cqe *cqe, - u16 cqe_idx) -{ - struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue]; - struct sk_buff *skb = rx_buf->skb; - /* alloc new skb */ - struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); - - /* Unmap skb in the pool anyway, as we are going to change - pool entry status to BNX2X_TPA_STOP even if new skb allocation - fails. */ - dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, DMA_FROM_DEVICE); - - if (likely(new_skb)) { - /* fix ip xsum and give it to the stack */ - /* (no need to map the new skb) */ -#ifdef BCM_VLAN - int is_vlan_cqe = - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN); - int is_not_hwaccel_vlan_cqe = - (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG))); -#endif - - prefetch(skb); - prefetch(((char *)(skb)) + 128); - -#ifdef BNX2X_STOP_ON_ERROR - if (pad + len > bp->rx_buf_size) { - BNX2X_ERR("skb_put is about to fail... " - "pad %d len %d rx_buf_size %d\n", - pad, len, bp->rx_buf_size); - bnx2x_panic(); - return; - } -#endif - - skb_reserve(skb, pad); - skb_put(skb, len); - - skb->protocol = eth_type_trans(skb, bp->dev); - skb->ip_summed = CHECKSUM_UNNECESSARY; - - { - struct iphdr *iph; - - iph = (struct iphdr *)skb->data; -#ifdef BCM_VLAN - /* If there is no Rx VLAN offloading - - take VLAN tag into an account */ - if (unlikely(is_not_hwaccel_vlan_cqe)) - iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN); -#endif - iph->check = 0; - iph->check = ip_fast_csum((u8 *)iph, iph->ihl); - } - - if (!bnx2x_fill_frag_skb(bp, fp, skb, - &cqe->fast_path_cqe, cqe_idx)) { -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && is_vlan_cqe && - (!is_not_hwaccel_vlan_cqe)) - vlan_gro_receive(&fp->napi, bp->vlgrp, - le16_to_cpu(cqe->fast_path_cqe. - vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); - } else { - DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages" - " - dropping packet!\n"); - dev_kfree_skb(skb); - } - - - /* put new skb in bin */ - fp->tpa_pool[queue].skb = new_skb; - - } else { - /* else drop the packet and keep the buffer in the bin */ - DP(NETIF_MSG_RX_STATUS, - "Failed to allocate new skb - dropping packet!\n"); - fp->eth_q_stats.rx_skb_alloc_failed++; - } - - fp->tpa_state[queue] = BNX2X_TPA_STOP; -} - -/* Set Toeplitz hash value in the skb using the value from the - * CQE (calculated by HW). - */ -static inline void bnx2x_set_skb_rxhash(struct bnx2x *bp, union eth_rx_cqe *cqe, - struct sk_buff *skb) -{ - /* Set Toeplitz hash from CQE */ - if ((bp->dev->features & NETIF_F_RXHASH) && - (cqe->fast_path_cqe.status_flags & - ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) - skb->rxhash = - le32_to_cpu(cqe->fast_path_cqe.rss_hash_result); -} - -int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) -{ - struct bnx2x *bp = fp->bp; - u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons; - u16 hw_comp_cons, sw_comp_cons, sw_comp_prod; - int rx_pkt = 0; - -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return 0; -#endif - - /* CQ "next element" is of the size of the regular element, - that's why it's ok here */ - hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb); - if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) - hw_comp_cons++; - - bd_cons = fp->rx_bd_cons; - bd_prod = fp->rx_bd_prod; - bd_prod_fw = bd_prod; - sw_comp_cons = fp->rx_comp_cons; - sw_comp_prod = fp->rx_comp_prod; - - /* Memory barrier necessary as speculative reads of the rx - * buffer can be ahead of the index in the status block - */ - rmb(); - - DP(NETIF_MSG_RX_STATUS, - "queue[%d]: hw_comp_cons %u sw_comp_cons %u\n", - fp->index, hw_comp_cons, sw_comp_cons); - - while (sw_comp_cons != hw_comp_cons) { - struct sw_rx_bd *rx_buf = NULL; - struct sk_buff *skb; - union eth_rx_cqe *cqe; - u8 cqe_fp_flags; - u16 len, pad; - - comp_ring_cons = RCQ_BD(sw_comp_cons); - bd_prod = RX_BD(bd_prod); - bd_cons = RX_BD(bd_cons); - - /* Prefetch the page containing the BD descriptor - at producer's index. It will be needed when new skb is - allocated */ - prefetch((void *)(PAGE_ALIGN((unsigned long) - (&fp->rx_desc_ring[bd_prod])) - - PAGE_SIZE + 1)); - - cqe = &fp->rx_comp_ring[comp_ring_cons]; - cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; - - DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x" - " queue %x vlan %x len %u\n", CQE_TYPE(cqe_fp_flags), - cqe_fp_flags, cqe->fast_path_cqe.status_flags, - le32_to_cpu(cqe->fast_path_cqe.rss_hash_result), - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), - le16_to_cpu(cqe->fast_path_cqe.pkt_len)); - - /* is this a slowpath msg? */ - if (unlikely(CQE_TYPE(cqe_fp_flags))) { - bnx2x_sp_event(fp, cqe); - goto next_cqe; - - /* this is an rx packet */ - } else { - rx_buf = &fp->rx_buf_ring[bd_cons]; - skb = rx_buf->skb; - prefetch(skb); - len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); - pad = cqe->fast_path_cqe.placement_offset; - - /* If CQE is marked both TPA_START and TPA_END - it is a non-TPA CQE */ - if ((!fp->disable_tpa) && - (TPA_TYPE(cqe_fp_flags) != - (TPA_TYPE_START | TPA_TYPE_END))) { - u16 queue = cqe->fast_path_cqe.queue_index; - - if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_START) { - DP(NETIF_MSG_RX_STATUS, - "calling tpa_start on queue %d\n", - queue); - - bnx2x_tpa_start(fp, queue, skb, - bd_cons, bd_prod); - - /* Set Toeplitz hash for an LRO skb */ - bnx2x_set_skb_rxhash(bp, cqe, skb); - - goto next_rx; - } - - if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) { - DP(NETIF_MSG_RX_STATUS, - "calling tpa_stop on queue %d\n", - queue); - - if (!BNX2X_RX_SUM_FIX(cqe)) - BNX2X_ERR("STOP on none TCP " - "data\n"); - - /* This is a size of the linear data - on this skb */ - len = le16_to_cpu(cqe->fast_path_cqe. - len_on_bd); - bnx2x_tpa_stop(bp, fp, queue, pad, - len, cqe, comp_ring_cons); -#ifdef BNX2X_STOP_ON_ERROR - if (bp->panic) - return 0; -#endif - - bnx2x_update_sge_prod(fp, - &cqe->fast_path_cqe); - goto next_cqe; - } - } - - dma_sync_single_for_device(&bp->pdev->dev, - dma_unmap_addr(rx_buf, mapping), - pad + RX_COPY_THRESH, - DMA_FROM_DEVICE); - prefetch(((char *)(skb)) + 128); - - /* is this an error packet? */ - if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { - DP(NETIF_MSG_RX_ERR, - "ERROR flags %x rx packet %u\n", - cqe_fp_flags, sw_comp_cons); - fp->eth_q_stats.rx_err_discard_pkt++; - goto reuse_rx; - } - - /* Since we don't have a jumbo ring - * copy small packets if mtu > 1500 - */ - if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && - (len <= RX_COPY_THRESH)) { - struct sk_buff *new_skb; - - new_skb = netdev_alloc_skb(bp->dev, - len + pad); - if (new_skb == NULL) { - DP(NETIF_MSG_RX_ERR, - "ERROR packet dropped " - "because of alloc failure\n"); - fp->eth_q_stats.rx_skb_alloc_failed++; - goto reuse_rx; - } - - /* aligned copy */ - skb_copy_from_linear_data_offset(skb, pad, - new_skb->data + pad, len); - skb_reserve(new_skb, pad); - skb_put(new_skb, len); - - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); - - skb = new_skb; - - } else - if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) { - dma_unmap_single(&bp->pdev->dev, - dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, - DMA_FROM_DEVICE); - skb_reserve(skb, pad); - skb_put(skb, len); - - } else { - DP(NETIF_MSG_RX_ERR, - "ERROR packet dropped because " - "of alloc failure\n"); - fp->eth_q_stats.rx_skb_alloc_failed++; -reuse_rx: - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); - goto next_rx; - } - - skb->protocol = eth_type_trans(skb, bp->dev); - - /* Set Toeplitz hash for a none-LRO skb */ - bnx2x_set_skb_rxhash(bp, cqe, skb); - - skb->ip_summed = CHECKSUM_NONE; - if (bp->rx_csum) { - if (likely(BNX2X_RX_CSUM_OK(cqe))) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - fp->eth_q_stats.hw_csum_err++; - } - } - - skb_record_rx_queue(skb, fp->index); - -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) && - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN)) - vlan_gro_receive(&fp->napi, bp->vlgrp, - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); - - -next_rx: - rx_buf->skb = NULL; - - bd_cons = NEXT_RX_IDX(bd_cons); - bd_prod = NEXT_RX_IDX(bd_prod); - bd_prod_fw = NEXT_RX_IDX(bd_prod_fw); - rx_pkt++; -next_cqe: - sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod); - sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons); - - if (rx_pkt == budget) - break; - } /* while */ - - fp->rx_bd_cons = bd_cons; - fp->rx_bd_prod = bd_prod_fw; - fp->rx_comp_cons = sw_comp_cons; - fp->rx_comp_prod = sw_comp_prod; - - /* Update producers */ - bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod, - fp->rx_sge_prod); - - fp->rx_pkt += rx_pkt; - fp->rx_calls++; - - return rx_pkt; -} - -static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) -{ - struct bnx2x_fastpath *fp = fp_cookie; - struct bnx2x *bp = fp->bp; - - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return IRQ_HANDLED; - } - - DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n", - fp->index, fp->sb_id); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); - -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return IRQ_HANDLED; -#endif - - /* Handle Rx and Tx according to MSI-X vector */ - prefetch(fp->rx_cons_sb); - prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->u_status_block.status_block_index); - prefetch(&fp->status_blk->c_status_block.status_block_index); - napi_schedule(&bnx2x_fp(bp, fp->index, napi)); - - return IRQ_HANDLED; -} - - -/* HW Lock for shared dual port PHYs */ -void bnx2x_acquire_phy_lock(struct bnx2x *bp) -{ - mutex_lock(&bp->port.phy_mutex); - - if (bp->port.need_hw_lock) - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_MDIO); -} - -void bnx2x_release_phy_lock(struct bnx2x *bp) -{ - if (bp->port.need_hw_lock) - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_MDIO); - - mutex_unlock(&bp->port.phy_mutex); -} - -void bnx2x_link_report(struct bnx2x *bp) -{ - if (bp->flags & MF_FUNC_DIS) { - netif_carrier_off(bp->dev); - netdev_err(bp->dev, "NIC Link is Down\n"); - return; - } - - if (bp->link_vars.link_up) { - u16 line_speed; - - if (bp->state == BNX2X_STATE_OPEN) - netif_carrier_on(bp->dev); - netdev_info(bp->dev, "NIC Link is Up, "); - - line_speed = bp->link_vars.line_speed; - if (IS_E1HMF(bp)) { - u16 vn_max_rate; - - vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; - if (vn_max_rate < line_speed) - line_speed = vn_max_rate; - } - pr_cont("%d Mbps ", line_speed); - - if (bp->link_vars.duplex == DUPLEX_FULL) - pr_cont("full duplex"); - else - pr_cont("half duplex"); - - if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) { - if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) { - pr_cont(", receive "); - if (bp->link_vars.flow_ctrl & - BNX2X_FLOW_CTRL_TX) - pr_cont("& transmit "); - } else { - pr_cont(", transmit "); - } - pr_cont("flow control ON"); - } - pr_cont("\n"); - - } else { /* link_down */ - netif_carrier_off(bp->dev); - netdev_err(bp->dev, "NIC Link is Down\n"); - } -} - -void bnx2x_init_rx_rings(struct bnx2x *bp) -{ - int func = BP_FUNC(bp); - int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : - ETH_MAX_AGGREGATION_QUEUES_E1H; - u16 ring_prod, cqe_ring_prod; - int i, j; - - bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; - DP(NETIF_MSG_IFUP, - "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - - if (bp->flags & TPA_ENABLE_FLAG) { - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; - - for (i = 0; i < max_agg_queues; i++) { - fp->tpa_pool[i].skb = - netdev_alloc_skb(bp->dev, bp->rx_buf_size); - if (!fp->tpa_pool[i].skb) { - BNX2X_ERR("Failed to allocate TPA " - "skb pool for queue[%d] - " - "disabling TPA on this " - "queue!\n", j); - bnx2x_free_tpa_pool(bp, fp, i); - fp->disable_tpa = 1; - break; - } - dma_unmap_addr_set((struct sw_rx_bd *) - &bp->fp->tpa_pool[i], - mapping, 0); - fp->tpa_state[i] = BNX2X_TPA_STOP; - } - } - } - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; - - fp->rx_bd_cons = 0; - fp->rx_cons_sb = BNX2X_RX_SB_INDEX; - fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX; - - /* "next page" elements initialization */ - /* SGE ring */ - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - struct eth_rx_sge *sge; - - sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; - sge->addr_hi = - cpu_to_le32(U64_HI(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - sge->addr_lo = - cpu_to_le32(U64_LO(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - } - - bnx2x_init_sge_ring_bit_mask(fp); - - /* RX BD ring */ - for (i = 1; i <= NUM_RX_RINGS; i++) { - struct eth_rx_bd *rx_bd; - - rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; - rx_bd->addr_hi = - cpu_to_le32(U64_HI(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - rx_bd->addr_lo = - cpu_to_le32(U64_LO(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - } - - /* CQ ring */ - for (i = 1; i <= NUM_RCQ_RINGS; i++) { - struct eth_rx_cqe_next_page *nextpg; - - nextpg = (struct eth_rx_cqe_next_page *) - &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; - nextpg->addr_hi = - cpu_to_le32(U64_HI(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - nextpg->addr_lo = - cpu_to_le32(U64_LO(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - } - - /* Allocate SGEs and initialize the ring elements */ - for (i = 0, ring_prod = 0; - i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { - - if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx sges\n", i); - BNX2X_ERR("disabling TPA for queue[%d]\n", j); - /* Cleanup already allocated elements */ - bnx2x_free_rx_sge_range(bp, fp, ring_prod); - bnx2x_free_tpa_pool(bp, fp, max_agg_queues); - fp->disable_tpa = 1; - ring_prod = 0; - break; - } - ring_prod = NEXT_SGE_IDX(ring_prod); - } - fp->rx_sge_prod = ring_prod; - - /* Allocate BDs and initialize BD ring */ - fp->rx_comp_cons = 0; - cqe_ring_prod = ring_prod = 0; - for (i = 0; i < bp->rx_ring_size; i++) { - if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx skbs on queue[%d]\n", i, j); - fp->eth_q_stats.rx_skb_alloc_failed++; - break; - } - ring_prod = NEXT_RX_IDX(ring_prod); - cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); - WARN_ON(ring_prod <= i); - } - - fp->rx_bd_prod = ring_prod; - /* must not have more available CQEs than BDs */ - fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, - cqe_ring_prod); - fp->rx_pkt = fp->rx_calls = 0; - - /* Warning! - * this will generate an interrupt (to the TSTORM) - * must only be done after chip is initialized - */ - bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod, - fp->rx_sge_prod); - if (j != 0) - continue; - - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, - U64_HI(fp->rx_comp_mapping)); - } -} -static void bnx2x_free_tx_skbs(struct bnx2x *bp) -{ - int i; - - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - u16 bd_cons = fp->tx_bd_cons; - u16 sw_prod = fp->tx_pkt_prod; - u16 sw_cons = fp->tx_pkt_cons; - - while (sw_cons != sw_prod) { - bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons)); - sw_cons++; - } - } -} - -static void bnx2x_free_rx_skbs(struct bnx2x *bp) -{ - int i, j; - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; - - for (i = 0; i < NUM_RX_BD; i++) { - struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; - struct sk_buff *skb = rx_buf->skb; - - if (skb == NULL) - continue; - - dma_unmap_single(&bp->pdev->dev, - dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, DMA_FROM_DEVICE); - - rx_buf->skb = NULL; - dev_kfree_skb(skb); - } - if (!fp->disable_tpa) - bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ? - ETH_MAX_AGGREGATION_QUEUES_E1 : - ETH_MAX_AGGREGATION_QUEUES_E1H); - } -} - -void bnx2x_free_skbs(struct bnx2x *bp) -{ - bnx2x_free_tx_skbs(bp); - bnx2x_free_rx_skbs(bp); -} - -static void bnx2x_free_msix_irqs(struct bnx2x *bp) -{ - int i, offset = 1; - - free_irq(bp->msix_table[0].vector, bp->dev); - DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", - bp->msix_table[0].vector); - -#ifdef BCM_CNIC - offset++; -#endif - for_each_queue(bp, i) { - DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " - "state %x\n", i, bp->msix_table[i + offset].vector, - bnx2x_fp(bp, i, state)); - - free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]); - } -} - -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only) -{ - if (bp->flags & USING_MSIX_FLAG) { - if (!disable_only) - bnx2x_free_msix_irqs(bp); - pci_disable_msix(bp->pdev); - bp->flags &= ~USING_MSIX_FLAG; - - } else if (bp->flags & USING_MSI_FLAG) { - if (!disable_only) - free_irq(bp->pdev->irq, bp->dev); - pci_disable_msi(bp->pdev); - bp->flags &= ~USING_MSI_FLAG; - - } else if (!disable_only) - free_irq(bp->pdev->irq, bp->dev); -} - -static int bnx2x_enable_msix(struct bnx2x *bp) -{ - int i, rc, offset = 1; - int igu_vec = 0; - - bp->msix_table[0].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec); - -#ifdef BCM_CNIC - igu_vec = BP_L_ID(bp) + offset; - bp->msix_table[1].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[1].entry = %d (CNIC)\n", igu_vec); - offset++; -#endif - for_each_queue(bp, i) { - igu_vec = BP_L_ID(bp) + offset + i; - bp->msix_table[i + offset].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " - "(fastpath #%u)\n", i + offset, igu_vec, i); - } - - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], - BNX2X_NUM_QUEUES(bp) + offset); - - /* - * reconfigure number of tx/rx queues according to available - * MSI-X vectors - */ - if (rc >= BNX2X_MIN_MSIX_VEC_CNT) { - /* vectors available for FP */ - int fp_vec = rc - BNX2X_MSIX_VEC_FP_START; - - DP(NETIF_MSG_IFUP, - "Trying to use less MSI-X vectors: %d\n", rc); - - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc); - - if (rc) { - DP(NETIF_MSG_IFUP, - "MSI-X is not attainable rc %d\n", rc); - return rc; - } - - bp->num_queues = min(bp->num_queues, fp_vec); - - DP(NETIF_MSG_IFUP, "New queue configuration set: %d\n", - bp->num_queues); - } else if (rc) { - DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc); - return rc; - } - - bp->flags |= USING_MSIX_FLAG; - - return 0; -} - -static int bnx2x_req_msix_irqs(struct bnx2x *bp) -{ - int i, rc, offset = 1; - - rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0, - bp->dev->name, bp->dev); - if (rc) { - BNX2X_ERR("request sp irq failed\n"); - return -EBUSY; - } - -#ifdef BCM_CNIC - offset++; -#endif - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", - bp->dev->name, i); - - rc = request_irq(bp->msix_table[i + offset].vector, - bnx2x_msix_fp_int, 0, fp->name, fp); - if (rc) { - BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc); - bnx2x_free_msix_irqs(bp); - return -EBUSY; - } - - fp->state = BNX2X_FP_STATE_IRQ; - } - - i = BNX2X_NUM_QUEUES(bp); - netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" - " ... fp[%d] %d\n", - bp->msix_table[0].vector, - 0, bp->msix_table[offset].vector, - i - 1, bp->msix_table[offset + i - 1].vector); - - return 0; -} - -static int bnx2x_enable_msi(struct bnx2x *bp) -{ - int rc; - - rc = pci_enable_msi(bp->pdev); - if (rc) { - DP(NETIF_MSG_IFUP, "MSI is not attainable\n"); - return -1; - } - bp->flags |= USING_MSI_FLAG; - - return 0; -} - -static int bnx2x_req_irq(struct bnx2x *bp) -{ - unsigned long flags; - int rc; - - if (bp->flags & USING_MSI_FLAG) - flags = 0; - else - flags = IRQF_SHARED; - - rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags, - bp->dev->name, bp->dev); - if (!rc) - bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ; - - return rc; -} - -static void bnx2x_napi_enable(struct bnx2x *bp) -{ - int i; - - for_each_queue(bp, i) - napi_enable(&bnx2x_fp(bp, i, napi)); -} - -static void bnx2x_napi_disable(struct bnx2x *bp) -{ - int i; - - for_each_queue(bp, i) - napi_disable(&bnx2x_fp(bp, i, napi)); -} - -void bnx2x_netif_start(struct bnx2x *bp) -{ - int intr_sem; - - intr_sem = atomic_dec_and_test(&bp->intr_sem); - smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ - - if (intr_sem) { - if (netif_running(bp->dev)) { - bnx2x_napi_enable(bp); - bnx2x_int_enable(bp); - if (bp->state == BNX2X_STATE_OPEN) - netif_tx_wake_all_queues(bp->dev); - } - } -} - -void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) -{ - bnx2x_int_disable_sync(bp, disable_hw); - bnx2x_napi_disable(bp); - netif_tx_disable(bp->dev); -} -static int bnx2x_set_num_queues(struct bnx2x *bp) -{ - int rc = 0; - - switch (bp->int_mode) { - case INT_MODE_INTx: - case INT_MODE_MSI: - bp->num_queues = 1; - DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); - break; - default: - /* Set number of queues according to bp->multi_mode value */ - bnx2x_set_num_queues_msix(bp); - - DP(NETIF_MSG_IFUP, "set number of queues to %d\n", - bp->num_queues); - - /* if we can't use MSI-X we only need one fp, - * so try to enable MSI-X with the requested number of fp's - * and fallback to MSI or legacy INTx with one fp - */ - rc = bnx2x_enable_msix(bp); - if (rc) - /* failed to enable MSI-X */ - bp->num_queues = 1; - break; - } - bp->dev->real_num_tx_queues = bp->num_queues; - return rc; -} - -/* must be called with rtnl_lock */ -int bnx2x_nic_load(struct bnx2x *bp, int load_mode) -{ - u32 load_code; - int i, rc; - -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return -EPERM; -#endif - - bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; - - rc = bnx2x_set_num_queues(bp); - - if (bnx2x_alloc_mem(bp)) { - bnx2x_free_irq(bp, true); - return -ENOMEM; - } - - for_each_queue(bp, i) - bnx2x_fp(bp, i, disable_tpa) = - ((bp->flags & TPA_ENABLE_FLAG) == 0); - - for_each_queue(bp, i) - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, 128); - - bnx2x_napi_enable(bp); - - if (bp->flags & USING_MSIX_FLAG) { - rc = bnx2x_req_msix_irqs(bp); - if (rc) { - bnx2x_free_irq(bp, true); - goto load_error1; - } - } else { - /* Fall to INTx if failed to enable MSI-X due to lack of - memory (in bnx2x_set_num_queues()) */ - if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) - bnx2x_enable_msi(bp); - bnx2x_ack_int(bp); - rc = bnx2x_req_irq(bp); - if (rc) { - BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); - bnx2x_free_irq(bp, true); - goto load_error1; - } - if (bp->flags & USING_MSI_FLAG) { - bp->dev->irq = bp->pdev->irq; - netdev_info(bp->dev, "using MSI IRQ %d\n", - bp->pdev->irq); - } - } - - /* Send LOAD_REQUEST command to MCP - Returns the type of LOAD command: - if it is the first port to be initialized - common blocks should be initialized, otherwise - not - */ - if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); - if (!load_code) { - BNX2X_ERR("MCP response failure, aborting\n"); - rc = -EBUSY; - goto load_error2; - } - if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { - rc = -EBUSY; /* other port in diagnostic mode */ - goto load_error2; - } - - } else { - int port = BP_PORT(bp); - - DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]++; - load_count[1 + port]++; - DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 1) - load_code = FW_MSG_CODE_DRV_LOAD_COMMON; - else if (load_count[1 + port] == 1) - load_code = FW_MSG_CODE_DRV_LOAD_PORT; - else - load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; - } - - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || - (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) - bp->port.pmf = 1; - else - bp->port.pmf = 0; - DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); - - /* Initialize HW */ - rc = bnx2x_init_hw(bp, load_code); - if (rc) { - BNX2X_ERR("HW init failed, aborting\n"); - bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); - goto load_error2; - } - - /* Setup NIC internals and enable interrupts */ - bnx2x_nic_init(bp, load_code); - - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) && - (bp->common.shmem2_base)) - SHMEM2_WR(bp, dcc_support, - (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV | - SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV)); - - /* Send LOAD_DONE command to MCP */ - if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); - if (!load_code) { - BNX2X_ERR("MCP response failure, aborting\n"); - rc = -EBUSY; - goto load_error3; - } - } - - bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - - rc = bnx2x_setup_leading(bp); - if (rc) { - BNX2X_ERR("Setup leading failed!\n"); -#ifndef BNX2X_STOP_ON_ERROR - goto load_error3; -#else - bp->panic = 1; - return -EBUSY; -#endif - } - - if (CHIP_IS_E1H(bp)) - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { - DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; - } - - if (bp->state == BNX2X_STATE_OPEN) { -#ifdef BCM_CNIC - /* Enable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); -#endif - for_each_nondefault_queue(bp, i) { - rc = bnx2x_setup_multi(bp, i); - if (rc) -#ifdef BCM_CNIC - goto load_error4; -#else - goto load_error3; -#endif - } - - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); -#ifdef BCM_CNIC - /* Set iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, - CNIC_SB_ID(bp)); - } - mutex_unlock(&bp->cnic_mutex); -#endif - } - - if (bp->port.pmf) - bnx2x_initial_phy_init(bp, load_mode); - - /* Start fast path */ - switch (load_mode) { - case LOAD_NORMAL: - if (bp->state == BNX2X_STATE_OPEN) { - /* Tx queue should be only reenabled */ - netif_tx_wake_all_queues(bp->dev); - } - /* Initialize the receive filter. */ - bnx2x_set_rx_mode(bp->dev); - break; - - case LOAD_OPEN: - netif_tx_start_all_queues(bp->dev); - if (bp->state != BNX2X_STATE_OPEN) - netif_tx_disable(bp->dev); - /* Initialize the receive filter. */ - bnx2x_set_rx_mode(bp->dev); - break; - - case LOAD_DIAG: - /* Initialize the receive filter. */ - bnx2x_set_rx_mode(bp->dev); - bp->state = BNX2X_STATE_DIAG; - break; - - default: - break; - } - - if (!bp->port.pmf) - bnx2x__link_status_update(bp); - - /* start the timer */ - mod_timer(&bp->timer, jiffies + bp->current_interval); - -#ifdef BCM_CNIC - bnx2x_setup_cnic_irq_info(bp); - if (bp->state == BNX2X_STATE_OPEN) - bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); -#endif - bnx2x_inc_load_cnt(bp); - - return 0; - -#ifdef BCM_CNIC -load_error4: - /* Disable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 0); -#endif -load_error3: - bnx2x_int_disable_sync(bp, 1); - if (!BP_NOMCP(bp)) { - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); - } - bp->port.pmf = 0; - /* Free SKBs, SGEs, TPA pool and driver internals */ - bnx2x_free_skbs(bp); - for_each_queue(bp, i) - bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); -load_error2: - /* Release IRQs */ - bnx2x_free_irq(bp, false); -load_error1: - bnx2x_napi_disable(bp); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); - bnx2x_free_mem(bp); - - return rc; -} - -/* must be called with rtnl_lock */ -int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) -{ - int i; - - if (bp->state == BNX2X_STATE_CLOSED) { - /* Interface has been removed - nothing to recover */ - bp->recovery_state = BNX2X_RECOVERY_DONE; - bp->is_leader = 0; - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08); - smp_wmb(); - - return -EINVAL; - } - -#ifdef BCM_CNIC - bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); -#endif - bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; - - /* Set "drop all" */ - bp->rx_mode = BNX2X_RX_MODE_NONE; - bnx2x_set_storm_rx_mode(bp); - - /* Disable HW interrupts, NAPI and Tx */ - bnx2x_netif_stop(bp, 1); - netif_carrier_off(bp->dev); - - del_timer_sync(&bp->timer); - SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, - (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - - /* Release IRQs */ - bnx2x_free_irq(bp, false); - - /* Cleanup the chip if needed */ - if (unload_mode != UNLOAD_RECOVERY) - bnx2x_chip_cleanup(bp, unload_mode); - - bp->port.pmf = 0; - - /* Free SKBs, SGEs, TPA pool and driver internals */ - bnx2x_free_skbs(bp); - for_each_queue(bp, i) - bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); - bnx2x_free_mem(bp); - - bp->state = BNX2X_STATE_CLOSED; - - /* The last driver must disable a "close the gate" if there is no - * parity attention or "process kill" pending. - */ - if ((!bnx2x_dec_load_cnt(bp)) && (!bnx2x_chk_parity_attn(bp)) && - bnx2x_reset_is_done(bp)) - bnx2x_disable_close_the_gate(bp); - - /* Reset MCP mail box sequence if there is on going recovery */ - if (unload_mode == UNLOAD_RECOVERY) - bp->fw_seq = 0; - - return 0; -} -int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) -{ - u16 pmcsr; - - pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); - - switch (state) { - case PCI_D0: - pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, - ((pmcsr & ~PCI_PM_CTRL_STATE_MASK) | - PCI_PM_CTRL_PME_STATUS)); - - if (pmcsr & PCI_PM_CTRL_STATE_MASK) - /* delay required during transition out of D3hot */ - msleep(20); - break; - - case PCI_D3hot: - /* If there are other clients above don't - shut down the power */ - if (atomic_read(&bp->pdev->enable_cnt) != 1) - return 0; - /* Don't shut down the power for emulation and FPGA */ - if (CHIP_REV_IS_SLOW(bp)) - return 0; - - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= 3; - - if (bp->wol) - pmcsr |= PCI_PM_CTRL_PME_ENABLE; - - pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, - pmcsr); - - /* No more memory access after this point until - * device is brought back to D0. - */ - break; - - default: - return -EINVAL; - } - return 0; -} - - - -/* - * net_device service functions - */ - -static int bnx2x_poll(struct napi_struct *napi, int budget) -{ - int work_done = 0; - struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath, - napi); - struct bnx2x *bp = fp->bp; - - while (1) { -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) { - napi_complete(napi); - return 0; - } -#endif - - if (bnx2x_has_tx_work(fp)) - bnx2x_tx_int(fp); - - if (bnx2x_has_rx_work(fp)) { - work_done += bnx2x_rx_int(fp, budget - work_done); - - /* must not complete if we consumed full budget */ - if (work_done >= budget) - break; - } - - /* Fall out from the NAPI loop if needed */ - if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { - bnx2x_update_fpsb_idx(fp); - /* bnx2x_has_rx_work() reads the status block, thus we need - * to ensure that status block indices have been actually read - * (bnx2x_update_fpsb_idx) prior to this check - * (bnx2x_has_rx_work) so that we won't write the "newer" - * value of the status block to IGU (if there was a DMA right - * after bnx2x_has_rx_work and if there is no rmb, the memory - * reading (bnx2x_update_fpsb_idx) may be postponed to right - * before bnx2x_ack_sb). In this case there will never be - * another interrupt until there is another update of the - * status block, while there is still unhandled work. - */ - rmb(); - - if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { - napi_complete(napi); - /* Re-enable interrupts */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, - le16_to_cpu(fp->fp_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, - le16_to_cpu(fp->fp_u_idx), - IGU_INT_ENABLE, 1); - break; - } - } - } - - return work_done; -} - - -/* we split the first BD into headers and data BDs - * to ease the pain of our fellow microcode engineers - * we use one mapping for both BDs - * So far this has only been observed to happen - * in Other Operating Systems(TM) - */ -static noinline u16 bnx2x_tx_split(struct bnx2x *bp, - struct bnx2x_fastpath *fp, - struct sw_tx_bd *tx_buf, - struct eth_tx_start_bd **tx_bd, u16 hlen, - u16 bd_prod, int nbd) -{ - struct eth_tx_start_bd *h_tx_bd = *tx_bd; - struct eth_tx_bd *d_tx_bd; - dma_addr_t mapping; - int old_len = le16_to_cpu(h_tx_bd->nbytes); - - /* first fix first BD */ - h_tx_bd->nbd = cpu_to_le16(nbd); - h_tx_bd->nbytes = cpu_to_le16(hlen); - - DP(NETIF_MSG_TX_QUEUED, "TSO split header size is %d " - "(%x:%x) nbd %d\n", h_tx_bd->nbytes, h_tx_bd->addr_hi, - h_tx_bd->addr_lo, h_tx_bd->nbd); - - /* now get a new data BD - * (after the pbd) and fill it */ - bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - d_tx_bd = &fp->tx_desc_ring[bd_prod].reg_bd; - - mapping = HILO_U64(le32_to_cpu(h_tx_bd->addr_hi), - le32_to_cpu(h_tx_bd->addr_lo)) + hlen; - - d_tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); - d_tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - d_tx_bd->nbytes = cpu_to_le16(old_len - hlen); - - /* this marks the BD as one that has no individual mapping */ - tx_buf->flags |= BNX2X_TSO_SPLIT_BD; - - DP(NETIF_MSG_TX_QUEUED, - "TSO split data size is %d (%x:%x)\n", - d_tx_bd->nbytes, d_tx_bd->addr_hi, d_tx_bd->addr_lo); - - /* update tx_bd */ - *tx_bd = (struct eth_tx_start_bd *)d_tx_bd; - - return bd_prod; -} - -static inline u16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) -{ - if (fix > 0) - csum = (u16) ~csum_fold(csum_sub(csum, - csum_partial(t_header - fix, fix, 0))); - - else if (fix < 0) - csum = (u16) ~csum_fold(csum_add(csum, - csum_partial(t_header, -fix, 0))); - - return swab16(csum); -} - -static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) -{ - u32 rc; - - if (skb->ip_summed != CHECKSUM_PARTIAL) - rc = XMIT_PLAIN; - - else { - if (skb->protocol == htons(ETH_P_IPV6)) { - rc = XMIT_CSUM_V6; - if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) - rc |= XMIT_CSUM_TCP; - - } else { - rc = XMIT_CSUM_V4; - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - rc |= XMIT_CSUM_TCP; - } - } - - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) - rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP); - - else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) - rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6); - - return rc; -} - -#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) -/* check if packet requires linearization (packet is too fragmented) - no need to check fragmentation if page size > 8K (there will be no - violation to FW restrictions) */ -static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, - u32 xmit_type) -{ - int to_copy = 0; - int hlen = 0; - int first_bd_sz = 0; - - /* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */ - if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) { - - if (xmit_type & XMIT_GSO) { - unsigned short lso_mss = skb_shinfo(skb)->gso_size; - /* Check if LSO packet needs to be copied: - 3 = 1 (for headers BD) + 2 (for PBD and last BD) */ - int wnd_size = MAX_FETCH_BD - 3; - /* Number of windows to check */ - int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size; - int wnd_idx = 0; - int frag_idx = 0; - u32 wnd_sum = 0; - - /* Headers length */ - hlen = (int)(skb_transport_header(skb) - skb->data) + - tcp_hdrlen(skb); - - /* Amount of data (w/o headers) on linear part of SKB*/ - first_bd_sz = skb_headlen(skb) - hlen; - - wnd_sum = first_bd_sz; - - /* Calculate the first sum - it's special */ - for (frag_idx = 0; frag_idx < wnd_size - 1; frag_idx++) - wnd_sum += - skb_shinfo(skb)->frags[frag_idx].size; - - /* If there was data on linear skb data - check it */ - if (first_bd_sz > 0) { - if (unlikely(wnd_sum < lso_mss)) { - to_copy = 1; - goto exit_lbl; - } - - wnd_sum -= first_bd_sz; - } - - /* Others are easier: run through the frag list and - check all windows */ - for (wnd_idx = 0; wnd_idx <= num_wnds; wnd_idx++) { - wnd_sum += - skb_shinfo(skb)->frags[wnd_idx + wnd_size - 1].size; - - if (unlikely(wnd_sum < lso_mss)) { - to_copy = 1; - break; - } - wnd_sum -= - skb_shinfo(skb)->frags[wnd_idx].size; - } - } else { - /* in non-LSO too fragmented packet should always - be linearized */ - to_copy = 1; - } - } - -exit_lbl: - if (unlikely(to_copy)) - DP(NETIF_MSG_TX_QUEUED, - "Linearization IS REQUIRED for %s packet. " - "num_frags %d hlen %d first_bd_sz %d\n", - (xmit_type & XMIT_GSO) ? "LSO" : "non-LSO", - skb_shinfo(skb)->nr_frags, hlen, first_bd_sz); - - return to_copy; -} -#endif - -/* called with netif_tx_lock - * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call - * netif_wake_queue() - */ -netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - struct bnx2x_fastpath *fp; - struct netdev_queue *txq; - struct sw_tx_bd *tx_buf; - struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; - struct eth_tx_parse_bd *pbd = NULL; - u16 pkt_prod, bd_prod; - int nbd, fp_index; - dma_addr_t mapping; - u32 xmit_type = bnx2x_xmit_type(bp, skb); - int i; - u8 hlen = 0; - __le16 pkt_size = 0; - struct ethhdr *eth; - u8 mac_type = UNICAST_ADDRESS; - -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return NETDEV_TX_BUSY; -#endif - - fp_index = skb_get_queue_mapping(skb); - txq = netdev_get_tx_queue(dev, fp_index); - - fp = &bp->fp[fp_index]; - - if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) { - fp->eth_q_stats.driver_xoff++; - netif_tx_stop_queue(txq); - BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); - return NETDEV_TX_BUSY; - } - - DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)" - " gso type %x xmit_type %x\n", - skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, - ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); - - eth = (struct ethhdr *)skb->data; - - /* set flag according to packet type (UNICAST_ADDRESS is default)*/ - if (unlikely(is_multicast_ether_addr(eth->h_dest))) { - if (is_broadcast_ether_addr(eth->h_dest)) - mac_type = BROADCAST_ADDRESS; - else - mac_type = MULTICAST_ADDRESS; - } - -#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) - /* First, check if we need to linearize the skb (due to FW - restrictions). No need to check fragmentation if page size > 8K - (there will be no violation to FW restrictions) */ - if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) { - /* Statistics of linearization */ - bp->lin_cnt++; - if (skb_linearize(skb) != 0) { - DP(NETIF_MSG_TX_QUEUED, "SKB linearization failed - " - "silently dropping this SKB\n"); - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - } -#endif - - /* - Please read carefully. First we use one BD which we mark as start, - then we have a parsing info BD (used for TSO or xsum), - and only then we have the rest of the TSO BDs. - (don't forget to mark the last one as last, - and to unmap only AFTER you write to the BD ...) - And above all, all pdb sizes are in words - NOT DWORDS! - */ - - pkt_prod = fp->tx_pkt_prod++; - bd_prod = TX_BD(fp->tx_bd_prod); - - /* get a tx_buf and first BD */ - tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)]; - tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; - - tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = (mac_type << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT); - /* header nbd */ - tx_start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); - - /* remember the first BD of the packet */ - tx_buf->first_bd = fp->tx_bd_prod; - tx_buf->skb = skb; - tx_buf->flags = 0; - - DP(NETIF_MSG_TX_QUEUED, - "sending pkt %u @%p next_idx %u bd %u @%p\n", - pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); - -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && - (bp->flags & HW_VLAN_TX_FLAG)) { - tx_start_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; - } else -#endif - tx_start_bd->vlan = cpu_to_le16(pkt_prod); - - /* turn on parsing and get a BD */ - bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp->tx_desc_ring[bd_prod].parse_bd; - - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); - - if (xmit_type & XMIT_CSUM) { - hlen = (skb_network_header(skb) - skb->data) / 2; - - /* for now NS flag is not used in Linux */ - pbd->global_data = - (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << - ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); - - pbd->ip_hlen = (skb_transport_header(skb) - - skb_network_header(skb)) / 2; - - hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2; - - pbd->total_hlen = cpu_to_le16(hlen); - hlen = hlen*2; - - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; - - if (xmit_type & XMIT_CSUM_V4) - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IP_CSUM; - else - tx_start_bd->bd_flags.as_bitfield |= - ETH_TX_BD_FLAGS_IPV6; - - if (xmit_type & XMIT_CSUM_TCP) { - pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); - - } else { - s8 fix = SKB_CS_OFF(skb); /* signed! */ - - pbd->global_data |= ETH_TX_PARSE_BD_UDP_CS_FLG; - - DP(NETIF_MSG_TX_QUEUED, - "hlen %d fix %d csum before fix %x\n", - le16_to_cpu(pbd->total_hlen), fix, SKB_CS(skb)); - - /* HW bug: fixup the CSUM */ - pbd->tcp_pseudo_csum = - bnx2x_csum_fix(skb_transport_header(skb), - SKB_CS(skb), fix); - - DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", - pbd->tcp_pseudo_csum); - } - } - - mapping = dma_map_single(&bp->pdev->dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); - - tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); - tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */ - tx_start_bd->nbd = cpu_to_le16(nbd); - tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); - pkt_size = tx_start_bd->nbytes; - - DP(NETIF_MSG_TX_QUEUED, "first bd @%p addr (%x:%x) nbd %d" - " nbytes %d flags %x vlan %x\n", - tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo, - le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes), - tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan)); - - if (xmit_type & XMIT_GSO) { - - DP(NETIF_MSG_TX_QUEUED, - "TSO packet len %d hlen %d total len %d tso size %d\n", - skb->len, hlen, skb_headlen(skb), - skb_shinfo(skb)->gso_size); - - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO; - - if (unlikely(skb_headlen(skb) > hlen)) - bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, - hlen, bd_prod, ++nbd); - - pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); - pbd->tcp_flags = pbd_tcp_flags(skb); - - if (xmit_type & XMIT_GSO_V4) { - pbd->ip_id = swab16(ip_hdr(skb)->id); - pbd->tcp_pseudo_csum = - swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, - ip_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - } else - pbd->tcp_pseudo_csum = - swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN; - } - tx_data_bd = (struct eth_tx_bd *)tx_start_bd; - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - tx_data_bd = &fp->tx_desc_ring[bd_prod].reg_bd; - if (total_pkt_bd == NULL) - total_pkt_bd = &fp->tx_desc_ring[bd_prod].reg_bd; - - mapping = dma_map_page(&bp->pdev->dev, frag->page, - frag->page_offset, - frag->size, DMA_TO_DEVICE); - - tx_data_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); - tx_data_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - tx_data_bd->nbytes = cpu_to_le16(frag->size); - le16_add_cpu(&pkt_size, frag->size); - - DP(NETIF_MSG_TX_QUEUED, - "frag %d bd @%p addr (%x:%x) nbytes %d\n", - i, tx_data_bd, tx_data_bd->addr_hi, tx_data_bd->addr_lo, - le16_to_cpu(tx_data_bd->nbytes)); - } - - DP(NETIF_MSG_TX_QUEUED, "last bd @%p\n", tx_data_bd); - - bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - - /* now send a tx doorbell, counting the next BD - * if the packet contains or ends with it - */ - if (TX_BD_POFF(bd_prod) < nbd) - nbd++; - - if (total_pkt_bd != NULL) - total_pkt_bd->total_pkt_bytes = pkt_size; - - if (pbd) - DP(NETIF_MSG_TX_QUEUED, - "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" - " tcp_flags %x xsum %x seq %u hlen %u\n", - pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id, - pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum, - pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen)); - - DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); - - /* - * Make sure that the BD data is updated before updating the producer - * since FW might read the BD right after the producer is updated. - * This is only applicable for weak-ordered memory model archs such - * as IA-64. The following barrier is also mandatory since FW will - * assumes packets must have BDs. - */ - wmb(); - - fp->tx_db.data.prod += nbd; - barrier(); - DOORBELL(bp, fp->index, fp->tx_db.raw); - - mmiowb(); - - fp->tx_bd_prod += nbd; - - if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { - netif_tx_stop_queue(txq); - - /* paired memory barrier is in bnx2x_tx_int(), we have to keep - * ordering of set_bit() in netif_tx_stop_queue() and read of - * fp->bd_tx_cons */ - smp_mb(); - - fp->eth_q_stats.driver_xoff++; - if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) - netif_tx_wake_queue(txq); - } - fp->tx_pkt++; - - return NETDEV_TX_OK; -} -/* called with rtnl_lock */ -int bnx2x_change_mac_addr(struct net_device *dev, void *p) -{ - struct sockaddr *addr = p; - struct bnx2x *bp = netdev_priv(dev); - - if (!is_valid_ether_addr((u8 *)(addr->sa_data))) - return -EINVAL; - - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - if (netif_running(dev)) { - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); - } - - return 0; -} - -/* called with rtnl_lock */ -int bnx2x_change_mtu(struct net_device *dev, int new_mtu) -{ - struct bnx2x *bp = netdev_priv(dev); - int rc = 0; - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - return -EAGAIN; - } - - if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) || - ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE)) - return -EINVAL; - - /* This does not race with packet allocation - * because the actual alloc size is - * only updated as part of load - */ - dev->mtu = new_mtu; - - if (netif_running(dev)) { - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - rc = bnx2x_nic_load(bp, LOAD_NORMAL); - } - - return rc; -} - -void bnx2x_tx_timeout(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - -#ifdef BNX2X_STOP_ON_ERROR - if (!bp->panic) - bnx2x_panic(); -#endif - /* This allows the netif to be shutdown gracefully before resetting */ - schedule_delayed_work(&bp->reset_task, 0); -} - -#ifdef BCM_VLAN -/* called with rtnl_lock */ -void bnx2x_vlan_rx_register(struct net_device *dev, - struct vlan_group *vlgrp) -{ - struct bnx2x *bp = netdev_priv(dev); - - bp->vlgrp = vlgrp; - - /* Set flags according to the required capabilities */ - bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); - - if (dev->features & NETIF_F_HW_VLAN_TX) - bp->flags |= HW_VLAN_TX_FLAG; - - if (dev->features & NETIF_F_HW_VLAN_RX) - bp->flags |= HW_VLAN_RX_FLAG; - - if (netif_running(dev)) - bnx2x_set_client_config(bp); -} - -#endif -int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp; - - if (!dev) { - dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n"); - return -ENODEV; - } - bp = netdev_priv(dev); - - rtnl_lock(); - - pci_save_state(pdev); - - if (!netif_running(dev)) { - rtnl_unlock(); - return 0; - } - - netif_device_detach(dev); - - bnx2x_nic_unload(bp, UNLOAD_CLOSE); - - bnx2x_set_power_state(bp, pci_choose_state(pdev, state)); - - rtnl_unlock(); - - return 0; -} - -int bnx2x_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct bnx2x *bp; - int rc; - - if (!dev) { - dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n"); - return -ENODEV; - } - bp = netdev_priv(dev); - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - return -EAGAIN; - } - - rtnl_lock(); - - pci_restore_state(pdev); - - if (!netif_running(dev)) { - rtnl_unlock(); - return 0; - } - - bnx2x_set_power_state(bp, PCI_D0); - netif_device_attach(dev); - - rc = bnx2x_nic_load(bp, LOAD_OPEN); - - rtnl_unlock(); - - return rc; -} diff --git a/trunk/drivers/net/bnx2x/bnx2x_cmn.h b/trunk/drivers/net/bnx2x/bnx2x_cmn.h deleted file mode 100644 index d1979b1a7ed2..000000000000 --- a/trunk/drivers/net/bnx2x/bnx2x_cmn.h +++ /dev/null @@ -1,652 +0,0 @@ -/* bnx2x_cmn.h: Broadcom Everest network driver. - * - * Copyright (c) 2007-2010 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation. - * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir - * Based on code from Michael Chan's bnx2 driver - * UDP CSUM errata workaround by Arik Gendelman - * Slowpath and fastpath rework by Vladislav Zolotarov - * Statistics and Link management by Yitchak Gertner - * - */ -#ifndef BNX2X_CMN_H -#define BNX2X_CMN_H - -#include -#include - - -#include "bnx2x.h" - - -/*********************** Interfaces **************************** - * Functions that need to be implemented by each driver version - */ - -/** - * Initialize link parameters structure variables. - * - * @param bp - * @param load_mode - * - * @return u8 - */ -u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode); - -/** - * Configure hw according to link parameters structure. - * - * @param bp - */ -void bnx2x_link_set(struct bnx2x *bp); - -/** - * Query link status - * - * @param bp - * - * @return 0 - link is UP - */ -u8 bnx2x_link_test(struct bnx2x *bp); - -/** - * Handles link status change - * - * @param bp - */ -void bnx2x__link_status_update(struct bnx2x *bp); - -/** - * MSI-X slowpath interrupt handler - * - * @param irq - * @param dev_instance - * - * @return irqreturn_t - */ -irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance); - -/** - * non MSI-X interrupt handler - * - * @param irq - * @param dev_instance - * - * @return irqreturn_t - */ -irqreturn_t bnx2x_interrupt(int irq, void *dev_instance); -#ifdef BCM_CNIC - -/** - * Send command to cnic driver - * - * @param bp - * @param cmd - */ -int bnx2x_cnic_notify(struct bnx2x *bp, int cmd); - -/** - * Provides cnic information for proper interrupt handling - * - * @param bp - */ -void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); -#endif - -/** - * Enable HW interrupts. - * - * @param bp - */ -void bnx2x_int_enable(struct bnx2x *bp); - -/** - * Disable interrupts. This function ensures that there are no - * ISRs or SP DPCs (sp_task) are running after it returns. - * - * @param bp - * @param disable_hw if true, disable HW interrupts. - */ -void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); - -/** - * Init HW blocks according to current initialization stage: - * COMMON, PORT or FUNCTION. - * - * @param bp - * @param load_code: COMMON, PORT or FUNCTION - * - * @return int - */ -int bnx2x_init_hw(struct bnx2x *bp, u32 load_code); - -/** - * Init driver internals: - * - rings - * - status blocks - * - etc. - * - * @param bp - * @param load_code COMMON, PORT or FUNCTION - */ -void bnx2x_nic_init(struct bnx2x *bp, u32 load_code); - -/** - * Allocate driver's memory. - * - * @param bp - * - * @return int - */ -int bnx2x_alloc_mem(struct bnx2x *bp); - -/** - * Release driver's memory. - * - * @param bp - */ -void bnx2x_free_mem(struct bnx2x *bp); - -/** - * Bring up a leading (the first) eth Client. - * - * @param bp - * - * @return int - */ -int bnx2x_setup_leading(struct bnx2x *bp); - -/** - * Setup non-leading eth Client. - * - * @param bp - * @param fp - * - * @return int - */ -int bnx2x_setup_multi(struct bnx2x *bp, int index); - -/** - * Set number of quueus according to mode and number of available - * msi-x vectors - * - * @param bp - * - */ -void bnx2x_set_num_queues_msix(struct bnx2x *bp); - -/** - * Cleanup chip internals: - * - Cleanup MAC configuration. - * - Close clients. - * - etc. - * - * @param bp - * @param unload_mode - */ -void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode); - -/** - * Acquire HW lock. - * - * @param bp - * @param resource Resource bit which was locked - * - * @return int - */ -int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource); - -/** - * Release HW lock. - * - * @param bp driver handle - * @param resource Resource bit which was locked - * - * @return int - */ -int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); - -/** - * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57711 - * - * @param bp driver handle - * @param set - */ -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set); - -/** - * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57710 - * - * @param bp driver handle - * @param set - */ -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set); - -#ifdef BCM_CNIC -/** - * Set iSCSI MAC(s) at the next enties in the CAM after the ETH - * MAC(s). The function will wait until the ramrod completion - * returns. - * - * @param bp driver handle - * @param set set or clear the CAM entry - * - * @return 0 if cussess, -ENODEV if ramrod doesn't return. - */ -int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set); -#endif - -/** - * Initialize status block in FW and HW - * - * @param bp driver handle - * @param sb host_status_block - * @param dma_addr_t mapping - * @param int sb_id - */ -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id); - -/** - * Reconfigure FW/HW according to dev->flags rx mode - * - * @param dev net_device - * - */ -void bnx2x_set_rx_mode(struct net_device *dev); - -/** - * Configure MAC filtering rules in a FW. - * - * @param bp driver handle - */ -void bnx2x_set_storm_rx_mode(struct bnx2x *bp); - -/* Parity errors related */ -void bnx2x_inc_load_cnt(struct bnx2x *bp); -u32 bnx2x_dec_load_cnt(struct bnx2x *bp); -bool bnx2x_chk_parity_attn(struct bnx2x *bp); -bool bnx2x_reset_is_done(struct bnx2x *bp); -void bnx2x_disable_close_the_gate(struct bnx2x *bp); - -/** - * Perform statistics handling according to event - * - * @param bp driver handle - * @param even tbnx2x_stats_event - */ -void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); - -/** - * Configures FW with client paramteres (like HW VLAN removal) - * for each active client. - * - * @param bp - */ -void bnx2x_set_client_config(struct bnx2x *bp); - -/** - * Handle sp events - * - * @param fp fastpath handle for the event - * @param rr_cqe eth_rx_cqe - */ -void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); - - -static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) -{ - struct host_status_block *fpsb = fp->status_blk; - - barrier(); /* status block is written to by the chip */ - fp->fp_c_idx = fpsb->c_status_block.status_block_index; - fp->fp_u_idx = fpsb->u_status_block.status_block_index; -} - -static inline void bnx2x_update_rx_prod(struct bnx2x *bp, - struct bnx2x_fastpath *fp, - u16 bd_prod, u16 rx_comp_prod, - u16 rx_sge_prod) -{ - struct ustorm_eth_rx_producers rx_prods = {0}; - int i; - - /* Update producers */ - rx_prods.bd_prod = bd_prod; - rx_prods.cqe_prod = rx_comp_prod; - rx_prods.sge_prod = rx_sge_prod; - - /* - * Make sure that the BD and SGE data is updated before updating the - * producers since FW might read the BD/SGE right after the producer - * is updated. - * This is only applicable for weak-ordered memory model archs such - * as IA-64. The following barrier is also mandatory since FW will - * assumes BDs must have buffers. - */ - wmb(); - - for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4, - ((u32 *)&rx_prods)[i]); - - mmiowb(); /* keep prod updates ordered */ - - DP(NETIF_MSG_RX_STATUS, - "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n", - fp->index, bd_prod, rx_comp_prod, rx_sge_prod); -} - - - -static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, - u8 storm, u16 index, u8 op, u8 update) -{ - u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + - COMMAND_REG_INT_ACK); - struct igu_ack_register igu_ack; - - igu_ack.status_block_index = index; - igu_ack.sb_id_and_flags = - ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) | - (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) | - (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) | - (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT)); - - DP(BNX2X_MSG_OFF, "write 0x%08x to HC addr 0x%x\n", - (*(u32 *)&igu_ack), hc_addr); - REG_WR(bp, hc_addr, (*(u32 *)&igu_ack)); - - /* Make sure that ACK is written */ - mmiowb(); - barrier(); -} -static inline u16 bnx2x_ack_int(struct bnx2x *bp) -{ - u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + - COMMAND_REG_SIMD_MASK); - u32 result = REG_RD(bp, hc_addr); - - DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n", - result, hc_addr); - - return result; -} - -/* - * fast path service functions - */ - -static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) -{ - /* Tell compiler that consumer and producer can change */ - barrier(); - return (fp->tx_pkt_prod != fp->tx_pkt_cons); -} - -static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) -{ - s16 used; - u16 prod; - u16 cons; - - prod = fp->tx_bd_prod; - cons = fp->tx_bd_cons; - - /* NUM_TX_RINGS = number of "next-page" entries - It will be used as a threshold */ - used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; - -#ifdef BNX2X_STOP_ON_ERROR - WARN_ON(used < 0); - WARN_ON(used > fp->bp->tx_ring_size); - WARN_ON((fp->bp->tx_ring_size - used) > MAX_TX_AVAIL); -#endif - - return (s16)(fp->bp->tx_ring_size) - used; -} - -static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) -{ - u16 hw_cons; - - /* Tell compiler that status block fields can change */ - barrier(); - hw_cons = le16_to_cpu(*fp->tx_cons_sb); - return hw_cons != fp->tx_pkt_cons; -} - -static inline void bnx2x_free_rx_sge(struct bnx2x *bp, - struct bnx2x_fastpath *fp, u16 index) -{ - struct sw_rx_page *sw_buf = &fp->rx_page_ring[index]; - struct page *page = sw_buf->page; - struct eth_rx_sge *sge = &fp->rx_sge_ring[index]; - - /* Skip "next page" elements */ - if (!page) - return; - - dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping), - SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); - __free_pages(page, PAGES_PER_SGE_SHIFT); - - sw_buf->page = NULL; - sge->addr_hi = 0; - sge->addr_lo = 0; -} - -static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, - struct bnx2x_fastpath *fp, int last) -{ - int i; - - for (i = 0; i < last; i++) - bnx2x_free_rx_sge(bp, fp, i); -} - -static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, - struct bnx2x_fastpath *fp, u16 index) -{ - struct page *page = alloc_pages(GFP_ATOMIC, PAGES_PER_SGE_SHIFT); - struct sw_rx_page *sw_buf = &fp->rx_page_ring[index]; - struct eth_rx_sge *sge = &fp->rx_sge_ring[index]; - dma_addr_t mapping; - - if (unlikely(page == NULL)) - return -ENOMEM; - - mapping = dma_map_page(&bp->pdev->dev, page, 0, - SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { - __free_pages(page, PAGES_PER_SGE_SHIFT); - return -ENOMEM; - } - - sw_buf->page = page; - dma_unmap_addr_set(sw_buf, mapping, mapping); - - sge->addr_hi = cpu_to_le32(U64_HI(mapping)); - sge->addr_lo = cpu_to_le32(U64_LO(mapping)); - - return 0; -} -static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, - struct bnx2x_fastpath *fp, u16 index) -{ - struct sk_buff *skb; - struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index]; - struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; - dma_addr_t mapping; - - skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); - if (unlikely(skb == NULL)) - return -ENOMEM; - - mapping = dma_map_single(&bp->pdev->dev, skb->data, bp->rx_buf_size, - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { - dev_kfree_skb(skb); - return -ENOMEM; - } - - rx_buf->skb = skb; - dma_unmap_addr_set(rx_buf, mapping, mapping); - - rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); - rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - - return 0; -} - -/* note that we are not allocating a new skb, - * we are just moving one from cons to prod - * we are not creating a new mapping, - * so there is no need to check for dma_mapping_error(). - */ -static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, - struct sk_buff *skb, u16 cons, u16 prod) -{ - struct bnx2x *bp = fp->bp; - struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; - struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; - struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons]; - struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; - - dma_sync_single_for_device(&bp->pdev->dev, - dma_unmap_addr(cons_rx_buf, mapping), - RX_COPY_THRESH, DMA_FROM_DEVICE); - - prod_rx_buf->skb = cons_rx_buf->skb; - dma_unmap_addr_set(prod_rx_buf, mapping, - dma_unmap_addr(cons_rx_buf, mapping)); - *prod_bd = *cons_bd; -} - -static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) -{ - int i, j; - - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - int idx = RX_SGE_CNT * i - 1; - - for (j = 0; j < 2; j++) { - SGE_MASK_CLEAR_BIT(fp, idx); - idx--; - } - } -} - -static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) -{ - /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ - memset(fp->sge_mask, 0xff, - (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); - - /* Clear the two last indices in the page to 1: - these are the indices that correspond to the "next" element, - hence will never be indicated and should be removed from - the calculations. */ - bnx2x_clear_sge_mask_next_elems(fp); -} -static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, - struct bnx2x_fastpath *fp, int last) -{ - int i; - - for (i = 0; i < last; i++) { - struct sw_rx_bd *rx_buf = &(fp->tpa_pool[i]); - struct sk_buff *skb = rx_buf->skb; - - if (skb == NULL) { - DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i); - continue; - } - - if (fp->tpa_state[i] == BNX2X_TPA_START) - dma_unmap_single(&bp->pdev->dev, - dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, DMA_FROM_DEVICE); - - dev_kfree_skb(skb); - rx_buf->skb = NULL; - } -} - - -static inline void bnx2x_init_tx_ring(struct bnx2x *bp) -{ - int i, j; - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; - - for (i = 1; i <= NUM_TX_RINGS; i++) { - struct eth_tx_next_bd *tx_next_bd = - &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd; - - tx_next_bd->addr_hi = - cpu_to_le32(U64_HI(fp->tx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); - tx_next_bd->addr_lo = - cpu_to_le32(U64_LO(fp->tx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); - } - - fp->tx_db.data.header.header = DOORBELL_HDR_DB_TYPE; - fp->tx_db.data.zero_fill1 = 0; - fp->tx_db.data.prod = 0; - - fp->tx_pkt_prod = 0; - fp->tx_pkt_cons = 0; - fp->tx_bd_prod = 0; - fp->tx_bd_cons = 0; - fp->tx_cons_sb = BNX2X_TX_SB_INDEX; - fp->tx_pkt = 0; - } -} -static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) -{ - u16 rx_cons_sb; - - /* Tell compiler that status block fields can change */ - barrier(); - rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); - if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) - rx_cons_sb++; - return (fp->rx_comp_cons != rx_cons_sb); -} - -/* HW Lock for shared dual port PHYs */ -void bnx2x_acquire_phy_lock(struct bnx2x *bp); -void bnx2x_release_phy_lock(struct bnx2x *bp); - -void bnx2x_link_report(struct bnx2x *bp); -int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); -int bnx2x_tx_int(struct bnx2x_fastpath *fp); -void bnx2x_init_rx_rings(struct bnx2x *bp); -netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); - -int bnx2x_change_mac_addr(struct net_device *dev, void *p); -void bnx2x_tx_timeout(struct net_device *dev); -void bnx2x_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp); -void bnx2x_netif_start(struct bnx2x *bp); -void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only); -int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); -int bnx2x_resume(struct pci_dev *pdev); -void bnx2x_free_skbs(struct bnx2x *bp); -int bnx2x_change_mtu(struct net_device *dev, int new_mtu); -int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); -int bnx2x_nic_load(struct bnx2x *bp, int load_mode); -int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); - -#endif /* BNX2X_CMN_H */ diff --git a/trunk/drivers/net/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/bnx2x/bnx2x_ethtool.c deleted file mode 100644 index 8b75b05e34c5..000000000000 --- a/trunk/drivers/net/bnx2x/bnx2x_ethtool.c +++ /dev/null @@ -1,1971 +0,0 @@ -/* bnx2x_ethtool.c: Broadcom Everest network driver. - * - * Copyright (c) 2007-2010 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation. - * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir - * Based on code from Michael Chan's bnx2 driver - * UDP CSUM errata workaround by Arik Gendelman - * Slowpath and fastpath rework by Vladislav Zolotarov - * Statistics and Link management by Yitchak Gertner - * - */ -#include -#include -#include -#include -#include - - -#include "bnx2x.h" -#include "bnx2x_cmn.h" -#include "bnx2x_dump.h" - - -static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct bnx2x *bp = netdev_priv(dev); - - cmd->supported = bp->port.supported; - cmd->advertising = bp->port.advertising; - - if ((bp->state == BNX2X_STATE_OPEN) && - !(bp->flags & MF_FUNC_DIS) && - (bp->link_vars.link_up)) { - cmd->speed = bp->link_vars.line_speed; - cmd->duplex = bp->link_vars.duplex; - if (IS_E1HMF(bp)) { - u16 vn_max_rate; - - vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; - if (vn_max_rate < cmd->speed) - cmd->speed = vn_max_rate; - } - } else { - cmd->speed = -1; - cmd->duplex = -1; - } - - if (bp->link_params.switch_cfg == SWITCH_CFG_10G) { - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - cmd->port = PORT_FIBRE; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - cmd->port = PORT_TP; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", - bp->link_params.ext_phy_config); - break; - - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); - break; - } - } else - cmd->port = PORT_TP; - - cmd->phy_address = bp->mdio.prtad; - cmd->transceiver = XCVR_INTERNAL; - - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) - cmd->autoneg = AUTONEG_ENABLE; - else - cmd->autoneg = AUTONEG_DISABLE; - - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; - - DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" - DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" - DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" - DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", - cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, - cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, - cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); - - return 0; -} - -static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct bnx2x *bp = netdev_priv(dev); - u32 advertising; - - if (IS_E1HMF(bp)) - return 0; - - DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" - DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" - DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" - DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", - cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, - cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, - cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); - - if (cmd->autoneg == AUTONEG_ENABLE) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { - DP(NETIF_MSG_LINK, "Autoneg not supported\n"); - return -EINVAL; - } - - /* advertise the requested speed and duplex if supported */ - cmd->advertising &= bp->port.supported; - - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->link_params.req_duplex = DUPLEX_FULL; - bp->port.advertising |= (ADVERTISED_Autoneg | - cmd->advertising); - - } else { /* forced speed */ - /* advertise the requested speed and duplex if supported */ - switch (cmd->speed) { - case SPEED_10: - if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & - SUPPORTED_10baseT_Full)) { - DP(NETIF_MSG_LINK, - "10M full not supported\n"); - return -EINVAL; - } - - advertising = (ADVERTISED_10baseT_Full | - ADVERTISED_TP); - } else { - if (!(bp->port.supported & - SUPPORTED_10baseT_Half)) { - DP(NETIF_MSG_LINK, - "10M half not supported\n"); - return -EINVAL; - } - - advertising = (ADVERTISED_10baseT_Half | - ADVERTISED_TP); - } - break; - - case SPEED_100: - if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & - SUPPORTED_100baseT_Full)) { - DP(NETIF_MSG_LINK, - "100M full not supported\n"); - return -EINVAL; - } - - advertising = (ADVERTISED_100baseT_Full | - ADVERTISED_TP); - } else { - if (!(bp->port.supported & - SUPPORTED_100baseT_Half)) { - DP(NETIF_MSG_LINK, - "100M half not supported\n"); - return -EINVAL; - } - - advertising = (ADVERTISED_100baseT_Half | - ADVERTISED_TP); - } - break; - - case SPEED_1000: - if (cmd->duplex != DUPLEX_FULL) { - DP(NETIF_MSG_LINK, "1G half not supported\n"); - return -EINVAL; - } - - if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) { - DP(NETIF_MSG_LINK, "1G full not supported\n"); - return -EINVAL; - } - - advertising = (ADVERTISED_1000baseT_Full | - ADVERTISED_TP); - break; - - case SPEED_2500: - if (cmd->duplex != DUPLEX_FULL) { - DP(NETIF_MSG_LINK, - "2.5G half not supported\n"); - return -EINVAL; - } - - if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) { - DP(NETIF_MSG_LINK, - "2.5G full not supported\n"); - return -EINVAL; - } - - advertising = (ADVERTISED_2500baseX_Full | - ADVERTISED_TP); - break; - - case SPEED_10000: - if (cmd->duplex != DUPLEX_FULL) { - DP(NETIF_MSG_LINK, "10G half not supported\n"); - return -EINVAL; - } - - if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) { - DP(NETIF_MSG_LINK, "10G full not supported\n"); - return -EINVAL; - } - - advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - break; - - default: - DP(NETIF_MSG_LINK, "Unsupported speed\n"); - return -EINVAL; - } - - bp->link_params.req_line_speed = cmd->speed; - bp->link_params.req_duplex = cmd->duplex; - bp->port.advertising = advertising; - } - - DP(NETIF_MSG_LINK, "req_line_speed %d\n" - DP_LEVEL " req_duplex %d advertising 0x%x\n", - bp->link_params.req_line_speed, bp->link_params.req_duplex, - bp->port.advertising); - - if (netif_running(dev)) { - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_link_set(bp); - } - - return 0; -} - -#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) -#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) - -static int bnx2x_get_regs_len(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - int regdump_len = 0; - int i; - - if (CHIP_IS_E1(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E1; i++) - if (IS_E1_ONLINE(wreg_addrs_e1[i].info)) - regdump_len += wreg_addrs_e1[i].size * - (1 + wreg_addrs_e1[i].read_regs_count); - - } else { /* E1H */ - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1H_ONLINE(reg_addrs[i].info)) - regdump_len += reg_addrs[i].size; - - for (i = 0; i < WREGS_COUNT_E1H; i++) - if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) - regdump_len += wreg_addrs_e1h[i].size * - (1 + wreg_addrs_e1h[i].read_regs_count); - } - regdump_len *= 4; - regdump_len += sizeof(struct dump_hdr); - - return regdump_len; -} - -static void bnx2x_get_regs(struct net_device *dev, - struct ethtool_regs *regs, void *_p) -{ - u32 *p = _p, i, j; - struct bnx2x *bp = netdev_priv(dev); - struct dump_hdr dump_hdr = {0}; - - regs->version = 0; - memset(p, 0, regs->len); - - if (!netif_running(bp->dev)) - return; - - dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1; - dump_hdr.dump_sign = dump_sign_all; - dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR); - dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR); - dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR); - dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR); - dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE; - - memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); - p += dump_hdr.hdr_size + 1; - - if (CHIP_IS_E1(bp)) { - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - - } else { /* E1H */ - for (i = 0; i < REGS_COUNT; i++) - if (IS_E1H_ONLINE(reg_addrs[i].info)) - for (j = 0; j < reg_addrs[i].size; j++) - *p++ = REG_RD(bp, - reg_addrs[i].addr + j*4); - } -} - -#define PHY_FW_VER_LEN 10 - -static void bnx2x_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct bnx2x *bp = netdev_priv(dev); - u8 phy_fw_ver[PHY_FW_VER_LEN]; - - strcpy(info->driver, DRV_MODULE_NAME); - strcpy(info->version, DRV_MODULE_VERSION); - - phy_fw_ver[0] = '\0'; - if (bp->port.pmf) { - bnx2x_acquire_phy_lock(bp); - bnx2x_get_ext_phy_fw_version(&bp->link_params, - (bp->state != BNX2X_STATE_CLOSED), - phy_fw_ver, PHY_FW_VER_LEN); - bnx2x_release_phy_lock(bp); - } - - strncpy(info->fw_version, bp->fw_ver, 32); - snprintf(info->fw_version + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver), - "bc %d.%d.%d%s%s", - (bp->common.bc_ver & 0xff0000) >> 16, - (bp->common.bc_ver & 0xff00) >> 8, - (bp->common.bc_ver & 0xff), - ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver); - strcpy(info->bus_info, pci_name(bp->pdev)); - info->n_stats = BNX2X_NUM_STATS; - info->testinfo_len = BNX2X_NUM_TESTS; - info->eedump_len = bp->common.flash_size; - info->regdump_len = bnx2x_get_regs_len(dev); -} - -static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct bnx2x *bp = netdev_priv(dev); - - if (bp->flags & NO_WOL_FLAG) { - wol->supported = 0; - wol->wolopts = 0; - } else { - wol->supported = WAKE_MAGIC; - if (bp->wol) - wol->wolopts = WAKE_MAGIC; - else - wol->wolopts = 0; - } - memset(&wol->sopass, 0, sizeof(wol->sopass)); -} - -static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct bnx2x *bp = netdev_priv(dev); - - if (wol->wolopts & ~WAKE_MAGIC) - return -EINVAL; - - if (wol->wolopts & WAKE_MAGIC) { - if (bp->flags & NO_WOL_FLAG) - return -EINVAL; - - bp->wol = 1; - } else - bp->wol = 0; - - return 0; -} - -static u32 bnx2x_get_msglevel(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - return bp->msg_enable; -} - -static void bnx2x_set_msglevel(struct net_device *dev, u32 level) -{ - struct bnx2x *bp = netdev_priv(dev); - - if (capable(CAP_NET_ADMIN)) - bp->msg_enable = level; -} - -static int bnx2x_nway_reset(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - if (!bp->port.pmf) - return 0; - - if (netif_running(dev)) { - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_link_set(bp); - } - - return 0; -} - -static u32 bnx2x_get_link(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - if (bp->flags & MF_FUNC_DIS) - return 0; - - return bp->link_vars.link_up; -} - -static int bnx2x_get_eeprom_len(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - return bp->common.flash_size; -} - -static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - int count, i; - u32 val = 0; - - /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; - if (CHIP_REV_IS_SLOW(bp)) - count *= 100; - - /* request access to nvram interface */ - REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB, - (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port)); - - for (i = 0; i < count*10; i++) { - val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB); - if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) - break; - - udelay(5); - } - - if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) { - DP(BNX2X_MSG_NVM, "cannot get access to nvram interface\n"); - return -EBUSY; - } - - return 0; -} - -static int bnx2x_release_nvram_lock(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - int count, i; - u32 val = 0; - - /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; - if (CHIP_REV_IS_SLOW(bp)) - count *= 100; - - /* relinquish nvram interface */ - REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB, - (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port)); - - for (i = 0; i < count*10; i++) { - val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB); - if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) - break; - - udelay(5); - } - - if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) { - DP(BNX2X_MSG_NVM, "cannot free access to nvram interface\n"); - return -EBUSY; - } - - return 0; -} - -static void bnx2x_enable_nvram_access(struct bnx2x *bp) -{ - u32 val; - - val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE); - - /* enable both bits, even on read */ - REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE, - (val | MCPR_NVM_ACCESS_ENABLE_EN | - MCPR_NVM_ACCESS_ENABLE_WR_EN)); -} - -static void bnx2x_disable_nvram_access(struct bnx2x *bp) -{ - u32 val; - - val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE); - - /* disable both bits, even after read */ - REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE, - (val & ~(MCPR_NVM_ACCESS_ENABLE_EN | - MCPR_NVM_ACCESS_ENABLE_WR_EN))); -} - -static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val, - u32 cmd_flags) -{ - int count, i, rc; - u32 val; - - /* build the command word */ - cmd_flags |= MCPR_NVM_COMMAND_DOIT; - - /* need to clear DONE bit separately */ - REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE); - - /* address of the NVRAM to read from */ - REG_WR(bp, MCP_REG_MCPR_NVM_ADDR, - (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE)); - - /* issue a read command */ - REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); - - /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; - if (CHIP_REV_IS_SLOW(bp)) - count *= 100; - - /* wait for completion */ - *ret_val = 0; - rc = -EBUSY; - for (i = 0; i < count; i++) { - udelay(5); - val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND); - - if (val & MCPR_NVM_COMMAND_DONE) { - val = REG_RD(bp, MCP_REG_MCPR_NVM_READ); - /* we read nvram data in cpu order - * but ethtool sees it as an array of bytes - * converting to big-endian will do the work */ - *ret_val = cpu_to_be32(val); - rc = 0; - break; - } - } - - return rc; -} - -static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf, - int buf_size) -{ - int rc; - u32 cmd_flags; - __be32 val; - - if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { - DP(BNX2X_MSG_NVM, - "Invalid parameter: offset 0x%x buf_size 0x%x\n", - offset, buf_size); - return -EINVAL; - } - - if (offset + buf_size > bp->common.flash_size) { - DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +" - " buf_size (0x%x) > flash_size (0x%x)\n", - offset, buf_size, bp->common.flash_size); - return -EINVAL; - } - - /* request access to nvram interface */ - rc = bnx2x_acquire_nvram_lock(bp); - if (rc) - return rc; - - /* enable access to nvram interface */ - bnx2x_enable_nvram_access(bp); - - /* read the first word(s) */ - cmd_flags = MCPR_NVM_COMMAND_FIRST; - while ((buf_size > sizeof(u32)) && (rc == 0)) { - rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags); - memcpy(ret_buf, &val, 4); - - /* advance to the next dword */ - offset += sizeof(u32); - ret_buf += sizeof(u32); - buf_size -= sizeof(u32); - cmd_flags = 0; - } - - if (rc == 0) { - cmd_flags |= MCPR_NVM_COMMAND_LAST; - rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags); - memcpy(ret_buf, &val, 4); - } - - /* disable access to nvram interface */ - bnx2x_disable_nvram_access(bp); - bnx2x_release_nvram_lock(bp); - - return rc; -} - -static int bnx2x_get_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *eebuf) -{ - struct bnx2x *bp = netdev_priv(dev); - int rc; - - if (!netif_running(dev)) - return -EAGAIN; - - DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n" - DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", - eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, - eeprom->len, eeprom->len); - - /* parameters already validated in ethtool_get_eeprom */ - - rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); - - return rc; -} - -static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, - u32 cmd_flags) -{ - int count, i, rc; - - /* build the command word */ - cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR; - - /* need to clear DONE bit separately */ - REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE); - - /* write the data */ - REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val); - - /* address of the NVRAM to write to */ - REG_WR(bp, MCP_REG_MCPR_NVM_ADDR, - (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE)); - - /* issue the write command */ - REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); - - /* adjust timeout for emulation/FPGA */ - count = NVRAM_TIMEOUT_COUNT; - if (CHIP_REV_IS_SLOW(bp)) - count *= 100; - - /* wait for completion */ - rc = -EBUSY; - for (i = 0; i < count; i++) { - udelay(5); - val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND); - if (val & MCPR_NVM_COMMAND_DONE) { - rc = 0; - break; - } - } - - return rc; -} - -#define BYTE_OFFSET(offset) (8 * (offset & 0x03)) - -static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf, - int buf_size) -{ - int rc; - u32 cmd_flags; - u32 align_offset; - __be32 val; - - if (offset + buf_size > bp->common.flash_size) { - DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +" - " buf_size (0x%x) > flash_size (0x%x)\n", - offset, buf_size, bp->common.flash_size); - return -EINVAL; - } - - /* request access to nvram interface */ - rc = bnx2x_acquire_nvram_lock(bp); - if (rc) - return rc; - - /* enable access to nvram interface */ - bnx2x_enable_nvram_access(bp); - - cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST); - align_offset = (offset & ~0x03); - rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags); - - if (rc == 0) { - val &= ~(0xff << BYTE_OFFSET(offset)); - val |= (*data_buf << BYTE_OFFSET(offset)); - - /* nvram data is returned as an array of bytes - * convert it back to cpu order */ - val = be32_to_cpu(val); - - rc = bnx2x_nvram_write_dword(bp, align_offset, val, - cmd_flags); - } - - /* disable access to nvram interface */ - bnx2x_disable_nvram_access(bp); - bnx2x_release_nvram_lock(bp); - - return rc; -} - -static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf, - int buf_size) -{ - int rc; - u32 cmd_flags; - u32 val; - u32 written_so_far; - - if (buf_size == 1) /* ethtool */ - return bnx2x_nvram_write1(bp, offset, data_buf, buf_size); - - if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { - DP(BNX2X_MSG_NVM, - "Invalid parameter: offset 0x%x buf_size 0x%x\n", - offset, buf_size); - return -EINVAL; - } - - if (offset + buf_size > bp->common.flash_size) { - DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +" - " buf_size (0x%x) > flash_size (0x%x)\n", - offset, buf_size, bp->common.flash_size); - return -EINVAL; - } - - /* request access to nvram interface */ - rc = bnx2x_acquire_nvram_lock(bp); - if (rc) - return rc; - - /* enable access to nvram interface */ - bnx2x_enable_nvram_access(bp); - - written_so_far = 0; - cmd_flags = MCPR_NVM_COMMAND_FIRST; - while ((written_so_far < buf_size) && (rc == 0)) { - if (written_so_far == (buf_size - sizeof(u32))) - cmd_flags |= MCPR_NVM_COMMAND_LAST; - else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0) - cmd_flags |= MCPR_NVM_COMMAND_LAST; - else if ((offset % NVRAM_PAGE_SIZE) == 0) - cmd_flags |= MCPR_NVM_COMMAND_FIRST; - - memcpy(&val, data_buf, 4); - - rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags); - - /* advance to the next dword */ - offset += sizeof(u32); - data_buf += sizeof(u32); - written_so_far += sizeof(u32); - cmd_flags = 0; - } - - /* disable access to nvram interface */ - bnx2x_disable_nvram_access(bp); - bnx2x_release_nvram_lock(bp); - - return rc; -} - -static int bnx2x_set_eeprom(struct net_device *dev, - struct ethtool_eeprom *eeprom, u8 *eebuf) -{ - struct bnx2x *bp = netdev_priv(dev); - int port = BP_PORT(bp); - int rc = 0; - - if (!netif_running(dev)) - return -EAGAIN; - - DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n" - DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", - eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, - eeprom->len, eeprom->len); - - /* parameters already validated in ethtool_set_eeprom */ - - /* PHY eeprom can be accessed only by the PMF */ - if ((eeprom->magic >= 0x50485900) && (eeprom->magic <= 0x504859FF) && - !bp->port.pmf) - return -EINVAL; - - if (eeprom->magic == 0x50485950) { - /* 'PHYP' (0x50485950): prepare phy for FW upgrade */ - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - - bnx2x_acquire_phy_lock(bp); - rc |= bnx2x_link_reset(&bp->link_params, - &bp->link_vars, 0); - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_HIGH, port); - bnx2x_release_phy_lock(bp); - bnx2x_link_report(bp); - - } else if (eeprom->magic == 0x50485952) { - /* 'PHYR' (0x50485952): re-init link after FW upgrade */ - if (bp->state == BNX2X_STATE_OPEN) { - bnx2x_acquire_phy_lock(bp); - rc |= bnx2x_link_reset(&bp->link_params, - &bp->link_vars, 1); - - rc |= bnx2x_phy_init(&bp->link_params, - &bp->link_vars); - bnx2x_release_phy_lock(bp); - bnx2x_calc_fc_adv(bp); - } - } else if (eeprom->magic == 0x53985943) { - /* 'PHYC' (0x53985943): PHY FW upgrade completed */ - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); - - /* DSP Remove Download Mode */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_LOW, port); - - bnx2x_acquire_phy_lock(bp); - - bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); - - /* wait 0.5 sec to allow it to run */ - msleep(500); - bnx2x_ext_phy_hw_reset(bp, port); - msleep(500); - bnx2x_release_phy_lock(bp); - } - } else - rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); - - return rc; -} -static int bnx2x_get_coalesce(struct net_device *dev, - struct ethtool_coalesce *coal) -{ - struct bnx2x *bp = netdev_priv(dev); - - memset(coal, 0, sizeof(struct ethtool_coalesce)); - - coal->rx_coalesce_usecs = bp->rx_ticks; - coal->tx_coalesce_usecs = bp->tx_ticks; - - return 0; -} - -static int bnx2x_set_coalesce(struct net_device *dev, - struct ethtool_coalesce *coal) -{ - struct bnx2x *bp = netdev_priv(dev); - - bp->rx_ticks = (u16)coal->rx_coalesce_usecs; - if (bp->rx_ticks > BNX2X_MAX_COALESCE_TOUT) - bp->rx_ticks = BNX2X_MAX_COALESCE_TOUT; - - bp->tx_ticks = (u16)coal->tx_coalesce_usecs; - if (bp->tx_ticks > BNX2X_MAX_COALESCE_TOUT) - bp->tx_ticks = BNX2X_MAX_COALESCE_TOUT; - - if (netif_running(dev)) - bnx2x_update_coalesce(bp); - - return 0; -} - -static void bnx2x_get_ringparam(struct net_device *dev, - struct ethtool_ringparam *ering) -{ - struct bnx2x *bp = netdev_priv(dev); - - ering->rx_max_pending = MAX_RX_AVAIL; - ering->rx_mini_max_pending = 0; - ering->rx_jumbo_max_pending = 0; - - ering->rx_pending = bp->rx_ring_size; - ering->rx_mini_pending = 0; - ering->rx_jumbo_pending = 0; - - ering->tx_max_pending = MAX_TX_AVAIL; - ering->tx_pending = bp->tx_ring_size; -} - -static int bnx2x_set_ringparam(struct net_device *dev, - struct ethtool_ringparam *ering) -{ - struct bnx2x *bp = netdev_priv(dev); - int rc = 0; - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - return -EAGAIN; - } - - if ((ering->rx_pending > MAX_RX_AVAIL) || - (ering->tx_pending > MAX_TX_AVAIL) || - (ering->tx_pending <= MAX_SKB_FRAGS + 4)) - return -EINVAL; - - bp->rx_ring_size = ering->rx_pending; - bp->tx_ring_size = ering->tx_pending; - - if (netif_running(dev)) { - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - rc = bnx2x_nic_load(bp, LOAD_NORMAL); - } - - return rc; -} - -static void bnx2x_get_pauseparam(struct net_device *dev, - struct ethtool_pauseparam *epause) -{ - struct bnx2x *bp = netdev_priv(dev); - - epause->autoneg = (bp->link_params.req_flow_ctrl == - BNX2X_FLOW_CTRL_AUTO) && - (bp->link_params.req_line_speed == SPEED_AUTO_NEG); - - epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) == - BNX2X_FLOW_CTRL_RX); - epause->tx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) == - BNX2X_FLOW_CTRL_TX); - - DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n" - DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", - epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); -} - -static int bnx2x_set_pauseparam(struct net_device *dev, - struct ethtool_pauseparam *epause) -{ - struct bnx2x *bp = netdev_priv(dev); - - if (IS_E1HMF(bp)) - return 0; - - DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n" - DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", - epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); - - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; - - if (epause->rx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX; - - if (epause->tx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX; - - if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - if (epause->autoneg) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { - DP(NETIF_MSG_LINK, "autoneg not supported\n"); - return -EINVAL; - } - - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; - } - - DP(NETIF_MSG_LINK, - "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl); - - if (netif_running(dev)) { - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_link_set(bp); - } - - return 0; -} - -static int bnx2x_set_flags(struct net_device *dev, u32 data) -{ - struct bnx2x *bp = netdev_priv(dev); - int changed = 0; - int rc = 0; - - if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH)) - return -EINVAL; - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - return -EAGAIN; - } - - /* TPA requires Rx CSUM offloading */ - if ((data & ETH_FLAG_LRO) && bp->rx_csum) { - if (!bp->disable_tpa) { - if (!(dev->features & NETIF_F_LRO)) { - dev->features |= NETIF_F_LRO; - bp->flags |= TPA_ENABLE_FLAG; - changed = 1; - } - } else - rc = -EINVAL; - } else if (dev->features & NETIF_F_LRO) { - dev->features &= ~NETIF_F_LRO; - bp->flags &= ~TPA_ENABLE_FLAG; - changed = 1; - } - - if (data & ETH_FLAG_RXHASH) - dev->features |= NETIF_F_RXHASH; - else - dev->features &= ~NETIF_F_RXHASH; - - if (changed && netif_running(dev)) { - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - rc = bnx2x_nic_load(bp, LOAD_NORMAL); - } - - return rc; -} - -static u32 bnx2x_get_rx_csum(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - return bp->rx_csum; -} - -static int bnx2x_set_rx_csum(struct net_device *dev, u32 data) -{ - struct bnx2x *bp = netdev_priv(dev); - int rc = 0; - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - return -EAGAIN; - } - - bp->rx_csum = data; - - /* Disable TPA, when Rx CSUM is disabled. Otherwise all - TPA'ed packets will be discarded due to wrong TCP CSUM */ - if (!data) { - u32 flags = ethtool_op_get_flags(dev); - - rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO)); - } - - return rc; -} - -static int bnx2x_set_tso(struct net_device *dev, u32 data) -{ - if (data) { - dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); - dev->features |= NETIF_F_TSO6; - } else { - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN); - dev->features &= ~NETIF_F_TSO6; - } - - return 0; -} - -static const struct { - char string[ETH_GSTRING_LEN]; -} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { - { "register_test (offline)" }, - { "memory_test (offline)" }, - { "loopback_test (offline)" }, - { "nvram_test (online)" }, - { "interrupt_test (online)" }, - { "link_test (online)" }, - { "idle check (online)" } -}; - -static int bnx2x_test_registers(struct bnx2x *bp) -{ - int idx, i, rc = -ENODEV; - u32 wr_val = 0; - int port = BP_PORT(bp); - static const struct { - u32 offset0; - u32 offset1; - u32 mask; - } reg_tbl[] = { -/* 0 */ { BRB1_REG_PAUSE_LOW_THRESHOLD_0, 4, 0x000003ff }, - { DORQ_REG_DB_ADDR0, 4, 0xffffffff }, - { HC_REG_AGG_INT_0, 4, 0x000003ff }, - { PBF_REG_MAC_IF0_ENABLE, 4, 0x00000001 }, - { PBF_REG_P0_INIT_CRD, 4, 0x000007ff }, - { PRS_REG_CID_PORT_0, 4, 0x00ffffff }, - { PXP2_REG_PSWRQ_CDU0_L2P, 4, 0x000fffff }, - { PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, - { PXP2_REG_PSWRQ_TM0_L2P, 4, 0x000fffff }, - { PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, -/* 10 */ { PXP2_REG_PSWRQ_TSDM0_L2P, 4, 0x000fffff }, - { QM_REG_CONNNUM_0, 4, 0x000fffff }, - { TM_REG_LIN0_MAX_ACTIVE_CID, 4, 0x0003ffff }, - { SRC_REG_KEYRSS0_0, 40, 0xffffffff }, - { SRC_REG_KEYRSS0_7, 40, 0xffffffff }, - { XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 }, - { XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 }, - { XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff }, - { NIG_REG_LLH0_T_BIT, 4, 0x00000001 }, - { NIG_REG_EMAC0_IN_EN, 4, 0x00000001 }, -/* 20 */ { NIG_REG_BMAC0_IN_EN, 4, 0x00000001 }, - { NIG_REG_XCM0_OUT_EN, 4, 0x00000001 }, - { NIG_REG_BRB0_OUT_EN, 4, 0x00000001 }, - { NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 }, - { NIG_REG_LLH0_ACPI_PAT_6_LEN, 68, 0x000000ff }, - { NIG_REG_LLH0_ACPI_PAT_0_CRC, 68, 0xffffffff }, - { NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff }, - { NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff }, - { NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 }, - { NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff }, -/* 30 */ { NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff }, - { NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff }, - { NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 }, - { NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 }, - { NIG_REG_STATUS_INTERRUPT_PORT0, 4, 0x07ffffff }, - { NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 }, - { NIG_REG_SERDES0_CTRL_PHY_ADDR, 16, 0x0000001f }, - - { 0xffffffff, 0, 0x00000000 } - }; - - if (!netif_running(bp->dev)) - return rc; - - /* Repeat the test twice: - First by writing 0x00000000, second by writing 0xffffffff */ - for (idx = 0; idx < 2; idx++) { - - switch (idx) { - case 0: - wr_val = 0; - break; - case 1: - wr_val = 0xffffffff; - break; - } - - for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { - u32 offset, mask, save_val, val; - - offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; - mask = reg_tbl[i].mask; - - save_val = REG_RD(bp, offset); - - REG_WR(bp, offset, (wr_val & mask)); - val = REG_RD(bp, offset); - - /* Restore the original register's value */ - REG_WR(bp, offset, save_val); - - /* verify value is as expected */ - if ((val & mask) != (wr_val & mask)) { - DP(NETIF_MSG_PROBE, - "offset 0x%x: val 0x%x != 0x%x mask 0x%x\n", - offset, val, wr_val, mask); - goto test_reg_exit; - } - } - } - - rc = 0; - -test_reg_exit: - return rc; -} - -static int bnx2x_test_memory(struct bnx2x *bp) -{ - int i, j, rc = -ENODEV; - u32 val; - static const struct { - u32 offset; - int size; - } mem_tbl[] = { - { CCM_REG_XX_DESCR_TABLE, CCM_REG_XX_DESCR_TABLE_SIZE }, - { CFC_REG_ACTIVITY_COUNTER, CFC_REG_ACTIVITY_COUNTER_SIZE }, - { CFC_REG_LINK_LIST, CFC_REG_LINK_LIST_SIZE }, - { DMAE_REG_CMD_MEM, DMAE_REG_CMD_MEM_SIZE }, - { TCM_REG_XX_DESCR_TABLE, TCM_REG_XX_DESCR_TABLE_SIZE }, - { UCM_REG_XX_DESCR_TABLE, UCM_REG_XX_DESCR_TABLE_SIZE }, - { XCM_REG_XX_DESCR_TABLE, XCM_REG_XX_DESCR_TABLE_SIZE }, - - { 0xffffffff, 0 } - }; - static const struct { - char *name; - u32 offset; - u32 e1_mask; - u32 e1h_mask; - } prty_tbl[] = { - { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 }, - { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 }, - { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 }, - { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 }, - { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 }, - { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 }, - - { NULL, 0xffffffff, 0, 0 } - }; - - if (!netif_running(bp->dev)) - return rc; - - /* Go through all the memories */ - for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) - for (j = 0; j < mem_tbl[i].size; j++) - REG_RD(bp, mem_tbl[i].offset + j*4); - - /* Check the parity status */ - for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { - val = REG_RD(bp, prty_tbl[i].offset); - if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || - (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) { - DP(NETIF_MSG_HW, - "%s is 0x%x\n", prty_tbl[i].name, val); - goto test_mem_exit; - } - } - - rc = 0; - -test_mem_exit: - return rc; -} - -static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up) -{ - int cnt = 1000; - - if (link_up) - while (bnx2x_link_test(bp) && cnt--) - msleep(10); -} - -static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) -{ - unsigned int pkt_size, num_pkts, i; - struct sk_buff *skb; - unsigned char *packet; - struct bnx2x_fastpath *fp_rx = &bp->fp[0]; - struct bnx2x_fastpath *fp_tx = &bp->fp[0]; - u16 tx_start_idx, tx_idx; - u16 rx_start_idx, rx_idx; - u16 pkt_prod, bd_prod; - struct sw_tx_bd *tx_buf; - struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_parse_bd *pbd = NULL; - dma_addr_t mapping; - union eth_rx_cqe *cqe; - u8 cqe_fp_flags; - struct sw_rx_bd *rx_buf; - u16 len; - int rc = -ENODEV; - - /* check the loopback mode */ - switch (loopback_mode) { - case BNX2X_PHY_LOOPBACK: - if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10) - return -EINVAL; - break; - case BNX2X_MAC_LOOPBACK: - bp->link_params.loopback_mode = LOOPBACK_BMAC; - bnx2x_phy_init(&bp->link_params, &bp->link_vars); - break; - default: - return -EINVAL; - } - - /* prepare the loopback packet */ - pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ? - bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN); - skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); - if (!skb) { - rc = -ENOMEM; - goto test_loopback_exit; - } - packet = skb_put(skb, pkt_size); - memcpy(packet, bp->dev->dev_addr, ETH_ALEN); - memset(packet + ETH_ALEN, 0, ETH_ALEN); - memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN)); - for (i = ETH_HLEN; i < pkt_size; i++) - packet[i] = (unsigned char) (i & 0xff); - - /* send the loopback packet */ - num_pkts = 0; - tx_start_idx = le16_to_cpu(*fp_tx->tx_cons_sb); - rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb); - - pkt_prod = fp_tx->tx_pkt_prod++; - tx_buf = &fp_tx->tx_buf_ring[TX_BD(pkt_prod)]; - tx_buf->first_bd = fp_tx->tx_bd_prod; - tx_buf->skb = skb; - tx_buf->flags = 0; - - bd_prod = TX_BD(fp_tx->tx_bd_prod); - tx_start_bd = &fp_tx->tx_desc_ring[bd_prod].start_bd; - mapping = dma_map_single(&bp->pdev->dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); - tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); - tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); - tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */ - tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); - tx_start_bd->vlan = cpu_to_le16(pkt_prod); - tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = ((UNICAST_ADDRESS << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1); - - /* turn on parsing and get a BD */ - bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd; - - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); - - wmb(); - - fp_tx->tx_db.data.prod += 2; - barrier(); - DOORBELL(bp, fp_tx->index, fp_tx->tx_db.raw); - - mmiowb(); - - num_pkts++; - fp_tx->tx_bd_prod += 2; /* start + pbd */ - - udelay(100); - - tx_idx = le16_to_cpu(*fp_tx->tx_cons_sb); - if (tx_idx != tx_start_idx + num_pkts) - goto test_loopback_exit; - - rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); - if (rx_idx != rx_start_idx + num_pkts) - goto test_loopback_exit; - - cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)]; - cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; - if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS)) - goto test_loopback_rx_exit; - - len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); - if (len != pkt_size) - goto test_loopback_rx_exit; - - rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)]; - skb = rx_buf->skb; - skb_reserve(skb, cqe->fast_path_cqe.placement_offset); - for (i = ETH_HLEN; i < pkt_size; i++) - if (*(skb->data + i) != (unsigned char) (i & 0xff)) - goto test_loopback_rx_exit; - - rc = 0; - -test_loopback_rx_exit: - - fp_rx->rx_bd_cons = NEXT_RX_IDX(fp_rx->rx_bd_cons); - fp_rx->rx_bd_prod = NEXT_RX_IDX(fp_rx->rx_bd_prod); - fp_rx->rx_comp_cons = NEXT_RCQ_IDX(fp_rx->rx_comp_cons); - fp_rx->rx_comp_prod = NEXT_RCQ_IDX(fp_rx->rx_comp_prod); - - /* Update producers */ - bnx2x_update_rx_prod(bp, fp_rx, fp_rx->rx_bd_prod, fp_rx->rx_comp_prod, - fp_rx->rx_sge_prod); - -test_loopback_exit: - bp->link_params.loopback_mode = LOOPBACK_NONE; - - return rc; -} - -static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) -{ - int rc = 0, res; - - if (BP_NOMCP(bp)) - return rc; - - if (!netif_running(bp->dev)) - return BNX2X_LOOPBACK_FAILED; - - bnx2x_netif_stop(bp, 1); - bnx2x_acquire_phy_lock(bp); - - res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up); - if (res) { - DP(NETIF_MSG_PROBE, " PHY loopback failed (res %d)\n", res); - rc |= BNX2X_PHY_LOOPBACK_FAILED; - } - - res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up); - if (res) { - DP(NETIF_MSG_PROBE, " MAC loopback failed (res %d)\n", res); - rc |= BNX2X_MAC_LOOPBACK_FAILED; - } - - bnx2x_release_phy_lock(bp); - bnx2x_netif_start(bp); - - return rc; -} - -#define CRC32_RESIDUAL 0xdebb20e3 - -static int bnx2x_test_nvram(struct bnx2x *bp) -{ - static const struct { - int offset; - int size; - } nvram_tbl[] = { - { 0, 0x14 }, /* bootstrap */ - { 0x14, 0xec }, /* dir */ - { 0x100, 0x350 }, /* manuf_info */ - { 0x450, 0xf0 }, /* feature_info */ - { 0x640, 0x64 }, /* upgrade_key_info */ - { 0x6a4, 0x64 }, - { 0x708, 0x70 }, /* manuf_key_info */ - { 0x778, 0x70 }, - { 0, 0 } - }; - __be32 buf[0x350 / 4]; - u8 *data = (u8 *)buf; - int i, rc; - u32 magic, crc; - - if (BP_NOMCP(bp)) - return 0; - - rc = bnx2x_nvram_read(bp, 0, data, 4); - if (rc) { - DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc); - goto test_nvram_exit; - } - - magic = be32_to_cpu(buf[0]); - if (magic != 0x669955aa) { - DP(NETIF_MSG_PROBE, "magic value (0x%08x)\n", magic); - rc = -ENODEV; - goto test_nvram_exit; - } - - for (i = 0; nvram_tbl[i].size; i++) { - - rc = bnx2x_nvram_read(bp, nvram_tbl[i].offset, data, - nvram_tbl[i].size); - if (rc) { - DP(NETIF_MSG_PROBE, - "nvram_tbl[%d] read data (rc %d)\n", i, rc); - goto test_nvram_exit; - } - - crc = ether_crc_le(nvram_tbl[i].size, data); - if (crc != CRC32_RESIDUAL) { - DP(NETIF_MSG_PROBE, - "nvram_tbl[%d] crc value (0x%08x)\n", i, crc); - rc = -ENODEV; - goto test_nvram_exit; - } - } - -test_nvram_exit: - return rc; -} - -static int bnx2x_test_intr(struct bnx2x *bp) -{ - struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); - int i, rc; - - if (!netif_running(bp->dev)) - return -ENODEV; - - config->hdr.length = 0; - if (CHIP_IS_E1(bp)) - /* use last unicast entries */ - config->hdr.offset = (BP_PORT(bp) ? 63 : 31); - else - config->hdr.offset = BP_FUNC(bp); - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending++; - smp_wmb(); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); - if (rc == 0) { - for (i = 0; i < 10; i++) { - if (!bp->set_mac_pending) - break; - smp_rmb(); - msleep_interruptible(10); - } - if (i == 10) - rc = -ENODEV; - } - - return rc; -} - -static void bnx2x_self_test(struct net_device *dev, - struct ethtool_test *etest, u64 *buf) -{ - struct bnx2x *bp = netdev_priv(dev); - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - etest->flags |= ETH_TEST_FL_FAILED; - return; - } - - memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS); - - if (!netif_running(dev)) - return; - - /* offline tests are not supported in MF mode */ - if (IS_E1HMF(bp)) - etest->flags &= ~ETH_TEST_FL_OFFLINE; - - if (etest->flags & ETH_TEST_FL_OFFLINE) { - int port = BP_PORT(bp); - u32 val; - u8 link_up; - - /* save current value of input enable for TX port IF */ - val = REG_RD(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4); - /* disable input for TX port IF */ - REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0); - - link_up = (bnx2x_link_test(bp) == 0); - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - bnx2x_nic_load(bp, LOAD_DIAG); - /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); - - if (bnx2x_test_registers(bp) != 0) { - buf[0] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } - if (bnx2x_test_memory(bp) != 0) { - buf[1] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } - buf[2] = bnx2x_test_loopback(bp, link_up); - if (buf[2] != 0) - etest->flags |= ETH_TEST_FL_FAILED; - - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - - /* restore input for TX port IF */ - REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val); - - bnx2x_nic_load(bp, LOAD_NORMAL); - /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); - } - if (bnx2x_test_nvram(bp) != 0) { - buf[3] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } - if (bnx2x_test_intr(bp) != 0) { - buf[4] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } - if (bp->port.pmf) - if (bnx2x_link_test(bp) != 0) { - buf[5] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } - -#ifdef BNX2X_EXTRA_DEBUG - bnx2x_panic_dump(bp); -#endif -} - -static const struct { - long offset; - int size; - u8 string[ETH_GSTRING_LEN]; -} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = { -/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" }, - { Q_STATS_OFFSET32(error_bytes_received_hi), - 8, "[%d]: rx_error_bytes" }, - { Q_STATS_OFFSET32(total_unicast_packets_received_hi), - 8, "[%d]: rx_ucast_packets" }, - { Q_STATS_OFFSET32(total_multicast_packets_received_hi), - 8, "[%d]: rx_mcast_packets" }, - { Q_STATS_OFFSET32(total_broadcast_packets_received_hi), - 8, "[%d]: rx_bcast_packets" }, - { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" }, - { Q_STATS_OFFSET32(rx_err_discard_pkt), - 4, "[%d]: rx_phy_ip_err_discards"}, - { Q_STATS_OFFSET32(rx_skb_alloc_failed), - 4, "[%d]: rx_skb_alloc_discard" }, - { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" }, - -/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" }, - { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), - 8, "[%d]: tx_ucast_packets" }, - { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi), - 8, "[%d]: tx_mcast_packets" }, - { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi), - 8, "[%d]: tx_bcast_packets" } -}; - -static const struct { - long offset; - int size; - u32 flags; -#define STATS_FLAGS_PORT 1 -#define STATS_FLAGS_FUNC 2 -#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT) - u8 string[ETH_GSTRING_LEN]; -} bnx2x_stats_arr[BNX2X_NUM_STATS] = { -/* 1 */ { STATS_OFFSET32(total_bytes_received_hi), - 8, STATS_FLAGS_BOTH, "rx_bytes" }, - { STATS_OFFSET32(error_bytes_received_hi), - 8, STATS_FLAGS_BOTH, "rx_error_bytes" }, - { STATS_OFFSET32(total_unicast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_ucast_packets" }, - { STATS_OFFSET32(total_multicast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_mcast_packets" }, - { STATS_OFFSET32(total_broadcast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_bcast_packets" }, - { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi), - 8, STATS_FLAGS_PORT, "rx_crc_errors" }, - { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi), - 8, STATS_FLAGS_PORT, "rx_align_errors" }, - { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi), - 8, STATS_FLAGS_PORT, "rx_undersize_packets" }, - { STATS_OFFSET32(etherstatsoverrsizepkts_hi), - 8, STATS_FLAGS_PORT, "rx_oversize_packets" }, -/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi), - 8, STATS_FLAGS_PORT, "rx_fragments" }, - { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), - 8, STATS_FLAGS_PORT, "rx_jabbers" }, - { STATS_OFFSET32(no_buff_discard_hi), - 8, STATS_FLAGS_BOTH, "rx_discards" }, - { STATS_OFFSET32(mac_filter_discard), - 4, STATS_FLAGS_PORT, "rx_filtered_packets" }, - { STATS_OFFSET32(xxoverflow_discard), - 4, STATS_FLAGS_PORT, "rx_fw_discards" }, - { STATS_OFFSET32(brb_drop_hi), - 8, STATS_FLAGS_PORT, "rx_brb_discard" }, - { STATS_OFFSET32(brb_truncate_hi), - 8, STATS_FLAGS_PORT, "rx_brb_truncate" }, - { STATS_OFFSET32(pause_frames_received_hi), - 8, STATS_FLAGS_PORT, "rx_pause_frames" }, - { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi), - 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" }, - { STATS_OFFSET32(nig_timer_max), - 4, STATS_FLAGS_PORT, "rx_constant_pause_events" }, -/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt), - 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"}, - { STATS_OFFSET32(rx_skb_alloc_failed), - 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" }, - { STATS_OFFSET32(hw_csum_err), - 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" }, - - { STATS_OFFSET32(total_bytes_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_bytes" }, - { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), - 8, STATS_FLAGS_PORT, "tx_error_bytes" }, - { STATS_OFFSET32(total_unicast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_ucast_packets" }, - { STATS_OFFSET32(total_multicast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_mcast_packets" }, - { STATS_OFFSET32(total_broadcast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_bcast_packets" }, - { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi), - 8, STATS_FLAGS_PORT, "tx_mac_errors" }, - { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi), - 8, STATS_FLAGS_PORT, "tx_carrier_errors" }, -/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi), - 8, STATS_FLAGS_PORT, "tx_single_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi), - 8, STATS_FLAGS_PORT, "tx_multi_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi), - 8, STATS_FLAGS_PORT, "tx_deferred" }, - { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi), - 8, STATS_FLAGS_PORT, "tx_excess_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi), - 8, STATS_FLAGS_PORT, "tx_late_collisions" }, - { STATS_OFFSET32(tx_stat_etherstatscollisions_hi), - 8, STATS_FLAGS_PORT, "tx_total_collisions" }, - { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi), - 8, STATS_FLAGS_PORT, "tx_64_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi), - 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi), - 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi), - 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" }, -/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi), - 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" }, - { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi), - 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" }, - { STATS_OFFSET32(etherstatspktsover1522octets_hi), - 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" }, - { STATS_OFFSET32(pause_frames_sent_hi), - 8, STATS_FLAGS_PORT, "tx_pause_frames" } -}; - -#define IS_PORT_STAT(i) \ - ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) -#define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) -#define IS_E1HMF_MODE_STAT(bp) \ - (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) - -static int bnx2x_get_sset_count(struct net_device *dev, int stringset) -{ - struct bnx2x *bp = netdev_priv(dev); - int i, num_stats; - - switch (stringset) { - case ETH_SS_STATS: - if (is_multi(bp)) { - num_stats = BNX2X_NUM_Q_STATS * bp->num_queues; - if (!IS_E1HMF_MODE_STAT(bp)) - num_stats += BNX2X_NUM_STATS; - } else { - if (IS_E1HMF_MODE_STAT(bp)) { - num_stats = 0; - for (i = 0; i < BNX2X_NUM_STATS; i++) - if (IS_FUNC_STAT(i)) - num_stats++; - } else - num_stats = BNX2X_NUM_STATS; - } - return num_stats; - - case ETH_SS_TEST: - return BNX2X_NUM_TESTS; - - default: - return -EINVAL; - } -} - -static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) -{ - struct bnx2x *bp = netdev_priv(dev); - int i, j, k; - - switch (stringset) { - case ETH_SS_STATS: - if (is_multi(bp)) { - k = 0; - for_each_queue(bp, i) { - for (j = 0; j < BNX2X_NUM_Q_STATS; j++) - sprintf(buf + (k + j)*ETH_GSTRING_LEN, - bnx2x_q_stats_arr[j].string, i); - k += BNX2X_NUM_Q_STATS; - } - if (IS_E1HMF_MODE_STAT(bp)) - break; - for (j = 0; j < BNX2X_NUM_STATS; j++) - strcpy(buf + (k + j)*ETH_GSTRING_LEN, - bnx2x_stats_arr[j].string); - } else { - for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) - continue; - strcpy(buf + j*ETH_GSTRING_LEN, - bnx2x_stats_arr[i].string); - j++; - } - } - break; - - case ETH_SS_TEST: - memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr)); - break; - } -} - -static void bnx2x_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, u64 *buf) -{ - struct bnx2x *bp = netdev_priv(dev); - u32 *hw_stats, *offset; - int i, j, k; - - if (is_multi(bp)) { - k = 0; - for_each_queue(bp, i) { - hw_stats = (u32 *)&bp->fp[i].eth_q_stats; - for (j = 0; j < BNX2X_NUM_Q_STATS; j++) { - if (bnx2x_q_stats_arr[j].size == 0) { - /* skip this counter */ - buf[k + j] = 0; - continue; - } - offset = (hw_stats + - bnx2x_q_stats_arr[j].offset); - if (bnx2x_q_stats_arr[j].size == 4) { - /* 4-byte counter */ - buf[k + j] = (u64) *offset; - continue; - } - /* 8-byte counter */ - buf[k + j] = HILO_U64(*offset, *(offset + 1)); - } - k += BNX2X_NUM_Q_STATS; - } - if (IS_E1HMF_MODE_STAT(bp)) - return; - hw_stats = (u32 *)&bp->eth_stats; - for (j = 0; j < BNX2X_NUM_STATS; j++) { - if (bnx2x_stats_arr[j].size == 0) { - /* skip this counter */ - buf[k + j] = 0; - continue; - } - offset = (hw_stats + bnx2x_stats_arr[j].offset); - if (bnx2x_stats_arr[j].size == 4) { - /* 4-byte counter */ - buf[k + j] = (u64) *offset; - continue; - } - /* 8-byte counter */ - buf[k + j] = HILO_U64(*offset, *(offset + 1)); - } - } else { - hw_stats = (u32 *)&bp->eth_stats; - for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) - continue; - if (bnx2x_stats_arr[i].size == 0) { - /* skip this counter */ - buf[j] = 0; - j++; - continue; - } - offset = (hw_stats + bnx2x_stats_arr[i].offset); - if (bnx2x_stats_arr[i].size == 4) { - /* 4-byte counter */ - buf[j] = (u64) *offset; - j++; - continue; - } - /* 8-byte counter */ - buf[j] = HILO_U64(*offset, *(offset + 1)); - j++; - } - } -} - -static int bnx2x_phys_id(struct net_device *dev, u32 data) -{ - struct bnx2x *bp = netdev_priv(dev); - int i; - - if (!netif_running(dev)) - return 0; - - if (!bp->port.pmf) - return 0; - - if (data == 0) - data = 2; - - for (i = 0; i < (data * 2); i++) { - if ((i % 2) == 0) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, - SPEED_1000); - else - bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0); - - msleep_interruptible(500); - if (signal_pending(current)) - break; - } - - if (bp->link_vars.link_up) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, - bp->link_vars.line_speed); - - return 0; -} - -static const struct ethtool_ops bnx2x_ethtool_ops = { - .get_settings = bnx2x_get_settings, - .set_settings = bnx2x_set_settings, - .get_drvinfo = bnx2x_get_drvinfo, - .get_regs_len = bnx2x_get_regs_len, - .get_regs = bnx2x_get_regs, - .get_wol = bnx2x_get_wol, - .set_wol = bnx2x_set_wol, - .get_msglevel = bnx2x_get_msglevel, - .set_msglevel = bnx2x_set_msglevel, - .nway_reset = bnx2x_nway_reset, - .get_link = bnx2x_get_link, - .get_eeprom_len = bnx2x_get_eeprom_len, - .get_eeprom = bnx2x_get_eeprom, - .set_eeprom = bnx2x_set_eeprom, - .get_coalesce = bnx2x_get_coalesce, - .set_coalesce = bnx2x_set_coalesce, - .get_ringparam = bnx2x_get_ringparam, - .set_ringparam = bnx2x_set_ringparam, - .get_pauseparam = bnx2x_get_pauseparam, - .set_pauseparam = bnx2x_set_pauseparam, - .get_rx_csum = bnx2x_get_rx_csum, - .set_rx_csum = bnx2x_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .set_flags = bnx2x_set_flags, - .get_flags = ethtool_op_get_flags, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = bnx2x_set_tso, - .self_test = bnx2x_self_test, - .get_sset_count = bnx2x_get_sset_count, - .get_strings = bnx2x_get_strings, - .phys_id = bnx2x_phys_id, - .get_ethtool_stats = bnx2x_get_ethtool_stats, -}; - -void bnx2x_set_ethtool_ops(struct net_device *netdev) -{ - SET_ETHTOOL_OPS(netdev, &bnx2x_ethtool_ops); -} diff --git a/trunk/drivers/net/bnx2x/bnx2x_stats.c b/trunk/drivers/net/bnx2x/bnx2x_stats.c deleted file mode 100644 index c74724461020..000000000000 --- a/trunk/drivers/net/bnx2x/bnx2x_stats.c +++ /dev/null @@ -1,1411 +0,0 @@ -/* bnx2x_stats.c: Broadcom Everest network driver. - * - * Copyright (c) 2007-2010 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation. - * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir - * Based on code from Michael Chan's bnx2 driver - * UDP CSUM errata workaround by Arik Gendelman - * Slowpath and fastpath rework by Vladislav Zolotarov - * Statistics and Link management by Yitchak Gertner - * - */ - #include "bnx2x_cmn.h" - #include "bnx2x_stats.h" - -/* Statistics */ - -/**************************************************************************** -* Macros -****************************************************************************/ - -/* sum[hi:lo] += add[hi:lo] */ -#define ADD_64(s_hi, a_hi, s_lo, a_lo) \ - do { \ - s_lo += a_lo; \ - s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ - } while (0) - -/* difference = minuend - subtrahend */ -#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ - do { \ - if (m_lo < s_lo) { \ - /* underflow */ \ - d_hi = m_hi - s_hi; \ - if (d_hi > 0) { \ - /* we can 'loan' 1 */ \ - d_hi--; \ - d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ - } else { \ - /* m_hi <= s_hi */ \ - d_hi = 0; \ - d_lo = 0; \ - } \ - } else { \ - /* m_lo >= s_lo */ \ - if (m_hi < s_hi) { \ - d_hi = 0; \ - d_lo = 0; \ - } else { \ - /* m_hi >= s_hi */ \ - d_hi = m_hi - s_hi; \ - d_lo = m_lo - s_lo; \ - } \ - } \ - } while (0) - -#define UPDATE_STAT64(s, t) \ - do { \ - DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \ - diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \ - pstats->mac_stx[0].t##_hi = new->s##_hi; \ - pstats->mac_stx[0].t##_lo = new->s##_lo; \ - ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \ - pstats->mac_stx[1].t##_lo, diff.lo); \ - } while (0) - -#define UPDATE_STAT64_NIG(s, t) \ - do { \ - DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \ - diff.lo, new->s##_lo, old->s##_lo); \ - ADD_64(estats->t##_hi, diff.hi, \ - estats->t##_lo, diff.lo); \ - } while (0) - -/* sum[hi:lo] += add */ -#define ADD_EXTEND_64(s_hi, s_lo, a) \ - do { \ - s_lo += a; \ - s_hi += (s_lo < a) ? 1 : 0; \ - } while (0) - -#define UPDATE_EXTEND_STAT(s) \ - do { \ - ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \ - pstats->mac_stx[1].s##_lo, \ - new->s); \ - } while (0) - -#define UPDATE_EXTEND_TSTAT(s, t) \ - do { \ - diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \ - old_tclient->s = tclient->s; \ - ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) - -#define UPDATE_EXTEND_USTAT(s, t) \ - do { \ - diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ - old_uclient->s = uclient->s; \ - ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) - -#define UPDATE_EXTEND_XSTAT(s, t) \ - do { \ - diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \ - old_xclient->s = xclient->s; \ - ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) - -/* minuend -= subtrahend */ -#define SUB_64(m_hi, s_hi, m_lo, s_lo) \ - do { \ - DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ - } while (0) - -/* minuend[hi:lo] -= subtrahend */ -#define SUB_EXTEND_64(m_hi, m_lo, s) \ - do { \ - SUB_64(m_hi, 0, m_lo, s); \ - } while (0) - -#define SUB_EXTEND_USTAT(s, t) \ - do { \ - diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ - SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ - } while (0) - -/* - * General service functions - */ - -static inline long bnx2x_hilo(u32 *hiref) -{ - u32 lo = *(hiref + 1); -#if (BITS_PER_LONG == 64) - u32 hi = *hiref; - - return HILO_U64(hi, lo); -#else - return lo; -#endif -} - -/* - * Init service functions - */ - - -static void bnx2x_storm_stats_post(struct bnx2x *bp) -{ - if (!bp->stats_pending) { - struct eth_query_ramrod_data ramrod_data = {0}; - int i, rc; - - spin_lock_bh(&bp->stats_lock); - - ramrod_data.drv_counter = bp->stats_counter++; - ramrod_data.collect_port = bp->port.pmf ? 1 : 0; - for_each_queue(bp, i) - ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); - - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, - ((u32 *)&ramrod_data)[1], - ((u32 *)&ramrod_data)[0], 0); - if (rc == 0) { - /* stats ramrod has it's own slot on the spq */ - bp->spq_left++; - bp->stats_pending = 1; - } - - spin_unlock_bh(&bp->stats_lock); - } -} - -static void bnx2x_hw_stats_post(struct bnx2x *bp) -{ - struct dmae_command *dmae = &bp->stats_dmae; - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - *stats_comp = DMAE_COMP_VAL; - if (CHIP_REV_IS_SLOW(bp)) - return; - - /* loader */ - if (bp->executer_idx) { - int loader_idx = PMF_DMAE_C(bp); - - memset(dmae, 0, sizeof(struct dmae_command)); - - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : - DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); - dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); - dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + - sizeof(struct dmae_command) * - (loader_idx + 1)) >> 2; - dmae->dst_addr_hi = 0; - dmae->len = sizeof(struct dmae_command) >> 2; - if (CHIP_IS_E1(bp)) - dmae->len--; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - *stats_comp = 0; - bnx2x_post_dmae(bp, dmae, loader_idx); - - } else if (bp->func_stx) { - *stats_comp = 0; - bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); - } -} - -static int bnx2x_stats_comp(struct bnx2x *bp) -{ - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - int cnt = 10; - - might_sleep(); - while (*stats_comp != DMAE_COMP_VAL) { - if (!cnt) { - BNX2X_ERR("timeout waiting for stats finished\n"); - break; - } - cnt--; - msleep(1); - } - return 1; -} - -/* - * Statistics service functions - */ - -static void bnx2x_stats_pmf_update(struct bnx2x *bp) -{ - struct dmae_command *dmae; - u32 opcode; - int loader_idx = PMF_DMAE_C(bp); - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - /* sanity */ - if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) { - BNX2X_ERR("BUG!\n"); - return; - } - - bp->executer_idx = 0; - - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); - dmae->src_addr_lo = bp->port.port_stx >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); - dmae->len = DMAE_LEN32_RD_MAX; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); - dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) + - DMAE_LEN32_RD_MAX * 4); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) + - DMAE_LEN32_RD_MAX * 4); - dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX; - dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_val = DMAE_COMP_VAL; - - *stats_comp = 0; - bnx2x_hw_stats_post(bp); - bnx2x_stats_comp(bp); -} - -static void bnx2x_port_stats_init(struct bnx2x *bp) -{ - struct dmae_command *dmae; - int port = BP_PORT(bp); - int vn = BP_E1HVN(bp); - u32 opcode; - int loader_idx = PMF_DMAE_C(bp); - u32 mac_addr; - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - /* sanity */ - if (!bp->link_vars.link_up || !bp->port.pmf) { - BNX2X_ERR("BUG!\n"); - return; - } - - bp->executer_idx = 0; - - /* MCP */ - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); - - if (bp->port.port_stx) { - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); - dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); - dmae->dst_addr_lo = bp->port.port_stx >> 2; - dmae->dst_addr_hi = 0; - dmae->len = sizeof(struct host_port_stats) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - } - - if (bp->func_stx) { - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); - dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); - dmae->dst_addr_lo = bp->func_stx >> 2; - dmae->dst_addr_hi = 0; - dmae->len = sizeof(struct host_func_stats) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - } - - /* MAC */ - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); - - if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { - - mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM : - NIG_REG_INGRESS_BMAC0_MEM); - - /* BIGMAC_REGISTER_TX_STAT_GTPKT .. - BIGMAC_REGISTER_TX_STAT_GTBYT */ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); - dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - - BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - /* BIGMAC_REGISTER_RX_STAT_GR64 .. - BIGMAC_REGISTER_RX_STAT_GRIPJ */ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); - dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { - - mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0); - - /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - EMAC_REG_EMAC_RX_STAT_AC) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); - dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - /* EMAC_REG_EMAC_RX_STAT_AC_28 */ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - EMAC_REG_EMAC_RX_STAT_AC_28) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct emac_stats, rx_stat_falsecarriererrors)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct emac_stats, rx_stat_falsecarriererrors)); - dmae->len = 1; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - EMAC_REG_EMAC_TX_STAT_AC) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); - dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - } - - /* NIG */ - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : - NIG_REG_STAT0_BRB_DISCARD) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats)); - dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = opcode; - dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 : - NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt0_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt0_lo)); - dmae->len = (2*sizeof(u32)) >> 2; - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); - dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : - NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt1_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + - offsetof(struct nig_stats, egress_mac_pkt1_lo)); - dmae->len = (2*sizeof(u32)) >> 2; - dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_val = DMAE_COMP_VAL; - - *stats_comp = 0; -} - -static void bnx2x_func_stats_init(struct bnx2x *bp) -{ - struct dmae_command *dmae = &bp->stats_dmae; - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - /* sanity */ - if (!bp->func_stx) { - BNX2X_ERR("BUG!\n"); - return; - } - - bp->executer_idx = 0; - memset(dmae, 0, sizeof(struct dmae_command)); - - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); - dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); - dmae->dst_addr_lo = bp->func_stx >> 2; - dmae->dst_addr_hi = 0; - dmae->len = sizeof(struct host_func_stats) >> 2; - dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_val = DMAE_COMP_VAL; - - *stats_comp = 0; -} - -static void bnx2x_stats_start(struct bnx2x *bp) -{ - if (bp->port.pmf) - bnx2x_port_stats_init(bp); - - else if (bp->func_stx) - bnx2x_func_stats_init(bp); - - bnx2x_hw_stats_post(bp); - bnx2x_storm_stats_post(bp); -} - -static void bnx2x_stats_pmf_start(struct bnx2x *bp) -{ - bnx2x_stats_comp(bp); - bnx2x_stats_pmf_update(bp); - bnx2x_stats_start(bp); -} - -static void bnx2x_stats_restart(struct bnx2x *bp) -{ - bnx2x_stats_comp(bp); - bnx2x_stats_start(bp); -} - -static void bnx2x_bmac_stats_update(struct bnx2x *bp) -{ - struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats); - struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); - struct bnx2x_eth_stats *estats = &bp->eth_stats; - struct { - u32 lo; - u32 hi; - } diff; - - UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); - UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); - UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); - UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); - UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); - UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); - UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); - UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); - UPDATE_STAT64(tx_stat_gt127, - tx_stat_etherstatspkts65octetsto127octets); - UPDATE_STAT64(tx_stat_gt255, - tx_stat_etherstatspkts128octetsto255octets); - UPDATE_STAT64(tx_stat_gt511, - tx_stat_etherstatspkts256octetsto511octets); - UPDATE_STAT64(tx_stat_gt1023, - tx_stat_etherstatspkts512octetsto1023octets); - UPDATE_STAT64(tx_stat_gt1518, - tx_stat_etherstatspkts1024octetsto1522octets); - UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); - UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); - UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); - UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); - UPDATE_STAT64(tx_stat_gterr, - tx_stat_dot3statsinternalmactransmiterrors); - UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); - - estats->pause_frames_received_hi = - pstats->mac_stx[1].rx_stat_bmac_xpf_hi; - estats->pause_frames_received_lo = - pstats->mac_stx[1].rx_stat_bmac_xpf_lo; - - estats->pause_frames_sent_hi = - pstats->mac_stx[1].tx_stat_outxoffsent_hi; - estats->pause_frames_sent_lo = - pstats->mac_stx[1].tx_stat_outxoffsent_lo; -} - -static void bnx2x_emac_stats_update(struct bnx2x *bp) -{ - struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats); - struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); - struct bnx2x_eth_stats *estats = &bp->eth_stats; - - UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets); - UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets); - UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors); - UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors); - UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors); - UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors); - UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts); - UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong); - UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments); - UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers); - UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived); - UPDATE_EXTEND_STAT(rx_stat_xoffstateentered); - UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived); - UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived); - UPDATE_EXTEND_STAT(tx_stat_outxonsent); - UPDATE_EXTEND_STAT(tx_stat_outxoffsent); - UPDATE_EXTEND_STAT(tx_stat_flowcontroldone); - UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions); - UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes); - UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes); - UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions); - UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions); - UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions); - UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets); - UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets); - UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets); - UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets); - UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets); - UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets); - UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets); - UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors); - - estats->pause_frames_received_hi = - pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi; - estats->pause_frames_received_lo = - pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo; - ADD_64(estats->pause_frames_received_hi, - pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi, - estats->pause_frames_received_lo, - pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo); - - estats->pause_frames_sent_hi = - pstats->mac_stx[1].tx_stat_outxonsent_hi; - estats->pause_frames_sent_lo = - pstats->mac_stx[1].tx_stat_outxonsent_lo; - ADD_64(estats->pause_frames_sent_hi, - pstats->mac_stx[1].tx_stat_outxoffsent_hi, - estats->pause_frames_sent_lo, - pstats->mac_stx[1].tx_stat_outxoffsent_lo); -} - -static int bnx2x_hw_stats_update(struct bnx2x *bp) -{ - struct nig_stats *new = bnx2x_sp(bp, nig_stats); - struct nig_stats *old = &(bp->port.old_nig_stats); - struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); - struct bnx2x_eth_stats *estats = &bp->eth_stats; - struct { - u32 lo; - u32 hi; - } diff; - - if (bp->link_vars.mac_type == MAC_TYPE_BMAC) - bnx2x_bmac_stats_update(bp); - - else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) - bnx2x_emac_stats_update(bp); - - else { /* unreached */ - BNX2X_ERR("stats updated by DMAE but no MAC active\n"); - return -1; - } - - ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo, - new->brb_discard - old->brb_discard); - ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo, - new->brb_truncate - old->brb_truncate); - - UPDATE_STAT64_NIG(egress_mac_pkt0, - etherstatspkts1024octetsto1522octets); - UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets); - - memcpy(old, new, sizeof(struct nig_stats)); - - memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]), - sizeof(struct mac_stx)); - estats->brb_drop_hi = pstats->brb_drop_hi; - estats->brb_drop_lo = pstats->brb_drop_lo; - - pstats->host_port_stats_start = ++pstats->host_port_stats_end; - - if (!BP_NOMCP(bp)) { - u32 nig_timer_max = - SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); - if (nig_timer_max != estats->nig_timer_max) { - estats->nig_timer_max = nig_timer_max; - BNX2X_ERR("NIG timer max (%u)\n", - estats->nig_timer_max); - } - } - - return 0; -} - -static int bnx2x_storm_stats_update(struct bnx2x *bp) -{ - struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); - struct tstorm_per_port_stats *tport = - &stats->tstorm_common.port_statistics; - struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); - struct bnx2x_eth_stats *estats = &bp->eth_stats; - int i; - u16 cur_stats_counter; - - /* Make sure we use the value of the counter - * used for sending the last stats ramrod. - */ - spin_lock_bh(&bp->stats_lock); - cur_stats_counter = bp->stats_counter - 1; - spin_unlock_bh(&bp->stats_lock); - - memcpy(&(fstats->total_bytes_received_hi), - &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), - sizeof(struct host_func_stats) - 2*sizeof(u32)); - estats->error_bytes_received_hi = 0; - estats->error_bytes_received_lo = 0; - estats->etherstatsoverrsizepkts_hi = 0; - estats->etherstatsoverrsizepkts_lo = 0; - estats->no_buff_discard_hi = 0; - estats->no_buff_discard_lo = 0; - - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - int cl_id = fp->cl_id; - struct tstorm_per_client_stats *tclient = - &stats->tstorm_common.client_statistics[cl_id]; - struct tstorm_per_client_stats *old_tclient = &fp->old_tclient; - struct ustorm_per_client_stats *uclient = - &stats->ustorm_common.client_statistics[cl_id]; - struct ustorm_per_client_stats *old_uclient = &fp->old_uclient; - struct xstorm_per_client_stats *xclient = - &stats->xstorm_common.client_statistics[cl_id]; - struct xstorm_per_client_stats *old_xclient = &fp->old_xclient; - struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; - u32 diff; - - /* are storm stats valid? */ - if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) { - DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" - " xstorm counter (0x%x) != stats_counter (0x%x)\n", - i, xclient->stats_counter, cur_stats_counter + 1); - return -1; - } - if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) { - DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" - " tstorm counter (0x%x) != stats_counter (0x%x)\n", - i, tclient->stats_counter, cur_stats_counter + 1); - return -2; - } - if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) { - DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" - " ustorm counter (0x%x) != stats_counter (0x%x)\n", - i, uclient->stats_counter, cur_stats_counter + 1); - return -4; - } - - qstats->total_bytes_received_hi = - le32_to_cpu(tclient->rcv_broadcast_bytes.hi); - qstats->total_bytes_received_lo = - le32_to_cpu(tclient->rcv_broadcast_bytes.lo); - - ADD_64(qstats->total_bytes_received_hi, - le32_to_cpu(tclient->rcv_multicast_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(tclient->rcv_multicast_bytes.lo)); - - ADD_64(qstats->total_bytes_received_hi, - le32_to_cpu(tclient->rcv_unicast_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(tclient->rcv_unicast_bytes.lo)); - - SUB_64(qstats->total_bytes_received_hi, - le32_to_cpu(uclient->bcast_no_buff_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(uclient->bcast_no_buff_bytes.lo)); - - SUB_64(qstats->total_bytes_received_hi, - le32_to_cpu(uclient->mcast_no_buff_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(uclient->mcast_no_buff_bytes.lo)); - - SUB_64(qstats->total_bytes_received_hi, - le32_to_cpu(uclient->ucast_no_buff_bytes.hi), - qstats->total_bytes_received_lo, - le32_to_cpu(uclient->ucast_no_buff_bytes.lo)); - - qstats->valid_bytes_received_hi = - qstats->total_bytes_received_hi; - qstats->valid_bytes_received_lo = - qstats->total_bytes_received_lo; - - qstats->error_bytes_received_hi = - le32_to_cpu(tclient->rcv_error_bytes.hi); - qstats->error_bytes_received_lo = - le32_to_cpu(tclient->rcv_error_bytes.lo); - - ADD_64(qstats->total_bytes_received_hi, - qstats->error_bytes_received_hi, - qstats->total_bytes_received_lo, - qstats->error_bytes_received_lo); - - UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, - total_unicast_packets_received); - UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, - total_multicast_packets_received); - UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, - total_broadcast_packets_received); - UPDATE_EXTEND_TSTAT(packets_too_big_discard, - etherstatsoverrsizepkts); - UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard); - - SUB_EXTEND_USTAT(ucast_no_buff_pkts, - total_unicast_packets_received); - SUB_EXTEND_USTAT(mcast_no_buff_pkts, - total_multicast_packets_received); - SUB_EXTEND_USTAT(bcast_no_buff_pkts, - total_broadcast_packets_received); - UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard); - UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard); - UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard); - - qstats->total_bytes_transmitted_hi = - le32_to_cpu(xclient->unicast_bytes_sent.hi); - qstats->total_bytes_transmitted_lo = - le32_to_cpu(xclient->unicast_bytes_sent.lo); - - ADD_64(qstats->total_bytes_transmitted_hi, - le32_to_cpu(xclient->multicast_bytes_sent.hi), - qstats->total_bytes_transmitted_lo, - le32_to_cpu(xclient->multicast_bytes_sent.lo)); - - ADD_64(qstats->total_bytes_transmitted_hi, - le32_to_cpu(xclient->broadcast_bytes_sent.hi), - qstats->total_bytes_transmitted_lo, - le32_to_cpu(xclient->broadcast_bytes_sent.lo)); - - UPDATE_EXTEND_XSTAT(unicast_pkts_sent, - total_unicast_packets_transmitted); - UPDATE_EXTEND_XSTAT(multicast_pkts_sent, - total_multicast_packets_transmitted); - UPDATE_EXTEND_XSTAT(broadcast_pkts_sent, - total_broadcast_packets_transmitted); - - old_tclient->checksum_discard = tclient->checksum_discard; - old_tclient->ttl0_discard = tclient->ttl0_discard; - - ADD_64(fstats->total_bytes_received_hi, - qstats->total_bytes_received_hi, - fstats->total_bytes_received_lo, - qstats->total_bytes_received_lo); - ADD_64(fstats->total_bytes_transmitted_hi, - qstats->total_bytes_transmitted_hi, - fstats->total_bytes_transmitted_lo, - qstats->total_bytes_transmitted_lo); - ADD_64(fstats->total_unicast_packets_received_hi, - qstats->total_unicast_packets_received_hi, - fstats->total_unicast_packets_received_lo, - qstats->total_unicast_packets_received_lo); - ADD_64(fstats->total_multicast_packets_received_hi, - qstats->total_multicast_packets_received_hi, - fstats->total_multicast_packets_received_lo, - qstats->total_multicast_packets_received_lo); - ADD_64(fstats->total_broadcast_packets_received_hi, - qstats->total_broadcast_packets_received_hi, - fstats->total_broadcast_packets_received_lo, - qstats->total_broadcast_packets_received_lo); - ADD_64(fstats->total_unicast_packets_transmitted_hi, - qstats->total_unicast_packets_transmitted_hi, - fstats->total_unicast_packets_transmitted_lo, - qstats->total_unicast_packets_transmitted_lo); - ADD_64(fstats->total_multicast_packets_transmitted_hi, - qstats->total_multicast_packets_transmitted_hi, - fstats->total_multicast_packets_transmitted_lo, - qstats->total_multicast_packets_transmitted_lo); - ADD_64(fstats->total_broadcast_packets_transmitted_hi, - qstats->total_broadcast_packets_transmitted_hi, - fstats->total_broadcast_packets_transmitted_lo, - qstats->total_broadcast_packets_transmitted_lo); - ADD_64(fstats->valid_bytes_received_hi, - qstats->valid_bytes_received_hi, - fstats->valid_bytes_received_lo, - qstats->valid_bytes_received_lo); - - ADD_64(estats->error_bytes_received_hi, - qstats->error_bytes_received_hi, - estats->error_bytes_received_lo, - qstats->error_bytes_received_lo); - ADD_64(estats->etherstatsoverrsizepkts_hi, - qstats->etherstatsoverrsizepkts_hi, - estats->etherstatsoverrsizepkts_lo, - qstats->etherstatsoverrsizepkts_lo); - ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi, - estats->no_buff_discard_lo, qstats->no_buff_discard_lo); - } - - ADD_64(fstats->total_bytes_received_hi, - estats->rx_stat_ifhcinbadoctets_hi, - fstats->total_bytes_received_lo, - estats->rx_stat_ifhcinbadoctets_lo); - - memcpy(estats, &(fstats->total_bytes_received_hi), - sizeof(struct host_func_stats) - 2*sizeof(u32)); - - ADD_64(estats->etherstatsoverrsizepkts_hi, - estats->rx_stat_dot3statsframestoolong_hi, - estats->etherstatsoverrsizepkts_lo, - estats->rx_stat_dot3statsframestoolong_lo); - ADD_64(estats->error_bytes_received_hi, - estats->rx_stat_ifhcinbadoctets_hi, - estats->error_bytes_received_lo, - estats->rx_stat_ifhcinbadoctets_lo); - - if (bp->port.pmf) { - estats->mac_filter_discard = - le32_to_cpu(tport->mac_filter_discard); - estats->xxoverflow_discard = - le32_to_cpu(tport->xxoverflow_discard); - estats->brb_truncate_discard = - le32_to_cpu(tport->brb_truncate_discard); - estats->mac_discard = le32_to_cpu(tport->mac_discard); - } - - fstats->host_func_stats_start = ++fstats->host_func_stats_end; - - bp->stats_pending = 0; - - return 0; -} - -static void bnx2x_net_stats_update(struct bnx2x *bp) -{ - struct bnx2x_eth_stats *estats = &bp->eth_stats; - struct net_device_stats *nstats = &bp->dev->stats; - int i; - - nstats->rx_packets = - bnx2x_hilo(&estats->total_unicast_packets_received_hi) + - bnx2x_hilo(&estats->total_multicast_packets_received_hi) + - bnx2x_hilo(&estats->total_broadcast_packets_received_hi); - - nstats->tx_packets = - bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) + - bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) + - bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi); - - nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); - - nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); - - nstats->rx_dropped = estats->mac_discard; - for_each_queue(bp, i) - nstats->rx_dropped += - le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); - - nstats->tx_dropped = 0; - - nstats->multicast = - bnx2x_hilo(&estats->total_multicast_packets_received_hi); - - nstats->collisions = - bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi); - - nstats->rx_length_errors = - bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) + - bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi); - nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) + - bnx2x_hilo(&estats->brb_truncate_hi); - nstats->rx_crc_errors = - bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi); - nstats->rx_frame_errors = - bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi); - nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi); - nstats->rx_missed_errors = estats->xxoverflow_discard; - - nstats->rx_errors = nstats->rx_length_errors + - nstats->rx_over_errors + - nstats->rx_crc_errors + - nstats->rx_frame_errors + - nstats->rx_fifo_errors + - nstats->rx_missed_errors; - - nstats->tx_aborted_errors = - bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) + - bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi); - nstats->tx_carrier_errors = - bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi); - nstats->tx_fifo_errors = 0; - nstats->tx_heartbeat_errors = 0; - nstats->tx_window_errors = 0; - - nstats->tx_errors = nstats->tx_aborted_errors + - nstats->tx_carrier_errors + - bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi); -} - -static void bnx2x_drv_stats_update(struct bnx2x *bp) -{ - struct bnx2x_eth_stats *estats = &bp->eth_stats; - int i; - - estats->driver_xoff = 0; - estats->rx_err_discard_pkt = 0; - estats->rx_skb_alloc_failed = 0; - estats->hw_csum_err = 0; - for_each_queue(bp, i) { - struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats; - - estats->driver_xoff += qstats->driver_xoff; - estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt; - estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed; - estats->hw_csum_err += qstats->hw_csum_err; - } -} - -static void bnx2x_stats_update(struct bnx2x *bp) -{ - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - if (*stats_comp != DMAE_COMP_VAL) - return; - - if (bp->port.pmf) - bnx2x_hw_stats_update(bp); - - if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { - BNX2X_ERR("storm stats were not updated for 3 times\n"); - bnx2x_panic(); - return; - } - - bnx2x_net_stats_update(bp); - bnx2x_drv_stats_update(bp); - - if (netif_msg_timer(bp)) { - struct bnx2x_eth_stats *estats = &bp->eth_stats; - int i; - - printk(KERN_DEBUG "%s: brb drops %u brb truncate %u\n", - bp->dev->name, - estats->brb_drop_lo, estats->brb_truncate_lo); - - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; - - printk(KERN_DEBUG "%s: rx usage(%4u) *rx_cons_sb(%u)" - " rx pkt(%lu) rx calls(%lu %lu)\n", - fp->name, (le16_to_cpu(*fp->rx_cons_sb) - - fp->rx_comp_cons), - le16_to_cpu(*fp->rx_cons_sb), - bnx2x_hilo(&qstats-> - total_unicast_packets_received_hi), - fp->rx_calls, fp->rx_pkt); - } - - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; - struct netdev_queue *txq = - netdev_get_tx_queue(bp->dev, i); - - printk(KERN_DEBUG "%s: tx avail(%4u) *tx_cons_sb(%u)" - " tx pkt(%lu) tx calls (%lu)" - " %s (Xoff events %u)\n", - fp->name, bnx2x_tx_avail(fp), - le16_to_cpu(*fp->tx_cons_sb), - bnx2x_hilo(&qstats-> - total_unicast_packets_transmitted_hi), - fp->tx_pkt, - (netif_tx_queue_stopped(txq) ? "Xoff" : "Xon"), - qstats->driver_xoff); - } - } - - bnx2x_hw_stats_post(bp); - bnx2x_storm_stats_post(bp); -} - -static void bnx2x_port_stats_stop(struct bnx2x *bp) -{ - struct dmae_command *dmae; - u32 opcode; - int loader_idx = PMF_DMAE_C(bp); - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - bp->executer_idx = 0; - - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - - if (bp->port.port_stx) { - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - if (bp->func_stx) - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); - else - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); - dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); - dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); - dmae->dst_addr_lo = bp->port.port_stx >> 2; - dmae->dst_addr_hi = 0; - dmae->len = sizeof(struct host_port_stats) >> 2; - if (bp->func_stx) { - dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; - dmae->comp_addr_hi = 0; - dmae->comp_val = 1; - } else { - dmae->comp_addr_lo = - U64_LO(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_addr_hi = - U64_HI(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_val = DMAE_COMP_VAL; - - *stats_comp = 0; - } - } - - if (bp->func_stx) { - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); - dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); - dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); - dmae->dst_addr_lo = bp->func_stx >> 2; - dmae->dst_addr_hi = 0; - dmae->len = sizeof(struct host_func_stats) >> 2; - dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_val = DMAE_COMP_VAL; - - *stats_comp = 0; - } -} - -static void bnx2x_stats_stop(struct bnx2x *bp) -{ - int update = 0; - - bnx2x_stats_comp(bp); - - if (bp->port.pmf) - update = (bnx2x_hw_stats_update(bp) == 0); - - update |= (bnx2x_storm_stats_update(bp) == 0); - - if (update) { - bnx2x_net_stats_update(bp); - - if (bp->port.pmf) - bnx2x_port_stats_stop(bp); - - bnx2x_hw_stats_post(bp); - bnx2x_stats_comp(bp); - } -} - -static void bnx2x_stats_do_nothing(struct bnx2x *bp) -{ -} - -static const struct { - void (*action)(struct bnx2x *bp); - enum bnx2x_stats_state next_state; -} bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = { -/* state event */ -{ -/* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED}, -/* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED}, -/* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}, -/* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED} -}, -{ -/* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED}, -/* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED}, -/* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED}, -/* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED} -} -}; - -void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) -{ - enum bnx2x_stats_state state; - - if (unlikely(bp->panic)) - return; - - /* Protect a state change flow */ - spin_lock_bh(&bp->stats_lock); - state = bp->stats_state; - bp->stats_state = bnx2x_stats_stm[state][event].next_state; - spin_unlock_bh(&bp->stats_lock); - - bnx2x_stats_stm[state][event].action(bp); - - if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) - DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", - state, event, bp->stats_state); -} - -static void bnx2x_port_stats_base_init(struct bnx2x *bp) -{ - struct dmae_command *dmae; - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - /* sanity */ - if (!bp->port.pmf || !bp->port.port_stx) { - BNX2X_ERR("BUG!\n"); - return; - } - - bp->executer_idx = 0; - - dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); - dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); - dmae->dst_addr_lo = bp->port.port_stx >> 2; - dmae->dst_addr_hi = 0; - dmae->len = sizeof(struct host_port_stats) >> 2; - dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_val = DMAE_COMP_VAL; - - *stats_comp = 0; - bnx2x_hw_stats_post(bp); - bnx2x_stats_comp(bp); -} - -static void bnx2x_func_stats_base_init(struct bnx2x *bp) -{ - int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; - int port = BP_PORT(bp); - int func; - u32 func_stx; - - /* sanity */ - if (!bp->port.pmf || !bp->func_stx) { - BNX2X_ERR("BUG!\n"); - return; - } - - /* save our func_stx */ - func_stx = bp->func_stx; - - for (vn = VN_0; vn < vn_max; vn++) { - func = 2*vn + port; - - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); - bnx2x_func_stats_init(bp); - bnx2x_hw_stats_post(bp); - bnx2x_stats_comp(bp); - } - - /* restore our func_stx */ - bp->func_stx = func_stx; -} - -static void bnx2x_func_stats_base_update(struct bnx2x *bp) -{ - struct dmae_command *dmae = &bp->stats_dmae; - u32 *stats_comp = bnx2x_sp(bp, stats_comp); - - /* sanity */ - if (!bp->func_stx) { - BNX2X_ERR("BUG!\n"); - return; - } - - bp->executer_idx = 0; - memset(dmae, 0, sizeof(struct dmae_command)); - - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - dmae->src_addr_lo = bp->func_stx >> 2; - dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base)); - dmae->len = sizeof(struct host_func_stats) >> 2; - dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); - dmae->comp_val = DMAE_COMP_VAL; - - *stats_comp = 0; - bnx2x_hw_stats_post(bp); - bnx2x_stats_comp(bp); -} - -void bnx2x_stats_init(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int i; - - bp->stats_pending = 0; - bp->executer_idx = 0; - bp->stats_counter = 0; - - /* port and func stats for management */ - if (!BP_NOMCP(bp)) { - bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); - - } else { - bp->port.port_stx = 0; - bp->func_stx = 0; - } - DP(BNX2X_MSG_STATS, "port_stx 0x%x func_stx 0x%x\n", - bp->port.port_stx, bp->func_stx); - - /* port stats */ - memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); - bp->port.old_nig_stats.brb_discard = - REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); - bp->port.old_nig_stats.brb_truncate = - REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38); - REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, - &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); - REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, - &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); - - /* function stats */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - memset(&fp->old_tclient, 0, - sizeof(struct tstorm_per_client_stats)); - memset(&fp->old_uclient, 0, - sizeof(struct ustorm_per_client_stats)); - memset(&fp->old_xclient, 0, - sizeof(struct xstorm_per_client_stats)); - memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); - } - - memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); - memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); - - bp->stats_state = STATS_STATE_DISABLED; - - if (bp->port.pmf) { - if (bp->port.port_stx) - bnx2x_port_stats_base_init(bp); - - if (bp->func_stx) - bnx2x_func_stats_base_init(bp); - - } else if (bp->func_stx) - bnx2x_func_stats_base_update(bp); -} diff --git a/trunk/drivers/net/bnx2x/bnx2x_stats.h b/trunk/drivers/net/bnx2x/bnx2x_stats.h deleted file mode 100644 index 38a4e908f4fb..000000000000 --- a/trunk/drivers/net/bnx2x/bnx2x_stats.h +++ /dev/null @@ -1,239 +0,0 @@ -/* bnx2x_stats.h: Broadcom Everest network driver. - * - * Copyright (c) 2007-2010 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation. - * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir - * Based on code from Michael Chan's bnx2 driver - */ - -#ifndef BNX2X_STATS_H -#define BNX2X_STATS_H - -#include - -struct bnx2x_eth_q_stats { - u32 total_bytes_received_hi; - u32 total_bytes_received_lo; - u32 total_bytes_transmitted_hi; - u32 total_bytes_transmitted_lo; - u32 total_unicast_packets_received_hi; - u32 total_unicast_packets_received_lo; - u32 total_multicast_packets_received_hi; - u32 total_multicast_packets_received_lo; - u32 total_broadcast_packets_received_hi; - u32 total_broadcast_packets_received_lo; - u32 total_unicast_packets_transmitted_hi; - u32 total_unicast_packets_transmitted_lo; - u32 total_multicast_packets_transmitted_hi; - u32 total_multicast_packets_transmitted_lo; - u32 total_broadcast_packets_transmitted_hi; - u32 total_broadcast_packets_transmitted_lo; - u32 valid_bytes_received_hi; - u32 valid_bytes_received_lo; - - u32 error_bytes_received_hi; - u32 error_bytes_received_lo; - u32 etherstatsoverrsizepkts_hi; - u32 etherstatsoverrsizepkts_lo; - u32 no_buff_discard_hi; - u32 no_buff_discard_lo; - - u32 driver_xoff; - u32 rx_err_discard_pkt; - u32 rx_skb_alloc_failed; - u32 hw_csum_err; -}; - -#define BNX2X_NUM_Q_STATS 13 -#define Q_STATS_OFFSET32(stat_name) \ - (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) - -struct nig_stats { - u32 brb_discard; - u32 brb_packet; - u32 brb_truncate; - u32 flow_ctrl_discard; - u32 flow_ctrl_octets; - u32 flow_ctrl_packet; - u32 mng_discard; - u32 mng_octet_inp; - u32 mng_octet_out; - u32 mng_packet_inp; - u32 mng_packet_out; - u32 pbf_octets; - u32 pbf_packet; - u32 safc_inp; - u32 egress_mac_pkt0_lo; - u32 egress_mac_pkt0_hi; - u32 egress_mac_pkt1_lo; - u32 egress_mac_pkt1_hi; -}; - - -enum bnx2x_stats_event { - STATS_EVENT_PMF = 0, - STATS_EVENT_LINK_UP, - STATS_EVENT_UPDATE, - STATS_EVENT_STOP, - STATS_EVENT_MAX -}; - -enum bnx2x_stats_state { - STATS_STATE_DISABLED = 0, - STATS_STATE_ENABLED, - STATS_STATE_MAX -}; - -struct bnx2x_eth_stats { - u32 total_bytes_received_hi; - u32 total_bytes_received_lo; - u32 total_bytes_transmitted_hi; - u32 total_bytes_transmitted_lo; - u32 total_unicast_packets_received_hi; - u32 total_unicast_packets_received_lo; - u32 total_multicast_packets_received_hi; - u32 total_multicast_packets_received_lo; - u32 total_broadcast_packets_received_hi; - u32 total_broadcast_packets_received_lo; - u32 total_unicast_packets_transmitted_hi; - u32 total_unicast_packets_transmitted_lo; - u32 total_multicast_packets_transmitted_hi; - u32 total_multicast_packets_transmitted_lo; - u32 total_broadcast_packets_transmitted_hi; - u32 total_broadcast_packets_transmitted_lo; - u32 valid_bytes_received_hi; - u32 valid_bytes_received_lo; - - u32 error_bytes_received_hi; - u32 error_bytes_received_lo; - u32 etherstatsoverrsizepkts_hi; - u32 etherstatsoverrsizepkts_lo; - u32 no_buff_discard_hi; - u32 no_buff_discard_lo; - - u32 rx_stat_ifhcinbadoctets_hi; - u32 rx_stat_ifhcinbadoctets_lo; - u32 tx_stat_ifhcoutbadoctets_hi; - u32 tx_stat_ifhcoutbadoctets_lo; - u32 rx_stat_dot3statsfcserrors_hi; - u32 rx_stat_dot3statsfcserrors_lo; - u32 rx_stat_dot3statsalignmenterrors_hi; - u32 rx_stat_dot3statsalignmenterrors_lo; - u32 rx_stat_dot3statscarriersenseerrors_hi; - u32 rx_stat_dot3statscarriersenseerrors_lo; - u32 rx_stat_falsecarriererrors_hi; - u32 rx_stat_falsecarriererrors_lo; - u32 rx_stat_etherstatsundersizepkts_hi; - u32 rx_stat_etherstatsundersizepkts_lo; - u32 rx_stat_dot3statsframestoolong_hi; - u32 rx_stat_dot3statsframestoolong_lo; - u32 rx_stat_etherstatsfragments_hi; - u32 rx_stat_etherstatsfragments_lo; - u32 rx_stat_etherstatsjabbers_hi; - u32 rx_stat_etherstatsjabbers_lo; - u32 rx_stat_maccontrolframesreceived_hi; - u32 rx_stat_maccontrolframesreceived_lo; - u32 rx_stat_bmac_xpf_hi; - u32 rx_stat_bmac_xpf_lo; - u32 rx_stat_bmac_xcf_hi; - u32 rx_stat_bmac_xcf_lo; - u32 rx_stat_xoffstateentered_hi; - u32 rx_stat_xoffstateentered_lo; - u32 rx_stat_xonpauseframesreceived_hi; - u32 rx_stat_xonpauseframesreceived_lo; - u32 rx_stat_xoffpauseframesreceived_hi; - u32 rx_stat_xoffpauseframesreceived_lo; - u32 tx_stat_outxonsent_hi; - u32 tx_stat_outxonsent_lo; - u32 tx_stat_outxoffsent_hi; - u32 tx_stat_outxoffsent_lo; - u32 tx_stat_flowcontroldone_hi; - u32 tx_stat_flowcontroldone_lo; - u32 tx_stat_etherstatscollisions_hi; - u32 tx_stat_etherstatscollisions_lo; - u32 tx_stat_dot3statssinglecollisionframes_hi; - u32 tx_stat_dot3statssinglecollisionframes_lo; - u32 tx_stat_dot3statsmultiplecollisionframes_hi; - u32 tx_stat_dot3statsmultiplecollisionframes_lo; - u32 tx_stat_dot3statsdeferredtransmissions_hi; - u32 tx_stat_dot3statsdeferredtransmissions_lo; - u32 tx_stat_dot3statsexcessivecollisions_hi; - u32 tx_stat_dot3statsexcessivecollisions_lo; - u32 tx_stat_dot3statslatecollisions_hi; - u32 tx_stat_dot3statslatecollisions_lo; - u32 tx_stat_etherstatspkts64octets_hi; - u32 tx_stat_etherstatspkts64octets_lo; - u32 tx_stat_etherstatspkts65octetsto127octets_hi; - u32 tx_stat_etherstatspkts65octetsto127octets_lo; - u32 tx_stat_etherstatspkts128octetsto255octets_hi; - u32 tx_stat_etherstatspkts128octetsto255octets_lo; - u32 tx_stat_etherstatspkts256octetsto511octets_hi; - u32 tx_stat_etherstatspkts256octetsto511octets_lo; - u32 tx_stat_etherstatspkts512octetsto1023octets_hi; - u32 tx_stat_etherstatspkts512octetsto1023octets_lo; - u32 tx_stat_etherstatspkts1024octetsto1522octets_hi; - u32 tx_stat_etherstatspkts1024octetsto1522octets_lo; - u32 tx_stat_etherstatspktsover1522octets_hi; - u32 tx_stat_etherstatspktsover1522octets_lo; - u32 tx_stat_bmac_2047_hi; - u32 tx_stat_bmac_2047_lo; - u32 tx_stat_bmac_4095_hi; - u32 tx_stat_bmac_4095_lo; - u32 tx_stat_bmac_9216_hi; - u32 tx_stat_bmac_9216_lo; - u32 tx_stat_bmac_16383_hi; - u32 tx_stat_bmac_16383_lo; - u32 tx_stat_dot3statsinternalmactransmiterrors_hi; - u32 tx_stat_dot3statsinternalmactransmiterrors_lo; - u32 tx_stat_bmac_ufl_hi; - u32 tx_stat_bmac_ufl_lo; - - u32 pause_frames_received_hi; - u32 pause_frames_received_lo; - u32 pause_frames_sent_hi; - u32 pause_frames_sent_lo; - - u32 etherstatspkts1024octetsto1522octets_hi; - u32 etherstatspkts1024octetsto1522octets_lo; - u32 etherstatspktsover1522octets_hi; - u32 etherstatspktsover1522octets_lo; - - u32 brb_drop_hi; - u32 brb_drop_lo; - u32 brb_truncate_hi; - u32 brb_truncate_lo; - - u32 mac_filter_discard; - u32 xxoverflow_discard; - u32 brb_truncate_discard; - u32 mac_discard; - - u32 driver_xoff; - u32 rx_err_discard_pkt; - u32 rx_skb_alloc_failed; - u32 hw_csum_err; - - u32 nig_timer_max; -}; - -#define BNX2X_NUM_STATS 43 -#define STATS_OFFSET32(stat_name) \ - (offsetof(struct bnx2x_eth_stats, stat_name) / 4) - -/* Forward declaration */ -struct bnx2x; - - -void bnx2x_stats_init(struct bnx2x *bp); - -extern const u32 dmae_reg_go_c[]; -extern int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common); - - -#endif /* BNX2X_STATS_H */ diff --git a/trunk/drivers/net/bnx2x/bnx2x_dump.h b/trunk/drivers/net/bnx2x_dump.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_dump.h rename to trunk/drivers/net/bnx2x_dump.h diff --git a/trunk/drivers/net/bnx2x/bnx2x_fw_defs.h b/trunk/drivers/net/bnx2x_fw_defs.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_fw_defs.h rename to trunk/drivers/net/bnx2x_fw_defs.h diff --git a/trunk/drivers/net/bnx2x/bnx2x_fw_file_hdr.h b/trunk/drivers/net/bnx2x_fw_file_hdr.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_fw_file_hdr.h rename to trunk/drivers/net/bnx2x_fw_file_hdr.h diff --git a/trunk/drivers/net/bnx2x/bnx2x_hsi.h b/trunk/drivers/net/bnx2x_hsi.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_hsi.h rename to trunk/drivers/net/bnx2x_hsi.h diff --git a/trunk/drivers/net/bnx2x/bnx2x_init.h b/trunk/drivers/net/bnx2x_init.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_init.h rename to trunk/drivers/net/bnx2x_init.h diff --git a/trunk/drivers/net/bnx2x/bnx2x_init_ops.h b/trunk/drivers/net/bnx2x_init_ops.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_init_ops.h rename to trunk/drivers/net/bnx2x_init_ops.h diff --git a/trunk/drivers/net/bnx2x/bnx2x_link.c b/trunk/drivers/net/bnx2x_link.c similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_link.c rename to trunk/drivers/net/bnx2x_link.c diff --git a/trunk/drivers/net/bnx2x/bnx2x_link.h b/trunk/drivers/net/bnx2x_link.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_link.h rename to trunk/drivers/net/bnx2x_link.h diff --git a/trunk/drivers/net/bnx2x/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c similarity index 56% rename from trunk/drivers/net/bnx2x/bnx2x_main.c rename to trunk/drivers/net/bnx2x_main.c index b4ec2b02a465..51b788339c90 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -51,12 +51,15 @@ #include #include -#define BNX2X_MAIN + #include "bnx2x.h" #include "bnx2x_init.h" #include "bnx2x_init_ops.h" -#include "bnx2x_cmn.h" +#include "bnx2x_dump.h" +#define DRV_MODULE_VERSION "1.52.53-1" +#define DRV_MODULE_RELDATE "2010/18/04" +#define BNX2X_BC_VER 0x040200 #include #include "bnx2x_fw_file_hdr.h" @@ -118,6 +121,8 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, " Default debug msglevel"); +static int load_count[3]; /* 0-common, 1-port0, 2-port1 */ + static struct workqueue_struct *bnx2x_wq; enum bnx2x_board_type { @@ -172,7 +177,7 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) return val; } -const u32 dmae_reg_go_c[] = { +static const u32 dmae_reg_go_c[] = { DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11, @@ -180,7 +185,8 @@ const u32 dmae_reg_go_c[] = { }; /* copy command into DMAE command memory and set DMAE command go */ -void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx) +static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, + int idx) { u32 cmd_offset; int i; @@ -535,7 +541,7 @@ static void bnx2x_fw_dump(struct bnx2x *bp) pr_err("end of fw dump\n"); } -void bnx2x_panic_dump(struct bnx2x *bp) +static void bnx2x_panic_dump(struct bnx2x *bp) { int i; u16 j, start, end; @@ -648,7 +654,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) BNX2X_ERR("end crash dump -----------------\n"); } -void bnx2x_int_enable(struct bnx2x *bp) +static void bnx2x_int_enable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -730,7 +736,7 @@ static void bnx2x_int_disable(struct bnx2x *bp) BNX2X_ERR("BUG! proper val not read from IGU!\n"); } -void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) +static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) { int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; int i, offset; @@ -800,12 +806,235 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) return false; } +static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, + u8 storm, u16 index, u8 op, u8 update) +{ + u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + + COMMAND_REG_INT_ACK); + struct igu_ack_register igu_ack; + + igu_ack.status_block_index = index; + igu_ack.sb_id_and_flags = + ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) | + (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) | + (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) | + (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT)); + + DP(BNX2X_MSG_OFF, "write 0x%08x to HC addr 0x%x\n", + (*(u32 *)&igu_ack), hc_addr); + REG_WR(bp, hc_addr, (*(u32 *)&igu_ack)); + + /* Make sure that ACK is written */ + mmiowb(); + barrier(); +} + +static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) +{ + struct host_status_block *fpsb = fp->status_blk; + + barrier(); /* status block is written to by the chip */ + fp->fp_c_idx = fpsb->c_status_block.status_block_index; + fp->fp_u_idx = fpsb->u_status_block.status_block_index; +} + +static u16 bnx2x_ack_int(struct bnx2x *bp) +{ + u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + + COMMAND_REG_SIMD_MASK); + u32 result = REG_RD(bp, hc_addr); + + DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n", + result, hc_addr); + + return result; +} + + +/* + * fast path service functions + */ + +static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) +{ + /* Tell compiler that consumer and producer can change */ + barrier(); + return (fp->tx_pkt_prod != fp->tx_pkt_cons); +} + +/* free skb in the packet ring at pos idx + * return idx of last bd freed + */ +static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, + u16 idx) +{ + struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx]; + struct eth_tx_start_bd *tx_start_bd; + struct eth_tx_bd *tx_data_bd; + struct sk_buff *skb = tx_buf->skb; + u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons; + int nbd; + + /* prefetch skb end pointer to speedup dev_kfree_skb() */ + prefetch(&skb->end); + + DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n", + idx, tx_buf, skb); + + /* unmap first bd */ + DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); + tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd; + dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), + BD_UNMAP_LEN(tx_start_bd), PCI_DMA_TODEVICE); + + nbd = le16_to_cpu(tx_start_bd->nbd) - 1; +#ifdef BNX2X_STOP_ON_ERROR + if ((nbd - 1) > (MAX_SKB_FRAGS + 2)) { + BNX2X_ERR("BAD nbd!\n"); + bnx2x_panic(); + } +#endif + new_cons = nbd + tx_buf->first_bd; + + /* Get the next bd */ + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + + /* Skip a parse bd... */ + --nbd; + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + + /* ...and the TSO split header bd since they have no mapping */ + if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) { + --nbd; + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + } + + /* now free frags */ + while (nbd > 0) { + + DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx); + tx_data_bd = &fp->tx_desc_ring[bd_idx].reg_bd; + dma_unmap_page(&bp->pdev->dev, BD_UNMAP_ADDR(tx_data_bd), + BD_UNMAP_LEN(tx_data_bd), DMA_TO_DEVICE); + if (--nbd) + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + } + + /* release skb */ + WARN_ON(!skb); + dev_kfree_skb(skb); + tx_buf->first_bd = 0; + tx_buf->skb = NULL; + + return new_cons; +} + +static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) +{ + s16 used; + u16 prod; + u16 cons; + + prod = fp->tx_bd_prod; + cons = fp->tx_bd_cons; + + /* NUM_TX_RINGS = number of "next-page" entries + It will be used as a threshold */ + used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; + +#ifdef BNX2X_STOP_ON_ERROR + WARN_ON(used < 0); + WARN_ON(used > fp->bp->tx_ring_size); + WARN_ON((fp->bp->tx_ring_size - used) > MAX_TX_AVAIL); +#endif + + return (s16)(fp->bp->tx_ring_size) - used; +} + +static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) +{ + u16 hw_cons; + + /* Tell compiler that status block fields can change */ + barrier(); + hw_cons = le16_to_cpu(*fp->tx_cons_sb); + return hw_cons != fp->tx_pkt_cons; +} + +static int bnx2x_tx_int(struct bnx2x_fastpath *fp) +{ + struct bnx2x *bp = fp->bp; + struct netdev_queue *txq; + u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons; + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return -1; +#endif + + txq = netdev_get_tx_queue(bp->dev, fp->index); + hw_cons = le16_to_cpu(*fp->tx_cons_sb); + sw_cons = fp->tx_pkt_cons; + + while (sw_cons != hw_cons) { + u16 pkt_cons; + + pkt_cons = TX_BD(sw_cons); + + /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */ + + DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n", + hw_cons, sw_cons, pkt_cons); + +/* if (NEXT_TX_IDX(sw_cons) != hw_cons) { + rmb(); + prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb); + } +*/ + bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons); + sw_cons++; + } + + fp->tx_pkt_cons = sw_cons; + fp->tx_bd_cons = bd_cons; + + /* Need to make the tx_bd_cons update visible to start_xmit() + * before checking for netif_tx_queue_stopped(). Without the + * memory barrier, there is a small possibility that + * start_xmit() will miss it and cause the queue to be stopped + * forever. + */ + smp_mb(); + + /* TBD need a thresh? */ + if (unlikely(netif_tx_queue_stopped(txq))) { + /* Taking tx_lock() is needed to prevent reenabling the queue + * while it's empty. This could have happen if rx_action() gets + * suspended in bnx2x_tx_int() after the condition before + * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()): + * + * stops the queue->sees fresh tx_bd_cons->releases the queue-> + * sends some packets consuming the whole queue again-> + * stops the queue + */ + + __netif_tx_lock(txq, smp_processor_id()); + + if ((netif_tx_queue_stopped(txq)) && + (bp->state == BNX2X_STATE_OPEN) && + (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)) + netif_tx_wake_queue(txq); + + __netif_tx_unlock(txq); + } + return 0; +} #ifdef BCM_CNIC static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid); #endif -void bnx2x_sp_event(struct bnx2x_fastpath *fp, +static void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe) { struct bnx2x *bp = fp->bp; @@ -889,5906 +1118,11419 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, mb(); /* force bnx2x_wait_ramrod() to see the change */ } -irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) +static inline void bnx2x_free_rx_sge(struct bnx2x *bp, + struct bnx2x_fastpath *fp, u16 index) { - struct bnx2x *bp = netdev_priv(dev_instance); - u16 status = bnx2x_ack_int(bp); - u16 mask; - int i; + struct sw_rx_page *sw_buf = &fp->rx_page_ring[index]; + struct page *page = sw_buf->page; + struct eth_rx_sge *sge = &fp->rx_sge_ring[index]; - /* Return here if interrupt is shared and it's not for us */ - if (unlikely(status == 0)) { - DP(NETIF_MSG_INTR, "not our interrupt!\n"); - return IRQ_NONE; - } - DP(NETIF_MSG_INTR, "got an interrupt status 0x%x\n", status); + /* Skip "next page" elements */ + if (!page) + return; - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return IRQ_HANDLED; - } + dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping), + SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + __free_pages(page, PAGES_PER_SGE_SHIFT); -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return IRQ_HANDLED; -#endif + sw_buf->page = NULL; + sge->addr_hi = 0; + sge->addr_lo = 0; +} - for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) { - struct bnx2x_fastpath *fp = &bp->fp[i]; +static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, + struct bnx2x_fastpath *fp, int last) +{ + int i; - mask = 0x2 << fp->sb_id; - if (status & mask) { - /* Handle Rx and Tx according to SB id */ - prefetch(fp->rx_cons_sb); - prefetch(&fp->status_blk->u_status_block. - status_block_index); - prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->c_status_block. - status_block_index); - napi_schedule(&bnx2x_fp(bp, fp->index, napi)); - status &= ~mask; - } - } + for (i = 0; i < last; i++) + bnx2x_free_rx_sge(bp, fp, i); +} -#ifdef BCM_CNIC - mask = 0x2 << CNIC_SB_ID(bp); - if (status & (mask | 0x1)) { - struct cnic_ops *c_ops = NULL; +static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, + struct bnx2x_fastpath *fp, u16 index) +{ + struct page *page = alloc_pages(GFP_ATOMIC, PAGES_PER_SGE_SHIFT); + struct sw_rx_page *sw_buf = &fp->rx_page_ring[index]; + struct eth_rx_sge *sge = &fp->rx_sge_ring[index]; + dma_addr_t mapping; - rcu_read_lock(); - c_ops = rcu_dereference(bp->cnic_ops); - if (c_ops) - c_ops->cnic_handler(bp->cnic_data, NULL); - rcu_read_unlock(); + if (unlikely(page == NULL)) + return -ENOMEM; - status &= ~mask; + mapping = dma_map_page(&bp->pdev->dev, page, 0, + SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + __free_pages(page, PAGES_PER_SGE_SHIFT); + return -ENOMEM; } -#endif - - if (unlikely(status & 0x1)) { - queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); - status &= ~0x1; - if (!status) - return IRQ_HANDLED; - } + sw_buf->page = page; + dma_unmap_addr_set(sw_buf, mapping, mapping); - if (unlikely(status)) - DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n", - status); + sge->addr_hi = cpu_to_le32(U64_HI(mapping)); + sge->addr_lo = cpu_to_le32(U64_LO(mapping)); - return IRQ_HANDLED; + return 0; } -/* end of fast path */ +static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, + struct bnx2x_fastpath *fp, u16 index) +{ + struct sk_buff *skb; + struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index]; + struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; + dma_addr_t mapping; + skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); + if (unlikely(skb == NULL)) + return -ENOMEM; -/* Link */ + mapping = dma_map_single(&bp->pdev->dev, skb->data, bp->rx_buf_size, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { + dev_kfree_skb(skb); + return -ENOMEM; + } -/* - * General service functions - */ + rx_buf->skb = skb; + dma_unmap_addr_set(rx_buf, mapping, mapping); + + rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + + return 0; +} -int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource) +/* note that we are not allocating a new skb, + * we are just moving one from cons to prod + * we are not creating a new mapping, + * so there is no need to check for dma_mapping_error(). + */ +static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, + struct sk_buff *skb, u16 cons, u16 prod) { - u32 lock_status; - u32 resource_bit = (1 << resource); - int func = BP_FUNC(bp); - u32 hw_lock_control_reg; - int cnt; + struct bnx2x *bp = fp->bp; + struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; + struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; + struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons]; + struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; - /* Validating that the resource is within range */ - if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { - DP(NETIF_MSG_HW, - "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", - resource, HW_LOCK_MAX_RESOURCE_VALUE); - return -EINVAL; - } + dma_sync_single_for_device(&bp->pdev->dev, + dma_unmap_addr(cons_rx_buf, mapping), + RX_COPY_THRESH, DMA_FROM_DEVICE); - if (func <= 5) { - hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8); - } else { - hw_lock_control_reg = - (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8); - } + prod_rx_buf->skb = cons_rx_buf->skb; + dma_unmap_addr_set(prod_rx_buf, mapping, + dma_unmap_addr(cons_rx_buf, mapping)); + *prod_bd = *cons_bd; +} - /* Validating that the resource is not already taken */ - lock_status = REG_RD(bp, hw_lock_control_reg); - if (lock_status & resource_bit) { - DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", - lock_status, resource_bit); - return -EEXIST; - } +static inline void bnx2x_update_last_max_sge(struct bnx2x_fastpath *fp, + u16 idx) +{ + u16 last_max = fp->last_max_sge; - /* Try for 5 second every 5ms */ - for (cnt = 0; cnt < 1000; cnt++) { - /* Try to acquire the lock */ - REG_WR(bp, hw_lock_control_reg + 4, resource_bit); - lock_status = REG_RD(bp, hw_lock_control_reg); - if (lock_status & resource_bit) - return 0; + if (SUB_S16(idx, last_max) > 0) + fp->last_max_sge = idx; +} - msleep(5); +static void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) +{ + int i, j; + + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + int idx = RX_SGE_CNT * i - 1; + + for (j = 0; j < 2; j++) { + SGE_MASK_CLEAR_BIT(fp, idx); + idx--; + } } - DP(NETIF_MSG_HW, "Timeout\n"); - return -EAGAIN; } -int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource) +static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, + struct eth_fast_path_rx_cqe *fp_cqe) { - u32 lock_status; - u32 resource_bit = (1 << resource); - int func = BP_FUNC(bp); - u32 hw_lock_control_reg; + struct bnx2x *bp = fp->bp; + u16 sge_len = SGE_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) - + le16_to_cpu(fp_cqe->len_on_bd)) >> + SGE_PAGE_SHIFT; + u16 last_max, last_elem, first_elem; + u16 delta = 0; + u16 i; - DP(NETIF_MSG_HW, "Releasing a lock on resource %d\n", resource); + if (!sge_len) + return; - /* Validating that the resource is within range */ - if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { - DP(NETIF_MSG_HW, - "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", - resource, HW_LOCK_MAX_RESOURCE_VALUE); - return -EINVAL; - } + /* First mark all used pages */ + for (i = 0; i < sge_len; i++) + SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i]))); - if (func <= 5) { - hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8); - } else { - hw_lock_control_reg = - (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8); + DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n", + sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + + /* Here we assume that the last SGE index is the biggest */ + prefetch((void *)(fp->sge_mask)); + bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + + last_max = RX_SGE(fp->last_max_sge); + last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT; + first_elem = RX_SGE(fp->rx_sge_prod) >> RX_SGE_MASK_ELEM_SHIFT; + + /* If ring is not full */ + if (last_elem + 1 != first_elem) + last_elem++; + + /* Now update the prod */ + for (i = first_elem; i != last_elem; i = NEXT_SGE_MASK_ELEM(i)) { + if (likely(fp->sge_mask[i])) + break; + + fp->sge_mask[i] = RX_SGE_MASK_ELEM_ONE_MASK; + delta += RX_SGE_MASK_ELEM_SZ; } - /* Validating that the resource is currently taken */ - lock_status = REG_RD(bp, hw_lock_control_reg); - if (!(lock_status & resource_bit)) { - DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", - lock_status, resource_bit); - return -EFAULT; + if (delta > 0) { + fp->rx_sge_prod += delta; + /* clear page-end entries */ + bnx2x_clear_sge_mask_next_elems(fp); } - REG_WR(bp, hw_lock_control_reg, resource_bit); - return 0; + DP(NETIF_MSG_RX_STATUS, + "fp->last_max_sge = %d fp->rx_sge_prod = %d\n", + fp->last_max_sge, fp->rx_sge_prod); } - -int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port) +static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) { - /* The GPIO should be swapped if swap register is set and active */ - int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && - REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; - int gpio_shift = gpio_num + - (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); - u32 gpio_mask = (1 << gpio_shift); - u32 gpio_reg; - int value; + /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ + memset(fp->sge_mask, 0xff, + (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); - if (gpio_num > MISC_REGISTERS_GPIO_3) { - BNX2X_ERR("Invalid GPIO %d\n", gpio_num); - return -EINVAL; - } + /* Clear the two last indices in the page to 1: + these are the indices that correspond to the "next" element, + hence will never be indicated and should be removed from + the calculations. */ + bnx2x_clear_sge_mask_next_elems(fp); +} - /* read GPIO value */ - gpio_reg = REG_RD(bp, MISC_REG_GPIO); +static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, + struct sk_buff *skb, u16 cons, u16 prod) +{ + struct bnx2x *bp = fp->bp; + struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; + struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; + struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; + dma_addr_t mapping; - /* get the requested pin value */ - if ((gpio_reg & gpio_mask) == gpio_mask) - value = 1; - else - value = 0; + /* move empty skb from pool to prod and map it */ + prod_rx_buf->skb = fp->tpa_pool[queue].skb; + mapping = dma_map_single(&bp->pdev->dev, fp->tpa_pool[queue].skb->data, + bp->rx_buf_size, DMA_FROM_DEVICE); + dma_unmap_addr_set(prod_rx_buf, mapping, mapping); - DP(NETIF_MSG_LINK, "pin %d value 0x%x\n", gpio_num, value); + /* move partial skb from cons to pool (don't unmap yet) */ + fp->tpa_pool[queue] = *cons_rx_buf; - return value; + /* mark bin state as start - print error if current state != stop */ + if (fp->tpa_state[queue] != BNX2X_TPA_STOP) + BNX2X_ERR("start of bin not in stop [%d]\n", queue); + + fp->tpa_state[queue] = BNX2X_TPA_START; + + /* point prod_bd to new skb */ + prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + +#ifdef BNX2X_STOP_ON_ERROR + fp->tpa_queue_used |= (1 << queue); +#ifdef _ASM_GENERIC_INT_L64_H + DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n", +#else + DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n", +#endif + fp->tpa_queue_used); +#endif } -int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) +static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, + struct sk_buff *skb, + struct eth_fast_path_rx_cqe *fp_cqe, + u16 cqe_idx) { - /* The GPIO should be swapped if swap register is set and active */ - int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && - REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; - int gpio_shift = gpio_num + - (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); - u32 gpio_mask = (1 << gpio_shift); - u32 gpio_reg; + struct sw_rx_page *rx_pg, old_rx_pg; + u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); + u32 i, frag_len, frag_size, pages; + int err; + int j; - if (gpio_num > MISC_REGISTERS_GPIO_3) { - BNX2X_ERR("Invalid GPIO %d\n", gpio_num); + frag_size = le16_to_cpu(fp_cqe->pkt_len) - len_on_bd; + pages = SGE_PAGE_ALIGN(frag_size) >> SGE_PAGE_SHIFT; + + /* This is needed in order to enable forwarding support */ + if (frag_size) + skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, + max(frag_size, (u32)len_on_bd)); + +#ifdef BNX2X_STOP_ON_ERROR + if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { + BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n", + pages, cqe_idx); + BNX2X_ERR("fp_cqe->pkt_len = %d fp_cqe->len_on_bd = %d\n", + fp_cqe->pkt_len, len_on_bd); + bnx2x_panic(); return -EINVAL; } +#endif - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); - /* read GPIO and mask except the float bits */ - gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT); + /* Run through the SGL and compose the fragmented skb */ + for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) { + u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j])); + + /* FW gives the indices of the SGE as if the ring is an array + (meaning that "next" element will consume 2 indices) */ + frag_len = min(frag_size, (u32)(SGE_PAGE_SIZE*PAGES_PER_SGE)); + rx_pg = &fp->rx_page_ring[sge_idx]; + old_rx_pg = *rx_pg; + + /* If we fail to allocate a substitute page, we simply stop + where we are and drop the whole packet */ + err = bnx2x_alloc_rx_sge(bp, fp, sge_idx); + if (unlikely(err)) { + fp->eth_q_stats.rx_skb_alloc_failed++; + return err; + } - switch (mode) { - case MISC_REGISTERS_GPIO_OUTPUT_LOW: - DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n", - gpio_num, gpio_shift); - /* clear FLOAT and set CLR */ - gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); - gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS); - break; + /* Unmap the page as we r going to pass it to the stack */ + dma_unmap_page(&bp->pdev->dev, + dma_unmap_addr(&old_rx_pg, mapping), + SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE); - case MISC_REGISTERS_GPIO_OUTPUT_HIGH: - DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n", - gpio_num, gpio_shift); - /* clear FLOAT and set SET */ - gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); - gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS); - break; + /* Add one frag and update the appropriate fields in the skb */ + skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len); - case MISC_REGISTERS_GPIO_INPUT_HI_Z: - DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n", - gpio_num, gpio_shift); - /* set FLOAT */ - gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); - break; + skb->data_len += frag_len; + skb->truesize += frag_len; + skb->len += frag_len; - default: - break; + frag_size -= frag_len; } - REG_WR(bp, MISC_REG_GPIO, gpio_reg); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); - return 0; } -int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) +static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, + u16 queue, int pad, int len, union eth_rx_cqe *cqe, + u16 cqe_idx) { - /* The GPIO should be swapped if swap register is set and active */ - int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && - REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; - int gpio_shift = gpio_num + - (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); - u32 gpio_mask = (1 << gpio_shift); - u32 gpio_reg; - - if (gpio_num > MISC_REGISTERS_GPIO_3) { - BNX2X_ERR("Invalid GPIO %d\n", gpio_num); - return -EINVAL; - } + struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue]; + struct sk_buff *skb = rx_buf->skb; + /* alloc new skb */ + struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); - /* read GPIO int */ - gpio_reg = REG_RD(bp, MISC_REG_GPIO_INT); - - switch (mode) { - case MISC_REGISTERS_GPIO_INT_OUTPUT_CLR: - DP(NETIF_MSG_LINK, "Clear GPIO INT %d (shift %d) -> " - "output low\n", gpio_num, gpio_shift); - /* clear SET and set CLR */ - gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS); - gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS); - break; + /* Unmap skb in the pool anyway, as we are going to change + pool entry status to BNX2X_TPA_STOP even if new skb allocation + fails. */ + dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), + bp->rx_buf_size, DMA_FROM_DEVICE); - case MISC_REGISTERS_GPIO_INT_OUTPUT_SET: - DP(NETIF_MSG_LINK, "Set GPIO INT %d (shift %d) -> " - "output high\n", gpio_num, gpio_shift); - /* clear CLR and set SET */ - gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS); - gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS); - break; + if (likely(new_skb)) { + /* fix ip xsum and give it to the stack */ + /* (no need to map the new skb) */ +#ifdef BCM_VLAN + int is_vlan_cqe = + (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & + PARSING_FLAGS_VLAN); + int is_not_hwaccel_vlan_cqe = + (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG))); +#endif - default: - break; - } + prefetch(skb); + prefetch(((char *)(skb)) + 128); - REG_WR(bp, MISC_REG_GPIO_INT, gpio_reg); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); +#ifdef BNX2X_STOP_ON_ERROR + if (pad + len > bp->rx_buf_size) { + BNX2X_ERR("skb_put is about to fail... " + "pad %d len %d rx_buf_size %d\n", + pad, len, bp->rx_buf_size); + bnx2x_panic(); + return; + } +#endif - return 0; -} + skb_reserve(skb, pad); + skb_put(skb, len); -static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) -{ - u32 spio_mask = (1 << spio_num); - u32 spio_reg; + skb->protocol = eth_type_trans(skb, bp->dev); + skb->ip_summed = CHECKSUM_UNNECESSARY; - if ((spio_num < MISC_REGISTERS_SPIO_4) || - (spio_num > MISC_REGISTERS_SPIO_7)) { - BNX2X_ERR("Invalid SPIO %d\n", spio_num); - return -EINVAL; - } + { + struct iphdr *iph; - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); - /* read SPIO and mask except the float bits */ - spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT); + iph = (struct iphdr *)skb->data; +#ifdef BCM_VLAN + /* If there is no Rx VLAN offloading - + take VLAN tag into an account */ + if (unlikely(is_not_hwaccel_vlan_cqe)) + iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN); +#endif + iph->check = 0; + iph->check = ip_fast_csum((u8 *)iph, iph->ihl); + } - switch (mode) { - case MISC_REGISTERS_SPIO_OUTPUT_LOW: - DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num); - /* clear FLOAT and set CLR */ - spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); - spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS); - break; + if (!bnx2x_fill_frag_skb(bp, fp, skb, + &cqe->fast_path_cqe, cqe_idx)) { +#ifdef BCM_VLAN + if ((bp->vlgrp != NULL) && is_vlan_cqe && + (!is_not_hwaccel_vlan_cqe)) + vlan_gro_receive(&fp->napi, bp->vlgrp, + le16_to_cpu(cqe->fast_path_cqe. + vlan_tag), skb); + else +#endif + napi_gro_receive(&fp->napi, skb); + } else { + DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages" + " - dropping packet!\n"); + dev_kfree_skb(skb); + } - case MISC_REGISTERS_SPIO_OUTPUT_HIGH: - DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num); - /* clear FLOAT and set SET */ - spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); - spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS); - break; - case MISC_REGISTERS_SPIO_INPUT_HI_Z: - DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num); - /* set FLOAT */ - spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); - break; + /* put new skb in bin */ + fp->tpa_pool[queue].skb = new_skb; - default: - break; + } else { + /* else drop the packet and keep the buffer in the bin */ + DP(NETIF_MSG_RX_STATUS, + "Failed to allocate new skb - dropping packet!\n"); + fp->eth_q_stats.rx_skb_alloc_failed++; } - REG_WR(bp, MISC_REG_SPIO, spio_reg); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); - - return 0; + fp->tpa_state[queue] = BNX2X_TPA_STOP; } -void bnx2x_calc_fc_adv(struct bnx2x *bp) +static inline void bnx2x_update_rx_prod(struct bnx2x *bp, + struct bnx2x_fastpath *fp, + u16 bd_prod, u16 rx_comp_prod, + u16 rx_sge_prod) { - switch (bp->link_vars.ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { - case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); - break; + struct ustorm_eth_rx_producers rx_prods = {0}; + int i; - case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: - bp->port.advertising |= (ADVERTISED_Asym_Pause | - ADVERTISED_Pause); - break; + /* Update producers */ + rx_prods.bd_prod = bd_prod; + rx_prods.cqe_prod = rx_comp_prod; + rx_prods.sge_prod = rx_sge_prod; - case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: - bp->port.advertising |= ADVERTISED_Asym_Pause; - break; + /* + * Make sure that the BD and SGE data is updated before updating the + * producers since FW might read the BD/SGE right after the producer + * is updated. + * This is only applicable for weak-ordered memory model archs such + * as IA-64. The following barrier is also mandatory since FW will + * assumes BDs must have buffers. + */ + wmb(); - default: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); - break; - } -} + for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++) + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4, + ((u32 *)&rx_prods)[i]); + + mmiowb(); /* keep prod updates ordered */ + DP(NETIF_MSG_RX_STATUS, + "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n", + fp->index, bd_prod, rx_comp_prod, rx_sge_prod); +} -u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) +/* Set Toeplitz hash value in the skb using the value from the + * CQE (calculated by HW). + */ +static inline void bnx2x_set_skb_rxhash(struct bnx2x *bp, union eth_rx_cqe *cqe, + struct sk_buff *skb) { - if (!BP_NOMCP(bp)) { - u8 rc; + /* Set Toeplitz hash from CQE */ + if ((bp->dev->features & NETIF_F_RXHASH) && + (cqe->fast_path_cqe.status_flags & + ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) + skb->rxhash = + le32_to_cpu(cqe->fast_path_cqe.rss_hash_result); +} - /* Initialize link parameters structure variables */ - /* It is recommended to turn off RX FC for jumbo frames - for better performance */ - if (bp->dev->mtu > 5000) - bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX; - else - bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; +static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) +{ + struct bnx2x *bp = fp->bp; + u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons; + u16 hw_comp_cons, sw_comp_cons, sw_comp_prod; + int rx_pkt = 0; - bnx2x_acquire_phy_lock(bp); +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return 0; +#endif - if (load_mode == LOAD_DIAG) - bp->link_params.loopback_mode = LOOPBACK_XGXS_10; + /* CQ "next element" is of the size of the regular element, + that's why it's ok here */ + hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb); + if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) + hw_comp_cons++; - rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); + bd_cons = fp->rx_bd_cons; + bd_prod = fp->rx_bd_prod; + bd_prod_fw = bd_prod; + sw_comp_cons = fp->rx_comp_cons; + sw_comp_prod = fp->rx_comp_prod; - bnx2x_release_phy_lock(bp); + /* Memory barrier necessary as speculative reads of the rx + * buffer can be ahead of the index in the status block + */ + rmb(); - bnx2x_calc_fc_adv(bp); + DP(NETIF_MSG_RX_STATUS, + "queue[%d]: hw_comp_cons %u sw_comp_cons %u\n", + fp->index, hw_comp_cons, sw_comp_cons); + + while (sw_comp_cons != hw_comp_cons) { + struct sw_rx_bd *rx_buf = NULL; + struct sk_buff *skb; + union eth_rx_cqe *cqe; + u8 cqe_fp_flags; + u16 len, pad; + + comp_ring_cons = RCQ_BD(sw_comp_cons); + bd_prod = RX_BD(bd_prod); + bd_cons = RX_BD(bd_cons); + + /* Prefetch the page containing the BD descriptor + at producer's index. It will be needed when new skb is + allocated */ + prefetch((void *)(PAGE_ALIGN((unsigned long) + (&fp->rx_desc_ring[bd_prod])) - + PAGE_SIZE + 1)); + + cqe = &fp->rx_comp_ring[comp_ring_cons]; + cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; + + DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x" + " queue %x vlan %x len %u\n", CQE_TYPE(cqe_fp_flags), + cqe_fp_flags, cqe->fast_path_cqe.status_flags, + le32_to_cpu(cqe->fast_path_cqe.rss_hash_result), + le16_to_cpu(cqe->fast_path_cqe.vlan_tag), + le16_to_cpu(cqe->fast_path_cqe.pkt_len)); + + /* is this a slowpath msg? */ + if (unlikely(CQE_TYPE(cqe_fp_flags))) { + bnx2x_sp_event(fp, cqe); + goto next_cqe; + + /* this is an rx packet */ + } else { + rx_buf = &fp->rx_buf_ring[bd_cons]; + skb = rx_buf->skb; + prefetch(skb); + len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); + pad = cqe->fast_path_cqe.placement_offset; + + /* If CQE is marked both TPA_START and TPA_END + it is a non-TPA CQE */ + if ((!fp->disable_tpa) && + (TPA_TYPE(cqe_fp_flags) != + (TPA_TYPE_START | TPA_TYPE_END))) { + u16 queue = cqe->fast_path_cqe.queue_index; + + if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_START) { + DP(NETIF_MSG_RX_STATUS, + "calling tpa_start on queue %d\n", + queue); + + bnx2x_tpa_start(fp, queue, skb, + bd_cons, bd_prod); + + /* Set Toeplitz hash for an LRO skb */ + bnx2x_set_skb_rxhash(bp, cqe, skb); + + goto next_rx; + } - if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) { - bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); - bnx2x_link_report(bp); - } + if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) { + DP(NETIF_MSG_RX_STATUS, + "calling tpa_stop on queue %d\n", + queue); + + if (!BNX2X_RX_SUM_FIX(cqe)) + BNX2X_ERR("STOP on none TCP " + "data\n"); + + /* This is a size of the linear data + on this skb */ + len = le16_to_cpu(cqe->fast_path_cqe. + len_on_bd); + bnx2x_tpa_stop(bp, fp, queue, pad, + len, cqe, comp_ring_cons); +#ifdef BNX2X_STOP_ON_ERROR + if (bp->panic) + return 0; +#endif - return rc; - } - BNX2X_ERR("Bootcode is missing - can not initialize link\n"); - return -EINVAL; -} + bnx2x_update_sge_prod(fp, + &cqe->fast_path_cqe); + goto next_cqe; + } + } -void bnx2x_link_set(struct bnx2x *bp) -{ - if (!BP_NOMCP(bp)) { - bnx2x_acquire_phy_lock(bp); - bnx2x_phy_init(&bp->link_params, &bp->link_vars); - bnx2x_release_phy_lock(bp); + dma_sync_single_for_device(&bp->pdev->dev, + dma_unmap_addr(rx_buf, mapping), + pad + RX_COPY_THRESH, + DMA_FROM_DEVICE); + prefetch(((char *)(skb)) + 128); + + /* is this an error packet? */ + if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { + DP(NETIF_MSG_RX_ERR, + "ERROR flags %x rx packet %u\n", + cqe_fp_flags, sw_comp_cons); + fp->eth_q_stats.rx_err_discard_pkt++; + goto reuse_rx; + } - bnx2x_calc_fc_adv(bp); - } else - BNX2X_ERR("Bootcode is missing - can not set link\n"); -} + /* Since we don't have a jumbo ring + * copy small packets if mtu > 1500 + */ + if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && + (len <= RX_COPY_THRESH)) { + struct sk_buff *new_skb; + + new_skb = netdev_alloc_skb(bp->dev, + len + pad); + if (new_skb == NULL) { + DP(NETIF_MSG_RX_ERR, + "ERROR packet dropped " + "because of alloc failure\n"); + fp->eth_q_stats.rx_skb_alloc_failed++; + goto reuse_rx; + } -static void bnx2x__link_reset(struct bnx2x *bp) -{ - if (!BP_NOMCP(bp)) { - bnx2x_acquire_phy_lock(bp); - bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1); - bnx2x_release_phy_lock(bp); - } else - BNX2X_ERR("Bootcode is missing - can not reset link\n"); -} + /* aligned copy */ + skb_copy_from_linear_data_offset(skb, pad, + new_skb->data + pad, len); + skb_reserve(new_skb, pad); + skb_put(new_skb, len); -u8 bnx2x_link_test(struct bnx2x *bp) -{ - u8 rc = 0; + bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); - if (!BP_NOMCP(bp)) { - bnx2x_acquire_phy_lock(bp); - rc = bnx2x_test_link(&bp->link_params, &bp->link_vars); - bnx2x_release_phy_lock(bp); - } else - BNX2X_ERR("Bootcode is missing - can not test link\n"); + skb = new_skb; - return rc; -} + } else + if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) { + dma_unmap_single(&bp->pdev->dev, + dma_unmap_addr(rx_buf, mapping), + bp->rx_buf_size, + DMA_FROM_DEVICE); + skb_reserve(skb, pad); + skb_put(skb, len); -static void bnx2x_init_port_minmax(struct bnx2x *bp) -{ - u32 r_param = bp->link_vars.line_speed / 8; - u32 fair_periodic_timeout_usec; - u32 t_fair; + } else { + DP(NETIF_MSG_RX_ERR, + "ERROR packet dropped because " + "of alloc failure\n"); + fp->eth_q_stats.rx_skb_alloc_failed++; +reuse_rx: + bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + goto next_rx; + } - memset(&(bp->cmng.rs_vars), 0, - sizeof(struct rate_shaping_vars_per_port)); - memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port)); + skb->protocol = eth_type_trans(skb, bp->dev); - /* 100 usec in SDM ticks = 25 since each tick is 4 usec */ - bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4; + /* Set Toeplitz hash for a none-LRO skb */ + bnx2x_set_skb_rxhash(bp, cqe, skb); - /* this is the threshold below which no timer arming will occur - 1.25 coefficient is for the threshold to be a little bigger - than the real time, to compensate for timer in-accuracy */ - bp->cmng.rs_vars.rs_threshold = - (RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4; + skb->ip_summed = CHECKSUM_NONE; + if (bp->rx_csum) { + if (likely(BNX2X_RX_CSUM_OK(cqe))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + fp->eth_q_stats.hw_csum_err++; + } + } - /* resolution of fairness timer */ - fair_periodic_timeout_usec = QM_ARB_BYTES / r_param; - /* for 10G it is 1000usec. for 1G it is 10000usec. */ - t_fair = T_FAIR_COEF / bp->link_vars.line_speed; + skb_record_rx_queue(skb, fp->index); - /* this is the threshold below which we won't arm the timer anymore */ - bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES; +#ifdef BCM_VLAN + if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) && + (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & + PARSING_FLAGS_VLAN)) + vlan_gro_receive(&fp->napi, bp->vlgrp, + le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb); + else +#endif + napi_gro_receive(&fp->napi, skb); - /* we multiply by 1e3/8 to get bytes/msec. - We don't want the credits to pass a credit - of the t_fair*FAIR_MEM (algorithm resolution) */ - bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM; - /* since each tick is 4 usec */ - bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4; -} -/* Calculates the sum of vn_min_rates. - It's needed for further normalizing of the min_rates. - Returns: - sum of vn_min_rates. - or - 0 - if all the min_rates are 0. - In the later case fainess algorithm should be deactivated. - If not all min_rates are zero then those that are zeroes will be set to 1. - */ -static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) -{ - int all_zero = 1; - int port = BP_PORT(bp); - int vn; +next_rx: + rx_buf->skb = NULL; - bp->vn_weight_sum = 0; - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - int func = 2*vn + port; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); - u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> - FUNC_MF_CFG_MIN_BW_SHIFT) * 100; + bd_cons = NEXT_RX_IDX(bd_cons); + bd_prod = NEXT_RX_IDX(bd_prod); + bd_prod_fw = NEXT_RX_IDX(bd_prod_fw); + rx_pkt++; +next_cqe: + sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod); + sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons); - /* Skip hidden vns */ - if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) - continue; + if (rx_pkt == budget) + break; + } /* while */ - /* If min rate is zero - set it to 1 */ - if (!vn_min_rate) - vn_min_rate = DEF_MIN_RATE; - else - all_zero = 0; + fp->rx_bd_cons = bd_cons; + fp->rx_bd_prod = bd_prod_fw; + fp->rx_comp_cons = sw_comp_cons; + fp->rx_comp_prod = sw_comp_prod; - bp->vn_weight_sum += vn_min_rate; - } + /* Update producers */ + bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod, + fp->rx_sge_prod); - /* ... only if all min rates are zeros - disable fairness */ - if (all_zero) { - bp->cmng.flags.cmng_enables &= - ~CMNG_FLAGS_PER_PORT_FAIRNESS_VN; - DP(NETIF_MSG_IFUP, "All MIN values are zeroes" - " fairness will be disabled\n"); - } else - bp->cmng.flags.cmng_enables |= - CMNG_FLAGS_PER_PORT_FAIRNESS_VN; + fp->rx_pkt += rx_pkt; + fp->rx_calls++; + + return rx_pkt; } -static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) +static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) { - struct rate_shaping_vars_per_vn m_rs_vn; - struct fairness_vars_per_vn m_fair_vn; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); - u16 vn_min_rate, vn_max_rate; - int i; - - /* If function is hidden - set min and max to zeroes */ - if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) { - vn_min_rate = 0; - vn_max_rate = 0; + struct bnx2x_fastpath *fp = fp_cookie; + struct bnx2x *bp = fp->bp; - } else { - vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> - FUNC_MF_CFG_MIN_BW_SHIFT) * 100; - /* If min rate is zero - set it to 1 */ - if (!vn_min_rate) - vn_min_rate = DEF_MIN_RATE; - vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + /* Return here if interrupt is disabled */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + return IRQ_HANDLED; } - DP(NETIF_MSG_IFUP, - "func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n", - func, vn_min_rate, vn_max_rate, bp->vn_weight_sum); - - memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn)); - memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn)); - - /* global vn counter - maximal Mbps for this vn */ - m_rs_vn.vn_counter.rate = vn_max_rate; - /* quota - number of bytes transmitted in this period */ - m_rs_vn.vn_counter.quota = - (vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8; + DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n", + fp->index, fp->sb_id); + bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); - if (bp->vn_weight_sum) { - /* credit for each period of the fairness algorithm: - number of bytes in T_FAIR (the vn share the port rate). - vn_weight_sum should not be larger than 10000, thus - T_FAIR_COEF / (8 * vn_weight_sum) will always be greater - than zero */ - m_fair_vn.vn_credit_delta = - max_t(u32, (vn_min_rate * (T_FAIR_COEF / - (8 * bp->vn_weight_sum))), - (bp->cmng.fair_vars.fair_threshold * 2)); - DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n", - m_fair_vn.vn_credit_delta); - } +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return IRQ_HANDLED; +#endif - /* Store it to internal memory */ - for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func) + i * 4, - ((u32 *)(&m_rs_vn))[i]); + /* Handle Rx and Tx according to MSI-X vector */ + prefetch(fp->rx_cons_sb); + prefetch(fp->tx_cons_sb); + prefetch(&fp->status_blk->u_status_block.status_block_index); + prefetch(&fp->status_blk->c_status_block.status_block_index); + napi_schedule(&bnx2x_fp(bp, fp->index, napi)); - for (i = 0; i < sizeof(struct fairness_vars_per_vn)/4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4, - ((u32 *)(&m_fair_vn))[i]); + return IRQ_HANDLED; } - -/* This function is called upon link interrupt */ -static void bnx2x_link_attn(struct bnx2x *bp) +static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) { - u32 prev_link_status = bp->link_vars.link_status; - /* Make sure that we are synced with the current statistics */ - bnx2x_stats_handle(bp, STATS_EVENT_STOP); + struct bnx2x *bp = netdev_priv(dev_instance); + u16 status = bnx2x_ack_int(bp); + u16 mask; + int i; - bnx2x_link_update(&bp->link_params, &bp->link_vars); + /* Return here if interrupt is shared and it's not for us */ + if (unlikely(status == 0)) { + DP(NETIF_MSG_INTR, "not our interrupt!\n"); + return IRQ_NONE; + } + DP(NETIF_MSG_INTR, "got an interrupt status 0x%x\n", status); - if (bp->link_vars.link_up) { + /* Return here if interrupt is disabled */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + return IRQ_HANDLED; + } - /* dropless flow control */ - if (CHIP_IS_E1H(bp) && bp->dropless_fc) { - int port = BP_PORT(bp); - u32 pause_enabled = 0; +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return IRQ_HANDLED; +#endif - if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) - pause_enabled = 1; + for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) { + struct bnx2x_fastpath *fp = &bp->fp[i]; - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_PAUSE_ENABLED_OFFSET(port), - pause_enabled); + mask = 0x2 << fp->sb_id; + if (status & mask) { + /* Handle Rx and Tx according to SB id */ + prefetch(fp->rx_cons_sb); + prefetch(&fp->status_blk->u_status_block. + status_block_index); + prefetch(fp->tx_cons_sb); + prefetch(&fp->status_blk->c_status_block. + status_block_index); + napi_schedule(&bnx2x_fp(bp, fp->index, napi)); + status &= ~mask; } + } - if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { - struct host_port_stats *pstats; +#ifdef BCM_CNIC + mask = 0x2 << CNIC_SB_ID(bp); + if (status & (mask | 0x1)) { + struct cnic_ops *c_ops = NULL; - pstats = bnx2x_sp(bp, port_stats); - /* reset old bmac stats */ - memset(&(pstats->mac_stx[0]), 0, - sizeof(struct mac_stx)); - } - if (bp->state == BNX2X_STATE_OPEN) - bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); + rcu_read_lock(); + c_ops = rcu_dereference(bp->cnic_ops); + if (c_ops) + c_ops->cnic_handler(bp->cnic_data, NULL); + rcu_read_unlock(); + + status &= ~mask; } +#endif - /* indicate link status only if link status actually changed */ - if (prev_link_status != bp->link_vars.link_status) - bnx2x_link_report(bp); + if (unlikely(status & 0x1)) { + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); - if (IS_E1HMF(bp)) { - int port = BP_PORT(bp); - int func; - int vn; + status &= ~0x1; + if (!status) + return IRQ_HANDLED; + } - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; + if (unlikely(status)) + DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n", + status); - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); - } + return IRQ_HANDLED; +} - if (bp->link_vars.link_up) { - int i; +/* end of fast path */ - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); +static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); +/* Link */ - /* Store it to internal memory */ - for (i = 0; - i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); - } - } -} +/* + * General service functions + */ -void bnx2x__link_status_update(struct bnx2x *bp) +static int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource) { - if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS)) - return; - - bnx2x_link_status_update(&bp->link_params, &bp->link_vars); - - if (bp->link_vars.link_up) - bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); - else - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - - bnx2x_calc_vn_weight_sum(bp); + u32 lock_status; + u32 resource_bit = (1 << resource); + int func = BP_FUNC(bp); + u32 hw_lock_control_reg; + int cnt; - /* indicate link status */ - bnx2x_link_report(bp); -} + /* Validating that the resource is within range */ + if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { + DP(NETIF_MSG_HW, + "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", + resource, HW_LOCK_MAX_RESOURCE_VALUE); + return -EINVAL; + } -static void bnx2x_pmf_update(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - u32 val; + if (func <= 5) { + hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8); + } else { + hw_lock_control_reg = + (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8); + } - bp->port.pmf = 1; - DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); + /* Validating that the resource is not already taken */ + lock_status = REG_RD(bp, hw_lock_control_reg); + if (lock_status & resource_bit) { + DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", + lock_status, resource_bit); + return -EEXIST; + } - /* enable nig attention */ - val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); + /* Try for 5 second every 5ms */ + for (cnt = 0; cnt < 1000; cnt++) { + /* Try to acquire the lock */ + REG_WR(bp, hw_lock_control_reg + 4, resource_bit); + lock_status = REG_RD(bp, hw_lock_control_reg); + if (lock_status & resource_bit) + return 0; - bnx2x_stats_handle(bp, STATS_EVENT_PMF); + msleep(5); + } + DP(NETIF_MSG_HW, "Timeout\n"); + return -EAGAIN; } -/* end of Link */ - -/* slow path */ - -/* - * General service functions - */ - -/* send the MCP a request, block until there is a reply */ -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) +static int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource) { + u32 lock_status; + u32 resource_bit = (1 << resource); int func = BP_FUNC(bp); - u32 seq = ++bp->fw_seq; - u32 rc = 0; - u32 cnt = 1; - u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; - - mutex_lock(&bp->fw_mb_mutex); - SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); - DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); - - do { - /* let the FW do it's magic ... */ - msleep(delay); + u32 hw_lock_control_reg; - rc = SHMEM_RD(bp, func_mb[func].fw_mb_header); + DP(NETIF_MSG_HW, "Releasing a lock on resource %d\n", resource); - /* Give the FW up to 5 second (500*10ms) */ - } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500)); + /* Validating that the resource is within range */ + if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { + DP(NETIF_MSG_HW, + "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", + resource, HW_LOCK_MAX_RESOURCE_VALUE); + return -EINVAL; + } - DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n", - cnt*delay, rc, seq); + if (func <= 5) { + hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8); + } else { + hw_lock_control_reg = + (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8); + } - /* is this a reply to our command? */ - if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) - rc &= FW_MSG_CODE_MASK; - else { - /* FW BUG! */ - BNX2X_ERR("FW failed to respond!\n"); - bnx2x_fw_dump(bp); - rc = 0; + /* Validating that the resource is currently taken */ + lock_status = REG_RD(bp, hw_lock_control_reg); + if (!(lock_status & resource_bit)) { + DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", + lock_status, resource_bit); + return -EFAULT; } - mutex_unlock(&bp->fw_mb_mutex); - return rc; + REG_WR(bp, hw_lock_control_reg, resource_bit); + return 0; } -static void bnx2x_e1h_disable(struct bnx2x *bp) +/* HW Lock for shared dual port PHYs */ +static void bnx2x_acquire_phy_lock(struct bnx2x *bp) { - int port = BP_PORT(bp); + mutex_lock(&bp->port.phy_mutex); - netif_tx_disable(bp->dev); + if (bp->port.need_hw_lock) + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_MDIO); +} - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); +static void bnx2x_release_phy_lock(struct bnx2x *bp) +{ + if (bp->port.need_hw_lock) + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_MDIO); - netif_carrier_off(bp->dev); + mutex_unlock(&bp->port.phy_mutex); } -static void bnx2x_e1h_enable(struct bnx2x *bp) +int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port) { - int port = BP_PORT(bp); + /* The GPIO should be swapped if swap register is set and active */ + int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && + REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; + int gpio_shift = gpio_num + + (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); + u32 gpio_mask = (1 << gpio_shift); + u32 gpio_reg; + int value; - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); + if (gpio_num > MISC_REGISTERS_GPIO_3) { + BNX2X_ERR("Invalid GPIO %d\n", gpio_num); + return -EINVAL; + } - /* Tx queue should be only reenabled */ - netif_tx_wake_all_queues(bp->dev); + /* read GPIO value */ + gpio_reg = REG_RD(bp, MISC_REG_GPIO); - /* - * Should not call netif_carrier_on since it will be called if the link - * is up when checking for link state - */ + /* get the requested pin value */ + if ((gpio_reg & gpio_mask) == gpio_mask) + value = 1; + else + value = 0; + + DP(NETIF_MSG_LINK, "pin %d value 0x%x\n", gpio_num, value); + + return value; } -static void bnx2x_update_min_max(struct bnx2x *bp) +int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) { - int port = BP_PORT(bp); - int vn, i; - - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); + /* The GPIO should be swapped if swap register is set and active */ + int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && + REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; + int gpio_shift = gpio_num + + (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); + u32 gpio_mask = (1 << gpio_shift); + u32 gpio_reg; - bnx2x_calc_vn_weight_sum(bp); + if (gpio_num > MISC_REGISTERS_GPIO_3) { + BNX2X_ERR("Invalid GPIO %d\n", gpio_num); + return -EINVAL; + } - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); + /* read GPIO and mask except the float bits */ + gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT); - if (bp->port.pmf) { - int func; + switch (mode) { + case MISC_REGISTERS_GPIO_OUTPUT_LOW: + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n", + gpio_num, gpio_shift); + /* clear FLOAT and set CLR */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS); + break; - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; + case MISC_REGISTERS_GPIO_OUTPUT_HIGH: + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n", + gpio_num, gpio_shift); + /* clear FLOAT and set SET */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS); + break; - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); - } + case MISC_REGISTERS_GPIO_INPUT_HI_Z: + DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n", + gpio_num, gpio_shift); + /* set FLOAT */ + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS); + break; - /* Store it to internal memory */ - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); + default: + break; } + + REG_WR(bp, MISC_REG_GPIO, gpio_reg); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); + + return 0; } -static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) +int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) { - DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); + /* The GPIO should be swapped if swap register is set and active */ + int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && + REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; + int gpio_shift = gpio_num + + (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); + u32 gpio_mask = (1 << gpio_shift); + u32 gpio_reg; - if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) { + if (gpio_num > MISC_REGISTERS_GPIO_3) { + BNX2X_ERR("Invalid GPIO %d\n", gpio_num); + return -EINVAL; + } - /* - * This is the only place besides the function initialization - * where the bp->flags can change so it is done without any - * locks - */ - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { - DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); + /* read GPIO int */ + gpio_reg = REG_RD(bp, MISC_REG_GPIO_INT); - bnx2x_e1h_disable(bp); - } else { - DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n"); - bp->flags &= ~MF_FUNC_DIS; + switch (mode) { + case MISC_REGISTERS_GPIO_INT_OUTPUT_CLR: + DP(NETIF_MSG_LINK, "Clear GPIO INT %d (shift %d) -> " + "output low\n", gpio_num, gpio_shift); + /* clear SET and set CLR */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS); + break; - bnx2x_e1h_enable(bp); - } - dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; - } - if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { + case MISC_REGISTERS_GPIO_INT_OUTPUT_SET: + DP(NETIF_MSG_LINK, "Set GPIO INT %d (shift %d) -> " + "output high\n", gpio_num, gpio_shift); + /* clear CLR and set SET */ + gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS); + gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS); + break; - bnx2x_update_min_max(bp); - dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; + default: + break; } - /* Report results to MCP */ - if (dcc_event) - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE); - else - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); -} - -/* must be called under the spq lock */ -static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp) -{ - struct eth_spe *next_spe = bp->spq_prod_bd; + REG_WR(bp, MISC_REG_GPIO_INT, gpio_reg); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); - if (bp->spq_prod_bd == bp->spq_last_bd) { - bp->spq_prod_bd = bp->spq; - bp->spq_prod_idx = 0; - DP(NETIF_MSG_TIMER, "end of spq\n"); - } else { - bp->spq_prod_bd++; - bp->spq_prod_idx++; - } - return next_spe; + return 0; } -/* must be called under the spq lock */ -static inline void bnx2x_sp_prod_update(struct bnx2x *bp) +static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) { - int func = BP_FUNC(bp); + u32 spio_mask = (1 << spio_num); + u32 spio_reg; - /* Make sure that BD data is updated before writing the producer */ - wmb(); + if ((spio_num < MISC_REGISTERS_SPIO_4) || + (spio_num > MISC_REGISTERS_SPIO_7)) { + BNX2X_ERR("Invalid SPIO %d\n", spio_num); + return -EINVAL; + } - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); - mmiowb(); -} + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); + /* read SPIO and mask except the float bits */ + spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT); -/* the slow path queue is odd since completions arrive on the fastpath ring */ -int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common) -{ - struct eth_spe *spe; + switch (mode) { + case MISC_REGISTERS_SPIO_OUTPUT_LOW: + DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num); + /* clear FLOAT and set CLR */ + spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS); + break; -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return -EIO; -#endif + case MISC_REGISTERS_SPIO_OUTPUT_HIGH: + DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num); + /* clear FLOAT and set SET */ + spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS); + break; - spin_lock_bh(&bp->spq_lock); + case MISC_REGISTERS_SPIO_INPUT_HI_Z: + DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num); + /* set FLOAT */ + spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); + break; - if (!bp->spq_left) { - BNX2X_ERR("BUG! SPQ ring full!\n"); - spin_unlock_bh(&bp->spq_lock); - bnx2x_panic(); - return -EBUSY; + default: + break; } - spe = bnx2x_sp_get_next(bp); + REG_WR(bp, MISC_REG_SPIO, spio_reg); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); - /* CID needs port number to be encoded int it */ - spe->hdr.conn_and_cmd_data = - cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | - HW_CID(bp, cid)); - spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE); - if (common) - spe->hdr.type |= - cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT)); + return 0; +} - spe->data.mac_config_addr.hi = cpu_to_le32(data_hi); - spe->data.mac_config_addr.lo = cpu_to_le32(data_lo); +static void bnx2x_calc_fc_adv(struct bnx2x *bp) +{ + switch (bp->link_vars.ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { + case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: + bp->port.advertising &= ~(ADVERTISED_Asym_Pause | + ADVERTISED_Pause); + break; - bp->spq_left--; + case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: + bp->port.advertising |= (ADVERTISED_Asym_Pause | + ADVERTISED_Pause); + break; - DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, - "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", - bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping), - (u32)(U64_LO(bp->spq_mapping) + - (void *)bp->spq_prod_bd - (void *)bp->spq), command, - HW_CID(bp, cid), data_hi, data_lo, bp->spq_left); + case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: + bp->port.advertising |= ADVERTISED_Asym_Pause; + break; - bnx2x_sp_prod_update(bp); - spin_unlock_bh(&bp->spq_lock); - return 0; + default: + bp->port.advertising &= ~(ADVERTISED_Asym_Pause | + ADVERTISED_Pause); + break; + } } -/* acquire split MCP access lock register */ -static int bnx2x_acquire_alr(struct bnx2x *bp) +static void bnx2x_link_report(struct bnx2x *bp) { - u32 j, val; - int rc = 0; + if (bp->flags & MF_FUNC_DIS) { + netif_carrier_off(bp->dev); + netdev_err(bp->dev, "NIC Link is Down\n"); + return; + } - might_sleep(); - for (j = 0; j < 1000; j++) { - val = (1UL << 31); - REG_WR(bp, GRCBASE_MCP + 0x9c, val); - val = REG_RD(bp, GRCBASE_MCP + 0x9c); - if (val & (1L << 31)) - break; + if (bp->link_vars.link_up) { + u16 line_speed; - msleep(5); - } - if (!(val & (1L << 31))) { - BNX2X_ERR("Cannot acquire MCP access lock register\n"); - rc = -EBUSY; - } + if (bp->state == BNX2X_STATE_OPEN) + netif_carrier_on(bp->dev); + netdev_info(bp->dev, "NIC Link is Up, "); - return rc; -} + line_speed = bp->link_vars.line_speed; + if (IS_E1HMF(bp)) { + u16 vn_max_rate; -/* release split MCP access lock register */ -static void bnx2x_release_alr(struct bnx2x *bp) -{ - REG_WR(bp, GRCBASE_MCP + 0x9c, 0); -} + vn_max_rate = + ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + if (vn_max_rate < line_speed) + line_speed = vn_max_rate; + } + pr_cont("%d Mbps ", line_speed); -static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) -{ - struct host_def_status_block *def_sb = bp->def_status_blk; - u16 rc = 0; + if (bp->link_vars.duplex == DUPLEX_FULL) + pr_cont("full duplex"); + else + pr_cont("half duplex"); + + if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) { + if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) { + pr_cont(", receive "); + if (bp->link_vars.flow_ctrl & + BNX2X_FLOW_CTRL_TX) + pr_cont("& transmit "); + } else { + pr_cont(", transmit "); + } + pr_cont("flow control ON"); + } + pr_cont("\n"); - barrier(); /* status block is written to by the chip */ - if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) { - bp->def_att_idx = def_sb->atten_status_block.attn_bits_index; - rc |= 1; - } - if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) { - bp->def_c_idx = def_sb->c_def_status_block.status_block_index; - rc |= 2; - } - if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) { - bp->def_u_idx = def_sb->u_def_status_block.status_block_index; - rc |= 4; - } - if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) { - bp->def_x_idx = def_sb->x_def_status_block.status_block_index; - rc |= 8; - } - if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) { - bp->def_t_idx = def_sb->t_def_status_block.status_block_index; - rc |= 16; + } else { /* link_down */ + netif_carrier_off(bp->dev); + netdev_err(bp->dev, "NIC Link is Down\n"); } - return rc; } -/* - * slow path service functions - */ - -static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) +static u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) { - int port = BP_PORT(bp); - u32 hc_addr = (HC_REG_COMMAND_REG + port*32 + - COMMAND_REG_ATTN_BITS_SET); - u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : - MISC_REG_AEU_MASK_ATTN_FUNC_0; - u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : - NIG_REG_MASK_INTERRUPT_PORT0; - u32 aeu_mask; - u32 nig_mask = 0; - - if (bp->attn_state & asserted) - BNX2X_ERR("IGU ERROR\n"); + if (!BP_NOMCP(bp)) { + u8 rc; - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); - aeu_mask = REG_RD(bp, aeu_addr); + /* Initialize link parameters structure variables */ + /* It is recommended to turn off RX FC for jumbo frames + for better performance */ + if (bp->dev->mtu > 5000) + bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX; + else + bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; - DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n", - aeu_mask, asserted); - aeu_mask &= ~(asserted & 0x3ff); - DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask); + bnx2x_acquire_phy_lock(bp); - REG_WR(bp, aeu_addr, aeu_mask); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); + if (load_mode == LOAD_DIAG) + bp->link_params.loopback_mode = LOOPBACK_XGXS_10; - DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state); - bp->attn_state |= asserted; - DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state); + rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); - if (asserted & ATTN_HARD_WIRED_MASK) { - if (asserted & ATTN_NIG_FOR_FUNC) { + bnx2x_release_phy_lock(bp); - bnx2x_acquire_phy_lock(bp); + bnx2x_calc_fc_adv(bp); - /* save nig interrupt mask */ - nig_mask = REG_RD(bp, nig_int_mask_addr); - REG_WR(bp, nig_int_mask_addr, 0); - - bnx2x_link_attn(bp); - - /* handle unicore attn? */ + if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) { + bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); + bnx2x_link_report(bp); } - if (asserted & ATTN_SW_TIMER_4_FUNC) - DP(NETIF_MSG_HW, "ATTN_SW_TIMER_4_FUNC!\n"); - - if (asserted & GPIO_2_FUNC) - DP(NETIF_MSG_HW, "GPIO_2_FUNC!\n"); - - if (asserted & GPIO_3_FUNC) - DP(NETIF_MSG_HW, "GPIO_3_FUNC!\n"); - if (asserted & GPIO_4_FUNC) - DP(NETIF_MSG_HW, "GPIO_4_FUNC!\n"); - - if (port == 0) { - if (asserted & ATTN_GENERAL_ATTN_1) { - DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_1!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_1, 0x0); - } - if (asserted & ATTN_GENERAL_ATTN_2) { - DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_2!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_2, 0x0); - } - if (asserted & ATTN_GENERAL_ATTN_3) { - DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_3!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_3, 0x0); - } - } else { - if (asserted & ATTN_GENERAL_ATTN_4) { - DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_4!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_4, 0x0); - } - if (asserted & ATTN_GENERAL_ATTN_5) { - DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_5!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_5, 0x0); - } - if (asserted & ATTN_GENERAL_ATTN_6) { - DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_6!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_6, 0x0); - } - } + return rc; + } + BNX2X_ERR("Bootcode is missing - can not initialize link\n"); + return -EINVAL; +} - } /* if hardwired */ +static void bnx2x_link_set(struct bnx2x *bp) +{ + if (!BP_NOMCP(bp)) { + bnx2x_acquire_phy_lock(bp); + bnx2x_phy_init(&bp->link_params, &bp->link_vars); + bnx2x_release_phy_lock(bp); - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - asserted, hc_addr); - REG_WR(bp, hc_addr, asserted); + bnx2x_calc_fc_adv(bp); + } else + BNX2X_ERR("Bootcode is missing - can not set link\n"); +} - /* now set back the mask */ - if (asserted & ATTN_NIG_FOR_FUNC) { - REG_WR(bp, nig_int_mask_addr, nig_mask); +static void bnx2x__link_reset(struct bnx2x *bp) +{ + if (!BP_NOMCP(bp)) { + bnx2x_acquire_phy_lock(bp); + bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1); bnx2x_release_phy_lock(bp); - } + } else + BNX2X_ERR("Bootcode is missing - can not reset link\n"); } -static inline void bnx2x_fan_failure(struct bnx2x *bp) +static u8 bnx2x_link_test(struct bnx2x *bp) { - int port = BP_PORT(bp); + u8 rc = 0; - /* mark the failure */ - bp->link_params.ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; - bp->link_params.ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; - SHMEM_WR(bp, dev_info.port_hw_config[port].external_phy_config, - bp->link_params.ext_phy_config); + if (!BP_NOMCP(bp)) { + bnx2x_acquire_phy_lock(bp); + rc = bnx2x_test_link(&bp->link_params, &bp->link_vars); + bnx2x_release_phy_lock(bp); + } else + BNX2X_ERR("Bootcode is missing - can not test link\n"); - /* log the failure */ - netdev_err(bp->dev, "Fan Failure on Network Controller has caused" - " the driver to shutdown the card to prevent permanent" - " damage. Please contact OEM Support for assistance\n"); + return rc; } -static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) +static void bnx2x_init_port_minmax(struct bnx2x *bp) { - int port = BP_PORT(bp); - int reg_offset; - u32 val, swap_val, swap_override; + u32 r_param = bp->link_vars.line_speed / 8; + u32 fair_periodic_timeout_usec; + u32 t_fair; - reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : - MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + memset(&(bp->cmng.rs_vars), 0, + sizeof(struct rate_shaping_vars_per_port)); + memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port)); - if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) { + /* 100 usec in SDM ticks = 25 since each tick is 4 usec */ + bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4; - val = REG_RD(bp, reg_offset); - val &= ~AEU_INPUTS_ATTN_BITS_SPIO5; - REG_WR(bp, reg_offset, val); + /* this is the threshold below which no timer arming will occur + 1.25 coefficient is for the threshold to be a little bigger + than the real time, to compensate for timer in-accuracy */ + bp->cmng.rs_vars.rs_threshold = + (RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4; - BNX2X_ERR("SPIO5 hw attention\n"); + /* resolution of fairness timer */ + fair_periodic_timeout_usec = QM_ARB_BYTES / r_param; + /* for 10G it is 1000usec. for 1G it is 10000usec. */ + t_fair = T_FAIR_COEF / bp->link_vars.line_speed; - /* Fan failure attention */ - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - /* Low power mode is controlled by GPIO 2 */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - /* The PHY reset is controlled by GPIO 1 */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - break; + /* this is the threshold below which we won't arm the timer anymore */ + bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - /* The PHY reset is controlled by GPIO 1 */ - /* fake the port number to cancel the swap done in - set_gpio() */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - port = (swap_val && swap_override) ^ 1; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - break; + /* we multiply by 1e3/8 to get bytes/msec. + We don't want the credits to pass a credit + of the t_fair*FAIR_MEM (algorithm resolution) */ + bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM; + /* since each tick is 4 usec */ + bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4; +} - default: - break; - } - bnx2x_fan_failure(bp); - } +/* Calculates the sum of vn_min_rates. + It's needed for further normalizing of the min_rates. + Returns: + sum of vn_min_rates. + or + 0 - if all the min_rates are 0. + In the later case fainess algorithm should be deactivated. + If not all min_rates are zero then those that are zeroes will be set to 1. + */ +static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) +{ + int all_zero = 1; + int port = BP_PORT(bp); + int vn; - if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 | - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) { - bnx2x_acquire_phy_lock(bp); - bnx2x_handle_module_detect_int(&bp->link_params); - bnx2x_release_phy_lock(bp); - } + bp->vn_weight_sum = 0; + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + int func = 2*vn + port; + u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> + FUNC_MF_CFG_MIN_BW_SHIFT) * 100; - if (attn & HW_INTERRUT_ASSERT_SET_0) { + /* Skip hidden vns */ + if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) + continue; - val = REG_RD(bp, reg_offset); - val &= ~(attn & HW_INTERRUT_ASSERT_SET_0); - REG_WR(bp, reg_offset, val); + /* If min rate is zero - set it to 1 */ + if (!vn_min_rate) + vn_min_rate = DEF_MIN_RATE; + else + all_zero = 0; - BNX2X_ERR("FATAL HW block attention set0 0x%x\n", - (u32)(attn & HW_INTERRUT_ASSERT_SET_0)); - bnx2x_panic(); + bp->vn_weight_sum += vn_min_rate; } + + /* ... only if all min rates are zeros - disable fairness */ + if (all_zero) { + bp->cmng.flags.cmng_enables &= + ~CMNG_FLAGS_PER_PORT_FAIRNESS_VN; + DP(NETIF_MSG_IFUP, "All MIN values are zeroes" + " fairness will be disabled\n"); + } else + bp->cmng.flags.cmng_enables |= + CMNG_FLAGS_PER_PORT_FAIRNESS_VN; } -static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn) +static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) { - u32 val; + struct rate_shaping_vars_per_vn m_rs_vn; + struct fairness_vars_per_vn m_fair_vn; + u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u16 vn_min_rate, vn_max_rate; + int i; - if (attn & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) { + /* If function is hidden - set min and max to zeroes */ + if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) { + vn_min_rate = 0; + vn_max_rate = 0; - val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR); - BNX2X_ERR("DB hw attention 0x%x\n", val); - /* DORQ discard attention */ - if (val & 0x2) - BNX2X_ERR("FATAL error from DORQ\n"); + } else { + vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> + FUNC_MF_CFG_MIN_BW_SHIFT) * 100; + /* If min rate is zero - set it to 1 */ + if (!vn_min_rate) + vn_min_rate = DEF_MIN_RATE; + vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT) * 100; } + DP(NETIF_MSG_IFUP, + "func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n", + func, vn_min_rate, vn_max_rate, bp->vn_weight_sum); - if (attn & HW_INTERRUT_ASSERT_SET_1) { - - int port = BP_PORT(bp); - int reg_offset; + memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn)); + memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn)); - reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1 : - MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1); + /* global vn counter - maximal Mbps for this vn */ + m_rs_vn.vn_counter.rate = vn_max_rate; - val = REG_RD(bp, reg_offset); - val &= ~(attn & HW_INTERRUT_ASSERT_SET_1); - REG_WR(bp, reg_offset, val); + /* quota - number of bytes transmitted in this period */ + m_rs_vn.vn_counter.quota = + (vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8; - BNX2X_ERR("FATAL HW block attention set1 0x%x\n", - (u32)(attn & HW_INTERRUT_ASSERT_SET_1)); - bnx2x_panic(); + if (bp->vn_weight_sum) { + /* credit for each period of the fairness algorithm: + number of bytes in T_FAIR (the vn share the port rate). + vn_weight_sum should not be larger than 10000, thus + T_FAIR_COEF / (8 * vn_weight_sum) will always be greater + than zero */ + m_fair_vn.vn_credit_delta = + max_t(u32, (vn_min_rate * (T_FAIR_COEF / + (8 * bp->vn_weight_sum))), + (bp->cmng.fair_vars.fair_threshold * 2)); + DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n", + m_fair_vn.vn_credit_delta); } -} - -static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) -{ - u32 val; - if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { + /* Store it to internal memory */ + for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func) + i * 4, + ((u32 *)(&m_rs_vn))[i]); - val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR); - BNX2X_ERR("CFC hw attention 0x%x\n", val); - /* CFC error attention */ - if (val & 0x2) - BNX2X_ERR("FATAL error from CFC\n"); - } + for (i = 0; i < sizeof(struct fairness_vars_per_vn)/4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4, + ((u32 *)(&m_fair_vn))[i]); +} - if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { - val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); - BNX2X_ERR("PXP hw attention 0x%x\n", val); - /* RQ_USDMDP_FIFO_OVERFLOW */ - if (val & 0x18000) - BNX2X_ERR("FATAL error from PXP\n"); - } +/* This function is called upon link interrupt */ +static void bnx2x_link_attn(struct bnx2x *bp) +{ + u32 prev_link_status = bp->link_vars.link_status; + /* Make sure that we are synced with the current statistics */ + bnx2x_stats_handle(bp, STATS_EVENT_STOP); - if (attn & HW_INTERRUT_ASSERT_SET_2) { + bnx2x_link_update(&bp->link_params, &bp->link_vars); - int port = BP_PORT(bp); - int reg_offset; + if (bp->link_vars.link_up) { - reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_2 : - MISC_REG_AEU_ENABLE1_FUNC_0_OUT_2); + /* dropless flow control */ + if (CHIP_IS_E1H(bp) && bp->dropless_fc) { + int port = BP_PORT(bp); + u32 pause_enabled = 0; - val = REG_RD(bp, reg_offset); - val &= ~(attn & HW_INTERRUT_ASSERT_SET_2); - REG_WR(bp, reg_offset, val); + if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) + pause_enabled = 1; - BNX2X_ERR("FATAL HW block attention set2 0x%x\n", - (u32)(attn & HW_INTERRUT_ASSERT_SET_2)); - bnx2x_panic(); - } -} + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_ETH_PAUSE_ENABLED_OFFSET(port), + pause_enabled); + } -static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) -{ - u32 val; + if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { + struct host_port_stats *pstats; - if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) { + pstats = bnx2x_sp(bp, port_stats); + /* reset old bmac stats */ + memset(&(pstats->mac_stx[0]), 0, + sizeof(struct mac_stx)); + } + if (bp->state == BNX2X_STATE_OPEN) + bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); + } - if (attn & BNX2X_PMF_LINK_ASSERT) { - int func = BP_FUNC(bp); + /* indicate link status only if link status actually changed */ + if (prev_link_status != bp->link_vars.link_status) + bnx2x_link_report(bp); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - bp->mf_config = SHMEM_RD(bp, - mf_cfg.func_mf_config[func].config); - val = SHMEM_RD(bp, func_mb[func].drv_status); - if (val & DRV_STATUS_DCC_EVENT_MASK) - bnx2x_dcc_event(bp, - (val & DRV_STATUS_DCC_EVENT_MASK)); - bnx2x__link_status_update(bp); - if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) - bnx2x_pmf_update(bp); + if (IS_E1HMF(bp)) { + int port = BP_PORT(bp); + int func; + int vn; - } else if (attn & BNX2X_MC_ASSERT_BITS) { + /* Set the attention towards other drivers on the same port */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + if (vn == BP_E1HVN(bp)) + continue; - BNX2X_ERR("MC assert!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0); - bnx2x_panic(); + func = ((vn << 1) | port); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + + (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); + } - } else if (attn & BNX2X_MCP_ASSERT) { + if (bp->link_vars.link_up) { + int i; - BNX2X_ERR("MCP assert!\n"); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0); - bnx2x_fw_dump(bp); + /* Init rate shaping and fairness contexts */ + bnx2x_init_port_minmax(bp); - } else - BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn); - } + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, 2*vn + port); - if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) { - BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn); - if (attn & BNX2X_GRC_TIMEOUT) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0; - BNX2X_ERR("GRC time-out 0x%08x\n", val); - } - if (attn & BNX2X_GRC_RSV) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0; - BNX2X_ERR("GRC reserved 0x%08x\n", val); + /* Store it to internal memory */ + for (i = 0; + i < sizeof(struct cmng_struct_per_port) / 4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, + ((u32 *)(&bp->cmng))[i]); } - REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff); } } -#define BNX2X_MISC_GEN_REG MISC_REG_GENERIC_POR_1 -#define LOAD_COUNTER_BITS 16 /* Number of bits for load counter */ -#define LOAD_COUNTER_MASK (((u32)0x1 << LOAD_COUNTER_BITS) - 1) -#define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK) -#define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS -#define CHIP_PARITY_SUPPORTED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) -/* - * should be run under rtnl lock - */ -static inline void bnx2x_set_reset_done(struct bnx2x *bp) -{ - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - val &= ~(1 << RESET_DONE_FLAG_SHIFT); - REG_WR(bp, BNX2X_MISC_GEN_REG, val); - barrier(); - mmiowb(); -} - -/* - * should be run under rtnl lock - */ -static inline void bnx2x_set_reset_in_progress(struct bnx2x *bp) +static void bnx2x__link_status_update(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - val |= (1 << 16); - REG_WR(bp, BNX2X_MISC_GEN_REG, val); - barrier(); - mmiowb(); -} + if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS)) + return; -/* - * should be run under rtnl lock - */ -bool bnx2x_reset_is_done(struct bnx2x *bp) -{ - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - DP(NETIF_MSG_HW, "GEN_REG_VAL=0x%08x\n", val); - return (val & RESET_DONE_FLAG_MASK) ? false : true; -} + bnx2x_link_status_update(&bp->link_params, &bp->link_vars); -/* - * should be run under rtnl lock - */ -inline void bnx2x_inc_load_cnt(struct bnx2x *bp) -{ - u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG); + if (bp->link_vars.link_up) + bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); + else + bnx2x_stats_handle(bp, STATS_EVENT_STOP); - DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); + bnx2x_calc_vn_weight_sum(bp); - val1 = ((val & LOAD_COUNTER_MASK) + 1) & LOAD_COUNTER_MASK; - REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1); - barrier(); - mmiowb(); + /* indicate link status */ + bnx2x_link_report(bp); } -/* - * should be run under rtnl lock - */ -u32 bnx2x_dec_load_cnt(struct bnx2x *bp) +static void bnx2x_pmf_update(struct bnx2x *bp) { - u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG); + int port = BP_PORT(bp); + u32 val; - DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); + bp->port.pmf = 1; + DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); - val1 = ((val & LOAD_COUNTER_MASK) - 1) & LOAD_COUNTER_MASK; - REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1); - barrier(); - mmiowb(); + /* enable nig attention */ + val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); - return val1; + bnx2x_stats_handle(bp, STATS_EVENT_PMF); } +/* end of Link */ + +/* slow path */ + /* - * should be run under rtnl lock + * General service functions */ -static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp) -{ - return REG_RD(bp, BNX2X_MISC_GEN_REG) & LOAD_COUNTER_MASK; -} - -static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) -{ - u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); - REG_WR(bp, BNX2X_MISC_GEN_REG, val & (~LOAD_COUNTER_MASK)); -} -static inline void _print_next_block(int idx, const char *blk) +/* send the MCP a request, block until there is a reply */ +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) { - if (idx) - pr_cont(", "); - pr_cont("%s", blk); -} + int func = BP_FUNC(bp); + u32 seq = ++bp->fw_seq; + u32 rc = 0; + u32 cnt = 1; + u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; -static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num) -{ - int i = 0; - u32 cur_bit = 0; - for (i = 0; sig; i++) { - cur_bit = ((u32)0x1 << i); - if (sig & cur_bit) { - switch (cur_bit) { - case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR: - _print_next_block(par_num++, "BRB"); - break; - case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR: - _print_next_block(par_num++, "PARSER"); - break; - case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR: - _print_next_block(par_num++, "TSDM"); - break; - case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR: - _print_next_block(par_num++, "SEARCHER"); - break; - case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR: - _print_next_block(par_num++, "TSEMI"); - break; - } - - /* Clear the bit */ - sig &= ~cur_bit; - } - } - - return par_num; -} + mutex_lock(&bp->fw_mb_mutex); + SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); -static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num) -{ - int i = 0; - u32 cur_bit = 0; - for (i = 0; sig; i++) { - cur_bit = ((u32)0x1 << i); - if (sig & cur_bit) { - switch (cur_bit) { - case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR: - _print_next_block(par_num++, "PBCLIENT"); - break; - case AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR: - _print_next_block(par_num++, "QM"); - break; - case AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR: - _print_next_block(par_num++, "XSDM"); - break; - case AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR: - _print_next_block(par_num++, "XSEMI"); - break; - case AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR: - _print_next_block(par_num++, "DOORBELLQ"); - break; - case AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR: - _print_next_block(par_num++, "VAUX PCI CORE"); - break; - case AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR: - _print_next_block(par_num++, "DEBUG"); - break; - case AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR: - _print_next_block(par_num++, "USDM"); - break; - case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR: - _print_next_block(par_num++, "USEMI"); - break; - case AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR: - _print_next_block(par_num++, "UPB"); - break; - case AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR: - _print_next_block(par_num++, "CSDM"); - break; - } + do { + /* let the FW do it's magic ... */ + msleep(delay); - /* Clear the bit */ - sig &= ~cur_bit; - } - } + rc = SHMEM_RD(bp, func_mb[func].fw_mb_header); - return par_num; -} + /* Give the FW up to 5 second (500*10ms) */ + } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500)); -static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num) -{ - int i = 0; - u32 cur_bit = 0; - for (i = 0; sig; i++) { - cur_bit = ((u32)0x1 << i); - if (sig & cur_bit) { - switch (cur_bit) { - case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR: - _print_next_block(par_num++, "CSEMI"); - break; - case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR: - _print_next_block(par_num++, "PXP"); - break; - case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR: - _print_next_block(par_num++, - "PXPPCICLOCKCLIENT"); - break; - case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR: - _print_next_block(par_num++, "CFC"); - break; - case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR: - _print_next_block(par_num++, "CDU"); - break; - case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR: - _print_next_block(par_num++, "IGU"); - break; - case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR: - _print_next_block(par_num++, "MISC"); - break; - } + DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n", + cnt*delay, rc, seq); - /* Clear the bit */ - sig &= ~cur_bit; - } + /* is this a reply to our command? */ + if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) + rc &= FW_MSG_CODE_MASK; + else { + /* FW BUG! */ + BNX2X_ERR("FW failed to respond!\n"); + bnx2x_fw_dump(bp); + rc = 0; } + mutex_unlock(&bp->fw_mb_mutex); - return par_num; + return rc; } -static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num) +static void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set); +static void bnx2x_set_rx_mode(struct net_device *dev); + +static void bnx2x_e1h_disable(struct bnx2x *bp) { - int i = 0; - u32 cur_bit = 0; - for (i = 0; sig; i++) { - cur_bit = ((u32)0x1 << i); - if (sig & cur_bit) { - switch (cur_bit) { - case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY: - _print_next_block(par_num++, "MCP ROM"); - break; - case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY: - _print_next_block(par_num++, "MCP UMP RX"); - break; - case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY: - _print_next_block(par_num++, "MCP UMP TX"); - break; - case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY: - _print_next_block(par_num++, "MCP SCPAD"); - break; - } + int port = BP_PORT(bp); - /* Clear the bit */ - sig &= ~cur_bit; - } - } + netif_tx_disable(bp->dev); - return par_num; -} + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); -static inline bool bnx2x_parity_attn(struct bnx2x *bp, u32 sig0, u32 sig1, - u32 sig2, u32 sig3) -{ - if ((sig0 & HW_PRTY_ASSERT_SET_0) || (sig1 & HW_PRTY_ASSERT_SET_1) || - (sig2 & HW_PRTY_ASSERT_SET_2) || (sig3 & HW_PRTY_ASSERT_SET_3)) { - int par_num = 0; - DP(NETIF_MSG_HW, "Was parity error: HW block parity attention: " - "[0]:0x%08x [1]:0x%08x " - "[2]:0x%08x [3]:0x%08x\n", - sig0 & HW_PRTY_ASSERT_SET_0, - sig1 & HW_PRTY_ASSERT_SET_1, - sig2 & HW_PRTY_ASSERT_SET_2, - sig3 & HW_PRTY_ASSERT_SET_3); - printk(KERN_ERR"%s: Parity errors detected in blocks: ", - bp->dev->name); - par_num = bnx2x_print_blocks_with_parity0( - sig0 & HW_PRTY_ASSERT_SET_0, par_num); - par_num = bnx2x_print_blocks_with_parity1( - sig1 & HW_PRTY_ASSERT_SET_1, par_num); - par_num = bnx2x_print_blocks_with_parity2( - sig2 & HW_PRTY_ASSERT_SET_2, par_num); - par_num = bnx2x_print_blocks_with_parity3( - sig3 & HW_PRTY_ASSERT_SET_3, par_num); - printk("\n"); - return true; - } else - return false; + netif_carrier_off(bp->dev); } -bool bnx2x_chk_parity_attn(struct bnx2x *bp) +static void bnx2x_e1h_enable(struct bnx2x *bp) { - struct attn_route attn; int port = BP_PORT(bp); - attn.sig[0] = REG_RD(bp, - MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + - port*4); - attn.sig[1] = REG_RD(bp, - MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + - port*4); - attn.sig[2] = REG_RD(bp, - MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + - port*4); - attn.sig[3] = REG_RD(bp, - MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + - port*4); + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); - return bnx2x_parity_attn(bp, attn.sig[0], attn.sig[1], attn.sig[2], - attn.sig[3]); + /* Tx queue should be only reenabled */ + netif_tx_wake_all_queues(bp->dev); + + /* + * Should not call netif_carrier_on since it will be called if the link + * is up when checking for link state + */ } -static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) +static void bnx2x_update_min_max(struct bnx2x *bp) { - struct attn_route attn, *group_mask; int port = BP_PORT(bp); - int index; - u32 reg_addr; - u32 val; - u32 aeu_mask; + int vn, i; - /* need to take HW lock because MCP or other port might also - try to handle this event */ - bnx2x_acquire_alr(bp); + /* Init rate shaping and fairness contexts */ + bnx2x_init_port_minmax(bp); - if (bnx2x_chk_parity_attn(bp)) { - bp->recovery_state = BNX2X_RECOVERY_INIT; - bnx2x_set_reset_in_progress(bp); - schedule_delayed_work(&bp->reset_task, 0); - /* Disable HW interrupts */ - bnx2x_int_disable(bp); - bnx2x_release_alr(bp); - /* In case of parity errors don't handle attentions so that - * other function would "see" parity errors. - */ - return; - } + bnx2x_calc_vn_weight_sum(bp); - attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4); - attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); - attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4); - attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n", - attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]); + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, 2*vn + port); - for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { - if (deasserted & (1 << index)) { - group_mask = &bp->attn_group[index]; + if (bp->port.pmf) { + int func; - DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n", - index, group_mask->sig[0], group_mask->sig[1], - group_mask->sig[2], group_mask->sig[3]); + /* Set the attention towards other drivers on the same port */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + if (vn == BP_E1HVN(bp)) + continue; - bnx2x_attn_int_deasserted3(bp, - attn.sig[3] & group_mask->sig[3]); - bnx2x_attn_int_deasserted1(bp, - attn.sig[1] & group_mask->sig[1]); - bnx2x_attn_int_deasserted2(bp, - attn.sig[2] & group_mask->sig[2]); - bnx2x_attn_int_deasserted0(bp, - attn.sig[0] & group_mask->sig[0]); + func = ((vn << 1) | port); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + + (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); } - } - - bnx2x_release_alr(bp); - reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR); + /* Store it to internal memory */ + for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, + ((u32 *)(&bp->cmng))[i]); + } +} - val = ~deasserted; - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - val, reg_addr); - REG_WR(bp, reg_addr, val); +static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) +{ + DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); - if (~bp->attn_state & deasserted) - BNX2X_ERR("IGU ERROR\n"); + if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) { - reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : - MISC_REG_AEU_MASK_ATTN_FUNC_0; + /* + * This is the only place besides the function initialization + * where the bp->flags can change so it is done without any + * locks + */ + if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { + DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); + bp->flags |= MF_FUNC_DIS; - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); - aeu_mask = REG_RD(bp, reg_addr); + bnx2x_e1h_disable(bp); + } else { + DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n"); + bp->flags &= ~MF_FUNC_DIS; - DP(NETIF_MSG_HW, "aeu_mask %x newly deasserted %x\n", - aeu_mask, deasserted); - aeu_mask |= (deasserted & 0x3ff); - DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask); + bnx2x_e1h_enable(bp); + } + dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; + } + if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { - REG_WR(bp, reg_addr, aeu_mask); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); + bnx2x_update_min_max(bp); + dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; + } - DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state); - bp->attn_state &= ~deasserted; - DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state); + /* Report results to MCP */ + if (dcc_event) + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE); + else + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); } -static void bnx2x_attn_int(struct bnx2x *bp) +/* must be called under the spq lock */ +static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp) { - /* read local copy of bits */ - u32 attn_bits = le32_to_cpu(bp->def_status_blk->atten_status_block. - attn_bits); - u32 attn_ack = le32_to_cpu(bp->def_status_blk->atten_status_block. - attn_bits_ack); - u32 attn_state = bp->attn_state; - - /* look for changed bits */ - u32 asserted = attn_bits & ~attn_ack & ~attn_state; - u32 deasserted = ~attn_bits & attn_ack & attn_state; + struct eth_spe *next_spe = bp->spq_prod_bd; - DP(NETIF_MSG_HW, - "attn_bits %x attn_ack %x asserted %x deasserted %x\n", - attn_bits, attn_ack, asserted, deasserted); + if (bp->spq_prod_bd == bp->spq_last_bd) { + bp->spq_prod_bd = bp->spq; + bp->spq_prod_idx = 0; + DP(NETIF_MSG_TIMER, "end of spq\n"); + } else { + bp->spq_prod_bd++; + bp->spq_prod_idx++; + } + return next_spe; +} - if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state)) - BNX2X_ERR("BAD attention state\n"); +/* must be called under the spq lock */ +static inline void bnx2x_sp_prod_update(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); - /* handle bits that were raised */ - if (asserted) - bnx2x_attn_int_asserted(bp, asserted); + /* Make sure that BD data is updated before writing the producer */ + wmb(); - if (deasserted) - bnx2x_attn_int_deasserted(bp, deasserted); + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), + bp->spq_prod_idx); + mmiowb(); } -static void bnx2x_sp_task(struct work_struct *work) +/* the slow path queue is odd since completions arrive on the fastpath ring */ +static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, + u32 data_hi, u32 data_lo, int common) { - struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work); - u16 status; - - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return; - } + struct eth_spe *spe; - status = bnx2x_update_dsb_idx(bp); -/* if (status == 0) */ -/* BNX2X_ERR("spurious slowpath interrupt!\n"); */ +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return -EIO; +#endif - DP(NETIF_MSG_INTR, "got a slowpath interrupt (status 0x%x)\n", status); + spin_lock_bh(&bp->spq_lock); - /* HW attentions */ - if (status & 0x1) { - bnx2x_attn_int(bp); - status &= ~0x1; + if (!bp->spq_left) { + BNX2X_ERR("BUG! SPQ ring full!\n"); + spin_unlock_bh(&bp->spq_lock); + bnx2x_panic(); + return -EBUSY; } - /* CStorm events: STAT_QUERY */ - if (status & 0x2) { - DP(BNX2X_MSG_SP, "CStorm events: STAT_QUERY\n"); - status &= ~0x2; - } + spe = bnx2x_sp_get_next(bp); - if (unlikely(status)) - DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n", - status); + /* CID needs port number to be encoded int it */ + spe->hdr.conn_and_cmd_data = + cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | + HW_CID(bp, cid)); + spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE); + if (common) + spe->hdr.type |= + cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT)); - bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx), - IGU_INT_ENABLE, 1); -} + spe->data.mac_config_addr.hi = cpu_to_le32(data_hi); + spe->data.mac_config_addr.lo = cpu_to_le32(data_lo); -irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) -{ - struct net_device *dev = dev_instance; - struct bnx2x *bp = netdev_priv(dev); + bp->spq_left--; - /* Return here if interrupt is disabled */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) { - DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); - return IRQ_HANDLED; - } + DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, + "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", + bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping), + (u32)(U64_LO(bp->spq_mapping) + + (void *)bp->spq_prod_bd - (void *)bp->spq), command, + HW_CID(bp, cid), data_hi, data_lo, bp->spq_left); - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0); + bnx2x_sp_prod_update(bp); + spin_unlock_bh(&bp->spq_lock); + return 0; +} -#ifdef BNX2X_STOP_ON_ERROR - if (unlikely(bp->panic)) - return IRQ_HANDLED; -#endif +/* acquire split MCP access lock register */ +static int bnx2x_acquire_alr(struct bnx2x *bp) +{ + u32 j, val; + int rc = 0; -#ifdef BCM_CNIC - { - struct cnic_ops *c_ops; + might_sleep(); + for (j = 0; j < 1000; j++) { + val = (1UL << 31); + REG_WR(bp, GRCBASE_MCP + 0x9c, val); + val = REG_RD(bp, GRCBASE_MCP + 0x9c); + if (val & (1L << 31)) + break; - rcu_read_lock(); - c_ops = rcu_dereference(bp->cnic_ops); - if (c_ops) - c_ops->cnic_handler(bp->cnic_data, NULL); - rcu_read_unlock(); + msleep(5); + } + if (!(val & (1L << 31))) { + BNX2X_ERR("Cannot acquire MCP access lock register\n"); + rc = -EBUSY; } -#endif - queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); - return IRQ_HANDLED; + return rc; } -/* end of slow path */ - -static void bnx2x_timer(unsigned long data) +/* release split MCP access lock register */ +static void bnx2x_release_alr(struct bnx2x *bp) { - struct bnx2x *bp = (struct bnx2x *) data; - - if (!netif_running(bp->dev)) - return; - - if (atomic_read(&bp->intr_sem) != 0) - goto timer_restart; + REG_WR(bp, GRCBASE_MCP + 0x9c, 0); +} - if (poll) { - struct bnx2x_fastpath *fp = &bp->fp[0]; - int rc; +static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) +{ + struct host_def_status_block *def_sb = bp->def_status_blk; + u16 rc = 0; - bnx2x_tx_int(fp); - rc = bnx2x_rx_int(fp, 1000); + barrier(); /* status block is written to by the chip */ + if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) { + bp->def_att_idx = def_sb->atten_status_block.attn_bits_index; + rc |= 1; + } + if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) { + bp->def_c_idx = def_sb->c_def_status_block.status_block_index; + rc |= 2; + } + if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) { + bp->def_u_idx = def_sb->u_def_status_block.status_block_index; + rc |= 4; + } + if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) { + bp->def_x_idx = def_sb->x_def_status_block.status_block_index; + rc |= 8; + } + if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) { + bp->def_t_idx = def_sb->t_def_status_block.status_block_index; + rc |= 16; } + return rc; +} - if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); - u32 drv_pulse; - u32 mcp_pulse; +/* + * slow path service functions + */ - ++bp->fw_drv_pulse_wr_seq; - bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; - /* TBD - add SYSTEM_TIME */ - drv_pulse = bp->fw_drv_pulse_wr_seq; - SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse); +static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) +{ + int port = BP_PORT(bp); + u32 hc_addr = (HC_REG_COMMAND_REG + port*32 + + COMMAND_REG_ATTN_BITS_SET); + u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0; + u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : + NIG_REG_MASK_INTERRUPT_PORT0; + u32 aeu_mask; + u32 nig_mask = 0; - mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) & - MCP_PULSE_SEQ_MASK); - /* The delta between driver pulse and mcp response - * should be 1 (before mcp response) or 0 (after mcp response) - */ - if ((drv_pulse != mcp_pulse) && - (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) { - /* someone lost a heartbeat... */ - BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n", - drv_pulse, mcp_pulse); - } - } + if (bp->attn_state & asserted) + BNX2X_ERR("IGU ERROR\n"); - if (bp->state == BNX2X_STATE_OPEN) - bnx2x_stats_handle(bp, STATS_EVENT_UPDATE); + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); + aeu_mask = REG_RD(bp, aeu_addr); -timer_restart: - mod_timer(&bp->timer, jiffies + bp->current_interval); -} + DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n", + aeu_mask, asserted); + aeu_mask &= ~(asserted & 0x3ff); + DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask); -/* end of Statistics */ + REG_WR(bp, aeu_addr, aeu_mask); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); -/* nic init */ + DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state); + bp->attn_state |= asserted; + DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state); -/* - * nic init service functions - */ + if (asserted & ATTN_HARD_WIRED_MASK) { + if (asserted & ATTN_NIG_FOR_FUNC) { -static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id) -{ - int port = BP_PORT(bp); + bnx2x_acquire_phy_lock(bp); - /* "CSTORM" */ - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_U_SIZE / 4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_C_SIZE / 4); -} + /* save nig interrupt mask */ + nig_mask = REG_RD(bp, nig_int_mask_addr); + REG_WR(bp, nig_int_mask_addr, 0); -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id) -{ - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int index; - u64 section; + bnx2x_link_attn(bp); - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - u_status_block); - sb->u_status_block.status_block_id = sb_id; + /* handle unicore attn? */ + } + if (asserted & ATTN_SW_TIMER_4_FUNC) + DP(NETIF_MSG_HW, "ATTN_SW_TIMER_4_FUNC!\n"); - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_USB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), func); + if (asserted & GPIO_2_FUNC) + DP(NETIF_MSG_HW, "GPIO_2_FUNC!\n"); - for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, index), 1); + if (asserted & GPIO_3_FUNC) + DP(NETIF_MSG_HW, "GPIO_3_FUNC!\n"); - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - c_status_block); - sb->c_status_block.status_block_id = sb_id; + if (asserted & GPIO_4_FUNC) + DP(NETIF_MSG_HW, "GPIO_4_FUNC!\n"); - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), func); + if (port == 0) { + if (asserted & ATTN_GENERAL_ATTN_1) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_1!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_1, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_2) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_2!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_2, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_3) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_3!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_3, 0x0); + } + } else { + if (asserted & ATTN_GENERAL_ATTN_4) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_4!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_4, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_5) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_5!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_5, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_6) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_6!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_6, 0x0); + } + } - for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, index), 1); + } /* if hardwired */ - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", + asserted, hc_addr); + REG_WR(bp, hc_addr, asserted); + + /* now set back the mask */ + if (asserted & ATTN_NIG_FOR_FUNC) { + REG_WR(bp, nig_int_mask_addr, nig_mask); + bnx2x_release_phy_lock(bp); + } } -static void bnx2x_zero_def_sb(struct bnx2x *bp) +static inline void bnx2x_fan_failure(struct bnx2x *bp) { - int func = BP_FUNC(bp); + int port = BP_PORT(bp); - bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct tstorm_def_status_block)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_u)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_c)/4); - bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct xstorm_def_status_block)/4); + /* mark the failure */ + bp->link_params.ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; + bp->link_params.ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; + SHMEM_WR(bp, dev_info.port_hw_config[port].external_phy_config, + bp->link_params.ext_phy_config); + + /* log the failure */ + netdev_err(bp->dev, "Fan Failure on Network Controller has caused" + " the driver to shutdown the card to prevent permanent" + " damage. Please contact OEM Support for assistance\n"); } -static void bnx2x_init_def_sb(struct bnx2x *bp, - struct host_def_status_block *def_sb, - dma_addr_t mapping, int sb_id) +static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) { int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int index, val, reg_offset; - u64 section; - - /* ATTN */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - atten_status_block); - def_sb->atten_status_block.status_block_id = sb_id; - - bp->attn_state = 0; + int reg_offset; + u32 val, swap_val, swap_override; reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); - for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { - bp->attn_group[index].sig[0] = REG_RD(bp, - reg_offset + 0x10*index); - bp->attn_group[index].sig[1] = REG_RD(bp, - reg_offset + 0x4 + 0x10*index); - bp->attn_group[index].sig[2] = REG_RD(bp, - reg_offset + 0x8 + 0x10*index); - bp->attn_group[index].sig[3] = REG_RD(bp, - reg_offset + 0xc + 0x10*index); - } + if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) { - reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : - HC_REG_ATTN_MSG0_ADDR_L); + val = REG_RD(bp, reg_offset); + val &= ~AEU_INPUTS_ATTN_BITS_SPIO5; + REG_WR(bp, reg_offset, val); - REG_WR(bp, reg_offset, U64_LO(section)); - REG_WR(bp, reg_offset + 4, U64_HI(section)); + BNX2X_ERR("SPIO5 hw attention\n"); - reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0); + /* Fan failure attention */ + switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + /* Low power mode is controlled by GPIO 2 */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + /* The PHY reset is controlled by GPIO 1 */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + break; - val = REG_RD(bp, reg_offset); - val |= sb_id; - REG_WR(bp, reg_offset, val); - - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - u_def_status_block); - def_sb->u_def_status_block.status_block_id = sb_id; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + /* The PHY reset is controlled by GPIO 1 */ + /* fake the port number to cancel the swap done in + set_gpio() */ + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + port = (swap_val && swap_override) ^ 1; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + break; - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_USB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), func); + default: + break; + } + bnx2x_fan_failure(bp); + } - for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(func, index), 1); + if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 | + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) { + bnx2x_acquire_phy_lock(bp); + bnx2x_handle_module_detect_int(&bp->link_params); + bnx2x_release_phy_lock(bp); + } - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - c_def_status_block); - def_sb->c_def_status_block.status_block_id = sb_id; + if (attn & HW_INTERRUT_ASSERT_SET_0) { - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), func); + val = REG_RD(bp, reg_offset); + val &= ~(attn & HW_INTERRUT_ASSERT_SET_0); + REG_WR(bp, reg_offset, val); - for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(func, index), 1); + BNX2X_ERR("FATAL HW block attention set0 0x%x\n", + (u32)(attn & HW_INTERRUT_ASSERT_SET_0)); + bnx2x_panic(); + } +} - /* TSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - t_def_status_block); - def_sb->t_def_status_block.status_block_id = sb_id; +static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn) +{ + u32 val; - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_TSTRORM_INTMEM + - ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); + if (attn & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) { - for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR); + BNX2X_ERR("DB hw attention 0x%x\n", val); + /* DORQ discard attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from DORQ\n"); + } - /* XSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - x_def_status_block); - def_sb->x_def_status_block.status_block_id = sb_id; + if (attn & HW_INTERRUT_ASSERT_SET_1) { - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_XSTRORM_INTMEM + - ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); + int port = BP_PORT(bp); + int reg_offset; - for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1 : + MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1); - bp->stats_pending = 0; - bp->set_mac_pending = 0; + val = REG_RD(bp, reg_offset); + val &= ~(attn & HW_INTERRUT_ASSERT_SET_1); + REG_WR(bp, reg_offset, val); - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + BNX2X_ERR("FATAL HW block attention set1 0x%x\n", + (u32)(attn & HW_INTERRUT_ASSERT_SET_1)); + bnx2x_panic(); + } } -void bnx2x_update_coalesce(struct bnx2x *bp) +static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) { - int port = BP_PORT(bp); - int i; + u32 val; - for_each_queue(bp, i) { - int sb_id = bp->fp[i].sb_id; + if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { - /* HC_INDEX_U_ETH_RX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - bp->rx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - (bp->rx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); + val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR); + BNX2X_ERR("CFC hw attention 0x%x\n", val); + /* CFC error attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from CFC\n"); + } - /* HC_INDEX_C_ETH_TX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - bp->tx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - (bp->tx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); + if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { + + val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); + BNX2X_ERR("PXP hw attention 0x%x\n", val); + /* RQ_USDMDP_FIFO_OVERFLOW */ + if (val & 0x18000) + BNX2X_ERR("FATAL error from PXP\n"); } -} -static void bnx2x_init_sp_ring(struct bnx2x *bp) -{ - int func = BP_FUNC(bp); + if (attn & HW_INTERRUT_ASSERT_SET_2) { - spin_lock_init(&bp->spq_lock); + int port = BP_PORT(bp); + int reg_offset; - bp->spq_left = MAX_SPQ_PENDING; - bp->spq_prod_idx = 0; - bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; - bp->spq_prod_bd = bp->spq; - bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT; + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_2 : + MISC_REG_AEU_ENABLE1_FUNC_0_OUT_2); - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func), - U64_LO(bp->spq_mapping)); - REG_WR(bp, - XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4, - U64_HI(bp->spq_mapping)); + val = REG_RD(bp, reg_offset); + val &= ~(attn & HW_INTERRUT_ASSERT_SET_2); + REG_WR(bp, reg_offset, val); - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); + BNX2X_ERR("FATAL HW block attention set2 0x%x\n", + (u32)(attn & HW_INTERRUT_ASSERT_SET_2)); + bnx2x_panic(); + } } -static void bnx2x_init_context(struct bnx2x *bp) +static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) { - int i; + u32 val; - /* Rx */ - for_each_queue(bp, i) { - struct eth_context *context = bnx2x_sp(bp, context[i].eth); - struct bnx2x_fastpath *fp = &bp->fp[i]; - u8 cl_id = fp->cl_id; + if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) { - context->ustorm_st_context.common.sb_index_numbers = - BNX2X_RX_SB_INDEX_NUM; - context->ustorm_st_context.common.clientId = cl_id; - context->ustorm_st_context.common.status_block_id = fp->sb_id; - context->ustorm_st_context.common.flags = - (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT | - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS); - context->ustorm_st_context.common.statistics_counter_id = - cl_id; - context->ustorm_st_context.common.mc_alignment_log_size = - BNX2X_RX_ALIGN_SHIFT; - context->ustorm_st_context.common.bd_buff_size = - bp->rx_buf_size; - context->ustorm_st_context.common.bd_page_base_hi = - U64_HI(fp->rx_desc_mapping); - context->ustorm_st_context.common.bd_page_base_lo = - U64_LO(fp->rx_desc_mapping); - if (!fp->disable_tpa) { - context->ustorm_st_context.common.flags |= - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA; - context->ustorm_st_context.common.sge_buff_size = - (u16)min_t(u32, SGE_PAGE_SIZE*PAGES_PER_SGE, - 0xffff); - context->ustorm_st_context.common.sge_page_base_hi = - U64_HI(fp->rx_sge_mapping); - context->ustorm_st_context.common.sge_page_base_lo = - U64_LO(fp->rx_sge_mapping); + if (attn & BNX2X_PMF_LINK_ASSERT) { + int func = BP_FUNC(bp); - context->ustorm_st_context.common.max_sges_for_packet = - SGE_PAGE_ALIGN(bp->dev->mtu) >> SGE_PAGE_SHIFT; - context->ustorm_st_context.common.max_sges_for_packet = - ((context->ustorm_st_context.common. - max_sges_for_packet + PAGES_PER_SGE - 1) & - (~(PAGES_PER_SGE - 1))) >> PAGES_PER_SGE_SHIFT; - } + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); + bp->mf_config = SHMEM_RD(bp, + mf_cfg.func_mf_config[func].config); + val = SHMEM_RD(bp, func_mb[func].drv_status); + if (val & DRV_STATUS_DCC_EVENT_MASK) + bnx2x_dcc_event(bp, + (val & DRV_STATUS_DCC_EVENT_MASK)); + bnx2x__link_status_update(bp); + if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) + bnx2x_pmf_update(bp); - context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); + } else if (attn & BNX2X_MC_ASSERT_BITS) { - context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); - } + BNX2X_ERR("MC assert!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0); + bnx2x_panic(); - /* Tx */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - struct eth_context *context = - bnx2x_sp(bp, context[i].eth); + } else if (attn & BNX2X_MCP_ASSERT) { - context->cstorm_st_context.sb_index_number = - C_SB_ETH_TX_CQ_INDEX; - context->cstorm_st_context.status_block_id = fp->sb_id; + BNX2X_ERR("MCP assert!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0); + bnx2x_fw_dump(bp); - context->xstorm_st_context.tx_bd_page_base_hi = - U64_HI(fp->tx_desc_mapping); - context->xstorm_st_context.tx_bd_page_base_lo = - U64_LO(fp->tx_desc_mapping); - context->xstorm_st_context.statistics_data = (fp->cl_id | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE); + } else + BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn); + } + + if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) { + BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn); + if (attn & BNX2X_GRC_TIMEOUT) { + val = CHIP_IS_E1H(bp) ? + REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0; + BNX2X_ERR("GRC time-out 0x%08x\n", val); + } + if (attn & BNX2X_GRC_RSV) { + val = CHIP_IS_E1H(bp) ? + REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0; + BNX2X_ERR("GRC reserved 0x%08x\n", val); + } + REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff); } } -static void bnx2x_init_ind_table(struct bnx2x *bp) -{ - int func = BP_FUNC(bp); - int i; +static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); +static int bnx2x_nic_load(struct bnx2x *bp, int load_mode); - if (bp->multi_mode == ETH_RSS_MODE_DISABLED) - return; - DP(NETIF_MSG_IFUP, - "Initializing indirection table multi_mode %d\n", bp->multi_mode); - for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) - REG_WR8(bp, BAR_TSTRORM_INTMEM + - TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, - bp->fp->cl_id + (i % bp->num_queues)); +#define BNX2X_MISC_GEN_REG MISC_REG_GENERIC_POR_1 +#define LOAD_COUNTER_BITS 16 /* Number of bits for load counter */ +#define LOAD_COUNTER_MASK (((u32)0x1 << LOAD_COUNTER_BITS) - 1) +#define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK) +#define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS +#define CHIP_PARITY_SUPPORTED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) +/* + * should be run under rtnl lock + */ +static inline void bnx2x_set_reset_done(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); + val &= ~(1 << RESET_DONE_FLAG_SHIFT); + REG_WR(bp, BNX2X_MISC_GEN_REG, val); + barrier(); + mmiowb(); } -void bnx2x_set_client_config(struct bnx2x *bp) +/* + * should be run under rtnl lock + */ +static inline void bnx2x_set_reset_in_progress(struct bnx2x *bp) { - struct tstorm_eth_client_config tstorm_client = {0}; - int port = BP_PORT(bp); - int i; - - tstorm_client.mtu = bp->dev->mtu; - tstorm_client.config_flags = - (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE | - TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE); -#ifdef BCM_VLAN - if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE; - DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); - } -#endif - - for_each_queue(bp, i) { - tstorm_client.statistics_counter_id = bp->fp[i].cl_id; - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id), - ((u32 *)&tstorm_client)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4, - ((u32 *)&tstorm_client)[1]); - } - - DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n", - ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); + u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); + val |= (1 << 16); + REG_WR(bp, BNX2X_MISC_GEN_REG, val); + barrier(); + mmiowb(); } -void bnx2x_set_storm_rx_mode(struct bnx2x *bp) +/* + * should be run under rtnl lock + */ +static inline bool bnx2x_reset_is_done(struct bnx2x *bp) { - struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0}; - int mode = bp->rx_mode; - int mask = bp->rx_mode_cl_mask; - int func = BP_FUNC(bp); - int port = BP_PORT(bp); - int i; - /* All but management unicast packets should pass to the host as well */ - u32 llh_mask = - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; - - DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask); - - switch (mode) { - case BNX2X_RX_MODE_NONE: /* no Rx */ - tstorm_mac_filter.ucast_drop_all = mask; - tstorm_mac_filter.mcast_drop_all = mask; - tstorm_mac_filter.bcast_drop_all = mask; - break; - - case BNX2X_RX_MODE_NORMAL: - tstorm_mac_filter.bcast_accept_all = mask; - break; + u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); + DP(NETIF_MSG_HW, "GEN_REG_VAL=0x%08x\n", val); + return (val & RESET_DONE_FLAG_MASK) ? false : true; +} - case BNX2X_RX_MODE_ALLMULTI: - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; - break; +/* + * should be run under rtnl lock + */ +static inline void bnx2x_inc_load_cnt(struct bnx2x *bp) +{ + u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG); - case BNX2X_RX_MODE_PROMISC: - tstorm_mac_filter.ucast_accept_all = mask; - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; - /* pass management unicast packets as well */ - llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; - break; + DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); - default: - BNX2X_ERR("BAD rx mode (%d)\n", mode); - break; - } + val1 = ((val & LOAD_COUNTER_MASK) + 1) & LOAD_COUNTER_MASK; + REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1); + barrier(); + mmiowb(); +} - REG_WR(bp, - (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK), - llh_mask); +/* + * should be run under rtnl lock + */ +static inline u32 bnx2x_dec_load_cnt(struct bnx2x *bp) +{ + u32 val1, val = REG_RD(bp, BNX2X_MISC_GEN_REG); - for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) { - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4, - ((u32 *)&tstorm_mac_filter)[i]); + DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); -/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, - ((u32 *)&tstorm_mac_filter)[i]); */ - } + val1 = ((val & LOAD_COUNTER_MASK) - 1) & LOAD_COUNTER_MASK; + REG_WR(bp, BNX2X_MISC_GEN_REG, (val & RESET_DONE_FLAG_MASK) | val1); + barrier(); + mmiowb(); - if (mode != BNX2X_RX_MODE_NONE) - bnx2x_set_client_config(bp); + return val1; } -static void bnx2x_init_internal_common(struct bnx2x *bp) +/* + * should be run under rtnl lock + */ +static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp) { - int i; - - /* Zero this manually as its initialization is - currently missing in the initTool */ - for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_AGG_DATA_OFFSET + i * 4, 0); + return REG_RD(bp, BNX2X_MISC_GEN_REG) & LOAD_COUNTER_MASK; } -static void bnx2x_init_internal_port(struct bnx2x *bp) +static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) { - int port = BP_PORT(bp); - - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_U_OFFSET(port), BNX2X_BTR); - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_C_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); + u32 val = REG_RD(bp, BNX2X_MISC_GEN_REG); + REG_WR(bp, BNX2X_MISC_GEN_REG, val & (~LOAD_COUNTER_MASK)); } -static void bnx2x_init_internal_func(struct bnx2x *bp) +static inline void _print_next_block(int idx, const char *blk) { - struct tstorm_eth_function_common_config tstorm_config = {0}; - struct stats_indication_flags stats_flags = {0}; - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int i, j; - u32 offset; - u16 max_agg_size; + if (idx) + pr_cont(", "); + pr_cont("%s", blk); +} - tstorm_config.config_flags = RSS_FLAGS(bp); +static inline int bnx2x_print_blocks_with_parity0(u32 sig, int par_num) +{ + int i = 0; + u32 cur_bit = 0; + for (i = 0; sig; i++) { + cur_bit = ((u32)0x1 << i); + if (sig & cur_bit) { + switch (cur_bit) { + case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR: + _print_next_block(par_num++, "BRB"); + break; + case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR: + _print_next_block(par_num++, "PARSER"); + break; + case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR: + _print_next_block(par_num++, "TSDM"); + break; + case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR: + _print_next_block(par_num++, "SEARCHER"); + break; + case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR: + _print_next_block(par_num++, "TSEMI"); + break; + } - if (is_multi(bp)) - tstorm_config.rss_result_mask = MULTI_MASK; + /* Clear the bit */ + sig &= ~cur_bit; + } + } - /* Enable TPA if needed */ - if (bp->flags & TPA_ENABLE_FLAG) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; + return par_num; +} - if (IS_E1HMF(bp)) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM; +static inline int bnx2x_print_blocks_with_parity1(u32 sig, int par_num) +{ + int i = 0; + u32 cur_bit = 0; + for (i = 0; sig; i++) { + cur_bit = ((u32)0x1 << i); + if (sig & cur_bit) { + switch (cur_bit) { + case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR: + _print_next_block(par_num++, "PBCLIENT"); + break; + case AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR: + _print_next_block(par_num++, "QM"); + break; + case AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR: + _print_next_block(par_num++, "XSDM"); + break; + case AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR: + _print_next_block(par_num++, "XSEMI"); + break; + case AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR: + _print_next_block(par_num++, "DOORBELLQ"); + break; + case AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR: + _print_next_block(par_num++, "VAUX PCI CORE"); + break; + case AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR: + _print_next_block(par_num++, "DEBUG"); + break; + case AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR: + _print_next_block(par_num++, "USDM"); + break; + case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR: + _print_next_block(par_num++, "USEMI"); + break; + case AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR: + _print_next_block(par_num++, "UPB"); + break; + case AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR: + _print_next_block(par_num++, "CSDM"); + break; + } + + /* Clear the bit */ + sig &= ~cur_bit; + } + } + + return par_num; +} + +static inline int bnx2x_print_blocks_with_parity2(u32 sig, int par_num) +{ + int i = 0; + u32 cur_bit = 0; + for (i = 0; sig; i++) { + cur_bit = ((u32)0x1 << i); + if (sig & cur_bit) { + switch (cur_bit) { + case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR: + _print_next_block(par_num++, "CSEMI"); + break; + case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR: + _print_next_block(par_num++, "PXP"); + break; + case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR: + _print_next_block(par_num++, + "PXPPCICLOCKCLIENT"); + break; + case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR: + _print_next_block(par_num++, "CFC"); + break; + case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR: + _print_next_block(par_num++, "CDU"); + break; + case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR: + _print_next_block(par_num++, "IGU"); + break; + case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR: + _print_next_block(par_num++, "MISC"); + break; + } + + /* Clear the bit */ + sig &= ~cur_bit; + } + } + + return par_num; +} + +static inline int bnx2x_print_blocks_with_parity3(u32 sig, int par_num) +{ + int i = 0; + u32 cur_bit = 0; + for (i = 0; sig; i++) { + cur_bit = ((u32)0x1 << i); + if (sig & cur_bit) { + switch (cur_bit) { + case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY: + _print_next_block(par_num++, "MCP ROM"); + break; + case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY: + _print_next_block(par_num++, "MCP UMP RX"); + break; + case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY: + _print_next_block(par_num++, "MCP UMP TX"); + break; + case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY: + _print_next_block(par_num++, "MCP SCPAD"); + break; + } + + /* Clear the bit */ + sig &= ~cur_bit; + } + } + + return par_num; +} + +static inline bool bnx2x_parity_attn(struct bnx2x *bp, u32 sig0, u32 sig1, + u32 sig2, u32 sig3) +{ + if ((sig0 & HW_PRTY_ASSERT_SET_0) || (sig1 & HW_PRTY_ASSERT_SET_1) || + (sig2 & HW_PRTY_ASSERT_SET_2) || (sig3 & HW_PRTY_ASSERT_SET_3)) { + int par_num = 0; + DP(NETIF_MSG_HW, "Was parity error: HW block parity attention: " + "[0]:0x%08x [1]:0x%08x " + "[2]:0x%08x [3]:0x%08x\n", + sig0 & HW_PRTY_ASSERT_SET_0, + sig1 & HW_PRTY_ASSERT_SET_1, + sig2 & HW_PRTY_ASSERT_SET_2, + sig3 & HW_PRTY_ASSERT_SET_3); + printk(KERN_ERR"%s: Parity errors detected in blocks: ", + bp->dev->name); + par_num = bnx2x_print_blocks_with_parity0( + sig0 & HW_PRTY_ASSERT_SET_0, par_num); + par_num = bnx2x_print_blocks_with_parity1( + sig1 & HW_PRTY_ASSERT_SET_1, par_num); + par_num = bnx2x_print_blocks_with_parity2( + sig2 & HW_PRTY_ASSERT_SET_2, par_num); + par_num = bnx2x_print_blocks_with_parity3( + sig3 & HW_PRTY_ASSERT_SET_3, par_num); + printk("\n"); + return true; + } else + return false; +} + +static bool bnx2x_chk_parity_attn(struct bnx2x *bp) +{ + struct attn_route attn; + int port = BP_PORT(bp); + + attn.sig[0] = REG_RD(bp, + MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + + port*4); + attn.sig[1] = REG_RD(bp, + MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + + port*4); + attn.sig[2] = REG_RD(bp, + MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + + port*4); + attn.sig[3] = REG_RD(bp, + MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + + port*4); + + return bnx2x_parity_attn(bp, attn.sig[0], attn.sig[1], attn.sig[2], + attn.sig[3]); +} + +static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) +{ + struct attn_route attn, *group_mask; + int port = BP_PORT(bp); + int index; + u32 reg_addr; + u32 val; + u32 aeu_mask; + + /* need to take HW lock because MCP or other port might also + try to handle this event */ + bnx2x_acquire_alr(bp); + + if (bnx2x_chk_parity_attn(bp)) { + bp->recovery_state = BNX2X_RECOVERY_INIT; + bnx2x_set_reset_in_progress(bp); + schedule_delayed_work(&bp->reset_task, 0); + /* Disable HW interrupts */ + bnx2x_int_disable(bp); + bnx2x_release_alr(bp); + /* In case of parity errors don't handle attentions so that + * other function would "see" parity errors. + */ + return; + } + + attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4); + attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); + attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4); + attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); + DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n", + attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]); + + for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { + if (deasserted & (1 << index)) { + group_mask = &bp->attn_group[index]; + + DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n", + index, group_mask->sig[0], group_mask->sig[1], + group_mask->sig[2], group_mask->sig[3]); + + bnx2x_attn_int_deasserted3(bp, + attn.sig[3] & group_mask->sig[3]); + bnx2x_attn_int_deasserted1(bp, + attn.sig[1] & group_mask->sig[1]); + bnx2x_attn_int_deasserted2(bp, + attn.sig[2] & group_mask->sig[2]); + bnx2x_attn_int_deasserted0(bp, + attn.sig[0] & group_mask->sig[0]); + } + } + + bnx2x_release_alr(bp); + + reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR); + + val = ~deasserted; + DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", + val, reg_addr); + REG_WR(bp, reg_addr, val); + + if (~bp->attn_state & deasserted) + BNX2X_ERR("IGU ERROR\n"); + + reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0; + + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); + aeu_mask = REG_RD(bp, reg_addr); + + DP(NETIF_MSG_HW, "aeu_mask %x newly deasserted %x\n", + aeu_mask, deasserted); + aeu_mask |= (deasserted & 0x3ff); + DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask); + + REG_WR(bp, reg_addr, aeu_mask); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port); + + DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state); + bp->attn_state &= ~deasserted; + DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state); +} + +static void bnx2x_attn_int(struct bnx2x *bp) +{ + /* read local copy of bits */ + u32 attn_bits = le32_to_cpu(bp->def_status_blk->atten_status_block. + attn_bits); + u32 attn_ack = le32_to_cpu(bp->def_status_blk->atten_status_block. + attn_bits_ack); + u32 attn_state = bp->attn_state; + + /* look for changed bits */ + u32 asserted = attn_bits & ~attn_ack & ~attn_state; + u32 deasserted = ~attn_bits & attn_ack & attn_state; + + DP(NETIF_MSG_HW, + "attn_bits %x attn_ack %x asserted %x deasserted %x\n", + attn_bits, attn_ack, asserted, deasserted); + + if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state)) + BNX2X_ERR("BAD attention state\n"); + + /* handle bits that were raised */ + if (asserted) + bnx2x_attn_int_asserted(bp, asserted); + + if (deasserted) + bnx2x_attn_int_deasserted(bp, deasserted); +} + +static void bnx2x_sp_task(struct work_struct *work) +{ + struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work); + u16 status; + + /* Return here if interrupt is disabled */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + return; + } + + status = bnx2x_update_dsb_idx(bp); +/* if (status == 0) */ +/* BNX2X_ERR("spurious slowpath interrupt!\n"); */ + + DP(NETIF_MSG_INTR, "got a slowpath interrupt (status 0x%x)\n", status); + + /* HW attentions */ + if (status & 0x1) { + bnx2x_attn_int(bp); + status &= ~0x1; + } + + /* CStorm events: STAT_QUERY */ + if (status & 0x2) { + DP(BNX2X_MSG_SP, "CStorm events: STAT_QUERY\n"); + status &= ~0x2; + } + + if (unlikely(status)) + DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n", + status); + + bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx), + IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), + IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx), + IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx), + IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx), + IGU_INT_ENABLE, 1); +} + +static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) +{ + struct net_device *dev = dev_instance; + struct bnx2x *bp = netdev_priv(dev); + + /* Return here if interrupt is disabled */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + return IRQ_HANDLED; + } + + bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0); + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return IRQ_HANDLED; +#endif + +#ifdef BCM_CNIC + { + struct cnic_ops *c_ops; + + rcu_read_lock(); + c_ops = rcu_dereference(bp->cnic_ops); + if (c_ops) + c_ops->cnic_handler(bp->cnic_data, NULL); + rcu_read_unlock(); + } +#endif + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); + + return IRQ_HANDLED; +} + +/* end of slow path */ + +/* Statistics */ + +/**************************************************************************** +* Macros +****************************************************************************/ + +/* sum[hi:lo] += add[hi:lo] */ +#define ADD_64(s_hi, a_hi, s_lo, a_lo) \ + do { \ + s_lo += a_lo; \ + s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ + } while (0) + +/* difference = minuend - subtrahend */ +#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ + do { \ + if (m_lo < s_lo) { \ + /* underflow */ \ + d_hi = m_hi - s_hi; \ + if (d_hi > 0) { \ + /* we can 'loan' 1 */ \ + d_hi--; \ + d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ + } else { \ + /* m_hi <= s_hi */ \ + d_hi = 0; \ + d_lo = 0; \ + } \ + } else { \ + /* m_lo >= s_lo */ \ + if (m_hi < s_hi) { \ + d_hi = 0; \ + d_lo = 0; \ + } else { \ + /* m_hi >= s_hi */ \ + d_hi = m_hi - s_hi; \ + d_lo = m_lo - s_lo; \ + } \ + } \ + } while (0) + +#define UPDATE_STAT64(s, t) \ + do { \ + DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \ + diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \ + pstats->mac_stx[0].t##_hi = new->s##_hi; \ + pstats->mac_stx[0].t##_lo = new->s##_lo; \ + ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \ + pstats->mac_stx[1].t##_lo, diff.lo); \ + } while (0) + +#define UPDATE_STAT64_NIG(s, t) \ + do { \ + DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \ + diff.lo, new->s##_lo, old->s##_lo); \ + ADD_64(estats->t##_hi, diff.hi, \ + estats->t##_lo, diff.lo); \ + } while (0) + +/* sum[hi:lo] += add */ +#define ADD_EXTEND_64(s_hi, s_lo, a) \ + do { \ + s_lo += a; \ + s_hi += (s_lo < a) ? 1 : 0; \ + } while (0) + +#define UPDATE_EXTEND_STAT(s) \ + do { \ + ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \ + pstats->mac_stx[1].s##_lo, \ + new->s); \ + } while (0) + +#define UPDATE_EXTEND_TSTAT(s, t) \ + do { \ + diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \ + old_tclient->s = tclient->s; \ + ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + +#define UPDATE_EXTEND_USTAT(s, t) \ + do { \ + diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ + old_uclient->s = uclient->s; \ + ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + +#define UPDATE_EXTEND_XSTAT(s, t) \ + do { \ + diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \ + old_xclient->s = xclient->s; \ + ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + +/* minuend -= subtrahend */ +#define SUB_64(m_hi, s_hi, m_lo, s_lo) \ + do { \ + DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ + } while (0) + +/* minuend[hi:lo] -= subtrahend */ +#define SUB_EXTEND_64(m_hi, m_lo, s) \ + do { \ + SUB_64(m_hi, 0, m_lo, s); \ + } while (0) + +#define SUB_EXTEND_USTAT(s, t) \ + do { \ + diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \ + SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \ + } while (0) + +/* + * General service functions + */ + +static inline long bnx2x_hilo(u32 *hiref) +{ + u32 lo = *(hiref + 1); +#if (BITS_PER_LONG == 64) + u32 hi = *hiref; + + return HILO_U64(hi, lo); +#else + return lo; +#endif +} + +/* + * Init service functions + */ + +static void bnx2x_storm_stats_post(struct bnx2x *bp) +{ + if (!bp->stats_pending) { + struct eth_query_ramrod_data ramrod_data = {0}; + int i, rc; + + ramrod_data.drv_counter = bp->stats_counter++; + ramrod_data.collect_port = bp->port.pmf ? 1 : 0; + for_each_queue(bp, i) + ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); + + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, + ((u32 *)&ramrod_data)[1], + ((u32 *)&ramrod_data)[0], 0); + if (rc == 0) { + /* stats ramrod has it's own slot on the spq */ + bp->spq_left++; + bp->stats_pending = 1; + } + } +} + +static void bnx2x_hw_stats_post(struct bnx2x *bp) +{ + struct dmae_command *dmae = &bp->stats_dmae; + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + *stats_comp = DMAE_COMP_VAL; + if (CHIP_REV_IS_SLOW(bp)) + return; + + /* loader */ + if (bp->executer_idx) { + int loader_idx = PMF_DMAE_C(bp); + + memset(dmae, 0, sizeof(struct dmae_command)); + + dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | + DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | + DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (BP_PORT(bp) ? DMAE_CMD_PORT_1 : + DMAE_CMD_PORT_0) | + (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); + dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + + sizeof(struct dmae_command) * + (loader_idx + 1)) >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct dmae_command) >> 2; + if (CHIP_IS_E1(bp)) + dmae->len--; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + *stats_comp = 0; + bnx2x_post_dmae(bp, dmae, loader_idx); + + } else if (bp->func_stx) { + *stats_comp = 0; + bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); + } +} + +static int bnx2x_stats_comp(struct bnx2x *bp) +{ + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + int cnt = 10; + + might_sleep(); + while (*stats_comp != DMAE_COMP_VAL) { + if (!cnt) { + BNX2X_ERR("timeout waiting for stats finished\n"); + break; + } + cnt--; + msleep(1); + } + return 1; +} + +/* + * Statistics service functions + */ + +static void bnx2x_stats_pmf_update(struct bnx2x *bp) +{ + struct dmae_command *dmae; + u32 opcode; + int loader_idx = PMF_DMAE_C(bp); + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + /* sanity */ + if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) { + BNX2X_ERR("BUG!\n"); + return; + } + + bp->executer_idx = 0; + + opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | + DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + dmae->src_addr_lo = bp->port.port_stx >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); + dmae->len = DMAE_LEN32_RD_MAX; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) + + DMAE_LEN32_RD_MAX * 4); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) + + DMAE_LEN32_RD_MAX * 4); + dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX; + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_val = DMAE_COMP_VAL; + + *stats_comp = 0; + bnx2x_hw_stats_post(bp); + bnx2x_stats_comp(bp); +} + +static void bnx2x_port_stats_init(struct bnx2x *bp) +{ + struct dmae_command *dmae; + int port = BP_PORT(bp); + int vn = BP_E1HVN(bp); + u32 opcode; + int loader_idx = PMF_DMAE_C(bp); + u32 mac_addr; + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + /* sanity */ + if (!bp->link_vars.link_up || !bp->port.pmf) { + BNX2X_ERR("BUG!\n"); + return; + } + + bp->executer_idx = 0; + + /* MCP */ + opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | + DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (vn << DMAE_CMD_E1HVN_SHIFT)); + + if (bp->port.port_stx) { + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); + dmae->dst_addr_lo = bp->port.port_stx >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct host_port_stats) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + } + + if (bp->func_stx) { + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); + dmae->dst_addr_lo = bp->func_stx >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct host_func_stats) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + } + + /* MAC */ + opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | + DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (vn << DMAE_CMD_E1HVN_SHIFT)); + + if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { + + mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM); + + /* BIGMAC_REGISTER_TX_STAT_GTPKT .. + BIGMAC_REGISTER_TX_STAT_GTBYT */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); + dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + /* BIGMAC_REGISTER_RX_STAT_GR64 .. + BIGMAC_REGISTER_RX_STAT_GRIPJ */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac_stats, rx_stat_gr64_lo)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac_stats, rx_stat_gr64_lo)); + dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) { + + mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0); + + /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + EMAC_REG_EMAC_RX_STAT_AC) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); + dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + /* EMAC_REG_EMAC_RX_STAT_AC_28 */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + EMAC_REG_EMAC_RX_STAT_AC_28) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, rx_stat_falsecarriererrors)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, rx_stat_falsecarriererrors)); + dmae->len = 1; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + EMAC_REG_EMAC_TX_STAT_AC) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, tx_stat_ifhcoutoctets)); + dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + } + + /* NIG */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : + NIG_REG_STAT0_BRB_DISCARD) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats)); + dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 : + NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt0_lo)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt0_lo)); + dmae->len = (2*sizeof(u32)) >> 2; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | + DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (vn << DMAE_CMD_E1HVN_SHIFT)); + dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : + NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt1_lo)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) + + offsetof(struct nig_stats, egress_mac_pkt1_lo)); + dmae->len = (2*sizeof(u32)) >> 2; + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_val = DMAE_COMP_VAL; + + *stats_comp = 0; +} + +static void bnx2x_func_stats_init(struct bnx2x *bp) +{ + struct dmae_command *dmae = &bp->stats_dmae; + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + /* sanity */ + if (!bp->func_stx) { + BNX2X_ERR("BUG!\n"); + return; + } + + bp->executer_idx = 0; + memset(dmae, 0, sizeof(struct dmae_command)); + + dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | + DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); + dmae->dst_addr_lo = bp->func_stx >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct host_func_stats) >> 2; + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_val = DMAE_COMP_VAL; + + *stats_comp = 0; +} + +static void bnx2x_stats_start(struct bnx2x *bp) +{ + if (bp->port.pmf) + bnx2x_port_stats_init(bp); + + else if (bp->func_stx) + bnx2x_func_stats_init(bp); + + bnx2x_hw_stats_post(bp); + bnx2x_storm_stats_post(bp); +} + +static void bnx2x_stats_pmf_start(struct bnx2x *bp) +{ + bnx2x_stats_comp(bp); + bnx2x_stats_pmf_update(bp); + bnx2x_stats_start(bp); +} + +static void bnx2x_stats_restart(struct bnx2x *bp) +{ + bnx2x_stats_comp(bp); + bnx2x_stats_start(bp); +} + +static void bnx2x_bmac_stats_update(struct bnx2x *bp) +{ + struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats); + struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); + struct bnx2x_eth_stats *estats = &bp->eth_stats; + struct { + u32 lo; + u32 hi; + } diff; + + UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); + UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); + UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); + UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); + UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); + UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); + UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); + UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); + UPDATE_STAT64(tx_stat_gt127, + tx_stat_etherstatspkts65octetsto127octets); + UPDATE_STAT64(tx_stat_gt255, + tx_stat_etherstatspkts128octetsto255octets); + UPDATE_STAT64(tx_stat_gt511, + tx_stat_etherstatspkts256octetsto511octets); + UPDATE_STAT64(tx_stat_gt1023, + tx_stat_etherstatspkts512octetsto1023octets); + UPDATE_STAT64(tx_stat_gt1518, + tx_stat_etherstatspkts1024octetsto1522octets); + UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gterr, + tx_stat_dot3statsinternalmactransmiterrors); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + + estats->pause_frames_received_hi = + pstats->mac_stx[1].rx_stat_bmac_xpf_hi; + estats->pause_frames_received_lo = + pstats->mac_stx[1].rx_stat_bmac_xpf_lo; + + estats->pause_frames_sent_hi = + pstats->mac_stx[1].tx_stat_outxoffsent_hi; + estats->pause_frames_sent_lo = + pstats->mac_stx[1].tx_stat_outxoffsent_lo; +} + +static void bnx2x_emac_stats_update(struct bnx2x *bp) +{ + struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats); + struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); + struct bnx2x_eth_stats *estats = &bp->eth_stats; + + UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets); + UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets); + UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors); + UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors); + UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors); + UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors); + UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts); + UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong); + UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments); + UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers); + UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived); + UPDATE_EXTEND_STAT(rx_stat_xoffstateentered); + UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived); + UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived); + UPDATE_EXTEND_STAT(tx_stat_outxonsent); + UPDATE_EXTEND_STAT(tx_stat_outxoffsent); + UPDATE_EXTEND_STAT(tx_stat_flowcontroldone); + UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions); + UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes); + UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes); + UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions); + UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions); + UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions); + UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets); + UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets); + UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets); + UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets); + UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets); + UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets); + UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets); + UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors); + + estats->pause_frames_received_hi = + pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi; + estats->pause_frames_received_lo = + pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo; + ADD_64(estats->pause_frames_received_hi, + pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi, + estats->pause_frames_received_lo, + pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo); + + estats->pause_frames_sent_hi = + pstats->mac_stx[1].tx_stat_outxonsent_hi; + estats->pause_frames_sent_lo = + pstats->mac_stx[1].tx_stat_outxonsent_lo; + ADD_64(estats->pause_frames_sent_hi, + pstats->mac_stx[1].tx_stat_outxoffsent_hi, + estats->pause_frames_sent_lo, + pstats->mac_stx[1].tx_stat_outxoffsent_lo); +} + +static int bnx2x_hw_stats_update(struct bnx2x *bp) +{ + struct nig_stats *new = bnx2x_sp(bp, nig_stats); + struct nig_stats *old = &(bp->port.old_nig_stats); + struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); + struct bnx2x_eth_stats *estats = &bp->eth_stats; + struct { + u32 lo; + u32 hi; + } diff; + + if (bp->link_vars.mac_type == MAC_TYPE_BMAC) + bnx2x_bmac_stats_update(bp); + + else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) + bnx2x_emac_stats_update(bp); + + else { /* unreached */ + BNX2X_ERR("stats updated by DMAE but no MAC active\n"); + return -1; + } + + ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo, + new->brb_discard - old->brb_discard); + ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo, + new->brb_truncate - old->brb_truncate); + + UPDATE_STAT64_NIG(egress_mac_pkt0, + etherstatspkts1024octetsto1522octets); + UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets); + + memcpy(old, new, sizeof(struct nig_stats)); + + memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]), + sizeof(struct mac_stx)); + estats->brb_drop_hi = pstats->brb_drop_hi; + estats->brb_drop_lo = pstats->brb_drop_lo; + + pstats->host_port_stats_start = ++pstats->host_port_stats_end; + + if (!BP_NOMCP(bp)) { + u32 nig_timer_max = + SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); + if (nig_timer_max != estats->nig_timer_max) { + estats->nig_timer_max = nig_timer_max; + BNX2X_ERR("NIG timer max (%u)\n", + estats->nig_timer_max); + } + } + + return 0; +} + +static int bnx2x_storm_stats_update(struct bnx2x *bp) +{ + struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); + struct tstorm_per_port_stats *tport = + &stats->tstorm_common.port_statistics; + struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); + struct bnx2x_eth_stats *estats = &bp->eth_stats; + int i; + + memcpy(&(fstats->total_bytes_received_hi), + &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), + sizeof(struct host_func_stats) - 2*sizeof(u32)); + estats->error_bytes_received_hi = 0; + estats->error_bytes_received_lo = 0; + estats->etherstatsoverrsizepkts_hi = 0; + estats->etherstatsoverrsizepkts_lo = 0; + estats->no_buff_discard_hi = 0; + estats->no_buff_discard_lo = 0; + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + int cl_id = fp->cl_id; + struct tstorm_per_client_stats *tclient = + &stats->tstorm_common.client_statistics[cl_id]; + struct tstorm_per_client_stats *old_tclient = &fp->old_tclient; + struct ustorm_per_client_stats *uclient = + &stats->ustorm_common.client_statistics[cl_id]; + struct ustorm_per_client_stats *old_uclient = &fp->old_uclient; + struct xstorm_per_client_stats *xclient = + &stats->xstorm_common.client_statistics[cl_id]; + struct xstorm_per_client_stats *old_xclient = &fp->old_xclient; + struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; + u32 diff; + + /* are storm stats valid? */ + if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) != + bp->stats_counter) { + DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" + " xstorm counter (0x%x) != stats_counter (0x%x)\n", + i, xclient->stats_counter, bp->stats_counter); + return -1; + } + if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) != + bp->stats_counter) { + DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" + " tstorm counter (0x%x) != stats_counter (0x%x)\n", + i, tclient->stats_counter, bp->stats_counter); + return -2; + } + if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) != + bp->stats_counter) { + DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" + " ustorm counter (0x%x) != stats_counter (0x%x)\n", + i, uclient->stats_counter, bp->stats_counter); + return -4; + } + + qstats->total_bytes_received_hi = + le32_to_cpu(tclient->rcv_broadcast_bytes.hi); + qstats->total_bytes_received_lo = + le32_to_cpu(tclient->rcv_broadcast_bytes.lo); + + ADD_64(qstats->total_bytes_received_hi, + le32_to_cpu(tclient->rcv_multicast_bytes.hi), + qstats->total_bytes_received_lo, + le32_to_cpu(tclient->rcv_multicast_bytes.lo)); + + ADD_64(qstats->total_bytes_received_hi, + le32_to_cpu(tclient->rcv_unicast_bytes.hi), + qstats->total_bytes_received_lo, + le32_to_cpu(tclient->rcv_unicast_bytes.lo)); + + SUB_64(qstats->total_bytes_received_hi, + le32_to_cpu(uclient->bcast_no_buff_bytes.hi), + qstats->total_bytes_received_lo, + le32_to_cpu(uclient->bcast_no_buff_bytes.lo)); + + SUB_64(qstats->total_bytes_received_hi, + le32_to_cpu(uclient->mcast_no_buff_bytes.hi), + qstats->total_bytes_received_lo, + le32_to_cpu(uclient->mcast_no_buff_bytes.lo)); + + SUB_64(qstats->total_bytes_received_hi, + le32_to_cpu(uclient->ucast_no_buff_bytes.hi), + qstats->total_bytes_received_lo, + le32_to_cpu(uclient->ucast_no_buff_bytes.lo)); + + qstats->valid_bytes_received_hi = + qstats->total_bytes_received_hi; + qstats->valid_bytes_received_lo = + qstats->total_bytes_received_lo; + + qstats->error_bytes_received_hi = + le32_to_cpu(tclient->rcv_error_bytes.hi); + qstats->error_bytes_received_lo = + le32_to_cpu(tclient->rcv_error_bytes.lo); + + ADD_64(qstats->total_bytes_received_hi, + qstats->error_bytes_received_hi, + qstats->total_bytes_received_lo, + qstats->error_bytes_received_lo); + + UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, + total_unicast_packets_received); + UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, + total_multicast_packets_received); + UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, + total_broadcast_packets_received); + UPDATE_EXTEND_TSTAT(packets_too_big_discard, + etherstatsoverrsizepkts); + UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard); + + SUB_EXTEND_USTAT(ucast_no_buff_pkts, + total_unicast_packets_received); + SUB_EXTEND_USTAT(mcast_no_buff_pkts, + total_multicast_packets_received); + SUB_EXTEND_USTAT(bcast_no_buff_pkts, + total_broadcast_packets_received); + UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard); + UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard); + UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard); + + qstats->total_bytes_transmitted_hi = + le32_to_cpu(xclient->unicast_bytes_sent.hi); + qstats->total_bytes_transmitted_lo = + le32_to_cpu(xclient->unicast_bytes_sent.lo); + + ADD_64(qstats->total_bytes_transmitted_hi, + le32_to_cpu(xclient->multicast_bytes_sent.hi), + qstats->total_bytes_transmitted_lo, + le32_to_cpu(xclient->multicast_bytes_sent.lo)); + + ADD_64(qstats->total_bytes_transmitted_hi, + le32_to_cpu(xclient->broadcast_bytes_sent.hi), + qstats->total_bytes_transmitted_lo, + le32_to_cpu(xclient->broadcast_bytes_sent.lo)); + + UPDATE_EXTEND_XSTAT(unicast_pkts_sent, + total_unicast_packets_transmitted); + UPDATE_EXTEND_XSTAT(multicast_pkts_sent, + total_multicast_packets_transmitted); + UPDATE_EXTEND_XSTAT(broadcast_pkts_sent, + total_broadcast_packets_transmitted); + + old_tclient->checksum_discard = tclient->checksum_discard; + old_tclient->ttl0_discard = tclient->ttl0_discard; + + ADD_64(fstats->total_bytes_received_hi, + qstats->total_bytes_received_hi, + fstats->total_bytes_received_lo, + qstats->total_bytes_received_lo); + ADD_64(fstats->total_bytes_transmitted_hi, + qstats->total_bytes_transmitted_hi, + fstats->total_bytes_transmitted_lo, + qstats->total_bytes_transmitted_lo); + ADD_64(fstats->total_unicast_packets_received_hi, + qstats->total_unicast_packets_received_hi, + fstats->total_unicast_packets_received_lo, + qstats->total_unicast_packets_received_lo); + ADD_64(fstats->total_multicast_packets_received_hi, + qstats->total_multicast_packets_received_hi, + fstats->total_multicast_packets_received_lo, + qstats->total_multicast_packets_received_lo); + ADD_64(fstats->total_broadcast_packets_received_hi, + qstats->total_broadcast_packets_received_hi, + fstats->total_broadcast_packets_received_lo, + qstats->total_broadcast_packets_received_lo); + ADD_64(fstats->total_unicast_packets_transmitted_hi, + qstats->total_unicast_packets_transmitted_hi, + fstats->total_unicast_packets_transmitted_lo, + qstats->total_unicast_packets_transmitted_lo); + ADD_64(fstats->total_multicast_packets_transmitted_hi, + qstats->total_multicast_packets_transmitted_hi, + fstats->total_multicast_packets_transmitted_lo, + qstats->total_multicast_packets_transmitted_lo); + ADD_64(fstats->total_broadcast_packets_transmitted_hi, + qstats->total_broadcast_packets_transmitted_hi, + fstats->total_broadcast_packets_transmitted_lo, + qstats->total_broadcast_packets_transmitted_lo); + ADD_64(fstats->valid_bytes_received_hi, + qstats->valid_bytes_received_hi, + fstats->valid_bytes_received_lo, + qstats->valid_bytes_received_lo); + + ADD_64(estats->error_bytes_received_hi, + qstats->error_bytes_received_hi, + estats->error_bytes_received_lo, + qstats->error_bytes_received_lo); + ADD_64(estats->etherstatsoverrsizepkts_hi, + qstats->etherstatsoverrsizepkts_hi, + estats->etherstatsoverrsizepkts_lo, + qstats->etherstatsoverrsizepkts_lo); + ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi, + estats->no_buff_discard_lo, qstats->no_buff_discard_lo); + } + + ADD_64(fstats->total_bytes_received_hi, + estats->rx_stat_ifhcinbadoctets_hi, + fstats->total_bytes_received_lo, + estats->rx_stat_ifhcinbadoctets_lo); + + memcpy(estats, &(fstats->total_bytes_received_hi), + sizeof(struct host_func_stats) - 2*sizeof(u32)); + + ADD_64(estats->etherstatsoverrsizepkts_hi, + estats->rx_stat_dot3statsframestoolong_hi, + estats->etherstatsoverrsizepkts_lo, + estats->rx_stat_dot3statsframestoolong_lo); + ADD_64(estats->error_bytes_received_hi, + estats->rx_stat_ifhcinbadoctets_hi, + estats->error_bytes_received_lo, + estats->rx_stat_ifhcinbadoctets_lo); + + if (bp->port.pmf) { + estats->mac_filter_discard = + le32_to_cpu(tport->mac_filter_discard); + estats->xxoverflow_discard = + le32_to_cpu(tport->xxoverflow_discard); + estats->brb_truncate_discard = + le32_to_cpu(tport->brb_truncate_discard); + estats->mac_discard = le32_to_cpu(tport->mac_discard); + } + + fstats->host_func_stats_start = ++fstats->host_func_stats_end; + + bp->stats_pending = 0; + + return 0; +} + +static void bnx2x_net_stats_update(struct bnx2x *bp) +{ + struct bnx2x_eth_stats *estats = &bp->eth_stats; + struct net_device_stats *nstats = &bp->dev->stats; + int i; + + nstats->rx_packets = + bnx2x_hilo(&estats->total_unicast_packets_received_hi) + + bnx2x_hilo(&estats->total_multicast_packets_received_hi) + + bnx2x_hilo(&estats->total_broadcast_packets_received_hi); + + nstats->tx_packets = + bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) + + bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) + + bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi); + + nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); + + nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); + + nstats->rx_dropped = estats->mac_discard; + for_each_queue(bp, i) + nstats->rx_dropped += + le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); + + nstats->tx_dropped = 0; + + nstats->multicast = + bnx2x_hilo(&estats->total_multicast_packets_received_hi); + + nstats->collisions = + bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi); + + nstats->rx_length_errors = + bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) + + bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi); + nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) + + bnx2x_hilo(&estats->brb_truncate_hi); + nstats->rx_crc_errors = + bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi); + nstats->rx_frame_errors = + bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi); + nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi); + nstats->rx_missed_errors = estats->xxoverflow_discard; + + nstats->rx_errors = nstats->rx_length_errors + + nstats->rx_over_errors + + nstats->rx_crc_errors + + nstats->rx_frame_errors + + nstats->rx_fifo_errors + + nstats->rx_missed_errors; + + nstats->tx_aborted_errors = + bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) + + bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi); + nstats->tx_carrier_errors = + bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi); + nstats->tx_fifo_errors = 0; + nstats->tx_heartbeat_errors = 0; + nstats->tx_window_errors = 0; + + nstats->tx_errors = nstats->tx_aborted_errors + + nstats->tx_carrier_errors + + bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi); +} + +static void bnx2x_drv_stats_update(struct bnx2x *bp) +{ + struct bnx2x_eth_stats *estats = &bp->eth_stats; + int i; + + estats->driver_xoff = 0; + estats->rx_err_discard_pkt = 0; + estats->rx_skb_alloc_failed = 0; + estats->hw_csum_err = 0; + for_each_queue(bp, i) { + struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats; + + estats->driver_xoff += qstats->driver_xoff; + estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt; + estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed; + estats->hw_csum_err += qstats->hw_csum_err; + } +} + +static void bnx2x_stats_update(struct bnx2x *bp) +{ + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + if (*stats_comp != DMAE_COMP_VAL) + return; + + if (bp->port.pmf) + bnx2x_hw_stats_update(bp); + + if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { + BNX2X_ERR("storm stats were not updated for 3 times\n"); + bnx2x_panic(); + return; + } + + bnx2x_net_stats_update(bp); + bnx2x_drv_stats_update(bp); + + if (netif_msg_timer(bp)) { + struct bnx2x_eth_stats *estats = &bp->eth_stats; + int i; + + printk(KERN_DEBUG "%s: brb drops %u brb truncate %u\n", + bp->dev->name, + estats->brb_drop_lo, estats->brb_truncate_lo); + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; + + printk(KERN_DEBUG "%s: rx usage(%4u) *rx_cons_sb(%u)" + " rx pkt(%lu) rx calls(%lu %lu)\n", + fp->name, (le16_to_cpu(*fp->rx_cons_sb) - + fp->rx_comp_cons), + le16_to_cpu(*fp->rx_cons_sb), + bnx2x_hilo(&qstats-> + total_unicast_packets_received_hi), + fp->rx_calls, fp->rx_pkt); + } + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; + struct netdev_queue *txq = + netdev_get_tx_queue(bp->dev, i); + + printk(KERN_DEBUG "%s: tx avail(%4u) *tx_cons_sb(%u)" + " tx pkt(%lu) tx calls (%lu)" + " %s (Xoff events %u)\n", + fp->name, bnx2x_tx_avail(fp), + le16_to_cpu(*fp->tx_cons_sb), + bnx2x_hilo(&qstats-> + total_unicast_packets_transmitted_hi), + fp->tx_pkt, + (netif_tx_queue_stopped(txq) ? "Xoff" : "Xon"), + qstats->driver_xoff); + } + } + + bnx2x_hw_stats_post(bp); + bnx2x_storm_stats_post(bp); +} + +static void bnx2x_port_stats_stop(struct bnx2x *bp) +{ + struct dmae_command *dmae; + u32 opcode; + int loader_idx = PMF_DMAE_C(bp); + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + bp->executer_idx = 0; + + opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | + DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + + if (bp->port.port_stx) { + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + if (bp->func_stx) + dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + else + dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); + dmae->dst_addr_lo = bp->port.port_stx >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct host_port_stats) >> 2; + if (bp->func_stx) { + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + } else { + dmae->comp_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_val = DMAE_COMP_VAL; + + *stats_comp = 0; + } + } + + if (bp->func_stx) { + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); + dmae->dst_addr_lo = bp->func_stx >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct host_func_stats) >> 2; + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_val = DMAE_COMP_VAL; + + *stats_comp = 0; + } +} + +static void bnx2x_stats_stop(struct bnx2x *bp) +{ + int update = 0; + + bnx2x_stats_comp(bp); + + if (bp->port.pmf) + update = (bnx2x_hw_stats_update(bp) == 0); + + update |= (bnx2x_storm_stats_update(bp) == 0); + + if (update) { + bnx2x_net_stats_update(bp); + + if (bp->port.pmf) + bnx2x_port_stats_stop(bp); + + bnx2x_hw_stats_post(bp); + bnx2x_stats_comp(bp); + } +} + +static void bnx2x_stats_do_nothing(struct bnx2x *bp) +{ +} + +static const struct { + void (*action)(struct bnx2x *bp); + enum bnx2x_stats_state next_state; +} bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = { +/* state event */ +{ +/* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED}, +/* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED}, +/* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}, +/* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED} +}, +{ +/* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED}, +/* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED}, +/* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED}, +/* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED} +} +}; + +static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) +{ + enum bnx2x_stats_state state = bp->stats_state; + + if (unlikely(bp->panic)) + return; + + bnx2x_stats_stm[state][event].action(bp); + bp->stats_state = bnx2x_stats_stm[state][event].next_state; + + /* Make sure the state has been "changed" */ + smp_wmb(); + + if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) + DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", + state, event, bp->stats_state); +} + +static void bnx2x_port_stats_base_init(struct bnx2x *bp) +{ + struct dmae_command *dmae; + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + /* sanity */ + if (!bp->port.pmf || !bp->port.port_stx) { + BNX2X_ERR("BUG!\n"); + return; + } + + bp->executer_idx = 0; + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | + DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); + dmae->dst_addr_lo = bp->port.port_stx >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct host_port_stats) >> 2; + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_val = DMAE_COMP_VAL; + + *stats_comp = 0; + bnx2x_hw_stats_post(bp); + bnx2x_stats_comp(bp); +} + +static void bnx2x_func_stats_base_init(struct bnx2x *bp) +{ + int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; + int port = BP_PORT(bp); + int func; + u32 func_stx; + + /* sanity */ + if (!bp->port.pmf || !bp->func_stx) { + BNX2X_ERR("BUG!\n"); + return; + } + + /* save our func_stx */ + func_stx = bp->func_stx; + + for (vn = VN_0; vn < vn_max; vn++) { + func = 2*vn + port; + + bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + bnx2x_func_stats_init(bp); + bnx2x_hw_stats_post(bp); + bnx2x_stats_comp(bp); + } + + /* restore our func_stx */ + bp->func_stx = func_stx; +} + +static void bnx2x_func_stats_base_update(struct bnx2x *bp) +{ + struct dmae_command *dmae = &bp->stats_dmae; + u32 *stats_comp = bnx2x_sp(bp, stats_comp); + + /* sanity */ + if (!bp->func_stx) { + BNX2X_ERR("BUG!\n"); + return; + } + + bp->executer_idx = 0; + memset(dmae, 0, sizeof(struct dmae_command)); + + dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | + DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | + DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | +#ifdef __BIG_ENDIAN + DMAE_CMD_ENDIANITY_B_DW_SWAP | +#else + DMAE_CMD_ENDIANITY_DW_SWAP | +#endif + (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | + (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->src_addr_lo = bp->func_stx >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base)); + dmae->len = sizeof(struct host_func_stats) >> 2; + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp)); + dmae->comp_val = DMAE_COMP_VAL; + + *stats_comp = 0; + bnx2x_hw_stats_post(bp); + bnx2x_stats_comp(bp); +} + +static void bnx2x_stats_init(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int func = BP_FUNC(bp); + int i; + + bp->stats_pending = 0; + bp->executer_idx = 0; + bp->stats_counter = 0; + + /* port and func stats for management */ + if (!BP_NOMCP(bp)) { + bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); + bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + + } else { + bp->port.port_stx = 0; + bp->func_stx = 0; + } + DP(BNX2X_MSG_STATS, "port_stx 0x%x func_stx 0x%x\n", + bp->port.port_stx, bp->func_stx); + + /* port stats */ + memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); + bp->port.old_nig_stats.brb_discard = + REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); + bp->port.old_nig_stats.brb_truncate = + REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38); + REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, + &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); + REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, + &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2); + + /* function stats */ + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + memset(&fp->old_tclient, 0, + sizeof(struct tstorm_per_client_stats)); + memset(&fp->old_uclient, 0, + sizeof(struct ustorm_per_client_stats)); + memset(&fp->old_xclient, 0, + sizeof(struct xstorm_per_client_stats)); + memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); + } + + memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); + memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); + + bp->stats_state = STATS_STATE_DISABLED; + + if (bp->port.pmf) { + if (bp->port.port_stx) + bnx2x_port_stats_base_init(bp); + + if (bp->func_stx) + bnx2x_func_stats_base_init(bp); + + } else if (bp->func_stx) + bnx2x_func_stats_base_update(bp); +} + +static void bnx2x_timer(unsigned long data) +{ + struct bnx2x *bp = (struct bnx2x *) data; + + if (!netif_running(bp->dev)) + return; + + if (atomic_read(&bp->intr_sem) != 0) + goto timer_restart; + + if (poll) { + struct bnx2x_fastpath *fp = &bp->fp[0]; + int rc; + + bnx2x_tx_int(fp); + rc = bnx2x_rx_int(fp, 1000); + } + + if (!BP_NOMCP(bp)) { + int func = BP_FUNC(bp); + u32 drv_pulse; + u32 mcp_pulse; + + ++bp->fw_drv_pulse_wr_seq; + bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; + /* TBD - add SYSTEM_TIME */ + drv_pulse = bp->fw_drv_pulse_wr_seq; + SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse); + + mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) & + MCP_PULSE_SEQ_MASK); + /* The delta between driver pulse and mcp response + * should be 1 (before mcp response) or 0 (after mcp response) + */ + if ((drv_pulse != mcp_pulse) && + (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) { + /* someone lost a heartbeat... */ + BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n", + drv_pulse, mcp_pulse); + } + } + + if (bp->state == BNX2X_STATE_OPEN) + bnx2x_stats_handle(bp, STATS_EVENT_UPDATE); + +timer_restart: + mod_timer(&bp->timer, jiffies + bp->current_interval); +} + +/* end of Statistics */ + +/* nic init */ + +/* + * nic init service functions + */ + +static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id) +{ + int port = BP_PORT(bp); + + /* "CSTORM" */ + bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + + CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), 0, + CSTORM_SB_STATUS_BLOCK_U_SIZE / 4); + bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + + CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), 0, + CSTORM_SB_STATUS_BLOCK_C_SIZE / 4); +} + +static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, + dma_addr_t mapping, int sb_id) +{ + int port = BP_PORT(bp); + int func = BP_FUNC(bp); + int index; + u64 section; + + /* USTORM */ + section = ((u64)mapping) + offsetof(struct host_status_block, + u_status_block); + sb->u_status_block.status_block_id = sb_id; + + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id), U64_LO(section)); + REG_WR(bp, BAR_CSTRORM_INTMEM + + ((CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id)) + 4), + U64_HI(section)); + REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_USB_FUNC_OFF + + CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), func); + + for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, index), 1); + + /* CSTORM */ + section = ((u64)mapping) + offsetof(struct host_status_block, + c_status_block); + sb->c_status_block.status_block_id = sb_id; + + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id), U64_LO(section)); + REG_WR(bp, BAR_CSTRORM_INTMEM + + ((CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id)) + 4), + U64_HI(section)); + REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF + + CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), func); + + for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, index), 1); + + bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); +} + +static void bnx2x_zero_def_sb(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + + bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY + + TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, + sizeof(struct tstorm_def_status_block)/4); + bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + + CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), 0, + sizeof(struct cstorm_def_status_block_u)/4); + bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + + CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), 0, + sizeof(struct cstorm_def_status_block_c)/4); + bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY + + XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, + sizeof(struct xstorm_def_status_block)/4); +} + +static void bnx2x_init_def_sb(struct bnx2x *bp, + struct host_def_status_block *def_sb, + dma_addr_t mapping, int sb_id) +{ + int port = BP_PORT(bp); + int func = BP_FUNC(bp); + int index, val, reg_offset; + u64 section; + + /* ATTN */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + atten_status_block); + def_sb->atten_status_block.status_block_id = sb_id; + + bp->attn_state = 0; + + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : + MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + + for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { + bp->attn_group[index].sig[0] = REG_RD(bp, + reg_offset + 0x10*index); + bp->attn_group[index].sig[1] = REG_RD(bp, + reg_offset + 0x4 + 0x10*index); + bp->attn_group[index].sig[2] = REG_RD(bp, + reg_offset + 0x8 + 0x10*index); + bp->attn_group[index].sig[3] = REG_RD(bp, + reg_offset + 0xc + 0x10*index); + } + + reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : + HC_REG_ATTN_MSG0_ADDR_L); + + REG_WR(bp, reg_offset, U64_LO(section)); + REG_WR(bp, reg_offset + 4, U64_HI(section)); + + reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0); + + val = REG_RD(bp, reg_offset); + val |= sb_id; + REG_WR(bp, reg_offset, val); + + /* USTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + u_def_status_block); + def_sb->u_def_status_block.status_block_id = sb_id; + + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func), U64_LO(section)); + REG_WR(bp, BAR_CSTRORM_INTMEM + + ((CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func)) + 4), + U64_HI(section)); + REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_USB_FUNC_OFF + + CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), func); + + for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(func, index), 1); + + /* CSTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + c_def_status_block); + def_sb->c_def_status_block.status_block_id = sb_id; + + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func), U64_LO(section)); + REG_WR(bp, BAR_CSTRORM_INTMEM + + ((CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func)) + 4), + U64_HI(section)); + REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF + + CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), func); + + for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(func, index), 1); + + /* TSTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + t_def_status_block); + def_sb->t_def_status_block.status_block_id = sb_id; + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); + REG_WR(bp, BAR_TSTRORM_INTMEM + + ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), + U64_HI(section)); + REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF + + TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); + + for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_TSTRORM_INTMEM + + TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + + /* XSTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + x_def_status_block); + def_sb->x_def_status_block.status_block_id = sb_id; + + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); + REG_WR(bp, BAR_XSTRORM_INTMEM + + ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), + U64_HI(section)); + REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF + + XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); + + for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_XSTRORM_INTMEM + + XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + + bp->stats_pending = 0; + bp->set_mac_pending = 0; + + bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); +} + +static void bnx2x_update_coalesce(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int i; + + for_each_queue(bp, i) { + int sb_id = bp->fp[i].sb_id; + + /* HC_INDEX_U_ETH_RX_CQ_CONS */ + REG_WR8(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id, + U_SB_ETH_RX_CQ_INDEX), + bp->rx_ticks/(4 * BNX2X_BTR)); + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, + U_SB_ETH_RX_CQ_INDEX), + (bp->rx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); + + /* HC_INDEX_C_ETH_TX_CQ_CONS */ + REG_WR8(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, + C_SB_ETH_TX_CQ_INDEX), + bp->tx_ticks/(4 * BNX2X_BTR)); + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, + C_SB_ETH_TX_CQ_INDEX), + (bp->tx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); + } +} + +static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, + struct bnx2x_fastpath *fp, int last) +{ + int i; + + for (i = 0; i < last; i++) { + struct sw_rx_bd *rx_buf = &(fp->tpa_pool[i]); + struct sk_buff *skb = rx_buf->skb; + + if (skb == NULL) { + DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i); + continue; + } + + if (fp->tpa_state[i] == BNX2X_TPA_START) + dma_unmap_single(&bp->pdev->dev, + dma_unmap_addr(rx_buf, mapping), + bp->rx_buf_size, DMA_FROM_DEVICE); + + dev_kfree_skb(skb); + rx_buf->skb = NULL; + } +} + +static void bnx2x_init_rx_rings(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : + ETH_MAX_AGGREGATION_QUEUES_E1H; + u16 ring_prod, cqe_ring_prod; + int i, j; + + bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; + DP(NETIF_MSG_IFUP, + "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); + + if (bp->flags & TPA_ENABLE_FLAG) { + + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + + for (i = 0; i < max_agg_queues; i++) { + fp->tpa_pool[i].skb = + netdev_alloc_skb(bp->dev, bp->rx_buf_size); + if (!fp->tpa_pool[i].skb) { + BNX2X_ERR("Failed to allocate TPA " + "skb pool for queue[%d] - " + "disabling TPA on this " + "queue!\n", j); + bnx2x_free_tpa_pool(bp, fp, i); + fp->disable_tpa = 1; + break; + } + dma_unmap_addr_set((struct sw_rx_bd *) + &bp->fp->tpa_pool[i], + mapping, 0); + fp->tpa_state[i] = BNX2X_TPA_STOP; + } + } + } + + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + + fp->rx_bd_cons = 0; + fp->rx_cons_sb = BNX2X_RX_SB_INDEX; + fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX; + + /* "next page" elements initialization */ + /* SGE ring */ + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + struct eth_rx_sge *sge; + + sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; + sge->addr_hi = + cpu_to_le32(U64_HI(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + sge->addr_lo = + cpu_to_le32(U64_LO(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + } + + bnx2x_init_sge_ring_bit_mask(fp); + + /* RX BD ring */ + for (i = 1; i <= NUM_RX_RINGS; i++) { + struct eth_rx_bd *rx_bd; + + rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; + rx_bd->addr_hi = + cpu_to_le32(U64_HI(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + rx_bd->addr_lo = + cpu_to_le32(U64_LO(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + } + + /* CQ ring */ + for (i = 1; i <= NUM_RCQ_RINGS; i++) { + struct eth_rx_cqe_next_page *nextpg; + + nextpg = (struct eth_rx_cqe_next_page *) + &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; + nextpg->addr_hi = + cpu_to_le32(U64_HI(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + nextpg->addr_lo = + cpu_to_le32(U64_LO(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + } + + /* Allocate SGEs and initialize the ring elements */ + for (i = 0, ring_prod = 0; + i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { + + if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx sges\n", i); + BNX2X_ERR("disabling TPA for queue[%d]\n", j); + /* Cleanup already allocated elements */ + bnx2x_free_rx_sge_range(bp, fp, ring_prod); + bnx2x_free_tpa_pool(bp, fp, max_agg_queues); + fp->disable_tpa = 1; + ring_prod = 0; + break; + } + ring_prod = NEXT_SGE_IDX(ring_prod); + } + fp->rx_sge_prod = ring_prod; + + /* Allocate BDs and initialize BD ring */ + fp->rx_comp_cons = 0; + cqe_ring_prod = ring_prod = 0; + for (i = 0; i < bp->rx_ring_size; i++) { + if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx skbs on queue[%d]\n", i, j); + fp->eth_q_stats.rx_skb_alloc_failed++; + break; + } + ring_prod = NEXT_RX_IDX(ring_prod); + cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); + WARN_ON(ring_prod <= i); + } + + fp->rx_bd_prod = ring_prod; + /* must not have more available CQEs than BDs */ + fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, + cqe_ring_prod); + fp->rx_pkt = fp->rx_calls = 0; + + /* Warning! + * this will generate an interrupt (to the TSTORM) + * must only be done after chip is initialized + */ + bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod, + fp->rx_sge_prod); + if (j != 0) + continue; + + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), + U64_LO(fp->rx_comp_mapping)); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, + U64_HI(fp->rx_comp_mapping)); + } +} + +static void bnx2x_init_tx_ring(struct bnx2x *bp) +{ + int i, j; + + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + + for (i = 1; i <= NUM_TX_RINGS; i++) { + struct eth_tx_next_bd *tx_next_bd = + &fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd; + + tx_next_bd->addr_hi = + cpu_to_le32(U64_HI(fp->tx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); + tx_next_bd->addr_lo = + cpu_to_le32(U64_LO(fp->tx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); + } + + fp->tx_db.data.header.header = DOORBELL_HDR_DB_TYPE; + fp->tx_db.data.zero_fill1 = 0; + fp->tx_db.data.prod = 0; + + fp->tx_pkt_prod = 0; + fp->tx_pkt_cons = 0; + fp->tx_bd_prod = 0; + fp->tx_bd_cons = 0; + fp->tx_cons_sb = BNX2X_TX_SB_INDEX; + fp->tx_pkt = 0; + } +} + +static void bnx2x_init_sp_ring(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + + spin_lock_init(&bp->spq_lock); + + bp->spq_left = MAX_SPQ_PENDING; + bp->spq_prod_idx = 0; + bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; + bp->spq_prod_bd = bp->spq; + bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT; + + REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func), + U64_LO(bp->spq_mapping)); + REG_WR(bp, + XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4, + U64_HI(bp->spq_mapping)); + + REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func), + bp->spq_prod_idx); +} + +static void bnx2x_init_context(struct bnx2x *bp) +{ + int i; + + /* Rx */ + for_each_queue(bp, i) { + struct eth_context *context = bnx2x_sp(bp, context[i].eth); + struct bnx2x_fastpath *fp = &bp->fp[i]; + u8 cl_id = fp->cl_id; + + context->ustorm_st_context.common.sb_index_numbers = + BNX2X_RX_SB_INDEX_NUM; + context->ustorm_st_context.common.clientId = cl_id; + context->ustorm_st_context.common.status_block_id = fp->sb_id; + context->ustorm_st_context.common.flags = + (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT | + USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS); + context->ustorm_st_context.common.statistics_counter_id = + cl_id; + context->ustorm_st_context.common.mc_alignment_log_size = + BNX2X_RX_ALIGN_SHIFT; + context->ustorm_st_context.common.bd_buff_size = + bp->rx_buf_size; + context->ustorm_st_context.common.bd_page_base_hi = + U64_HI(fp->rx_desc_mapping); + context->ustorm_st_context.common.bd_page_base_lo = + U64_LO(fp->rx_desc_mapping); + if (!fp->disable_tpa) { + context->ustorm_st_context.common.flags |= + USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA; + context->ustorm_st_context.common.sge_buff_size = + (u16)min_t(u32, SGE_PAGE_SIZE*PAGES_PER_SGE, + 0xffff); + context->ustorm_st_context.common.sge_page_base_hi = + U64_HI(fp->rx_sge_mapping); + context->ustorm_st_context.common.sge_page_base_lo = + U64_LO(fp->rx_sge_mapping); + + context->ustorm_st_context.common.max_sges_for_packet = + SGE_PAGE_ALIGN(bp->dev->mtu) >> SGE_PAGE_SHIFT; + context->ustorm_st_context.common.max_sges_for_packet = + ((context->ustorm_st_context.common. + max_sges_for_packet + PAGES_PER_SGE - 1) & + (~(PAGES_PER_SGE - 1))) >> PAGES_PER_SGE_SHIFT; + } + + context->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), + CDU_REGION_NUMBER_UCM_AG, + ETH_CONNECTION_TYPE); + + context->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), + CDU_REGION_NUMBER_XCM_AG, + ETH_CONNECTION_TYPE); + } + + /* Tx */ + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + struct eth_context *context = + bnx2x_sp(bp, context[i].eth); + + context->cstorm_st_context.sb_index_number = + C_SB_ETH_TX_CQ_INDEX; + context->cstorm_st_context.status_block_id = fp->sb_id; + + context->xstorm_st_context.tx_bd_page_base_hi = + U64_HI(fp->tx_desc_mapping); + context->xstorm_st_context.tx_bd_page_base_lo = + U64_LO(fp->tx_desc_mapping); + context->xstorm_st_context.statistics_data = (fp->cl_id | + XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE); + } +} + +static void bnx2x_init_ind_table(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + int i; + + if (bp->multi_mode == ETH_RSS_MODE_DISABLED) + return; + + DP(NETIF_MSG_IFUP, + "Initializing indirection table multi_mode %d\n", bp->multi_mode); + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) + REG_WR8(bp, BAR_TSTRORM_INTMEM + + TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, + bp->fp->cl_id + (i % bp->num_queues)); +} + +static void bnx2x_set_client_config(struct bnx2x *bp) +{ + struct tstorm_eth_client_config tstorm_client = {0}; + int port = BP_PORT(bp); + int i; + + tstorm_client.mtu = bp->dev->mtu; + tstorm_client.config_flags = + (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE | + TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE); +#ifdef BCM_VLAN + if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) { + tstorm_client.config_flags |= + TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE; + DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); + } +#endif + + for_each_queue(bp, i) { + tstorm_client.statistics_counter_id = bp->fp[i].cl_id; + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id), + ((u32 *)&tstorm_client)[0]); + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4, + ((u32 *)&tstorm_client)[1]); + } + + DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n", + ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); +} + +static void bnx2x_set_storm_rx_mode(struct bnx2x *bp) +{ + struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0}; + int mode = bp->rx_mode; + int mask = bp->rx_mode_cl_mask; + int func = BP_FUNC(bp); + int port = BP_PORT(bp); + int i; + /* All but management unicast packets should pass to the host as well */ + u32 llh_mask = + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; + + DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask); + + switch (mode) { + case BNX2X_RX_MODE_NONE: /* no Rx */ + tstorm_mac_filter.ucast_drop_all = mask; + tstorm_mac_filter.mcast_drop_all = mask; + tstorm_mac_filter.bcast_drop_all = mask; + break; + + case BNX2X_RX_MODE_NORMAL: + tstorm_mac_filter.bcast_accept_all = mask; + break; + + case BNX2X_RX_MODE_ALLMULTI: + tstorm_mac_filter.mcast_accept_all = mask; + tstorm_mac_filter.bcast_accept_all = mask; + break; + + case BNX2X_RX_MODE_PROMISC: + tstorm_mac_filter.ucast_accept_all = mask; + tstorm_mac_filter.mcast_accept_all = mask; + tstorm_mac_filter.bcast_accept_all = mask; + /* pass management unicast packets as well */ + llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; + break; + + default: + BNX2X_ERR("BAD rx mode (%d)\n", mode); + break; + } + + REG_WR(bp, + (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK), + llh_mask); + + for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) { + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4, + ((u32 *)&tstorm_mac_filter)[i]); + +/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, + ((u32 *)&tstorm_mac_filter)[i]); */ + } + + if (mode != BNX2X_RX_MODE_NONE) + bnx2x_set_client_config(bp); +} + +static void bnx2x_init_internal_common(struct bnx2x *bp) +{ + int i; + + /* Zero this manually as its initialization is + currently missing in the initTool */ + for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_AGG_DATA_OFFSET + i * 4, 0); +} + +static void bnx2x_init_internal_port(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + + REG_WR(bp, + BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_U_OFFSET(port), BNX2X_BTR); + REG_WR(bp, + BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_C_OFFSET(port), BNX2X_BTR); + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); +} + +static void bnx2x_init_internal_func(struct bnx2x *bp) +{ + struct tstorm_eth_function_common_config tstorm_config = {0}; + struct stats_indication_flags stats_flags = {0}; + int port = BP_PORT(bp); + int func = BP_FUNC(bp); + int i, j; + u32 offset; + u16 max_agg_size; + + tstorm_config.config_flags = RSS_FLAGS(bp); + + if (is_multi(bp)) + tstorm_config.rss_result_mask = MULTI_MASK; + + /* Enable TPA if needed */ + if (bp->flags & TPA_ENABLE_FLAG) + tstorm_config.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; + + if (IS_E1HMF(bp)) + tstorm_config.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM; + + tstorm_config.leading_client_id = BP_L_ID(bp); + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func), + (*(u32 *)&tstorm_config)); + + bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ + bp->rx_mode_cl_mask = (1 << BP_L_ID(bp)); + bnx2x_set_storm_rx_mode(bp); + + for_each_queue(bp, i) { + u8 cl_id = bp->fp[i].cl_id; + + /* reset xstorm per client statistics */ + offset = BAR_XSTRORM_INTMEM + + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); + for (j = 0; + j < sizeof(struct xstorm_per_client_stats) / 4; j++) + REG_WR(bp, offset + j*4, 0); + + /* reset tstorm per client statistics */ + offset = BAR_TSTRORM_INTMEM + + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); + for (j = 0; + j < sizeof(struct tstorm_per_client_stats) / 4; j++) + REG_WR(bp, offset + j*4, 0); + + /* reset ustorm per client statistics */ + offset = BAR_USTRORM_INTMEM + + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); + for (j = 0; + j < sizeof(struct ustorm_per_client_stats) / 4; j++) + REG_WR(bp, offset + j*4, 0); + } + + /* Init statistics related context */ + stats_flags.collect_eth = 1; + + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), + ((u32 *)&stats_flags)[0]); + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4, + ((u32 *)&stats_flags)[1]); + + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), + ((u32 *)&stats_flags)[0]); + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4, + ((u32 *)&stats_flags)[1]); + + REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func), + ((u32 *)&stats_flags)[0]); + REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4, + ((u32 *)&stats_flags)[1]); + + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), + ((u32 *)&stats_flags)[0]); + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4, + ((u32 *)&stats_flags)[1]); + + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), + U64_LO(bnx2x_sp_mapping(bp, fw_stats))); + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, + U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), + U64_LO(bnx2x_sp_mapping(bp, fw_stats))); + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, + U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), + U64_LO(bnx2x_sp_mapping(bp, fw_stats))); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, + U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + + if (CHIP_IS_E1H(bp)) { + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, + IS_E1HMF(bp)); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, + IS_E1HMF(bp)); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, + IS_E1HMF(bp)); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, + IS_E1HMF(bp)); + + REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func), + bp->e1hov); + } + + /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */ + max_agg_size = min_t(u32, (min_t(u32, 8, MAX_SKB_FRAGS) * + SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id), + U64_LO(fp->rx_comp_mapping)); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4, + U64_HI(fp->rx_comp_mapping)); + + /* Next page */ + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id), + U64_LO(fp->rx_comp_mapping + BCM_PAGE_SIZE)); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id) + 4, + U64_HI(fp->rx_comp_mapping + BCM_PAGE_SIZE)); + + REG_WR16(bp, BAR_USTRORM_INTMEM + + USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id), + max_agg_size); + } + + /* dropless flow control */ + if (CHIP_IS_E1H(bp)) { + struct ustorm_eth_rx_pause_data_e1h rx_pause = {0}; + + rx_pause.bd_thr_low = 250; + rx_pause.cqe_thr_low = 250; + rx_pause.cos = 1; + rx_pause.sge_thr_low = 0; + rx_pause.bd_thr_high = 350; + rx_pause.cqe_thr_high = 350; + rx_pause.sge_thr_high = 0; + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + if (!fp->disable_tpa) { + rx_pause.sge_thr_low = 150; + rx_pause.sge_thr_high = 250; + } + + + offset = BAR_USTRORM_INTMEM + + USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, + fp->cl_id); + for (j = 0; + j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4; + j++) + REG_WR(bp, offset + j*4, + ((u32 *)&rx_pause)[j]); + } + } + + memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); + + /* Init rate shaping and fairness contexts */ + if (IS_E1HMF(bp)) { + int vn; + + /* During init there is no active link + Until link is up, set link rate to 10Gbps */ + bp->link_vars.line_speed = SPEED_10000; + bnx2x_init_port_minmax(bp); + + if (!BP_NOMCP(bp)) + bp->mf_config = + SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + bnx2x_calc_vn_weight_sum(bp); + + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, 2*vn + port); + + /* Enable rate shaping and fairness */ + bp->cmng.flags.cmng_enables |= + CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; + + } else { + /* rate shaping and fairness are disabled */ + DP(NETIF_MSG_IFUP, + "single function mode minmax will be disabled\n"); + } + + + /* Store cmng structures to internal memory */ + if (bp->port.pmf) + for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4, + ((u32 *)(&bp->cmng))[i]); +} + +static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) +{ + switch (load_code) { + case FW_MSG_CODE_DRV_LOAD_COMMON: + bnx2x_init_internal_common(bp); + /* no break */ + + case FW_MSG_CODE_DRV_LOAD_PORT: + bnx2x_init_internal_port(bp); + /* no break */ + + case FW_MSG_CODE_DRV_LOAD_FUNCTION: + bnx2x_init_internal_func(bp); + break; + + default: + BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code); + break; + } +} + +static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) +{ + int i; + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + fp->bp = bp; + fp->state = BNX2X_FP_STATE_CLOSED; + fp->index = i; + fp->cl_id = BP_L_ID(bp) + i; +#ifdef BCM_CNIC + fp->sb_id = fp->cl_id + 1; +#else + fp->sb_id = fp->cl_id; +#endif + DP(NETIF_MSG_IFUP, + "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n", + i, bp, fp->status_blk, fp->cl_id, fp->sb_id); + bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, + fp->sb_id); + bnx2x_update_fpsb_idx(fp); + } + + /* ensure status block indices were read */ + rmb(); + + + bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping, + DEF_SB_ID); + bnx2x_update_dsb_idx(bp); + bnx2x_update_coalesce(bp); + bnx2x_init_rx_rings(bp); + bnx2x_init_tx_ring(bp); + bnx2x_init_sp_ring(bp); + bnx2x_init_context(bp); + bnx2x_init_internal(bp, load_code); + bnx2x_init_ind_table(bp); + bnx2x_stats_init(bp); + + /* At this point, we are ready for interrupts */ + atomic_set(&bp->intr_sem, 0); + + /* flush all before enabling interrupts */ + mb(); + mmiowb(); + + bnx2x_int_enable(bp); + + /* Check for SPIO5 */ + bnx2x_attn_int_deasserted0(bp, + REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + BP_PORT(bp)*4) & + AEU_INPUTS_ATTN_BITS_SPIO5); +} + +/* end of nic init */ + +/* + * gzip service functions + */ + +static int bnx2x_gunzip_init(struct bnx2x *bp) +{ + bp->gunzip_buf = dma_alloc_coherent(&bp->pdev->dev, FW_BUF_SIZE, + &bp->gunzip_mapping, GFP_KERNEL); + if (bp->gunzip_buf == NULL) + goto gunzip_nomem1; + + bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL); + if (bp->strm == NULL) + goto gunzip_nomem2; + + bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(), + GFP_KERNEL); + if (bp->strm->workspace == NULL) + goto gunzip_nomem3; + + return 0; + +gunzip_nomem3: + kfree(bp->strm); + bp->strm = NULL; + +gunzip_nomem2: + dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf, + bp->gunzip_mapping); + bp->gunzip_buf = NULL; + +gunzip_nomem1: + netdev_err(bp->dev, "Cannot allocate firmware buffer for" + " un-compression\n"); + return -ENOMEM; +} + +static void bnx2x_gunzip_end(struct bnx2x *bp) +{ + kfree(bp->strm->workspace); + + kfree(bp->strm); + bp->strm = NULL; + + if (bp->gunzip_buf) { + dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf, + bp->gunzip_mapping); + bp->gunzip_buf = NULL; + } +} + +static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len) +{ + int n, rc; + + /* check gzip header */ + if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) { + BNX2X_ERR("Bad gzip header\n"); + return -EINVAL; + } + + n = 10; + +#define FNAME 0x8 + + if (zbuf[3] & FNAME) + while ((zbuf[n++] != 0) && (n < len)); + + bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n; + bp->strm->avail_in = len - n; + bp->strm->next_out = bp->gunzip_buf; + bp->strm->avail_out = FW_BUF_SIZE; + + rc = zlib_inflateInit2(bp->strm, -MAX_WBITS); + if (rc != Z_OK) + return rc; + + rc = zlib_inflate(bp->strm, Z_FINISH); + if ((rc != Z_OK) && (rc != Z_STREAM_END)) + netdev_err(bp->dev, "Firmware decompression error: %s\n", + bp->strm->msg); + + bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out); + if (bp->gunzip_outlen & 0x3) + netdev_err(bp->dev, "Firmware decompression error:" + " gunzip_outlen (%d) not aligned\n", + bp->gunzip_outlen); + bp->gunzip_outlen >>= 2; + + zlib_inflateEnd(bp->strm); + + if (rc == Z_STREAM_END) + return 0; + + return rc; +} + +/* nic load/unload */ + +/* + * General service functions + */ + +/* send a NIG loopback debug packet */ +static void bnx2x_lb_pckt(struct bnx2x *bp) +{ + u32 wb_write[3]; + + /* Ethernet source and destination addresses */ + wb_write[0] = 0x55555555; + wb_write[1] = 0x55555555; + wb_write[2] = 0x20; /* SOP */ + REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3); + + /* NON-IP protocol */ + wb_write[0] = 0x09000000; + wb_write[1] = 0x55555555; + wb_write[2] = 0x10; /* EOP, eop_bvalid = 0 */ + REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3); +} + +/* some of the internal memories + * are not directly readable from the driver + * to test them we send debug packets + */ +static int bnx2x_int_mem_test(struct bnx2x *bp) +{ + int factor; + int count, i; + u32 val = 0; + + if (CHIP_REV_IS_FPGA(bp)) + factor = 120; + else if (CHIP_REV_IS_EMUL(bp)) + factor = 200; + else + factor = 1; + + DP(NETIF_MSG_HW, "start part1\n"); + + /* Disable inputs of parser neighbor blocks */ + REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); + REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); + REG_WR(bp, CFC_REG_DEBUG0, 0x1); + REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0); + + /* Write 0 to parser credits for CFC search request */ + REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); + + /* send Ethernet packet */ + bnx2x_lb_pckt(bp); + + /* TODO do i reset NIG statistic? */ + /* Wait until NIG register shows 1 packet of size 0x10 */ + count = 1000 * factor; + while (count) { + + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); + if (val == 0x10) + break; + + msleep(10); + count--; + } + if (val != 0x10) { + BNX2X_ERR("NIG timeout val = 0x%x\n", val); + return -1; + } + + /* Wait until PRS register shows 1 packet */ + count = 1000 * factor; + while (count) { + val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); + if (val == 1) + break; + + msleep(10); + count--; + } + if (val != 0x1) { + BNX2X_ERR("PRS timeout val = 0x%x\n", val); + return -2; + } + + /* Reset and init BRB, PRS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03); + msleep(50); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); + msleep(50); + bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); + + DP(NETIF_MSG_HW, "part2\n"); + + /* Disable inputs of parser neighbor blocks */ + REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); + REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); + REG_WR(bp, CFC_REG_DEBUG0, 0x1); + REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0); + + /* Write 0 to parser credits for CFC search request */ + REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); + + /* send 10 Ethernet packets */ + for (i = 0; i < 10; i++) + bnx2x_lb_pckt(bp); + + /* Wait until NIG register shows 10 + 1 + packets of size 11*0x10 = 0xb0 */ + count = 1000 * factor; + while (count) { + + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); + if (val == 0xb0) + break; + + msleep(10); + count--; + } + if (val != 0xb0) { + BNX2X_ERR("NIG timeout val = 0x%x\n", val); + return -3; + } + + /* Wait until PRS register shows 2 packets */ + val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); + if (val != 2) + BNX2X_ERR("PRS timeout val = 0x%x\n", val); + + /* Write 1 to parser credits for CFC search request */ + REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x1); + + /* Wait until PRS register shows 3 packets */ + msleep(10 * factor); + /* Wait until NIG register shows 1 packet of size 0x10 */ + val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); + if (val != 3) + BNX2X_ERR("PRS timeout val = 0x%x\n", val); + + /* clear NIG EOP FIFO */ + for (i = 0; i < 11; i++) + REG_RD(bp, NIG_REG_INGRESS_EOP_LB_FIFO); + val = REG_RD(bp, NIG_REG_INGRESS_EOP_LB_EMPTY); + if (val != 1) { + BNX2X_ERR("clear of NIG failed\n"); + return -4; + } + + /* Reset and init BRB, PRS, NIG */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03); + msleep(50); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); + msleep(50); + bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); +#ifndef BCM_CNIC + /* set NIC mode */ + REG_WR(bp, PRS_REG_NIC_MODE, 1); +#endif + + /* Enable inputs of parser neighbor blocks */ + REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff); + REG_WR(bp, TCM_REG_PRS_IFEN, 0x1); + REG_WR(bp, CFC_REG_DEBUG0, 0x0); + REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x1); + + DP(NETIF_MSG_HW, "done\n"); + + return 0; /* OK */ +} + +static void enable_blocks_attention(struct bnx2x *bp) +{ + REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); + REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); + REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); + REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); + REG_WR(bp, QM_REG_QM_INT_MASK, 0); + REG_WR(bp, TM_REG_TM_INT_MASK, 0); + REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0); + REG_WR(bp, XSDM_REG_XSDM_INT_MASK_1, 0); + REG_WR(bp, XCM_REG_XCM_INT_MASK, 0); +/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_0, 0); */ +/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_1, 0); */ + REG_WR(bp, USDM_REG_USDM_INT_MASK_0, 0); + REG_WR(bp, USDM_REG_USDM_INT_MASK_1, 0); + REG_WR(bp, UCM_REG_UCM_INT_MASK, 0); +/* REG_WR(bp, USEM_REG_USEM_INT_MASK_0, 0); */ +/* REG_WR(bp, USEM_REG_USEM_INT_MASK_1, 0); */ + REG_WR(bp, GRCBASE_UPB + PB_REG_PB_INT_MASK, 0); + REG_WR(bp, CSDM_REG_CSDM_INT_MASK_0, 0); + REG_WR(bp, CSDM_REG_CSDM_INT_MASK_1, 0); + REG_WR(bp, CCM_REG_CCM_INT_MASK, 0); +/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */ +/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */ + if (CHIP_REV_IS_FPGA(bp)) + REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); + else + REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000); + REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0); + REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0); + REG_WR(bp, TCM_REG_TCM_INT_MASK, 0); +/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */ +/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */ + REG_WR(bp, CDU_REG_CDU_INT_MASK, 0); + REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0); +/* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */ + REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18); /* bit 3,4 masked */ +} + +static const struct { + u32 addr; + u32 mask; +} bnx2x_parity_mask[] = { + {PXP_REG_PXP_PRTY_MASK, 0xffffffff}, + {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, + {PXP2_REG_PXP2_PRTY_MASK_1, 0xffffffff}, + {HC_REG_HC_PRTY_MASK, 0xffffffff}, + {MISC_REG_MISC_PRTY_MASK, 0xffffffff}, + {QM_REG_QM_PRTY_MASK, 0x0}, + {DORQ_REG_DORQ_PRTY_MASK, 0x0}, + {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, + {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 0x0}, + {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ + {CDU_REG_CDU_PRTY_MASK, 0x0}, + {CFC_REG_CFC_PRTY_MASK, 0x0}, + {DBG_REG_DBG_PRTY_MASK, 0x0}, + {DMAE_REG_DMAE_PRTY_MASK, 0x0}, + {BRB1_REG_BRB1_PRTY_MASK, 0x0}, + {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ + {TSDM_REG_TSDM_PRTY_MASK, 0x18},/* bit 3,4 */ + {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {USDM_REG_USDM_PRTY_MASK, 0x38},/* bit 3,4,5 */ + {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, + {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, + {USEM_REG_USEM_PRTY_MASK_0, 0x0}, + {USEM_REG_USEM_PRTY_MASK_1, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} +}; + +static void enable_blocks_parity(struct bnx2x *bp) +{ + int i, mask_arr_len = + sizeof(bnx2x_parity_mask)/(sizeof(bnx2x_parity_mask[0])); + + for (i = 0; i < mask_arr_len; i++) + REG_WR(bp, bnx2x_parity_mask[i].addr, + bnx2x_parity_mask[i].mask); +} + + +static void bnx2x_reset_common(struct bnx2x *bp) +{ + /* reset_common */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + 0xd3ffff7f); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403); +} + +static void bnx2x_init_pxp(struct bnx2x *bp) +{ + u16 devctl; + int r_order, w_order; + + pci_read_config_word(bp->pdev, + bp->pcie_cap + PCI_EXP_DEVCTL, &devctl); + DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl); + w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); + if (bp->mrrs == -1) + r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12); + else { + DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs); + r_order = bp->mrrs; + } + + bnx2x_init_pxp_arb(bp, r_order, w_order); +} + +static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) +{ + int is_required; + u32 val; + int port; + + if (BP_NOMCP(bp)) + return; + + is_required = 0; + val = SHMEM_RD(bp, dev_info.shared_hw_config.config2) & + SHARED_HW_CFG_FAN_FAILURE_MASK; + + if (val == SHARED_HW_CFG_FAN_FAILURE_ENABLED) + is_required = 1; + + /* + * The fan failure mechanism is usually related to the PHY type since + * the power consumption of the board is affected by the PHY. Currently, + * fan is required for most designs with SFX7101, BCM8727 and BCM8481. + */ + else if (val == SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE) + for (port = PORT_0; port < PORT_MAX; port++) { + u32 phy_type = + SHMEM_RD(bp, dev_info.port_hw_config[port]. + external_phy_config) & + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; + is_required |= + ((phy_type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) || + (phy_type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) || + (phy_type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)); + } + + DP(NETIF_MSG_HW, "fan detection setting: %d\n", is_required); + + if (is_required == 0) + return; + + /* Fan failure is indicated by SPIO 5 */ + bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5, + MISC_REGISTERS_SPIO_INPUT_HI_Z); + + /* set to active low mode */ + val = REG_RD(bp, MISC_REG_SPIO_INT); + val |= ((1 << MISC_REGISTERS_SPIO_5) << + MISC_REGISTERS_SPIO_INT_OLD_SET_POS); + REG_WR(bp, MISC_REG_SPIO_INT, val); + + /* enable interrupt to signal the IGU */ + val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN); + val |= (1 << MISC_REGISTERS_SPIO_5); + REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); +} + +static int bnx2x_init_common(struct bnx2x *bp) +{ + u32 val, i; +#ifdef BCM_CNIC + u32 wb_write[2]; +#endif + + DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp)); + + bnx2x_reset_common(bp); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); + + bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); + if (CHIP_IS_E1H(bp)) + REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp)); + + REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); + msleep(30); + REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); + + bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE); + if (CHIP_IS_E1(bp)) { + /* enable HW interrupt from PXP on USDM overflow + bit 16 on INT_MASK_0 */ + REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); + } + + bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE); + bnx2x_init_pxp(bp); + +#ifdef __BIG_ENDIAN + REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1); + /* make sure this value is 0 */ + REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0); + +/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */ + REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1); + REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1); + REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1); + REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); +#endif + + REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2); +#ifdef BCM_CNIC + REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5); + REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5); + REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5); +#endif + + if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) + REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1); + + /* let the HW do it's magic ... */ + msleep(100); + /* finish PXP init */ + val = REG_RD(bp, PXP2_REG_RQ_CFG_DONE); + if (val != 1) { + BNX2X_ERR("PXP2 CFG failed\n"); + return -EBUSY; + } + val = REG_RD(bp, PXP2_REG_RD_INIT_DONE); + if (val != 1) { + BNX2X_ERR("PXP2 RD_INIT failed\n"); + return -EBUSY; + } + + REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); + REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); + + bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE); + + /* clean the DMAE memory */ + bp->dmae_ready = 1; + bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8); + + bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE); + + bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3); + bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3); + bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3); + bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3); + + bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); + +#ifdef BCM_CNIC + wb_write[0] = 0; + wb_write[1] = 0; + for (i = 0; i < 64; i++) { + REG_WR(bp, QM_REG_BASEADDR + i*4, 1024 * 4 * (i%16)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, wb_write, 2); + + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, 1024*4*(i%16)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, + wb_write, 2); + } + } +#endif + /* soft reset pulse */ + REG_WR(bp, QM_REG_SOFT_RESET, 1); + REG_WR(bp, QM_REG_SOFT_RESET, 0); + +#ifdef BCM_CNIC + bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE); +#endif + + bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE); + REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT); + if (!CHIP_REV_IS_SLOW(bp)) { + /* enable hw interrupt from doorbell Q */ + REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); + } + + bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); + REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); +#ifndef BCM_CNIC + /* set NIC mode */ + REG_WR(bp, PRS_REG_NIC_MODE, 1); +#endif + if (CHIP_IS_E1H(bp)) + REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); + + bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE); + + bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); + bnx2x_init_fill(bp, USEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); + bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); + bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); + + bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE); + + /* sync semi rtc */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + 0x80000000); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + 0x80000000); + + bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); + + REG_WR(bp, SRC_REG_SOFT_RST, 1); + for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) + REG_WR(bp, i, random32()); + bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE); +#ifdef BCM_CNIC + REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); + REG_WR(bp, SRC_REG_KEYSEARCH_1, 0x24b8f2cc); + REG_WR(bp, SRC_REG_KEYSEARCH_2, 0x223aef9b); + REG_WR(bp, SRC_REG_KEYSEARCH_3, 0x26001e3a); + REG_WR(bp, SRC_REG_KEYSEARCH_4, 0x7ae91116); + REG_WR(bp, SRC_REG_KEYSEARCH_5, 0x5ce5230b); + REG_WR(bp, SRC_REG_KEYSEARCH_6, 0x298d8adf); + REG_WR(bp, SRC_REG_KEYSEARCH_7, 0x6eb0ff09); + REG_WR(bp, SRC_REG_KEYSEARCH_8, 0x1830f82f); + REG_WR(bp, SRC_REG_KEYSEARCH_9, 0x01e46be7); +#endif + REG_WR(bp, SRC_REG_SOFT_RST, 0); + + if (sizeof(union cdu_context) != 1024) + /* we currently assume that a context is 1024 bytes */ + dev_alert(&bp->pdev->dev, "please adjust the size " + "of cdu_context(%ld)\n", + (long)sizeof(union cdu_context)); + + bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE); + val = (4 << 24) + (0 << 12) + 1024; + REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val); + + bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE); + REG_WR(bp, CFC_REG_INIT_REG, 0x7FF); + /* enable context validation interrupt from CFC */ + REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); + + /* set the thresholds to prevent CFC/CDU race */ + REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); + + bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE); + + bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE); + /* Reset PCIE errors for debug */ + REG_WR(bp, 0x2814, 0xffffffff); + REG_WR(bp, 0x3820, 0xffffffff); + + bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE); + + bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp)); + REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp)); + } + + if (CHIP_REV_IS_SLOW(bp)) + msleep(200); + + /* finish CFC init */ + val = reg_poll(bp, CFC_REG_LL_INIT_DONE, 1, 100, 10); + if (val != 1) { + BNX2X_ERR("CFC LL_INIT failed\n"); + return -EBUSY; + } + val = reg_poll(bp, CFC_REG_AC_INIT_DONE, 1, 100, 10); + if (val != 1) { + BNX2X_ERR("CFC AC_INIT failed\n"); + return -EBUSY; + } + val = reg_poll(bp, CFC_REG_CAM_INIT_DONE, 1, 100, 10); + if (val != 1) { + BNX2X_ERR("CFC CAM_INIT failed\n"); + return -EBUSY; + } + REG_WR(bp, CFC_REG_DEBUG0, 0); + + /* read NIG statistic + to see if this is our first up since powerup */ + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); + + /* do internal memory self test */ + if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) { + BNX2X_ERR("internal mem self test failed\n"); + return -EBUSY; + } + + switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + bp->port.need_hw_lock = 1; + break; + + default: + break; + } + + bnx2x_setup_fan_failure_detection(bp); + + /* clear PXP2 attentions */ + REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0); + + enable_blocks_attention(bp); + if (CHIP_PARITY_SUPPORTED(bp)) + enable_blocks_parity(bp); + + if (!BP_NOMCP(bp)) { + bnx2x_acquire_phy_lock(bp); + bnx2x_common_init_phy(bp, bp->common.shmem_base); + bnx2x_release_phy_lock(bp); + } else + BNX2X_ERR("Bootcode is missing - can not initialize link\n"); + + return 0; +} + +static int bnx2x_init_port(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int init_stage = port ? PORT1_STAGE : PORT0_STAGE; + u32 low, high; + u32 val; + + DP(BNX2X_MSG_MCP, "starting port init port %d\n", port); + + REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); + + bnx2x_init_block(bp, PXP_BLOCK, init_stage); + bnx2x_init_block(bp, PXP2_BLOCK, init_stage); + + bnx2x_init_block(bp, TCM_BLOCK, init_stage); + bnx2x_init_block(bp, UCM_BLOCK, init_stage); + bnx2x_init_block(bp, CCM_BLOCK, init_stage); + bnx2x_init_block(bp, XCM_BLOCK, init_stage); + +#ifdef BCM_CNIC + REG_WR(bp, QM_REG_CONNNUM_0 + port*4, 1024/16 - 1); + + bnx2x_init_block(bp, TIMERS_BLOCK, init_stage); + REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); + REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); +#endif + + bnx2x_init_block(bp, DQ_BLOCK, init_stage); + + bnx2x_init_block(bp, BRB1_BLOCK, init_stage); + if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { + /* no pause for emulation and FPGA */ + low = 0; + high = 513; + } else { + if (IS_E1HMF(bp)) + low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); + else if (bp->dev->mtu > 4096) { + if (bp->flags & ONE_PORT_FLAG) + low = 160; + else { + val = bp->dev->mtu; + /* (24*1024 + val*4)/256 */ + low = 96 + (val/64) + ((val % 64) ? 1 : 0); + } + } else + low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); + high = low + 56; /* 14*1024/256 */ + } + REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); + REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); + + + bnx2x_init_block(bp, PRS_BLOCK, init_stage); + + bnx2x_init_block(bp, TSDM_BLOCK, init_stage); + bnx2x_init_block(bp, CSDM_BLOCK, init_stage); + bnx2x_init_block(bp, USDM_BLOCK, init_stage); + bnx2x_init_block(bp, XSDM_BLOCK, init_stage); + + bnx2x_init_block(bp, TSEM_BLOCK, init_stage); + bnx2x_init_block(bp, USEM_BLOCK, init_stage); + bnx2x_init_block(bp, CSEM_BLOCK, init_stage); + bnx2x_init_block(bp, XSEM_BLOCK, init_stage); + + bnx2x_init_block(bp, UPB_BLOCK, init_stage); + bnx2x_init_block(bp, XPB_BLOCK, init_stage); + + bnx2x_init_block(bp, PBF_BLOCK, init_stage); + + /* configure PBF to work without PAUSE mtu 9000 */ + REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); + + /* update threshold */ + REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); + /* update init credit */ + REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); + + /* probe changes */ + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); + msleep(5); + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + +#ifdef BCM_CNIC + bnx2x_init_block(bp, SRCH_BLOCK, init_stage); +#endif + bnx2x_init_block(bp, CDU_BLOCK, init_stage); + bnx2x_init_block(bp, CFC_BLOCK, init_stage); + + if (CHIP_IS_E1(bp)) { + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } + bnx2x_init_block(bp, HC_BLOCK, init_stage); + + bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage); + /* init aeu_mask_attn_func_0/1: + * - SF mode: bits 3-7 are masked. only bits 0-2 are in use + * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF + * bits 4-7 are used for "per vn group attention" */ + REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, + (IS_E1HMF(bp) ? 0xF7 : 0x7)); + + bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); + bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); + bnx2x_init_block(bp, EMAC1_BLOCK, init_stage); + bnx2x_init_block(bp, DBU_BLOCK, init_stage); + bnx2x_init_block(bp, DBG_BLOCK, init_stage); + + bnx2x_init_block(bp, NIG_BLOCK, init_stage); + + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); + + if (CHIP_IS_E1H(bp)) { + /* 0x2 disable e1hov, 0x1 enable */ + REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, + (IS_E1HMF(bp) ? 0x1 : 0x2)); + + { + REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); + REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0); + REG_WR(bp, NIG_REG_PAUSE_ENABLE_0 + port*4, 1); + } + } + + bnx2x_init_block(bp, MCP_BLOCK, init_stage); + bnx2x_init_block(bp, DMAE_BLOCK, init_stage); + + switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + { + u32 swap_val, swap_override, aeu_gpio_mask, offset; + + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_INPUT_HI_Z, port); + + /* The GPIO should be swapped if the swap register is + set and active */ + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + + /* Select function upon port-swap configuration */ + if (port == 0) { + offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; + } else { + offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; + } + val = REG_RD(bp, offset); + /* add GPIO3 to group */ + val |= aeu_gpio_mask; + REG_WR(bp, offset, val); + } + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + /* add SPIO 5 to group 0 */ + { + u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : + MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + val = REG_RD(bp, reg_addr); + val |= AEU_INPUTS_ATTN_BITS_SPIO5; + REG_WR(bp, reg_addr, val); + } + break; + + default: + break; + } + + bnx2x__link_reset(bp); + + return 0; +} + +#define ILT_PER_FUNC (768/2) +#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) +/* the phys address is shifted right 12 bits and has an added + 1=valid bit added to the 53rd bit + then since this is a wide register(TM) + we split it into two 32 bit writes + */ +#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) +#define PXP_ONE_ILT(x) (((x) << 10) | x) +#define PXP_ILT_RANGE(f, l) (((l) << 10) | f) + +#ifdef BCM_CNIC +#define CNIC_ILT_LINES 127 +#define CNIC_CTX_PER_ILT 16 +#else +#define CNIC_ILT_LINES 0 +#endif + +static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) +{ + int reg; + + if (CHIP_IS_E1H(bp)) + reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; + else /* E1 */ + reg = PXP2_REG_RQ_ONCHIP_AT + index*8; + + bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr)); +} + +static int bnx2x_init_func(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int func = BP_FUNC(bp); + u32 addr, val; + int i; + + DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); + + /* set MSI reconfigure capability */ + addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); + val = REG_RD(bp, addr); + val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; + REG_WR(bp, addr, val); + + i = FUNC_ILT_BASE(func); + + bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context)); + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i); + REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES); + } else /* E1 */ + REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, + PXP_ILT_RANGE(i, i + CNIC_ILT_LINES)); + +#ifdef BCM_CNIC + i += 1 + CNIC_ILT_LINES; + bnx2x_ilt_wr(bp, i, bp->timers_mapping); + if (CHIP_IS_E1(bp)) + REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i)); + else { + REG_WR(bp, PXP2_REG_RQ_TM_FIRST_ILT, i); + REG_WR(bp, PXP2_REG_RQ_TM_LAST_ILT, i); + } + + i++; + bnx2x_ilt_wr(bp, i, bp->qm_mapping); + if (CHIP_IS_E1(bp)) + REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i)); + else { + REG_WR(bp, PXP2_REG_RQ_QM_FIRST_ILT, i); + REG_WR(bp, PXP2_REG_RQ_QM_LAST_ILT, i); + } + + i++; + bnx2x_ilt_wr(bp, i, bp->t1_mapping); + if (CHIP_IS_E1(bp)) + REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); + else { + REG_WR(bp, PXP2_REG_RQ_SRC_FIRST_ILT, i); + REG_WR(bp, PXP2_REG_RQ_SRC_LAST_ILT, i); + } + + /* tell the searcher where the T2 table is */ + REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, 16*1024/64); + + bnx2x_wb_wr(bp, SRC_REG_FIRSTFREE0 + port*16, + U64_LO(bp->t2_mapping), U64_HI(bp->t2_mapping)); + + bnx2x_wb_wr(bp, SRC_REG_LASTFREE0 + port*16, + U64_LO((u64)bp->t2_mapping + 16*1024 - 64), + U64_HI((u64)bp->t2_mapping + 16*1024 - 64)); + + REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, 10); +#endif + + if (CHIP_IS_E1H(bp)) { + bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); + REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); + } + + /* HC init per function */ + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); + + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } + bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); + + /* Reset PCIE errors for debug */ + REG_WR(bp, 0x2114, 0xffffffff); + REG_WR(bp, 0x2120, 0xffffffff); + + return 0; +} + +static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) +{ + int i, rc = 0; + + DP(BNX2X_MSG_MCP, "function %d load_code %x\n", + BP_FUNC(bp), load_code); + + bp->dmae_ready = 0; + mutex_init(&bp->dmae_mutex); + rc = bnx2x_gunzip_init(bp); + if (rc) + return rc; + + switch (load_code) { + case FW_MSG_CODE_DRV_LOAD_COMMON: + rc = bnx2x_init_common(bp); + if (rc) + goto init_hw_err; + /* no break */ + + case FW_MSG_CODE_DRV_LOAD_PORT: + bp->dmae_ready = 1; + rc = bnx2x_init_port(bp); + if (rc) + goto init_hw_err; + /* no break */ + + case FW_MSG_CODE_DRV_LOAD_FUNCTION: + bp->dmae_ready = 1; + rc = bnx2x_init_func(bp); + if (rc) + goto init_hw_err; + break; + + default: + BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code); + break; + } + + if (!BP_NOMCP(bp)) { + int func = BP_FUNC(bp); + + bp->fw_drv_pulse_wr_seq = + (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) & + DRV_PULSE_SEQ_MASK); + DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); + } + + /* this needs to be done before gunzip end */ + bnx2x_zero_def_sb(bp); + for_each_queue(bp, i) + bnx2x_zero_sb(bp, BP_L_ID(bp) + i); +#ifdef BCM_CNIC + bnx2x_zero_sb(bp, BP_L_ID(bp) + i); +#endif + +init_hw_err: + bnx2x_gunzip_end(bp); + + return rc; +} + +static void bnx2x_free_mem(struct bnx2x *bp) +{ + +#define BNX2X_PCI_FREE(x, y, size) \ + do { \ + if (x) { \ + dma_free_coherent(&bp->pdev->dev, size, x, y); \ + x = NULL; \ + y = 0; \ + } \ + } while (0) + +#define BNX2X_FREE(x) \ + do { \ + if (x) { \ + vfree(x); \ + x = NULL; \ + } \ + } while (0) + + int i; + + /* fastpath */ + /* Common */ + for_each_queue(bp, i) { + + /* status blocks */ + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk), + bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_status_block)); + } + /* Rx */ + for_each_queue(bp, i) { + + /* fastpath rx rings: rx_buf rx_desc rx_comp */ + BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring)); + BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring), + bnx2x_fp(bp, i, rx_desc_mapping), + sizeof(struct eth_rx_bd) * NUM_RX_BD); + + BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring), + bnx2x_fp(bp, i, rx_comp_mapping), + sizeof(struct eth_fast_path_rx_cqe) * + NUM_RCQ_BD); + + /* SGE ring */ + BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring)); + BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring), + bnx2x_fp(bp, i, rx_sge_mapping), + BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); + } + /* Tx */ + for_each_queue(bp, i) { + + /* fastpath tx rings: tx_buf tx_desc */ + BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring)); + BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring), + bnx2x_fp(bp, i, tx_desc_mapping), + sizeof(union eth_tx_bd_types) * NUM_TX_BD); + } + /* end of fastpath */ + + BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, + sizeof(struct host_def_status_block)); + + BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, + sizeof(struct bnx2x_slowpath)); + +#ifdef BCM_CNIC + BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024); + BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024); + BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024); + BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024); + BNX2X_PCI_FREE(bp->cnic_sb, bp->cnic_sb_mapping, + sizeof(struct host_status_block)); +#endif + BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); + +#undef BNX2X_PCI_FREE +#undef BNX2X_KFREE +} + +static int bnx2x_alloc_mem(struct bnx2x *bp) +{ + +#define BNX2X_PCI_ALLOC(x, y, size) \ + do { \ + x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ + if (x == NULL) \ + goto alloc_mem_err; \ + memset(x, 0, size); \ + } while (0) + +#define BNX2X_ALLOC(x, size) \ + do { \ + x = vmalloc(size); \ + if (x == NULL) \ + goto alloc_mem_err; \ + memset(x, 0, size); \ + } while (0) + + int i; + + /* fastpath */ + /* Common */ + for_each_queue(bp, i) { + bnx2x_fp(bp, i, bp) = bp; + + /* status blocks */ + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk), + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_status_block)); + } + /* Rx */ + for_each_queue(bp, i) { + + /* fastpath rx rings: rx_buf rx_desc rx_comp */ + BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring), + sizeof(struct sw_rx_bd) * NUM_RX_BD); + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring), + &bnx2x_fp(bp, i, rx_desc_mapping), + sizeof(struct eth_rx_bd) * NUM_RX_BD); + + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring), + &bnx2x_fp(bp, i, rx_comp_mapping), + sizeof(struct eth_fast_path_rx_cqe) * + NUM_RCQ_BD); + + /* SGE ring */ + BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring), + sizeof(struct sw_rx_page) * NUM_RX_SGE); + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring), + &bnx2x_fp(bp, i, rx_sge_mapping), + BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); + } + /* Tx */ + for_each_queue(bp, i) { + + /* fastpath tx rings: tx_buf tx_desc */ + BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring), + sizeof(struct sw_tx_bd) * NUM_TX_BD); + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring), + &bnx2x_fp(bp, i, tx_desc_mapping), + sizeof(union eth_tx_bd_types) * NUM_TX_BD); + } + /* end of fastpath */ + + BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, + sizeof(struct host_def_status_block)); + + BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, + sizeof(struct bnx2x_slowpath)); + +#ifdef BCM_CNIC + BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024); + + /* allocate searcher T2 table + we allocate 1/4 of alloc num for T2 + (which is not entered into the ILT) */ + BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024); + + /* Initialize T2 (for 1024 connections) */ + for (i = 0; i < 16*1024; i += 64) + *(u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; + + /* Timer block array (8*MAX_CONN) phys uncached for now 1024 conns */ + BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024); + + /* QM queues (128*MAX_CONN) */ + BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024); + + BNX2X_PCI_ALLOC(bp->cnic_sb, &bp->cnic_sb_mapping, + sizeof(struct host_status_block)); +#endif + + /* Slow path ring */ + BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE); + + return 0; + +alloc_mem_err: + bnx2x_free_mem(bp); + return -ENOMEM; + +#undef BNX2X_PCI_ALLOC +#undef BNX2X_ALLOC +} + +static void bnx2x_free_tx_skbs(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + u16 bd_cons = fp->tx_bd_cons; + u16 sw_prod = fp->tx_pkt_prod; + u16 sw_cons = fp->tx_pkt_cons; + + while (sw_cons != sw_prod) { + bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons)); + sw_cons++; + } + } +} + +static void bnx2x_free_rx_skbs(struct bnx2x *bp) +{ + int i, j; + + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + + for (i = 0; i < NUM_RX_BD; i++) { + struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; + struct sk_buff *skb = rx_buf->skb; + + if (skb == NULL) + continue; + + dma_unmap_single(&bp->pdev->dev, + dma_unmap_addr(rx_buf, mapping), + bp->rx_buf_size, DMA_FROM_DEVICE); + + rx_buf->skb = NULL; + dev_kfree_skb(skb); + } + if (!fp->disable_tpa) + bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ? + ETH_MAX_AGGREGATION_QUEUES_E1 : + ETH_MAX_AGGREGATION_QUEUES_E1H); + } +} + +static void bnx2x_free_skbs(struct bnx2x *bp) +{ + bnx2x_free_tx_skbs(bp); + bnx2x_free_rx_skbs(bp); +} + +static void bnx2x_free_msix_irqs(struct bnx2x *bp) +{ + int i, offset = 1; + + free_irq(bp->msix_table[0].vector, bp->dev); + DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n", + bp->msix_table[0].vector); + +#ifdef BCM_CNIC + offset++; +#endif + for_each_queue(bp, i) { + DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " + "state %x\n", i, bp->msix_table[i + offset].vector, + bnx2x_fp(bp, i, state)); + + free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]); + } +} + +static void bnx2x_free_irq(struct bnx2x *bp, bool disable_only) +{ + if (bp->flags & USING_MSIX_FLAG) { + if (!disable_only) + bnx2x_free_msix_irqs(bp); + pci_disable_msix(bp->pdev); + bp->flags &= ~USING_MSIX_FLAG; + + } else if (bp->flags & USING_MSI_FLAG) { + if (!disable_only) + free_irq(bp->pdev->irq, bp->dev); + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + + } else if (!disable_only) + free_irq(bp->pdev->irq, bp->dev); +} + +static int bnx2x_enable_msix(struct bnx2x *bp) +{ + int i, rc, offset = 1; + int igu_vec = 0; + + bp->msix_table[0].entry = igu_vec; + DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec); + +#ifdef BCM_CNIC + igu_vec = BP_L_ID(bp) + offset; + bp->msix_table[1].entry = igu_vec; + DP(NETIF_MSG_IFUP, "msix_table[1].entry = %d (CNIC)\n", igu_vec); + offset++; +#endif + for_each_queue(bp, i) { + igu_vec = BP_L_ID(bp) + offset + i; + bp->msix_table[i + offset].entry = igu_vec; + DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " + "(fastpath #%u)\n", i + offset, igu_vec, i); + } + + rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], + BNX2X_NUM_QUEUES(bp) + offset); + + /* + * reconfigure number of tx/rx queues according to available + * MSI-X vectors + */ + if (rc >= BNX2X_MIN_MSIX_VEC_CNT) { + /* vectors available for FP */ + int fp_vec = rc - BNX2X_MSIX_VEC_FP_START; + + DP(NETIF_MSG_IFUP, + "Trying to use less MSI-X vectors: %d\n", rc); + + rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc); + + if (rc) { + DP(NETIF_MSG_IFUP, + "MSI-X is not attainable rc %d\n", rc); + return rc; + } + + bp->num_queues = min(bp->num_queues, fp_vec); + + DP(NETIF_MSG_IFUP, "New queue configuration set: %d\n", + bp->num_queues); + } else if (rc) { + DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc); + return rc; + } + + bp->flags |= USING_MSIX_FLAG; + + return 0; +} + +static int bnx2x_req_msix_irqs(struct bnx2x *bp) +{ + int i, rc, offset = 1; + + rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0, + bp->dev->name, bp->dev); + if (rc) { + BNX2X_ERR("request sp irq failed\n"); + return -EBUSY; + } + +#ifdef BCM_CNIC + offset++; +#endif + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", + bp->dev->name, i); + + rc = request_irq(bp->msix_table[i + offset].vector, + bnx2x_msix_fp_int, 0, fp->name, fp); + if (rc) { + BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc); + bnx2x_free_msix_irqs(bp); + return -EBUSY; + } + + fp->state = BNX2X_FP_STATE_IRQ; + } + + i = BNX2X_NUM_QUEUES(bp); + netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" + " ... fp[%d] %d\n", + bp->msix_table[0].vector, + 0, bp->msix_table[offset].vector, + i - 1, bp->msix_table[offset + i - 1].vector); + + return 0; +} + +static int bnx2x_enable_msi(struct bnx2x *bp) +{ + int rc; + + rc = pci_enable_msi(bp->pdev); + if (rc) { + DP(NETIF_MSG_IFUP, "MSI is not attainable\n"); + return -1; + } + bp->flags |= USING_MSI_FLAG; + + return 0; +} + +static int bnx2x_req_irq(struct bnx2x *bp) +{ + unsigned long flags; + int rc; + + if (bp->flags & USING_MSI_FLAG) + flags = 0; + else + flags = IRQF_SHARED; + + rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags, + bp->dev->name, bp->dev); + if (!rc) + bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ; + + return rc; +} + +static void bnx2x_napi_enable(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) + napi_enable(&bnx2x_fp(bp, i, napi)); +} + +static void bnx2x_napi_disable(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) + napi_disable(&bnx2x_fp(bp, i, napi)); +} + +static void bnx2x_netif_start(struct bnx2x *bp) +{ + int intr_sem; + + intr_sem = atomic_dec_and_test(&bp->intr_sem); + smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ + + if (intr_sem) { + if (netif_running(bp->dev)) { + bnx2x_napi_enable(bp); + bnx2x_int_enable(bp); + if (bp->state == BNX2X_STATE_OPEN) + netif_tx_wake_all_queues(bp->dev); + } + } +} + +static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) +{ + bnx2x_int_disable_sync(bp, disable_hw); + bnx2x_napi_disable(bp); + netif_tx_disable(bp->dev); +} + +/* + * Init service functions + */ + +/** + * Sets a MAC in a CAM for a few L2 Clients for E1 chip + * + * @param bp driver descriptor + * @param set set or clear an entry (1 or 0) + * @param mac pointer to a buffer containing a MAC + * @param cl_bit_vec bit vector of clients to register a MAC for + * @param cam_offset offset in a CAM to use + * @param with_bcast set broadcast MAC as well + */ +static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 with_bcast) +{ + struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); + int port = BP_PORT(bp); + + /* CAM allocation + * unicasts 0-31:port0 32-63:port1 + * multicast 64-127:port0 128-191:port1 + */ + config->hdr.length = 1 + (with_bcast ? 1 : 0); + config->hdr.offset = cam_offset; + config->hdr.client_id = 0xff; + config->hdr.reserved1 = 0; + + /* primary MAC */ + config->config_table[0].cam_entry.msb_mac_addr = + swab16(*(u16 *)&mac[0]); + config->config_table[0].cam_entry.middle_mac_addr = + swab16(*(u16 *)&mac[2]); + config->config_table[0].cam_entry.lsb_mac_addr = + swab16(*(u16 *)&mac[4]); + config->config_table[0].cam_entry.flags = cpu_to_le16(port); + if (set) + config->config_table[0].target_table_entry.flags = 0; + else + CAM_INVALIDATE(config->config_table[0]); + config->config_table[0].target_table_entry.clients_bit_vector = + cpu_to_le32(cl_bit_vec); + config->config_table[0].target_table_entry.vlan_id = 0; + + DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n", + (set ? "setting" : "clearing"), + config->config_table[0].cam_entry.msb_mac_addr, + config->config_table[0].cam_entry.middle_mac_addr, + config->config_table[0].cam_entry.lsb_mac_addr); + + /* broadcast */ + if (with_bcast) { + config->config_table[1].cam_entry.msb_mac_addr = + cpu_to_le16(0xffff); + config->config_table[1].cam_entry.middle_mac_addr = + cpu_to_le16(0xffff); + config->config_table[1].cam_entry.lsb_mac_addr = + cpu_to_le16(0xffff); + config->config_table[1].cam_entry.flags = cpu_to_le16(port); + if (set) + config->config_table[1].target_table_entry.flags = + TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST; + else + CAM_INVALIDATE(config->config_table[1]); + config->config_table[1].target_table_entry.clients_bit_vector = + cpu_to_le32(cl_bit_vec); + config->config_table[1].target_table_entry.vlan_id = 0; + } + + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + U64_HI(bnx2x_sp_mapping(bp, mac_config)), + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); +} + +/** + * Sets a MAC in a CAM for a few L2 Clients for E1H chip + * + * @param bp driver descriptor + * @param set set or clear an entry (1 or 0) + * @param mac pointer to a buffer containing a MAC + * @param cl_bit_vec bit vector of clients to register a MAC for + * @param cam_offset offset in a CAM to use + */ +static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, + u32 cl_bit_vec, u8 cam_offset) +{ + struct mac_configuration_cmd_e1h *config = + (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config); + + config->hdr.length = 1; + config->hdr.offset = cam_offset; + config->hdr.client_id = 0xff; + config->hdr.reserved1 = 0; + + /* primary MAC */ + config->config_table[0].msb_mac_addr = + swab16(*(u16 *)&mac[0]); + config->config_table[0].middle_mac_addr = + swab16(*(u16 *)&mac[2]); + config->config_table[0].lsb_mac_addr = + swab16(*(u16 *)&mac[4]); + config->config_table[0].clients_bit_vector = + cpu_to_le32(cl_bit_vec); + config->config_table[0].vlan_id = 0; + config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov); + if (set) + config->config_table[0].flags = BP_PORT(bp); + else + config->config_table[0].flags = + MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE; + + DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID mask %d\n", + (set ? "setting" : "clearing"), + config->config_table[0].msb_mac_addr, + config->config_table[0].middle_mac_addr, + config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + U64_HI(bnx2x_sp_mapping(bp, mac_config)), + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); +} + +static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int poll) +{ + /* can take a while if any port is running */ + int cnt = 5000; + + DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", + poll ? "polling" : "waiting", state, idx); + + might_sleep(); + while (cnt--) { + if (poll) { + bnx2x_rx_int(bp->fp, 10); + /* if index is different from 0 + * the reply for some commands will + * be on the non default queue + */ + if (idx) + bnx2x_rx_int(&bp->fp[idx], 10); + } + + mb(); /* state is changed by bnx2x_sp_event() */ + if (*state_p == state) { +#ifdef BNX2X_STOP_ON_ERROR + DP(NETIF_MSG_IFUP, "exit (cnt %d)\n", 5000 - cnt); +#endif + return 0; + } + + msleep(1); + + if (bp->panic) + return -EIO; + } + + /* timeout! */ + BNX2X_ERR("timeout %s for state %x on IDX [%d]\n", + poll ? "polling" : "waiting", state, idx); +#ifdef BNX2X_STOP_ON_ERROR + bnx2x_panic(); +#endif + + return -EBUSY; +} + +static void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set) +{ + bp->set_mac_pending++; + smp_wmb(); + + bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr, + (1 << bp->fp->cl_id), BP_FUNC(bp)); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); +} + +static void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) +{ + bp->set_mac_pending++; + smp_wmb(); + + bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr, + (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0), + 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); +} + +#ifdef BCM_CNIC +/** + * Set iSCSI MAC(s) at the next enties in the CAM after the ETH + * MAC(s). This function will wait until the ramdord completion + * returns. + * + * @param bp driver handle + * @param set set or clear the CAM entry + * + * @return 0 if cussess, -ENODEV if ramrod doesn't return. + */ +static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) +{ + u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID); + + bp->set_mac_pending++; + smp_wmb(); + + /* Send a SET_MAC ramrod */ + if (CHIP_IS_E1(bp)) + bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac, + cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2, + 1); + else + /* CAM allocation for E1H + * unicasts: by func number + * multicast: 20+FUNC*20, 20 each + */ + bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac, + cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp)); + + /* Wait for a completion when setting */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + + return 0; +} +#endif + +static int bnx2x_setup_leading(struct bnx2x *bp) +{ + int rc; + + /* reset IGU state */ + bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + + /* SETUP ramrod */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0); + + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0); + + return rc; +} + +static int bnx2x_setup_multi(struct bnx2x *bp, int index) +{ + struct bnx2x_fastpath *fp = &bp->fp[index]; + + /* reset IGU state */ + bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + + /* SETUP ramrod */ + fp->state = BNX2X_FP_STATE_OPENING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, + fp->cl_id, 0); + + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, + &(fp->state), 0); +} + +static int bnx2x_poll(struct napi_struct *napi, int budget); + +static void bnx2x_set_num_queues_msix(struct bnx2x *bp) +{ + + switch (bp->multi_mode) { + case ETH_RSS_MODE_DISABLED: + bp->num_queues = 1; + break; + + case ETH_RSS_MODE_REGULAR: + if (num_queues) + bp->num_queues = min_t(u32, num_queues, + BNX2X_MAX_QUEUES(bp)); + else + bp->num_queues = min_t(u32, num_online_cpus(), + BNX2X_MAX_QUEUES(bp)); + break; + + + default: + bp->num_queues = 1; + break; + } +} + +static int bnx2x_set_num_queues(struct bnx2x *bp) +{ + int rc = 0; + + switch (int_mode) { + case INT_MODE_INTx: + case INT_MODE_MSI: + bp->num_queues = 1; + DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); + break; + default: + /* Set number of queues according to bp->multi_mode value */ + bnx2x_set_num_queues_msix(bp); + + DP(NETIF_MSG_IFUP, "set number of queues to %d\n", + bp->num_queues); + + /* if we can't use MSI-X we only need one fp, + * so try to enable MSI-X with the requested number of fp's + * and fallback to MSI or legacy INTx with one fp + */ + rc = bnx2x_enable_msix(bp); + if (rc) + /* failed to enable MSI-X */ + bp->num_queues = 1; + break; + } + bp->dev->real_num_tx_queues = bp->num_queues; + return rc; +} - tstorm_config.leading_client_id = BP_L_ID(bp); +#ifdef BCM_CNIC +static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd); +static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); +#endif - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func), - (*(u32 *)&tstorm_config)); +/* must be called with rtnl_lock */ +static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) +{ + u32 load_code; + int i, rc; - bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ - bp->rx_mode_cl_mask = (1 << BP_L_ID(bp)); - bnx2x_set_storm_rx_mode(bp); +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return -EPERM; +#endif - for_each_queue(bp, i) { - u8 cl_id = bp->fp[i].cl_id; + bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; - /* reset xstorm per client statistics */ - offset = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct xstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); + rc = bnx2x_set_num_queues(bp); - /* reset tstorm per client statistics */ - offset = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct tstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); + if (bnx2x_alloc_mem(bp)) { + bnx2x_free_irq(bp, true); + return -ENOMEM; + } - /* reset ustorm per client statistics */ - offset = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct ustorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); + for_each_queue(bp, i) + bnx2x_fp(bp, i, disable_tpa) = + ((bp->flags & TPA_ENABLE_FLAG) == 0); + + for_each_queue(bp, i) + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), + bnx2x_poll, 128); + + bnx2x_napi_enable(bp); + + if (bp->flags & USING_MSIX_FLAG) { + rc = bnx2x_req_msix_irqs(bp); + if (rc) { + bnx2x_free_irq(bp, true); + goto load_error1; + } + } else { + /* Fall to INTx if failed to enable MSI-X due to lack of + memory (in bnx2x_set_num_queues()) */ + if ((rc != -ENOMEM) && (int_mode != INT_MODE_INTx)) + bnx2x_enable_msi(bp); + bnx2x_ack_int(bp); + rc = bnx2x_req_irq(bp); + if (rc) { + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); + bnx2x_free_irq(bp, true); + goto load_error1; + } + if (bp->flags & USING_MSI_FLAG) { + bp->dev->irq = bp->pdev->irq; + netdev_info(bp->dev, "using MSI IRQ %d\n", + bp->pdev->irq); + } } - /* Init statistics related context */ - stats_flags.collect_eth = 1; + /* Send LOAD_REQUEST command to MCP + Returns the type of LOAD command: + if it is the first port to be initialized + common blocks should be initialized, otherwise - not + */ + if (!BP_NOMCP(bp)) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); + if (!load_code) { + BNX2X_ERR("MCP response failure, aborting\n"); + rc = -EBUSY; + goto load_error2; + } + if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { + rc = -EBUSY; /* other port in diagnostic mode */ + goto load_error2; + } - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); + } else { + int port = BP_PORT(bp); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); + DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n", + load_count[0], load_count[1], load_count[2]); + load_count[0]++; + load_count[1 + port]++; + DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n", + load_count[0], load_count[1], load_count[2]); + if (load_count[0] == 1) + load_code = FW_MSG_CODE_DRV_LOAD_COMMON; + else if (load_count[1 + port] == 1) + load_code = FW_MSG_CODE_DRV_LOAD_PORT; + else + load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; + } - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); + if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || + (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) + bp->port.pmf = 1; + else + bp->port.pmf = 0; + DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); + /* Initialize HW */ + rc = bnx2x_init_hw(bp, load_code); + if (rc) { + BNX2X_ERR("HW init failed, aborting\n"); + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + goto load_error2; + } - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + /* Setup NIC internals and enable interrupts */ + bnx2x_nic_init(bp, load_code); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) && + (bp->common.shmem2_base)) + SHMEM2_WR(bp, dcc_support, + (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV | + SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + /* Send LOAD_DONE command to MCP */ + if (!BP_NOMCP(bp)) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + if (!load_code) { + BNX2X_ERR("MCP response failure, aborting\n"); + rc = -EBUSY; + goto load_error3; + } + } - if (CHIP_IS_E1H(bp)) { - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func), - bp->e1hov); + rc = bnx2x_setup_leading(bp); + if (rc) { + BNX2X_ERR("Setup leading failed!\n"); +#ifndef BNX2X_STOP_ON_ERROR + goto load_error3; +#else + bp->panic = 1; + return -EBUSY; +#endif } - /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */ - max_agg_size = min_t(u32, (min_t(u32, 8, MAX_SKB_FRAGS) * - SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; + if (CHIP_IS_E1H(bp)) + if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { + DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); + bp->flags |= MF_FUNC_DIS; + } - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping)); + if (bp->state == BNX2X_STATE_OPEN) { +#ifdef BCM_CNIC + /* Enable Timer scan */ + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); +#endif + for_each_nondefault_queue(bp, i) { + rc = bnx2x_setup_multi(bp, i); + if (rc) +#ifdef BCM_CNIC + goto load_error4; +#else + goto load_error3; +#endif + } - /* Next page */ - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping + BCM_PAGE_SIZE)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping + BCM_PAGE_SIZE)); + if (CHIP_IS_E1(bp)) + bnx2x_set_eth_mac_addr_e1(bp, 1); + else + bnx2x_set_eth_mac_addr_e1h(bp, 1); +#ifdef BCM_CNIC + /* Set iSCSI L2 MAC */ + mutex_lock(&bp->cnic_mutex); + if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { + bnx2x_set_iscsi_eth_mac_addr(bp, 1); + bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; + bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, + CNIC_SB_ID(bp)); + } + mutex_unlock(&bp->cnic_mutex); +#endif + } - REG_WR16(bp, BAR_USTRORM_INTMEM + - USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id), - max_agg_size); + if (bp->port.pmf) + bnx2x_initial_phy_init(bp, load_mode); + + /* Start fast path */ + switch (load_mode) { + case LOAD_NORMAL: + if (bp->state == BNX2X_STATE_OPEN) { + /* Tx queue should be only reenabled */ + netif_tx_wake_all_queues(bp->dev); + } + /* Initialize the receive filter. */ + bnx2x_set_rx_mode(bp->dev); + break; + + case LOAD_OPEN: + netif_tx_start_all_queues(bp->dev); + if (bp->state != BNX2X_STATE_OPEN) + netif_tx_disable(bp->dev); + /* Initialize the receive filter. */ + bnx2x_set_rx_mode(bp->dev); + break; + + case LOAD_DIAG: + /* Initialize the receive filter. */ + bnx2x_set_rx_mode(bp->dev); + bp->state = BNX2X_STATE_DIAG; + break; + + default: + break; } - /* dropless flow control */ - if (CHIP_IS_E1H(bp)) { - struct ustorm_eth_rx_pause_data_e1h rx_pause = {0}; + if (!bp->port.pmf) + bnx2x__link_status_update(bp); - rx_pause.bd_thr_low = 250; - rx_pause.cqe_thr_low = 250; - rx_pause.cos = 1; - rx_pause.sge_thr_low = 0; - rx_pause.bd_thr_high = 350; - rx_pause.cqe_thr_high = 350; - rx_pause.sge_thr_high = 0; + /* start the timer */ + mod_timer(&bp->timer, jiffies + bp->current_interval); - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; +#ifdef BCM_CNIC + bnx2x_setup_cnic_irq_info(bp); + if (bp->state == BNX2X_STATE_OPEN) + bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); +#endif + bnx2x_inc_load_cnt(bp); - if (!fp->disable_tpa) { - rx_pause.sge_thr_low = 150; - rx_pause.sge_thr_high = 250; - } + return 0; + +#ifdef BCM_CNIC +load_error4: + /* Disable Timer scan */ + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 0); +#endif +load_error3: + bnx2x_int_disable_sync(bp, 1); + if (!BP_NOMCP(bp)) { + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + } + bp->port.pmf = 0; + /* Free SKBs, SGEs, TPA pool and driver internals */ + bnx2x_free_skbs(bp); + for_each_queue(bp, i) + bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); +load_error2: + /* Release IRQs */ + bnx2x_free_irq(bp, false); +load_error1: + bnx2x_napi_disable(bp); + for_each_queue(bp, i) + netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); + + return rc; +} + +static int bnx2x_stop_multi(struct bnx2x *bp, int index) +{ + struct bnx2x_fastpath *fp = &bp->fp[index]; + int rc; + + /* halt the connection */ + fp->state = BNX2X_FP_STATE_HALTING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0); + + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, + &(fp->state), 1); + if (rc) /* timeout */ + return rc; + + /* delete cfc entry */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); + + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index, + &(fp->state), 1); + return rc; +} + +static int bnx2x_stop_leading(struct bnx2x *bp) +{ + __le16 dsb_sp_prod_idx; + /* if the other port is handling traffic, + this can take a lot of time */ + int cnt = 500; + int rc; + might_sleep(); + + /* Send HALT ramrod */ + bp->fp[0].state = BNX2X_FP_STATE_HALTING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0); + + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0, + &(bp->fp[0].state), 1); + if (rc) /* timeout */ + return rc; + + dsb_sp_prod_idx = *bp->dsb_sp_prod; + + /* Send PORT_DELETE ramrod */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); - offset = BAR_USTRORM_INTMEM + - USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, - fp->cl_id); - for (j = 0; - j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4; - j++) - REG_WR(bp, offset + j*4, - ((u32 *)&rx_pause)[j]); + /* Wait for completion to arrive on default status block + we are going to reset the chip anyway + so there is not much to do if this times out + */ + while (dsb_sp_prod_idx == *bp->dsb_sp_prod) { + if (!cnt) { + DP(NETIF_MSG_IFDOWN, "timeout waiting for port del " + "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", + *bp->dsb_sp_prod, dsb_sp_prod_idx); +#ifdef BNX2X_STOP_ON_ERROR + bnx2x_panic(); +#endif + rc = -EBUSY; + break; } + cnt--; + msleep(1); + rmb(); /* Refresh the dsb_sp_prod */ } + bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + bp->fp[0].state = BNX2X_FP_STATE_CLOSED; - memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); + return rc; +} - /* Init rate shaping and fairness contexts */ - if (IS_E1HMF(bp)) { - int vn; +static void bnx2x_reset_func(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int func = BP_FUNC(bp); + int base, i; - /* During init there is no active link - Until link is up, set link rate to 10Gbps */ - bp->link_vars.line_speed = SPEED_10000; - bnx2x_init_port_minmax(bp); + /* Configure IGU */ + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); - if (!BP_NOMCP(bp)) - bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); - bnx2x_calc_vn_weight_sum(bp); +#ifdef BCM_CNIC + /* Disable Timer scan */ + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0); + /* + * Wait for at least 10ms and up to 2 second for the timers scan to + * complete + */ + for (i = 0; i < 200; i++) { + msleep(10); + if (!REG_RD(bp, TM_REG_LIN0_SCAN_ON + port*4)) + break; + } +#endif + /* Clear ILT */ + base = FUNC_ILT_BASE(func); + for (i = base; i < base + ILT_PER_FUNC; i++) + bnx2x_ilt_wr(bp, i, 0); +} - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); +static void bnx2x_reset_port(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + u32 val; - /* Enable rate shaping and fairness */ - bp->cmng.flags.cmng_enables |= - CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; + REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); - } else { - /* rate shaping and fairness are disabled */ - DP(NETIF_MSG_IFUP, - "single function mode minmax will be disabled\n"); - } + /* Do not rcv packets to BRB */ + REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + port*4, 0x0); + /* Do not direct rcv packets that are not for MCP to the BRB */ + REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP : + NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); + /* Configure AEU */ + REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, 0); - /* Store cmng structures to internal memory */ - if (bp->port.pmf) - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4, - ((u32 *)(&bp->cmng))[i]); + msleep(100); + /* Check for BRB port occupancy */ + val = REG_RD(bp, BRB1_REG_PORT_NUM_OCC_BLOCKS_0 + port*4); + if (val) + DP(NETIF_MSG_IFDOWN, + "BRB1 is not empty %d blocks are occupied\n", val); + + /* TODO: Close Doorbell port? */ } -static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) +static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) { - switch (load_code) { - case FW_MSG_CODE_DRV_LOAD_COMMON: - bnx2x_init_internal_common(bp); - /* no break */ + DP(BNX2X_MSG_MCP, "function %d reset_code %x\n", + BP_FUNC(bp), reset_code); - case FW_MSG_CODE_DRV_LOAD_PORT: - bnx2x_init_internal_port(bp); - /* no break */ + switch (reset_code) { + case FW_MSG_CODE_DRV_UNLOAD_COMMON: + bnx2x_reset_port(bp); + bnx2x_reset_func(bp); + bnx2x_reset_common(bp); + break; - case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bnx2x_init_internal_func(bp); + case FW_MSG_CODE_DRV_UNLOAD_PORT: + bnx2x_reset_port(bp); + bnx2x_reset_func(bp); + break; + + case FW_MSG_CODE_DRV_UNLOAD_FUNCTION: + bnx2x_reset_func(bp); break; default: - BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code); + BNX2X_ERR("Unknown reset_code (0x%x) from MCP\n", reset_code); break; } } -void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) +static void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) { - int i; + int port = BP_PORT(bp); + u32 reset_code = 0; + int i, cnt, rc; + /* Wait until tx fastpath tasks complete */ for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - fp->bp = bp; - fp->state = BNX2X_FP_STATE_CLOSED; - fp->index = i; - fp->cl_id = BP_L_ID(bp) + i; -#ifdef BCM_CNIC - fp->sb_id = fp->cl_id + 1; + cnt = 1000; + while (bnx2x_has_tx_work_unload(fp)) { + + bnx2x_tx_int(fp); + if (!cnt) { + BNX2X_ERR("timeout waiting for queue[%d]\n", + i); +#ifdef BNX2X_STOP_ON_ERROR + bnx2x_panic(); + return -EBUSY; #else - fp->sb_id = fp->cl_id; + break; #endif - DP(NETIF_MSG_IFUP, - "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n", - i, bp, fp->status_blk, fp->cl_id, fp->sb_id); - bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, - fp->sb_id); - bnx2x_update_fpsb_idx(fp); + } + cnt--; + msleep(1); + } } + /* Give HW time to discard old tx messages */ + msleep(1); - /* ensure status block indices were read */ - rmb(); - - - bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping, - DEF_SB_ID); - bnx2x_update_dsb_idx(bp); - bnx2x_update_coalesce(bp); - bnx2x_init_rx_rings(bp); - bnx2x_init_tx_ring(bp); - bnx2x_init_sp_ring(bp); - bnx2x_init_context(bp); - bnx2x_init_internal(bp, load_code); - bnx2x_init_ind_table(bp); - bnx2x_stats_init(bp); - - /* At this point, we are ready for interrupts */ - atomic_set(&bp->intr_sem, 0); - - /* flush all before enabling interrupts */ - mb(); - mmiowb(); - - bnx2x_int_enable(bp); - - /* Check for SPIO5 */ - bnx2x_attn_int_deasserted0(bp, - REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + BP_PORT(bp)*4) & - AEU_INPUTS_ATTN_BITS_SPIO5); -} - -/* end of nic init */ - -/* - * gzip service functions - */ - -static int bnx2x_gunzip_init(struct bnx2x *bp) -{ - bp->gunzip_buf = dma_alloc_coherent(&bp->pdev->dev, FW_BUF_SIZE, - &bp->gunzip_mapping, GFP_KERNEL); - if (bp->gunzip_buf == NULL) - goto gunzip_nomem1; - - bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL); - if (bp->strm == NULL) - goto gunzip_nomem2; + if (CHIP_IS_E1(bp)) { + struct mac_configuration_cmd *config = + bnx2x_sp(bp, mcast_config); - bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(), - GFP_KERNEL); - if (bp->strm->workspace == NULL) - goto gunzip_nomem3; + bnx2x_set_eth_mac_addr_e1(bp, 0); - return 0; + for (i = 0; i < config->hdr.length; i++) + CAM_INVALIDATE(config->config_table[i]); -gunzip_nomem3: - kfree(bp->strm); - bp->strm = NULL; + config->hdr.length = i; + if (CHIP_REV_IS_SLOW(bp)) + config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port); + else + config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port); + config->hdr.client_id = bp->fp->cl_id; + config->hdr.reserved1 = 0; -gunzip_nomem2: - dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf, - bp->gunzip_mapping); - bp->gunzip_buf = NULL; + bp->set_mac_pending++; + smp_wmb(); -gunzip_nomem1: - netdev_err(bp->dev, "Cannot allocate firmware buffer for" - " un-compression\n"); - return -ENOMEM; -} + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + U64_HI(bnx2x_sp_mapping(bp, mcast_config)), + U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0); -static void bnx2x_gunzip_end(struct bnx2x *bp) -{ - kfree(bp->strm->workspace); + } else { /* E1H */ + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); - kfree(bp->strm); - bp->strm = NULL; + bnx2x_set_eth_mac_addr_e1h(bp, 0); - if (bp->gunzip_buf) { - dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf, - bp->gunzip_mapping); - bp->gunzip_buf = NULL; + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); + + REG_WR(bp, MISC_REG_E1HMF_MODE, 0); } -} +#ifdef BCM_CNIC + /* Clear iSCSI L2 MAC */ + mutex_lock(&bp->cnic_mutex); + if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { + bnx2x_set_iscsi_eth_mac_addr(bp, 0); + bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; + } + mutex_unlock(&bp->cnic_mutex); +#endif -static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len) -{ - int n, rc; + if (unload_mode == UNLOAD_NORMAL) + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - /* check gzip header */ - if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) { - BNX2X_ERR("Bad gzip header\n"); - return -EINVAL; - } + else if (bp->flags & NO_WOL_FLAG) + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP; - n = 10; + else if (bp->wol) { + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u8 *mac_addr = bp->dev->dev_addr; + u32 val; + /* The mac address is written to entries 1-4 to + preserve entry 0 which is used by the PMF */ + u8 entry = (BP_E1HVN(bp) + 1)*8; -#define FNAME 0x8 + val = (mac_addr[0] << 8) | mac_addr[1]; + EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry, val); - if (zbuf[3] & FNAME) - while ((zbuf[n++] != 0) && (n < len)); + val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | + (mac_addr[4] << 8) | mac_addr[5]; + EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val); - bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n; - bp->strm->avail_in = len - n; - bp->strm->next_out = bp->gunzip_buf; - bp->strm->avail_out = FW_BUF_SIZE; + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN; - rc = zlib_inflateInit2(bp->strm, -MAX_WBITS); - if (rc != Z_OK) - return rc; + } else + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - rc = zlib_inflate(bp->strm, Z_FINISH); - if ((rc != Z_OK) && (rc != Z_STREAM_END)) - netdev_err(bp->dev, "Firmware decompression error: %s\n", - bp->strm->msg); + /* Close multi and leading connections + Completions for ramrods are collected in a synchronous way */ + for_each_nondefault_queue(bp, i) + if (bnx2x_stop_multi(bp, i)) + goto unload_error; - bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out); - if (bp->gunzip_outlen & 0x3) - netdev_err(bp->dev, "Firmware decompression error:" - " gunzip_outlen (%d) not aligned\n", - bp->gunzip_outlen); - bp->gunzip_outlen >>= 2; + rc = bnx2x_stop_leading(bp); + if (rc) { + BNX2X_ERR("Stop leading failed!\n"); +#ifdef BNX2X_STOP_ON_ERROR + return -EBUSY; +#else + goto unload_error; +#endif + } - zlib_inflateEnd(bp->strm); +unload_error: + if (!BP_NOMCP(bp)) + reset_code = bnx2x_fw_command(bp, reset_code); + else { + DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", + load_count[0], load_count[1], load_count[2]); + load_count[0]--; + load_count[1 + port]--; + DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n", + load_count[0], load_count[1], load_count[2]); + if (load_count[0] == 0) + reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; + else if (load_count[1 + port] == 0) + reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; + else + reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; + } - if (rc == Z_STREAM_END) - return 0; + if ((reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) || + (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT)) + bnx2x__link_reset(bp); - return rc; -} + /* Reset the chip */ + bnx2x_reset_chip(bp, reset_code); -/* nic load/unload */ + /* Report UNLOAD_DONE to MCP */ + if (!BP_NOMCP(bp)) + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); -/* - * General service functions - */ +} -/* send a NIG loopback debug packet */ -static void bnx2x_lb_pckt(struct bnx2x *bp) +static inline void bnx2x_disable_close_the_gate(struct bnx2x *bp) { - u32 wb_write[3]; + u32 val; - /* Ethernet source and destination addresses */ - wb_write[0] = 0x55555555; - wb_write[1] = 0x55555555; - wb_write[2] = 0x20; /* SOP */ - REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3); + DP(NETIF_MSG_HW, "Disabling \"close the gates\"\n"); - /* NON-IP protocol */ - wb_write[0] = 0x09000000; - wb_write[1] = 0x55555555; - wb_write[2] = 0x10; /* EOP, eop_bvalid = 0 */ - REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3); + if (CHIP_IS_E1(bp)) { + int port = BP_PORT(bp); + u32 addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0; + + val = REG_RD(bp, addr); + val &= ~(0x300); + REG_WR(bp, addr, val); + } else if (CHIP_IS_E1H(bp)) { + val = REG_RD(bp, MISC_REG_AEU_GENERAL_MASK); + val &= ~(MISC_AEU_GENERAL_MASK_REG_AEU_PXP_CLOSE_MASK | + MISC_AEU_GENERAL_MASK_REG_AEU_NIG_CLOSE_MASK); + REG_WR(bp, MISC_REG_AEU_GENERAL_MASK, val); + } } -/* some of the internal memories - * are not directly readable from the driver - * to test them we send debug packets - */ -static int bnx2x_int_mem_test(struct bnx2x *bp) +/* must be called with rtnl_lock */ +static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) { - int factor; - int count, i; - u32 val = 0; + int i; - if (CHIP_REV_IS_FPGA(bp)) - factor = 120; - else if (CHIP_REV_IS_EMUL(bp)) - factor = 200; - else - factor = 1; + if (bp->state == BNX2X_STATE_CLOSED) { + /* Interface has been removed - nothing to recover */ + bp->recovery_state = BNX2X_RECOVERY_DONE; + bp->is_leader = 0; + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08); + smp_wmb(); - DP(NETIF_MSG_HW, "start part1\n"); + return -EINVAL; + } - /* Disable inputs of parser neighbor blocks */ - REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); - REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); - REG_WR(bp, CFC_REG_DEBUG0, 0x1); - REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0); +#ifdef BCM_CNIC + bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); +#endif + bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; - /* Write 0 to parser credits for CFC search request */ - REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); + /* Set "drop all" */ + bp->rx_mode = BNX2X_RX_MODE_NONE; + bnx2x_set_storm_rx_mode(bp); - /* send Ethernet packet */ - bnx2x_lb_pckt(bp); + /* Disable HW interrupts, NAPI and Tx */ + bnx2x_netif_stop(bp, 1); + netif_carrier_off(bp->dev); - /* TODO do i reset NIG statistic? */ - /* Wait until NIG register shows 1 packet of size 0x10 */ - count = 1000 * factor; - while (count) { + del_timer_sync(&bp->timer); + SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, + (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); + bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); - val = *bnx2x_sp(bp, wb_data[0]); - if (val == 0x10) - break; + /* Release IRQs */ + bnx2x_free_irq(bp, false); - msleep(10); - count--; - } - if (val != 0x10) { - BNX2X_ERR("NIG timeout val = 0x%x\n", val); - return -1; - } + /* Cleanup the chip if needed */ + if (unload_mode != UNLOAD_RECOVERY) + bnx2x_chip_cleanup(bp, unload_mode); - /* Wait until PRS register shows 1 packet */ - count = 1000 * factor; - while (count) { - val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); - if (val == 1) - break; + bp->port.pmf = 0; - msleep(10); - count--; - } - if (val != 0x1) { - BNX2X_ERR("PRS timeout val = 0x%x\n", val); - return -2; - } + /* Free SKBs, SGEs, TPA pool and driver internals */ + bnx2x_free_skbs(bp); + for_each_queue(bp, i) + bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); + for_each_queue(bp, i) + netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); - /* Reset and init BRB, PRS */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03); - msleep(50); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); - msleep(50); - bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); + bp->state = BNX2X_STATE_CLOSED; - DP(NETIF_MSG_HW, "part2\n"); + /* The last driver must disable a "close the gate" if there is no + * parity attention or "process kill" pending. + */ + if ((!bnx2x_dec_load_cnt(bp)) && (!bnx2x_chk_parity_attn(bp)) && + bnx2x_reset_is_done(bp)) + bnx2x_disable_close_the_gate(bp); - /* Disable inputs of parser neighbor blocks */ - REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); - REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); - REG_WR(bp, CFC_REG_DEBUG0, 0x1); - REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0); + /* Reset MCP mail box sequence if there is on going recovery */ + if (unload_mode == UNLOAD_RECOVERY) + bp->fw_seq = 0; - /* Write 0 to parser credits for CFC search request */ - REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); + return 0; +} - /* send 10 Ethernet packets */ - for (i = 0; i < 10; i++) - bnx2x_lb_pckt(bp); +/* Close gates #2, #3 and #4: */ +static void bnx2x_set_234_gates(struct bnx2x *bp, bool close) +{ + u32 val, addr; - /* Wait until NIG register shows 10 + 1 - packets of size 11*0x10 = 0xb0 */ - count = 1000 * factor; - while (count) { + /* Gates #2 and #4a are closed/opened for "not E1" only */ + if (!CHIP_IS_E1(bp)) { + /* #4 */ + val = REG_RD(bp, PXP_REG_HST_DISCARD_DOORBELLS); + REG_WR(bp, PXP_REG_HST_DISCARD_DOORBELLS, + close ? (val | 0x1) : (val & (~(u32)1))); + /* #2 */ + val = REG_RD(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES); + REG_WR(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES, + close ? (val | 0x1) : (val & (~(u32)1))); + } - bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); - val = *bnx2x_sp(bp, wb_data[0]); - if (val == 0xb0) - break; + /* #3 */ + addr = BP_PORT(bp) ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; + val = REG_RD(bp, addr); + REG_WR(bp, addr, (!close) ? (val | 0x1) : (val & (~(u32)1))); - msleep(10); - count--; - } - if (val != 0xb0) { - BNX2X_ERR("NIG timeout val = 0x%x\n", val); - return -3; - } + DP(NETIF_MSG_HW, "%s gates #2, #3 and #4\n", + close ? "closing" : "opening"); + mmiowb(); +} - /* Wait until PRS register shows 2 packets */ - val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); - if (val != 2) - BNX2X_ERR("PRS timeout val = 0x%x\n", val); +#define SHARED_MF_CLP_MAGIC 0x80000000 /* `magic' bit */ - /* Write 1 to parser credits for CFC search request */ - REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x1); +static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val) +{ + /* Do some magic... */ + u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb); + *magic_val = val & SHARED_MF_CLP_MAGIC; + MF_CFG_WR(bp, shared_mf_config.clp_mb, val | SHARED_MF_CLP_MAGIC); +} - /* Wait until PRS register shows 3 packets */ - msleep(10 * factor); - /* Wait until NIG register shows 1 packet of size 0x10 */ - val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); - if (val != 3) - BNX2X_ERR("PRS timeout val = 0x%x\n", val); +/* Restore the value of the `magic' bit. + * + * @param pdev Device handle. + * @param magic_val Old value of the `magic' bit. + */ +static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val) +{ + /* Restore the `magic' bit value... */ + /* u32 val = SHMEM_RD(bp, mf_cfg.shared_mf_config.clp_mb); + SHMEM_WR(bp, mf_cfg.shared_mf_config.clp_mb, + (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); */ + u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb); + MF_CFG_WR(bp, shared_mf_config.clp_mb, + (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); +} - /* clear NIG EOP FIFO */ - for (i = 0; i < 11; i++) - REG_RD(bp, NIG_REG_INGRESS_EOP_LB_FIFO); - val = REG_RD(bp, NIG_REG_INGRESS_EOP_LB_EMPTY); - if (val != 1) { - BNX2X_ERR("clear of NIG failed\n"); - return -4; - } +/* Prepares for MCP reset: takes care of CLP configurations. + * + * @param bp + * @param magic_val Old value of 'magic' bit. + */ +static void bnx2x_reset_mcp_prep(struct bnx2x *bp, u32 *magic_val) +{ + u32 shmem; + u32 validity_offset; - /* Reset and init BRB, PRS, NIG */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03); - msleep(50); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); - msleep(50); - bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); -#ifndef BCM_CNIC - /* set NIC mode */ - REG_WR(bp, PRS_REG_NIC_MODE, 1); -#endif + DP(NETIF_MSG_HW, "Starting\n"); - /* Enable inputs of parser neighbor blocks */ - REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff); - REG_WR(bp, TCM_REG_PRS_IFEN, 0x1); - REG_WR(bp, CFC_REG_DEBUG0, 0x0); - REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x1); + /* Set `magic' bit in order to save MF config */ + if (!CHIP_IS_E1(bp)) + bnx2x_clp_reset_prep(bp, magic_val); - DP(NETIF_MSG_HW, "done\n"); + /* Get shmem offset */ + shmem = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); + validity_offset = offsetof(struct shmem_region, validity_map[0]); - return 0; /* OK */ + /* Clear validity map flags */ + if (shmem > 0) + REG_WR(bp, shmem + validity_offset, 0); } -static void enable_blocks_attention(struct bnx2x *bp) +#define MCP_TIMEOUT 5000 /* 5 seconds (in ms) */ +#define MCP_ONE_TIMEOUT 100 /* 100 ms */ + +/* Waits for MCP_ONE_TIMEOUT or MCP_ONE_TIMEOUT*10, + * depending on the HW type. + * + * @param bp + */ +static inline void bnx2x_mcp_wait_one(struct bnx2x *bp) { - REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); - REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); - REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); - REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); - REG_WR(bp, QM_REG_QM_INT_MASK, 0); - REG_WR(bp, TM_REG_TM_INT_MASK, 0); - REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0); - REG_WR(bp, XSDM_REG_XSDM_INT_MASK_1, 0); - REG_WR(bp, XCM_REG_XCM_INT_MASK, 0); -/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_0, 0); */ -/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_1, 0); */ - REG_WR(bp, USDM_REG_USDM_INT_MASK_0, 0); - REG_WR(bp, USDM_REG_USDM_INT_MASK_1, 0); - REG_WR(bp, UCM_REG_UCM_INT_MASK, 0); -/* REG_WR(bp, USEM_REG_USEM_INT_MASK_0, 0); */ -/* REG_WR(bp, USEM_REG_USEM_INT_MASK_1, 0); */ - REG_WR(bp, GRCBASE_UPB + PB_REG_PB_INT_MASK, 0); - REG_WR(bp, CSDM_REG_CSDM_INT_MASK_0, 0); - REG_WR(bp, CSDM_REG_CSDM_INT_MASK_1, 0); - REG_WR(bp, CCM_REG_CCM_INT_MASK, 0); -/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */ -/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */ - if (CHIP_REV_IS_FPGA(bp)) - REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); + /* special handling for emulation and FPGA, + wait 10 times longer */ + if (CHIP_REV_IS_SLOW(bp)) + msleep(MCP_ONE_TIMEOUT*10); else - REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000); - REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0); - REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0); - REG_WR(bp, TCM_REG_TCM_INT_MASK, 0); -/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */ -/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */ - REG_WR(bp, CDU_REG_CDU_INT_MASK, 0); - REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0); -/* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */ - REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18); /* bit 3,4 masked */ + msleep(MCP_ONE_TIMEOUT); } -static const struct { - u32 addr; - u32 mask; -} bnx2x_parity_mask[] = { - {PXP_REG_PXP_PRTY_MASK, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_1, 0xffffffff}, - {HC_REG_HC_PRTY_MASK, 0xffffffff}, - {MISC_REG_MISC_PRTY_MASK, 0xffffffff}, - {QM_REG_QM_PRTY_MASK, 0x0}, - {DORQ_REG_DORQ_PRTY_MASK, 0x0}, - {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, - {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 0x0}, - {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ - {CDU_REG_CDU_PRTY_MASK, 0x0}, - {CFC_REG_CFC_PRTY_MASK, 0x0}, - {DBG_REG_DBG_PRTY_MASK, 0x0}, - {DMAE_REG_DMAE_PRTY_MASK, 0x0}, - {BRB1_REG_BRB1_PRTY_MASK, 0x0}, - {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ - {TSDM_REG_TSDM_PRTY_MASK, 0x18},/* bit 3,4 */ - {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {USDM_REG_USDM_PRTY_MASK, 0x38},/* bit 3,4,5 */ - {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, - {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, - {USEM_REG_USEM_PRTY_MASK_0, 0x0}, - {USEM_REG_USEM_PRTY_MASK_1, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} -}; - -static void enable_blocks_parity(struct bnx2x *bp) +static int bnx2x_reset_mcp_comp(struct bnx2x *bp, u32 magic_val) { - int i, mask_arr_len = - sizeof(bnx2x_parity_mask)/(sizeof(bnx2x_parity_mask[0])); + u32 shmem, cnt, validity_offset, val; + int rc = 0; - for (i = 0; i < mask_arr_len; i++) - REG_WR(bp, bnx2x_parity_mask[i].addr, - bnx2x_parity_mask[i].mask); -} + msleep(100); + /* Get shmem offset */ + shmem = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); + if (shmem == 0) { + BNX2X_ERR("Shmem 0 return failure\n"); + rc = -ENOTTY; + goto exit_lbl; + } -static void bnx2x_reset_common(struct bnx2x *bp) -{ - /* reset_common */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, - 0xd3ffff7f); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403); + validity_offset = offsetof(struct shmem_region, validity_map[0]); + + /* Wait for MCP to come up */ + for (cnt = 0; cnt < (MCP_TIMEOUT / MCP_ONE_TIMEOUT); cnt++) { + /* TBD: its best to check validity map of last port. + * currently checks on port 0. + */ + val = REG_RD(bp, shmem + validity_offset); + DP(NETIF_MSG_HW, "shmem 0x%x validity map(0x%x)=0x%x\n", shmem, + shmem + validity_offset, val); + + /* check that shared memory is valid. */ + if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + == (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + break; + + bnx2x_mcp_wait_one(bp); + } + + DP(NETIF_MSG_HW, "Cnt=%d Shmem validity map 0x%x\n", cnt, val); + + /* Check that shared memory is valid. This indicates that MCP is up. */ + if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != + (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) { + BNX2X_ERR("Shmem signature not present. MCP is not up !!\n"); + rc = -ENOTTY; + goto exit_lbl; + } + +exit_lbl: + /* Restore the `magic' bit value */ + if (!CHIP_IS_E1(bp)) + bnx2x_clp_reset_done(bp, magic_val); + + return rc; } -static void bnx2x_init_pxp(struct bnx2x *bp) +static void bnx2x_pxp_prep(struct bnx2x *bp) { - u16 devctl; - int r_order, w_order; - - pci_read_config_word(bp->pdev, - bp->pcie_cap + PCI_EXP_DEVCTL, &devctl); - DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl); - w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); - if (bp->mrrs == -1) - r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12); - else { - DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs); - r_order = bp->mrrs; + if (!CHIP_IS_E1(bp)) { + REG_WR(bp, PXP2_REG_RD_START_INIT, 0); + REG_WR(bp, PXP2_REG_RQ_RBC_DONE, 0); + REG_WR(bp, PXP2_REG_RQ_CFG_DONE, 0); + mmiowb(); } - - bnx2x_init_pxp_arb(bp, r_order, w_order); } -static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) +/* + * Reset the whole chip except for: + * - PCIE core + * - PCI Glue, PSWHST, PXP/PXP2 RF (all controlled by + * one reset bit) + * - IGU + * - MISC (including AEU) + * - GRC + * - RBCN, RBCP + */ +static void bnx2x_process_kill_chip_reset(struct bnx2x *bp) { - int is_required; - u32 val; - int port; - - if (BP_NOMCP(bp)) - return; - - is_required = 0; - val = SHMEM_RD(bp, dev_info.shared_hw_config.config2) & - SHARED_HW_CFG_FAN_FAILURE_MASK; + u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2; - if (val == SHARED_HW_CFG_FAN_FAILURE_ENABLED) - is_required = 1; + not_reset_mask1 = + MISC_REGISTERS_RESET_REG_1_RST_HC | + MISC_REGISTERS_RESET_REG_1_RST_PXPV | + MISC_REGISTERS_RESET_REG_1_RST_PXP; - /* - * The fan failure mechanism is usually related to the PHY type since - * the power consumption of the board is affected by the PHY. Currently, - * fan is required for most designs with SFX7101, BCM8727 and BCM8481. - */ - else if (val == SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE) - for (port = PORT_0; port < PORT_MAX; port++) { - u32 phy_type = - SHMEM_RD(bp, dev_info.port_hw_config[port]. - external_phy_config) & - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; - is_required |= - ((phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) || - (phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) || - (phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)); - } + not_reset_mask2 = + MISC_REGISTERS_RESET_REG_2_RST_MDIO | + MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE | + MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE | + MISC_REGISTERS_RESET_REG_2_RST_MISC_CORE | + MISC_REGISTERS_RESET_REG_2_RST_RBCN | + MISC_REGISTERS_RESET_REG_2_RST_GRC | + MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE | + MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B; - DP(NETIF_MSG_HW, "fan detection setting: %d\n", is_required); + reset_mask1 = 0xffffffff; - if (is_required == 0) - return; + if (CHIP_IS_E1(bp)) + reset_mask2 = 0xffff; + else + reset_mask2 = 0x1ffff; - /* Fan failure is indicated by SPIO 5 */ - bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5, - MISC_REGISTERS_SPIO_INPUT_HI_Z); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + reset_mask1 & (~not_reset_mask1)); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + reset_mask2 & (~not_reset_mask2)); - /* set to active low mode */ - val = REG_RD(bp, MISC_REG_SPIO_INT); - val |= ((1 << MISC_REGISTERS_SPIO_5) << - MISC_REGISTERS_SPIO_INT_OLD_SET_POS); - REG_WR(bp, MISC_REG_SPIO_INT, val); + barrier(); + mmiowb(); - /* enable interrupt to signal the IGU */ - val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN); - val |= (1 << MISC_REGISTERS_SPIO_5); - REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, reset_mask2); + mmiowb(); } -static int bnx2x_init_common(struct bnx2x *bp) +static int bnx2x_process_kill(struct bnx2x *bp) { - u32 val, i; -#ifdef BCM_CNIC - u32 wb_write[2]; -#endif - - DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp)); - - bnx2x_reset_common(bp); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); + int cnt = 1000; + u32 val = 0; + u32 sr_cnt, blk_cnt, port_is_idle_0, port_is_idle_1, pgl_exp_rom2; - bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) - REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp)); - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); - msleep(30); - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); + /* Empty the Tetris buffer, wait for 1s */ + do { + sr_cnt = REG_RD(bp, PXP2_REG_RD_SR_CNT); + blk_cnt = REG_RD(bp, PXP2_REG_RD_BLK_CNT); + port_is_idle_0 = REG_RD(bp, PXP2_REG_RD_PORT_IS_IDLE_0); + port_is_idle_1 = REG_RD(bp, PXP2_REG_RD_PORT_IS_IDLE_1); + pgl_exp_rom2 = REG_RD(bp, PXP2_REG_PGL_EXP_ROM2); + if ((sr_cnt == 0x7e) && (blk_cnt == 0xa0) && + ((port_is_idle_0 & 0x1) == 0x1) && + ((port_is_idle_1 & 0x1) == 0x1) && + (pgl_exp_rom2 == 0xffffffff)) + break; + msleep(1); + } while (cnt-- > 0); - bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1(bp)) { - /* enable HW interrupt from PXP on USDM overflow - bit 16 on INT_MASK_0 */ - REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); + if (cnt <= 0) { + DP(NETIF_MSG_HW, "Tetris buffer didn't get empty or there" + " are still" + " outstanding read requests after 1s!\n"); + DP(NETIF_MSG_HW, "sr_cnt=0x%08x, blk_cnt=0x%08x," + " port_is_idle_0=0x%08x," + " port_is_idle_1=0x%08x, pgl_exp_rom2=0x%08x\n", + sr_cnt, blk_cnt, port_is_idle_0, port_is_idle_1, + pgl_exp_rom2); + return -EAGAIN; } - bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE); - bnx2x_init_pxp(bp); - -#ifdef __BIG_ENDIAN - REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1); - REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1); - REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1); - REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1); - REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1); - /* make sure this value is 0 */ - REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0); + barrier(); -/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */ - REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1); - REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1); - REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1); - REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); -#endif + /* Close gates #2, #3 and #4 */ + bnx2x_set_234_gates(bp, true); - REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2); -#ifdef BCM_CNIC - REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5); -#endif + /* TBD: Indicate that "process kill" is in progress to MCP */ - if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) - REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1); + /* Clear "unprepared" bit */ + REG_WR(bp, MISC_REG_UNPREPARED, 0); + barrier(); - /* let the HW do it's magic ... */ - msleep(100); - /* finish PXP init */ - val = REG_RD(bp, PXP2_REG_RQ_CFG_DONE); - if (val != 1) { - BNX2X_ERR("PXP2 CFG failed\n"); - return -EBUSY; - } - val = REG_RD(bp, PXP2_REG_RD_INIT_DONE); - if (val != 1) { - BNX2X_ERR("PXP2 RD_INIT failed\n"); - return -EBUSY; - } + /* Make sure all is written to the chip before the reset */ + mmiowb(); - REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); - REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); + /* Wait for 1ms to empty GLUE and PCI-E core queues, + * PSWHST, GRC and PSWRD Tetris buffer. + */ + msleep(1); - bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE); + /* Prepare to chip reset: */ + /* MCP */ + bnx2x_reset_mcp_prep(bp, &val); - /* clean the DMAE memory */ - bp->dmae_ready = 1; - bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8); + /* PXP */ + bnx2x_pxp_prep(bp); + barrier(); - bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE); + /* reset the chip */ + bnx2x_process_kill_chip_reset(bp); + barrier(); - bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3); - bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3); - bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3); - bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3); + /* Recover after reset: */ + /* MCP */ + if (bnx2x_reset_mcp_comp(bp, val)) + return -EAGAIN; - bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); + /* PXP */ + bnx2x_pxp_prep(bp); -#ifdef BCM_CNIC - wb_write[0] = 0; - wb_write[1] = 0; - for (i = 0; i < 64; i++) { - REG_WR(bp, QM_REG_BASEADDR + i*4, 1024 * 4 * (i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, wb_write, 2); + /* Open the gates #2, #3 and #4 */ + bnx2x_set_234_gates(bp, false); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, 1024*4*(i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, - wb_write, 2); - } - } -#endif - /* soft reset pulse */ - REG_WR(bp, QM_REG_SOFT_RESET, 1); - REG_WR(bp, QM_REG_SOFT_RESET, 0); + /* TBD: IGU/AEU preparation bring back the AEU/IGU to a + * reset state, re-enable attentions. */ -#ifdef BCM_CNIC - bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE); -#endif + return 0; +} - bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE); - REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT); - if (!CHIP_REV_IS_SLOW(bp)) { - /* enable hw interrupt from doorbell Q */ - REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); +static int bnx2x_leader_reset(struct bnx2x *bp) +{ + int rc = 0; + /* Try to recover after the failure */ + if (bnx2x_process_kill(bp)) { + printk(KERN_ERR "%s: Something bad had happen! Aii!\n", + bp->dev->name); + rc = -EAGAIN; + goto exit_leader_reset; } - bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); - REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); -#ifndef BCM_CNIC - /* set NIC mode */ - REG_WR(bp, PRS_REG_NIC_MODE, 1); -#endif - if (CHIP_IS_E1H(bp)) - REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); + /* Clear "reset is in progress" bit and update the driver state */ + bnx2x_set_reset_done(bp); + bp->recovery_state = BNX2X_RECOVERY_DONE; - bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE); +exit_leader_reset: + bp->is_leader = 0; + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08); + smp_wmb(); + return rc; +} - bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); - bnx2x_init_fill(bp, USEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); - bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp)); +static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); - bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE); +/* Assumption: runs under rtnl lock. This together with the fact + * that it's called only from bnx2x_reset_task() ensure that it + * will never be called when netif_running(bp->dev) is false. + */ +static void bnx2x_parity_recover(struct bnx2x *bp) +{ + DP(NETIF_MSG_HW, "Handling parity\n"); + while (1) { + switch (bp->recovery_state) { + case BNX2X_RECOVERY_INIT: + DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n"); + /* Try to get a LEADER_LOCK HW lock */ + if (bnx2x_trylock_hw_lock(bp, + HW_LOCK_RESOURCE_RESERVED_08)) + bp->is_leader = 1; - /* sync semi rtc */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, - 0x80000000); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, - 0x80000000); + /* Stop the driver */ + /* If interface has been removed - break */ + if (bnx2x_nic_unload(bp, UNLOAD_RECOVERY)) + return; - bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); + bp->recovery_state = BNX2X_RECOVERY_WAIT; + /* Ensure "is_leader" and "recovery_state" + * update values are seen on other CPUs + */ + smp_wmb(); + break; - REG_WR(bp, SRC_REG_SOFT_RST, 1); - for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) - REG_WR(bp, i, random32()); - bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE); -#ifdef BCM_CNIC - REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); - REG_WR(bp, SRC_REG_KEYSEARCH_1, 0x24b8f2cc); - REG_WR(bp, SRC_REG_KEYSEARCH_2, 0x223aef9b); - REG_WR(bp, SRC_REG_KEYSEARCH_3, 0x26001e3a); - REG_WR(bp, SRC_REG_KEYSEARCH_4, 0x7ae91116); - REG_WR(bp, SRC_REG_KEYSEARCH_5, 0x5ce5230b); - REG_WR(bp, SRC_REG_KEYSEARCH_6, 0x298d8adf); - REG_WR(bp, SRC_REG_KEYSEARCH_7, 0x6eb0ff09); - REG_WR(bp, SRC_REG_KEYSEARCH_8, 0x1830f82f); - REG_WR(bp, SRC_REG_KEYSEARCH_9, 0x01e46be7); -#endif - REG_WR(bp, SRC_REG_SOFT_RST, 0); + case BNX2X_RECOVERY_WAIT: + DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_WAIT\n"); + if (bp->is_leader) { + u32 load_counter = bnx2x_get_load_cnt(bp); + if (load_counter) { + /* Wait until all other functions get + * down. + */ + schedule_delayed_work(&bp->reset_task, + HZ/10); + return; + } else { + /* If all other functions got down - + * try to bring the chip back to + * normal. In any case it's an exit + * point for a leader. + */ + if (bnx2x_leader_reset(bp) || + bnx2x_nic_load(bp, LOAD_NORMAL)) { + printk(KERN_ERR"%s: Recovery " + "has failed. Power cycle is " + "needed.\n", bp->dev->name); + /* Disconnect this device */ + netif_device_detach(bp->dev); + /* Block ifup for all function + * of this ASIC until + * "process kill" or power + * cycle. + */ + bnx2x_set_reset_in_progress(bp); + /* Shut down the power */ + bnx2x_set_power_state(bp, + PCI_D3hot); + return; + } - if (sizeof(union cdu_context) != 1024) - /* we currently assume that a context is 1024 bytes */ - dev_alert(&bp->pdev->dev, "please adjust the size " - "of cdu_context(%ld)\n", - (long)sizeof(union cdu_context)); + return; + } + } else { /* non-leader */ + if (!bnx2x_reset_is_done(bp)) { + /* Try to get a LEADER_LOCK HW lock as + * long as a former leader may have + * been unloaded by the user or + * released a leadership by another + * reason. + */ + if (bnx2x_trylock_hw_lock(bp, + HW_LOCK_RESOURCE_RESERVED_08)) { + /* I'm a leader now! Restart a + * switch case. + */ + bp->is_leader = 1; + break; + } - bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE); - val = (4 << 24) + (0 << 12) + 1024; - REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val); + schedule_delayed_work(&bp->reset_task, + HZ/10); + return; - bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE); - REG_WR(bp, CFC_REG_INIT_REG, 0x7FF); - /* enable context validation interrupt from CFC */ - REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); + } else { /* A leader has completed + * the "process kill". It's an exit + * point for a non-leader. + */ + bnx2x_nic_load(bp, LOAD_NORMAL); + bp->recovery_state = + BNX2X_RECOVERY_DONE; + smp_wmb(); + return; + } + } + default: + return; + } + } +} - /* set the thresholds to prevent CFC/CDU race */ - REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); +/* bnx2x_nic_unload() flushes the bnx2x_wq, thus reset task is + * scheduled on a general queue in order to prevent a dead lock. + */ +static void bnx2x_reset_task(struct work_struct *work) +{ + struct bnx2x *bp = container_of(work, struct bnx2x, reset_task.work); - bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE); +#ifdef BNX2X_STOP_ON_ERROR + BNX2X_ERR("reset task called but STOP_ON_ERROR defined" + " so reset not done to allow debug dump,\n" + KERN_ERR " you will need to reboot when done\n"); + return; +#endif - bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE); - /* Reset PCIE errors for debug */ - REG_WR(bp, 0x2814, 0xffffffff); - REG_WR(bp, 0x3820, 0xffffffff); + rtnl_lock(); - bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE); + if (!netif_running(bp->dev)) + goto reset_task_exit; - bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp)); - REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp)); + if (unlikely(bp->recovery_state != BNX2X_RECOVERY_DONE)) + bnx2x_parity_recover(bp); + else { + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + bnx2x_nic_load(bp, LOAD_NORMAL); } - if (CHIP_REV_IS_SLOW(bp)) - msleep(200); +reset_task_exit: + rtnl_unlock(); +} - /* finish CFC init */ - val = reg_poll(bp, CFC_REG_LL_INIT_DONE, 1, 100, 10); - if (val != 1) { - BNX2X_ERR("CFC LL_INIT failed\n"); - return -EBUSY; - } - val = reg_poll(bp, CFC_REG_AC_INIT_DONE, 1, 100, 10); - if (val != 1) { - BNX2X_ERR("CFC AC_INIT failed\n"); - return -EBUSY; - } - val = reg_poll(bp, CFC_REG_CAM_INIT_DONE, 1, 100, 10); - if (val != 1) { - BNX2X_ERR("CFC CAM_INIT failed\n"); - return -EBUSY; - } - REG_WR(bp, CFC_REG_DEBUG0, 0); +/* end of nic load/unload */ - /* read NIG statistic - to see if this is our first up since powerup */ - bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); - val = *bnx2x_sp(bp, wb_data[0]); +/* ethtool_ops */ - /* do internal memory self test */ - if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) { - BNX2X_ERR("internal mem self test failed\n"); - return -EBUSY; +/* + * Init service functions + */ + +static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func) +{ + switch (func) { + case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0; + case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1; + case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2; + case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3; + case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4; + case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5; + case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6; + case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7; + default: + BNX2X_ERR("Unsupported function index: %d\n", func); + return (u32)(-1); } +} - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - bp->port.need_hw_lock = 1; - break; +static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) +{ + u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val; - default: - break; - } + /* Flush all outstanding writes */ + mmiowb(); - bnx2x_setup_fan_failure_detection(bp); + /* Pretend to be function 0 */ + REG_WR(bp, reg, 0); + /* Flush the GRC transaction (in the chip) */ + new_val = REG_RD(bp, reg); + if (new_val != 0) { + BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n", + new_val); + BUG(); + } - /* clear PXP2 attentions */ - REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0); + /* From now we are in the "like-E1" mode */ + bnx2x_int_disable(bp); - enable_blocks_attention(bp); - if (CHIP_PARITY_SUPPORTED(bp)) - enable_blocks_parity(bp); + /* Flush all outstanding writes */ + mmiowb(); - if (!BP_NOMCP(bp)) { - bnx2x_acquire_phy_lock(bp); - bnx2x_common_init_phy(bp, bp->common.shmem_base); - bnx2x_release_phy_lock(bp); - } else - BNX2X_ERR("Bootcode is missing - can not initialize link\n"); + /* Restore the original funtion settings */ + REG_WR(bp, reg, orig_func); + new_val = REG_RD(bp, reg); + if (new_val != orig_func) { + BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n", + orig_func, new_val); + BUG(); + } +} - return 0; +static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func) +{ + if (CHIP_IS_E1H(bp)) + bnx2x_undi_int_disable_e1h(bp, func); + else + bnx2x_int_disable(bp); } -static int bnx2x_init_port(struct bnx2x *bp) +static void __devinit bnx2x_undi_unload(struct bnx2x *bp) { - int port = BP_PORT(bp); - int init_stage = port ? PORT1_STAGE : PORT0_STAGE; - u32 low, high; u32 val; - DP(BNX2X_MSG_MCP, "starting port init port %d\n", port); + /* Check if there is any driver already loaded */ + val = REG_RD(bp, MISC_REG_UNPREPARED); + if (val == 0x1) { + /* Check if it is the UNDI driver + * UNDI driver initializes CID offset for normal bell to 0x7 + */ + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); + val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); + if (val == 0x7) { + u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + /* save our func */ + int func = BP_FUNC(bp); + u32 swap_en; + u32 swap_val; - REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); + /* clear the UNDI indication */ + REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); - bnx2x_init_block(bp, PXP_BLOCK, init_stage); - bnx2x_init_block(bp, PXP2_BLOCK, init_stage); + BNX2X_DEV_INFO("UNDI is active! reset device\n"); - bnx2x_init_block(bp, TCM_BLOCK, init_stage); - bnx2x_init_block(bp, UCM_BLOCK, init_stage); - bnx2x_init_block(bp, CCM_BLOCK, init_stage); - bnx2x_init_block(bp, XCM_BLOCK, init_stage); + /* try unload UNDI on port 0 */ + bp->func = 0; + bp->fw_seq = + (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + reset_code = bnx2x_fw_command(bp, reset_code); -#ifdef BCM_CNIC - REG_WR(bp, QM_REG_CONNNUM_0 + port*4, 1024/16 - 1); + /* if UNDI is loaded on the other port */ + if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { - bnx2x_init_block(bp, TIMERS_BLOCK, init_stage); - REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); - REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); -#endif + /* send "DONE" for previous unload */ + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); - bnx2x_init_block(bp, DQ_BLOCK, init_stage); + /* unload UNDI on port 1 */ + bp->func = 1; + bp->fw_seq = + (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - bnx2x_init_block(bp, BRB1_BLOCK, init_stage); - if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { - /* no pause for emulation and FPGA */ - low = 0; - high = 513; - } else { - if (IS_E1HMF(bp)) - low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); - else if (bp->dev->mtu > 4096) { - if (bp->flags & ONE_PORT_FLAG) - low = 160; - else { - val = bp->dev->mtu; - /* (24*1024 + val*4)/256 */ - low = 96 + (val/64) + ((val % 64) ? 1 : 0); + bnx2x_fw_command(bp, reset_code); } + + /* now it's safe to release the lock */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); + + bnx2x_undi_int_disable(bp, func); + + /* close input traffic and wait for it */ + /* Do not rcv packets to BRB */ + REG_WR(bp, + (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK), 0x0); + /* Do not direct rcv packets that are not for MCP to + * the BRB */ + REG_WR(bp, + (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_NOT_MCP : + NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); + /* clear AEU */ + REG_WR(bp, + (BP_PORT(bp) ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0), 0); + msleep(10); + + /* save NIG port swap info */ + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_en = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + /* reset device */ + REG_WR(bp, + GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + 0xd3ffffff); + REG_WR(bp, + GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + 0x1403); + /* take the NIG out of reset and restore swap values */ + REG_WR(bp, + GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + MISC_REGISTERS_RESET_REG_1_RST_NIG); + REG_WR(bp, NIG_REG_PORT_SWAP, swap_val); + REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en); + + /* send unload done to the MCP */ + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + + /* restore our func and fw_seq */ + bp->func = func; + bp->fw_seq = + (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + } else - low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); - high = low + 56; /* 14*1024/256 */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); } - REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); - REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); +} +static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) +{ + u32 val, val2, val3, val4, id; + u16 pmc; - bnx2x_init_block(bp, PRS_BLOCK, init_stage); + /* Get the chip revision id and number. */ + /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ + val = REG_RD(bp, MISC_REG_CHIP_NUM); + id = ((val & 0xffff) << 16); + val = REG_RD(bp, MISC_REG_CHIP_REV); + id |= ((val & 0xf) << 12); + val = REG_RD(bp, MISC_REG_CHIP_METAL); + id |= ((val & 0xff) << 4); + val = REG_RD(bp, MISC_REG_BOND_ID); + id |= (val & 0xf); + bp->common.chip_id = id; + bp->link_params.chip_id = bp->common.chip_id; + BNX2X_DEV_INFO("chip ID is 0x%x\n", id); - bnx2x_init_block(bp, TSDM_BLOCK, init_stage); - bnx2x_init_block(bp, CSDM_BLOCK, init_stage); - bnx2x_init_block(bp, USDM_BLOCK, init_stage); - bnx2x_init_block(bp, XSDM_BLOCK, init_stage); + val = (REG_RD(bp, 0x2874) & 0x55); + if ((bp->common.chip_id & 0x1) || + (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) { + bp->flags |= ONE_PORT_FLAG; + BNX2X_DEV_INFO("single port device\n"); + } - bnx2x_init_block(bp, TSEM_BLOCK, init_stage); - bnx2x_init_block(bp, USEM_BLOCK, init_stage); - bnx2x_init_block(bp, CSEM_BLOCK, init_stage); - bnx2x_init_block(bp, XSEM_BLOCK, init_stage); + val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4); + bp->common.flash_size = (NVRAM_1MB_SIZE << + (val & MCPR_NVM_CFG4_FLASH_SIZE)); + BNX2X_DEV_INFO("flash_size 0x%x (%d)\n", + bp->common.flash_size, bp->common.flash_size); - bnx2x_init_block(bp, UPB_BLOCK, init_stage); - bnx2x_init_block(bp, XPB_BLOCK, init_stage); + bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); + bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); + bp->link_params.shmem_base = bp->common.shmem_base; + BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", + bp->common.shmem_base, bp->common.shmem2_base); - bnx2x_init_block(bp, PBF_BLOCK, init_stage); + if (!bp->common.shmem_base || + (bp->common.shmem_base < 0xA0000) || + (bp->common.shmem_base >= 0xC0000)) { + BNX2X_DEV_INFO("MCP not active\n"); + bp->flags |= NO_MCP_FLAG; + return; + } - /* configure PBF to work without PAUSE mtu 9000 */ - REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); + val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); + if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + BNX2X_ERROR("BAD MCP validity signature\n"); + + bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); + BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config); + + bp->link_params.hw_led_mode = ((bp->common.hw_config & + SHARED_HW_CFG_LED_MODE_MASK) >> + SHARED_HW_CFG_LED_MODE_SHIFT); + + bp->link_params.feature_config_flags = 0; + val = SHMEM_RD(bp, dev_info.shared_feature_config.config); + if (val & SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED) + bp->link_params.feature_config_flags |= + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED; + else + bp->link_params.feature_config_flags &= + ~FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED; + + val = SHMEM_RD(bp, dev_info.bc_rev) >> 8; + bp->common.bc_ver = val; + BNX2X_DEV_INFO("bc_ver %X\n", val); + if (val < BNX2X_BC_VER) { + /* for now only warn + * later we might need to enforce this */ + BNX2X_ERROR("This driver needs bc_ver %X but found %X, " + "please upgrade BC\n", BNX2X_BC_VER, val); + } + bp->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ? + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; - /* update threshold */ - REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); - /* update init credit */ - REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); + if (BP_E1HVN(bp) == 0) { + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc); + bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG; + } else { + /* no WOL capability for E1HVN != 0 */ + bp->flags |= NO_WOL_FLAG; + } + BNX2X_DEV_INFO("%sWoL capable\n", + (bp->flags & NO_WOL_FLAG) ? "not " : ""); - /* probe changes */ - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); - msleep(5); - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num); + val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]); + val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]); + val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]); -#ifdef BCM_CNIC - bnx2x_init_block(bp, SRCH_BLOCK, init_stage); -#endif - bnx2x_init_block(bp, CDU_BLOCK, init_stage); - bnx2x_init_block(bp, CFC_BLOCK, init_stage); + dev_info(&bp->pdev->dev, "part number %X-%X-%X-%X\n", + val, val2, val3, val4); +} - if (CHIP_IS_E1(bp)) { - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); - } - bnx2x_init_block(bp, HC_BLOCK, init_stage); +static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, + u32 switch_cfg) +{ + int port = BP_PORT(bp); + u32 ext_phy_type; - bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage); - /* init aeu_mask_attn_func_0/1: - * - SF mode: bits 3-7 are masked. only bits 0-2 are in use - * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF - * bits 4-7 are used for "per vn group attention" */ - REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, - (IS_E1HMF(bp) ? 0xF7 : 0x7)); + switch (switch_cfg) { + case SWITCH_CFG_1G: + BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg); - bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); - bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); - bnx2x_init_block(bp, EMAC1_BLOCK, init_stage); - bnx2x_init_block(bp, DBU_BLOCK, init_stage); - bnx2x_init_block(bp, DBG_BLOCK, init_stage); + ext_phy_type = + SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config); + switch (ext_phy_type) { + case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: + BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", + ext_phy_type); - bnx2x_init_block(bp, NIG_BLOCK, init_stage); + bp->port.supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_TP | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); + case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: + BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n", + ext_phy_type); - if (CHIP_IS_E1H(bp)) { - /* 0x2 disable e1hov, 0x1 enable */ - REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, - (IS_E1HMF(bp) ? 0x1 : 0x2)); + bp->port.supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_TP | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - { - REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); - REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0); - REG_WR(bp, NIG_REG_PAUSE_ENABLE_0 + port*4, 1); + default: + BNX2X_ERR("NVRAM config error. " + "BAD SerDes ext_phy_config 0x%x\n", + bp->link_params.ext_phy_config); + return; } - } - bnx2x_init_block(bp, MCP_BLOCK, init_stage); - bnx2x_init_block(bp, DMAE_BLOCK, init_stage); + bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + + port*0x10); + BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); + break; - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - { - u32 swap_val, swap_override, aeu_gpio_mask, offset; + case SWITCH_CFG_10G: + BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INPUT_HI_Z, port); + ext_phy_type = + XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); + switch (ext_phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", + ext_phy_type); - /* The GPIO should be swapped if the swap register is - set and active */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + bp->port.supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - /* Select function upon port-swap configuration */ - if (port == 0) { - offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; - } else { - offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; - } - val = REG_RD(bp, offset); - /* add GPIO3 to group */ - val |= aeu_gpio_mask; - REG_WR(bp, offset, val); - } - break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", + ext_phy_type); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - /* add SPIO 5 to group 0 */ - { - u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : - MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); - val = REG_RD(bp, reg_addr); - val |= AEU_INPUTS_ATTN_BITS_SPIO5; - REG_WR(bp, reg_addr, val); - } - break; + bp->port.supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - default: - break; - } + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", + ext_phy_type); - bnx2x__link_reset(bp); + bp->port.supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - return 0; -} + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", + ext_phy_type); -#define ILT_PER_FUNC (768/2) -#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) -/* the phys address is shifted right 12 bits and has an added - 1=valid bit added to the 53rd bit - then since this is a wide register(TM) - we split it into two 32 bit writes - */ -#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) -#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) -#define PXP_ONE_ILT(x) (((x) << 10) | x) -#define PXP_ILT_RANGE(f, l) (((l) << 10) | f) + bp->port.supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; -#ifdef BCM_CNIC -#define CNIC_ILT_LINES 127 -#define CNIC_CTX_PER_ILT 16 -#else -#define CNIC_ILT_LINES 0 -#endif + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", + ext_phy_type); -static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) -{ - int reg; + bp->port.supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - if (CHIP_IS_E1H(bp)) - reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; - else /* E1 */ - reg = PXP2_REG_RQ_ONCHIP_AT + index*8; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n", + ext_phy_type); + + bp->port.supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr)); -} + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n", + ext_phy_type); -static int bnx2x_init_func(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - u32 addr, val; - int i; + bp->port.supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n", + ext_phy_type); - /* set MSI reconfigure capability */ - addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); - val = REG_RD(bp, addr); - val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; - REG_WR(bp, addr, val); + bp->port.supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; - i = FUNC_ILT_BASE(func); + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: + BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n", + ext_phy_type); - bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context)); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES); - } else /* E1 */ - REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, - PXP_ILT_RANGE(i, i + CNIC_ILT_LINES)); + bp->port.supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; -#ifdef BCM_CNIC - i += 1 + CNIC_ILT_LINES; - bnx2x_ilt_wr(bp, i, bp->timers_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_TM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_TM_LAST_ILT, i); - } + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: + BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", + bp->link_params.ext_phy_config); + break; - i++; - bnx2x_ilt_wr(bp, i, bp->qm_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_QM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_QM_LAST_ILT, i); - } + default: + BNX2X_ERR("NVRAM config error. " + "BAD XGXS ext_phy_config 0x%x\n", + bp->link_params.ext_phy_config); + return; + } - i++; - bnx2x_ilt_wr(bp, i, bp->t1_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_SRC_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_SRC_LAST_ILT, i); - } + bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + + port*0x18); + BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - /* tell the searcher where the T2 table is */ - REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, 16*1024/64); + break; - bnx2x_wb_wr(bp, SRC_REG_FIRSTFREE0 + port*16, - U64_LO(bp->t2_mapping), U64_HI(bp->t2_mapping)); + default: + BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", + bp->port.link_config); + return; + } + bp->link_params.phy_addr = bp->port.phy_addr; - bnx2x_wb_wr(bp, SRC_REG_LASTFREE0 + port*16, - U64_LO((u64)bp->t2_mapping + 16*1024 - 64), - U64_HI((u64)bp->t2_mapping + 16*1024 - 64)); + /* mask what we support according to speed_cap_mask */ + if (!(bp->link_params.speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) + bp->port.supported &= ~SUPPORTED_10baseT_Half; - REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, 10); -#endif + if (!(bp->link_params.speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL)) + bp->port.supported &= ~SUPPORTED_10baseT_Full; - if (CHIP_IS_E1H(bp)) { - bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + if (!(bp->link_params.speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) + bp->port.supported &= ~SUPPORTED_100baseT_Half; - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); - REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); - } + if (!(bp->link_params.speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL)) + bp->port.supported &= ~SUPPORTED_100baseT_Full; - /* HC init per function */ - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); + if (!(bp->link_params.speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) + bp->port.supported &= ~(SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); - } - bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); + if (!(bp->link_params.speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) + bp->port.supported &= ~SUPPORTED_2500baseX_Full; - /* Reset PCIE errors for debug */ - REG_WR(bp, 0x2114, 0xffffffff); - REG_WR(bp, 0x2120, 0xffffffff); + if (!(bp->link_params.speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) + bp->port.supported &= ~SUPPORTED_10000baseT_Full; - return 0; + BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported); } -int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) +static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) { - int i, rc = 0; + bp->link_params.req_duplex = DUPLEX_FULL; - DP(BNX2X_MSG_MCP, "function %d load_code %x\n", - BP_FUNC(bp), load_code); + switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) { + case PORT_FEATURE_LINK_SPEED_AUTO: + if (bp->port.supported & SUPPORTED_Autoneg) { + bp->link_params.req_line_speed = SPEED_AUTO_NEG; + bp->port.advertising = bp->port.supported; + } else { + u32 ext_phy_type = + XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - bp->dmae_ready = 0; - mutex_init(&bp->dmae_mutex); - rc = bnx2x_gunzip_init(bp); - if (rc) - return rc; + if ((ext_phy_type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || + (ext_phy_type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) { + /* force 10G, no AN */ + bp->link_params.req_line_speed = SPEED_10000; + bp->port.advertising = + (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + break; + } + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " Autoneg not supported\n", + bp->port.link_config); + return; + } + break; - switch (load_code) { - case FW_MSG_CODE_DRV_LOAD_COMMON: - rc = bnx2x_init_common(bp); - if (rc) - goto init_hw_err; - /* no break */ + case PORT_FEATURE_LINK_SPEED_10M_FULL: + if (bp->port.supported & SUPPORTED_10baseT_Full) { + bp->link_params.req_line_speed = SPEED_10; + bp->port.advertising = (ADVERTISED_10baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->port.link_config, + bp->link_params.speed_cap_mask); + return; + } + break; - case FW_MSG_CODE_DRV_LOAD_PORT: - bp->dmae_ready = 1; - rc = bnx2x_init_port(bp); - if (rc) - goto init_hw_err; - /* no break */ + case PORT_FEATURE_LINK_SPEED_10M_HALF: + if (bp->port.supported & SUPPORTED_10baseT_Half) { + bp->link_params.req_line_speed = SPEED_10; + bp->link_params.req_duplex = DUPLEX_HALF; + bp->port.advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->port.link_config, + bp->link_params.speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_100M_FULL: + if (bp->port.supported & SUPPORTED_100baseT_Full) { + bp->link_params.req_line_speed = SPEED_100; + bp->port.advertising = (ADVERTISED_100baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->port.link_config, + bp->link_params.speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_100M_HALF: + if (bp->port.supported & SUPPORTED_100baseT_Half) { + bp->link_params.req_line_speed = SPEED_100; + bp->link_params.req_duplex = DUPLEX_HALF; + bp->port.advertising = (ADVERTISED_100baseT_Half | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->port.link_config, + bp->link_params.speed_cap_mask); + return; + } + break; - case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bp->dmae_ready = 1; - rc = bnx2x_init_func(bp); - if (rc) - goto init_hw_err; + case PORT_FEATURE_LINK_SPEED_1G: + if (bp->port.supported & SUPPORTED_1000baseT_Full) { + bp->link_params.req_line_speed = SPEED_1000; + bp->port.advertising = (ADVERTISED_1000baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->port.link_config, + bp->link_params.speed_cap_mask); + return; + } break; - default: - BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code); + case PORT_FEATURE_LINK_SPEED_2_5G: + if (bp->port.supported & SUPPORTED_2500baseX_Full) { + bp->link_params.req_line_speed = SPEED_2500; + bp->port.advertising = (ADVERTISED_2500baseX_Full | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->port.link_config, + bp->link_params.speed_cap_mask); + return; + } break; - } - if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); + case PORT_FEATURE_LINK_SPEED_10G_CX4: + case PORT_FEATURE_LINK_SPEED_10G_KX4: + case PORT_FEATURE_LINK_SPEED_10G_KR: + if (bp->port.supported & SUPPORTED_10000baseT_Full) { + bp->link_params.req_line_speed = SPEED_10000; + bp->port.advertising = (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->port.link_config, + bp->link_params.speed_cap_mask); + return; + } + break; - bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) & - DRV_PULSE_SEQ_MASK); - DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); + default: + BNX2X_ERROR("NVRAM config error. " + "BAD link speed link_config 0x%x\n", + bp->port.link_config); + bp->link_params.req_line_speed = SPEED_AUTO_NEG; + bp->port.advertising = bp->port.supported; + break; } - /* this needs to be done before gunzip end */ - bnx2x_zero_def_sb(bp); - for_each_queue(bp, i) - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#ifdef BCM_CNIC - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#endif - -init_hw_err: - bnx2x_gunzip_end(bp); + bp->link_params.req_flow_ctrl = (bp->port.link_config & + PORT_FEATURE_FLOW_CONTROL_MASK); + if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && + !(bp->port.supported & SUPPORTED_Autoneg)) + bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; - return rc; + BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x" + " advertising 0x%x\n", + bp->link_params.req_line_speed, + bp->link_params.req_duplex, + bp->link_params.req_flow_ctrl, bp->port.advertising); } -void bnx2x_free_mem(struct bnx2x *bp) +static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) { - -#define BNX2X_PCI_FREE(x, y, size) \ - do { \ - if (x) { \ - dma_free_coherent(&bp->pdev->dev, size, x, y); \ - x = NULL; \ - y = 0; \ - } \ - } while (0) - -#define BNX2X_FREE(x) \ - do { \ - if (x) { \ - vfree(x); \ - x = NULL; \ - } \ - } while (0) - - int i; - - /* fastpath */ - /* Common */ - for_each_queue(bp, i) { - - /* status blocks */ - BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk), - bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); - } - /* Rx */ - for_each_queue(bp, i) { - - /* fastpath rx rings: rx_buf rx_desc rx_comp */ - BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring)); - BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring), - bnx2x_fp(bp, i, rx_desc_mapping), - sizeof(struct eth_rx_bd) * NUM_RX_BD); - - BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring), - bnx2x_fp(bp, i, rx_comp_mapping), - sizeof(struct eth_fast_path_rx_cqe) * - NUM_RCQ_BD); - - /* SGE ring */ - BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring)); - BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring), - bnx2x_fp(bp, i, rx_sge_mapping), - BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); - } - /* Tx */ - for_each_queue(bp, i) { - - /* fastpath tx rings: tx_buf tx_desc */ - BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring)); - BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring), - bnx2x_fp(bp, i, tx_desc_mapping), - sizeof(union eth_tx_bd_types) * NUM_TX_BD); - } - /* end of fastpath */ - - BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); - - BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, - sizeof(struct bnx2x_slowpath)); - -#ifdef BCM_CNIC - BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024); - BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024); - BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024); - BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024); - BNX2X_PCI_FREE(bp->cnic_sb, bp->cnic_sb_mapping, - sizeof(struct host_status_block)); -#endif - BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); - -#undef BNX2X_PCI_FREE -#undef BNX2X_KFREE + mac_hi = cpu_to_be16(mac_hi); + mac_lo = cpu_to_be32(mac_lo); + memcpy(mac_buf, &mac_hi, sizeof(mac_hi)); + memcpy(mac_buf + sizeof(mac_hi), &mac_lo, sizeof(mac_lo)); } -int bnx2x_alloc_mem(struct bnx2x *bp) +static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) { + int port = BP_PORT(bp); + u32 val, val2; + u32 config; + u16 i; + u32 ext_phy_type; -#define BNX2X_PCI_ALLOC(x, y, size) \ - do { \ - x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ - if (x == NULL) \ - goto alloc_mem_err; \ - memset(x, 0, size); \ - } while (0) - -#define BNX2X_ALLOC(x, size) \ - do { \ - x = vmalloc(size); \ - if (x == NULL) \ - goto alloc_mem_err; \ - memset(x, 0, size); \ - } while (0) - - int i; - - /* fastpath */ - /* Common */ - for_each_queue(bp, i) { - bnx2x_fp(bp, i, bp) = bp; + bp->link_params.bp = bp; + bp->link_params.port = port; - /* status blocks */ - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk), - &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); + bp->link_params.lane_config = + SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); + bp->link_params.ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + /* BCM8727_NOC => BCM8727 no over current */ + if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) { + bp->link_params.ext_phy_config &= + ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; + bp->link_params.ext_phy_config |= + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727; + bp->link_params.feature_config_flags |= + FEATURE_CONFIG_BCM8727_NOC; } - /* Rx */ - for_each_queue(bp, i) { - /* fastpath rx rings: rx_buf rx_desc rx_comp */ - BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring), - sizeof(struct sw_rx_bd) * NUM_RX_BD); - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring), - &bnx2x_fp(bp, i, rx_desc_mapping), - sizeof(struct eth_rx_bd) * NUM_RX_BD); + bp->link_params.speed_cap_mask = + SHMEM_RD(bp, + dev_info.port_hw_config[port].speed_capability_mask); - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring), - &bnx2x_fp(bp, i, rx_comp_mapping), - sizeof(struct eth_fast_path_rx_cqe) * - NUM_RCQ_BD); + bp->port.link_config = + SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); - /* SGE ring */ - BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring), - sizeof(struct sw_rx_page) * NUM_RX_SGE); - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring), - &bnx2x_fp(bp, i, rx_sge_mapping), - BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); - } - /* Tx */ - for_each_queue(bp, i) { + /* Get the 4 lanes xgxs config rx and tx */ + for (i = 0; i < 2; i++) { + val = SHMEM_RD(bp, + dev_info.port_hw_config[port].xgxs_config_rx[i<<1]); + bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff); + bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff); - /* fastpath tx rings: tx_buf tx_desc */ - BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring), - sizeof(struct sw_tx_bd) * NUM_TX_BD); - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring), - &bnx2x_fp(bp, i, tx_desc_mapping), - sizeof(union eth_tx_bd_types) * NUM_TX_BD); + val = SHMEM_RD(bp, + dev_info.port_hw_config[port].xgxs_config_tx[i<<1]); + bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff); + bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff); } - /* end of fastpath */ - BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); + /* If the device is capable of WoL, set the default state according + * to the HW + */ + config = SHMEM_RD(bp, dev_info.port_feature_config[port].config); + bp->wol = (!(bp->flags & NO_WOL_FLAG) && + (config & PORT_FEATURE_WOL_ENABLED)); - BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, - sizeof(struct bnx2x_slowpath)); + BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x" + " speed_cap_mask 0x%08x link_config 0x%08x\n", + bp->link_params.lane_config, + bp->link_params.ext_phy_config, + bp->link_params.speed_cap_mask, bp->port.link_config); -#ifdef BCM_CNIC - BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024); + bp->link_params.switch_cfg |= (bp->port.link_config & + PORT_FEATURE_CONNECTED_SWITCH_MASK); + bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); - /* allocate searcher T2 table - we allocate 1/4 of alloc num for T2 - (which is not entered into the ILT) */ - BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024); + bnx2x_link_settings_requested(bp); - /* Initialize T2 (for 1024 connections) */ - for (i = 0; i < 16*1024; i += 64) - *(u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; + /* + * If connected directly, work with the internal PHY, otherwise, work + * with the external PHY + */ + ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); + if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) + bp->mdio.prtad = bp->link_params.phy_addr; - /* Timer block array (8*MAX_CONN) phys uncached for now 1024 conns */ - BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024); + else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && + (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) + bp->mdio.prtad = + XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); - /* QM queues (128*MAX_CONN) */ - BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024); + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); + bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); + memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); + memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); - BNX2X_PCI_ALLOC(bp->cnic_sb, &bp->cnic_sb_mapping, - sizeof(struct host_status_block)); +#ifdef BCM_CNIC + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_lower); + bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); #endif +} - /* Slow path ring */ - BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE); - - return 0; +static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + u32 val, val2; + int rc = 0; -alloc_mem_err: - bnx2x_free_mem(bp); - return -ENOMEM; + bnx2x_get_common_hwinfo(bp); -#undef BNX2X_PCI_ALLOC -#undef BNX2X_ALLOC -} + bp->e1hov = 0; + bp->e1hmf = 0; + if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { + bp->mf_config = + SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + val = (SHMEM_RD(bp, mf_cfg.func_mf_config[FUNC_0].e1hov_tag) & + FUNC_MF_CFG_E1HOV_TAG_MASK); + if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) + bp->e1hmf = 1; + BNX2X_DEV_INFO("%s function mode\n", + IS_E1HMF(bp) ? "multi" : "single"); -/* - * Init service functions - */ + if (IS_E1HMF(bp)) { + val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func]. + e1hov_tag) & + FUNC_MF_CFG_E1HOV_TAG_MASK); + if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { + bp->e1hov = val; + BNX2X_DEV_INFO("E1HOV for func %d is %d " + "(0x%04x)\n", + func, bp->e1hov, bp->e1hov); + } else { + BNX2X_ERROR("No valid E1HOV for func %d," + " aborting\n", func); + rc = -EPERM; + } + } else { + if (BP_E1HVN(bp)) { + BNX2X_ERROR("VN %d in single function mode," + " aborting\n", BP_E1HVN(bp)); + rc = -EPERM; + } + } + } -/** - * Sets a MAC in a CAM for a few L2 Clients for E1 chip - * - * @param bp driver descriptor - * @param set set or clear an entry (1 or 0) - * @param mac pointer to a buffer containing a MAC - * @param cl_bit_vec bit vector of clients to register a MAC for - * @param cam_offset offset in a CAM to use - * @param with_bcast set broadcast MAC as well - */ -static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 with_bcast) -{ - struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); - int port = BP_PORT(bp); + if (!BP_NOMCP(bp)) { + bnx2x_get_port_hwinfo(bp); - /* CAM allocation - * unicasts 0-31:port0 32-63:port1 - * multicast 64-127:port0 128-191:port1 - */ - config->hdr.length = 1 + (with_bcast ? 1 : 0); - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; + bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); + } - /* primary MAC */ - config->config_table[0].cam_entry.msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].cam_entry.middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].cam_entry.lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[0].target_table_entry.flags = 0; - else - CAM_INVALIDATE(config->config_table[0]); - config->config_table[0].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].target_table_entry.vlan_id = 0; + if (IS_E1HMF(bp)) { + val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper); + val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower); + if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && + (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { + bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); + bp->dev->dev_addr[1] = (u8)(val2 & 0xff); + bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff); + bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff); + bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff); + bp->dev->dev_addr[5] = (u8)(val & 0xff); + memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, + ETH_ALEN); + memcpy(bp->dev->perm_addr, bp->dev->dev_addr, + ETH_ALEN); + } - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n", - (set ? "setting" : "clearing"), - config->config_table[0].cam_entry.msb_mac_addr, - config->config_table[0].cam_entry.middle_mac_addr, - config->config_table[0].cam_entry.lsb_mac_addr); + return rc; + } - /* broadcast */ - if (with_bcast) { - config->config_table[1].cam_entry.msb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.middle_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.lsb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[1].target_table_entry.flags = - TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST; - else - CAM_INVALIDATE(config->config_table[1]); - config->config_table[1].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[1].target_table_entry.vlan_id = 0; + if (BP_NOMCP(bp)) { + /* only supposed to happen on emulation/FPGA */ + BNX2X_ERROR("warning: random MAC workaround active\n"); + random_ether_addr(bp->dev->dev_addr); + memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); } - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + return rc; } -/** - * Sets a MAC in a CAM for a few L2 Clients for E1H chip - * - * @param bp driver descriptor - * @param set set or clear an entry (1 or 0) - * @param mac pointer to a buffer containing a MAC - * @param cl_bit_vec bit vector of clients to register a MAC for - * @param cam_offset offset in a CAM to use - */ -static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset) +static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp) { - struct mac_configuration_cmd_e1h *config = - (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config); + int cnt, i, block_end, rodi; + char vpd_data[BNX2X_VPD_LEN+1]; + char str_id_reg[VENDOR_ID_LEN+1]; + char str_id_cap[VENDOR_ID_LEN+1]; + u8 len; - config->hdr.length = 1; - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; + cnt = pci_read_vpd(bp->pdev, 0, BNX2X_VPD_LEN, vpd_data); + memset(bp->fw_ver, 0, sizeof(bp->fw_ver)); + + if (cnt < BNX2X_VPD_LEN) + goto out_not_found; + + i = pci_vpd_find_tag(vpd_data, 0, BNX2X_VPD_LEN, + PCI_VPD_LRDT_RO_DATA); + if (i < 0) + goto out_not_found; + + + block_end = i + PCI_VPD_LRDT_TAG_SIZE + + pci_vpd_lrdt_size(&vpd_data[i]); + + i += PCI_VPD_LRDT_TAG_SIZE; + + if (block_end > BNX2X_VPD_LEN) + goto out_not_found; - /* primary MAC */ - config->config_table[0].msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].vlan_id = 0; - config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov); - if (set) - config->config_table[0].flags = BP_PORT(bp); - else - config->config_table[0].flags = - MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE; + rodi = pci_vpd_find_info_keyword(vpd_data, i, block_end, + PCI_VPD_RO_KEYWORD_MFR_ID); + if (rodi < 0) + goto out_not_found; - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID mask %d\n", - (set ? "setting" : "clearing"), - config->config_table[0].msb_mac_addr, - config->config_table[0].middle_mac_addr, - config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec); + len = pci_vpd_info_field_size(&vpd_data[rodi]); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); -} + if (len != VENDOR_ID_LEN) + goto out_not_found; -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int poll) -{ - /* can take a while if any port is running */ - int cnt = 5000; + rodi += PCI_VPD_INFO_FLD_HDR_SIZE; - DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", - poll ? "polling" : "waiting", state, idx); + /* vendor specific info */ + snprintf(str_id_reg, VENDOR_ID_LEN + 1, "%04x", PCI_VENDOR_ID_DELL); + snprintf(str_id_cap, VENDOR_ID_LEN + 1, "%04X", PCI_VENDOR_ID_DELL); + if (!strncmp(str_id_reg, &vpd_data[rodi], VENDOR_ID_LEN) || + !strncmp(str_id_cap, &vpd_data[rodi], VENDOR_ID_LEN)) { - might_sleep(); - while (cnt--) { - if (poll) { - bnx2x_rx_int(bp->fp, 10); - /* if index is different from 0 - * the reply for some commands will - * be on the non default queue - */ - if (idx) - bnx2x_rx_int(&bp->fp[idx], 10); - } + rodi = pci_vpd_find_info_keyword(vpd_data, i, block_end, + PCI_VPD_RO_KEYWORD_VENDOR0); + if (rodi >= 0) { + len = pci_vpd_info_field_size(&vpd_data[rodi]); - mb(); /* state is changed by bnx2x_sp_event() */ - if (*state_p == state) { -#ifdef BNX2X_STOP_ON_ERROR - DP(NETIF_MSG_IFUP, "exit (cnt %d)\n", 5000 - cnt); -#endif - return 0; + rodi += PCI_VPD_INFO_FLD_HDR_SIZE; + + if (len < 32 && (len + rodi) <= BNX2X_VPD_LEN) { + memcpy(bp->fw_ver, &vpd_data[rodi], len); + bp->fw_ver[len] = ' '; + } } + return; + } +out_not_found: + return; +} - msleep(1); +static int __devinit bnx2x_init_bp(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + int timer_interval; + int rc; - if (bp->panic) - return -EIO; - } + /* Disable interrupt handling until HW is initialized */ + atomic_set(&bp->intr_sem, 1); + smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ - /* timeout! */ - BNX2X_ERR("timeout %s for state %x on IDX [%d]\n", - poll ? "polling" : "waiting", state, idx); -#ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); + mutex_init(&bp->port.phy_mutex); + mutex_init(&bp->fw_mb_mutex); +#ifdef BCM_CNIC + mutex_init(&bp->cnic_mutex); #endif - return -EBUSY; -} + INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); + INIT_DELAYED_WORK(&bp->reset_task, bnx2x_reset_task); -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set) -{ - bp->set_mac_pending++; - smp_wmb(); + rc = bnx2x_get_hwinfo(bp); - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), BP_FUNC(bp)); + bnx2x_read_fwinfo(bp); + /* need to reset chip if undi was active */ + if (!BP_NOMCP(bp)) + bnx2x_undi_unload(bp); - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); -} + if (CHIP_REV_IS_FPGA(bp)) + dev_err(&bp->pdev->dev, "FPGA detected\n"); -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) -{ - bp->set_mac_pending++; - smp_wmb(); + if (BP_NOMCP(bp) && (func == 0)) + dev_err(&bp->pdev->dev, "MCP disabled, " + "must load devices in order!\n"); - bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0), - 1); + /* Set multi queue mode */ + if ((multi_mode != ETH_RSS_MODE_DISABLED) && + ((int_mode == INT_MODE_INTx) || (int_mode == INT_MODE_MSI))) { + dev_err(&bp->pdev->dev, "Multi disabled since int_mode " + "requested is not MSI-X\n"); + multi_mode = ETH_RSS_MODE_DISABLED; + } + bp->multi_mode = multi_mode; - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); -} -#ifdef BCM_CNIC -/** - * Set iSCSI MAC(s) at the next enties in the CAM after the ETH - * MAC(s). This function will wait until the ramdord completion - * returns. - * - * @param bp driver handle - * @param set set or clear the CAM entry - * - * @return 0 if cussess, -ENODEV if ramrod doesn't return. - */ -int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) -{ - u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID); + bp->dev->features |= NETIF_F_GRO; - bp->set_mac_pending++; - smp_wmb(); + /* Set TPA flags */ + if (disable_tpa) { + bp->flags &= ~TPA_ENABLE_FLAG; + bp->dev->features &= ~NETIF_F_LRO; + } else { + bp->flags |= TPA_ENABLE_FLAG; + bp->dev->features |= NETIF_F_LRO; + } - /* Send a SET_MAC ramrod */ if (CHIP_IS_E1(bp)) - bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2, - 1); + bp->dropless_fc = 0; else - /* CAM allocation for E1H - * unicasts: by func number - * multicast: 20+FUNC*20, 20 each - */ - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp)); + bp->dropless_fc = dropless_fc; - /* Wait for a completion when setting */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + bp->mrrs = mrrs; - return 0; -} -#endif + bp->tx_ring_size = MAX_TX_AVAIL; + bp->rx_ring_size = MAX_RX_AVAIL; -int bnx2x_setup_leading(struct bnx2x *bp) -{ - int rc; + bp->rx_csum = 1; - /* reset IGU state */ - bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + /* make sure that the numbers are in the right granularity */ + bp->tx_ticks = (50 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); + bp->rx_ticks = (25 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); - /* SETUP ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0); + timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ); + bp->current_interval = (poll ? poll : timer_interval); - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0); + init_timer(&bp->timer); + bp->timer.expires = jiffies + bp->current_interval; + bp->timer.data = (unsigned long) bp; + bp->timer.function = bnx2x_timer; return rc; } -int bnx2x_setup_multi(struct bnx2x *bp, int index) +/* + * ethtool service functions + */ + +/* All ethtool functions called with rtnl_lock */ + +static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct bnx2x_fastpath *fp = &bp->fp[index]; + struct bnx2x *bp = netdev_priv(dev); - /* reset IGU state */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + cmd->supported = bp->port.supported; + cmd->advertising = bp->port.advertising; - /* SETUP ramrod */ - fp->state = BNX2X_FP_STATE_OPENING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, - fp->cl_id, 0); + if ((bp->state == BNX2X_STATE_OPEN) && + !(bp->flags & MF_FUNC_DIS) && + (bp->link_vars.link_up)) { + cmd->speed = bp->link_vars.line_speed; + cmd->duplex = bp->link_vars.duplex; + if (IS_E1HMF(bp)) { + u16 vn_max_rate; - /* Wait for completion */ - return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, - &(fp->state), 0); -} + vn_max_rate = + ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + if (vn_max_rate < cmd->speed) + cmd->speed = vn_max_rate; + } + } else { + cmd->speed = -1; + cmd->duplex = -1; + } + if (bp->link_params.switch_cfg == SWITCH_CFG_10G) { + u32 ext_phy_type = + XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); -void bnx2x_set_num_queues_msix(struct bnx2x *bp) -{ + switch (ext_phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + cmd->port = PORT_FIBRE; + break; - switch (bp->multi_mode) { - case ETH_RSS_MODE_DISABLED: - bp->num_queues = 1; - break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: + cmd->port = PORT_TP; + break; - case ETH_RSS_MODE_REGULAR: - if (num_queues) - bp->num_queues = min_t(u32, num_queues, - BNX2X_MAX_QUEUES(bp)); - else - bp->num_queues = min_t(u32, num_online_cpus(), - BNX2X_MAX_QUEUES(bp)); - break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: + BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", + bp->link_params.ext_phy_config); + break; + + default: + DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", + bp->link_params.ext_phy_config); + break; + } + } else + cmd->port = PORT_TP; + + cmd->phy_address = bp->mdio.prtad; + cmd->transceiver = XCVR_INTERNAL; + if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) + cmd->autoneg = AUTONEG_ENABLE; + else + cmd->autoneg = AUTONEG_DISABLE; - default: - bp->num_queues = 1; - break; - } -} + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" + DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" + DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" + DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", + cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, + cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, + cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + return 0; +} -static int bnx2x_stop_multi(struct bnx2x *bp, int index) +static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct bnx2x_fastpath *fp = &bp->fp[index]; - int rc; + struct bnx2x *bp = netdev_priv(dev); + u32 advertising; - /* halt the connection */ - fp->state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0); + if (IS_E1HMF(bp)) + return 0; - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, - &(fp->state), 1); - if (rc) /* timeout */ - return rc; + DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" + DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" + DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" + DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", + cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, + cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, + cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + + if (cmd->autoneg == AUTONEG_ENABLE) { + if (!(bp->port.supported & SUPPORTED_Autoneg)) { + DP(NETIF_MSG_LINK, "Autoneg not supported\n"); + return -EINVAL; + } - /* delete cfc entry */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); + /* advertise the requested speed and duplex if supported */ + cmd->advertising &= bp->port.supported; - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index, - &(fp->state), 1); - return rc; -} + bp->link_params.req_line_speed = SPEED_AUTO_NEG; + bp->link_params.req_duplex = DUPLEX_FULL; + bp->port.advertising |= (ADVERTISED_Autoneg | + cmd->advertising); + + } else { /* forced speed */ + /* advertise the requested speed and duplex if supported */ + switch (cmd->speed) { + case SPEED_10: + if (cmd->duplex == DUPLEX_FULL) { + if (!(bp->port.supported & + SUPPORTED_10baseT_Full)) { + DP(NETIF_MSG_LINK, + "10M full not supported\n"); + return -EINVAL; + } -static int bnx2x_stop_leading(struct bnx2x *bp) -{ - __le16 dsb_sp_prod_idx; - /* if the other port is handling traffic, - this can take a lot of time */ - int cnt = 500; - int rc; + advertising = (ADVERTISED_10baseT_Full | + ADVERTISED_TP); + } else { + if (!(bp->port.supported & + SUPPORTED_10baseT_Half)) { + DP(NETIF_MSG_LINK, + "10M half not supported\n"); + return -EINVAL; + } - might_sleep(); + advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_TP); + } + break; - /* Send HALT ramrod */ - bp->fp[0].state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0); + case SPEED_100: + if (cmd->duplex == DUPLEX_FULL) { + if (!(bp->port.supported & + SUPPORTED_100baseT_Full)) { + DP(NETIF_MSG_LINK, + "100M full not supported\n"); + return -EINVAL; + } - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0, - &(bp->fp[0].state), 1); - if (rc) /* timeout */ - return rc; + advertising = (ADVERTISED_100baseT_Full | + ADVERTISED_TP); + } else { + if (!(bp->port.supported & + SUPPORTED_100baseT_Half)) { + DP(NETIF_MSG_LINK, + "100M half not supported\n"); + return -EINVAL; + } - dsb_sp_prod_idx = *bp->dsb_sp_prod; + advertising = (ADVERTISED_100baseT_Half | + ADVERTISED_TP); + } + break; - /* Send PORT_DELETE ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); + case SPEED_1000: + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, "1G half not supported\n"); + return -EINVAL; + } - /* Wait for completion to arrive on default status block - we are going to reset the chip anyway - so there is not much to do if this times out - */ - while (dsb_sp_prod_idx == *bp->dsb_sp_prod) { - if (!cnt) { - DP(NETIF_MSG_IFDOWN, "timeout waiting for port del " - "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", - *bp->dsb_sp_prod, dsb_sp_prod_idx); -#ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); -#endif - rc = -EBUSY; - break; - } - cnt--; - msleep(1); - rmb(); /* Refresh the dsb_sp_prod */ - } - bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; - bp->fp[0].state = BNX2X_FP_STATE_CLOSED; + if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) { + DP(NETIF_MSG_LINK, "1G full not supported\n"); + return -EINVAL; + } - return rc; -} + advertising = (ADVERTISED_1000baseT_Full | + ADVERTISED_TP); + break; -static void bnx2x_reset_func(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int base, i; + case SPEED_2500: + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, + "2.5G half not supported\n"); + return -EINVAL; + } - /* Configure IGU */ - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) { + DP(NETIF_MSG_LINK, + "2.5G full not supported\n"); + return -EINVAL; + } -#ifdef BCM_CNIC - /* Disable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0); - /* - * Wait for at least 10ms and up to 2 second for the timers scan to - * complete - */ - for (i = 0; i < 200; i++) { - msleep(10); - if (!REG_RD(bp, TM_REG_LIN0_SCAN_ON + port*4)) + advertising = (ADVERTISED_2500baseX_Full | + ADVERTISED_TP); break; - } -#endif - /* Clear ILT */ - base = FUNC_ILT_BASE(func); - for (i = base; i < base + ILT_PER_FUNC; i++) - bnx2x_ilt_wr(bp, i, 0); -} -static void bnx2x_reset_port(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - u32 val; + case SPEED_10000: + if (cmd->duplex != DUPLEX_FULL) { + DP(NETIF_MSG_LINK, "10G half not supported\n"); + return -EINVAL; + } - REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); + if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) { + DP(NETIF_MSG_LINK, "10G full not supported\n"); + return -EINVAL; + } - /* Do not rcv packets to BRB */ - REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + port*4, 0x0); - /* Do not direct rcv packets that are not for MCP to the BRB */ - REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP : - NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); + advertising = (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + break; - /* Configure AEU */ - REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, 0); + default: + DP(NETIF_MSG_LINK, "Unsupported speed\n"); + return -EINVAL; + } - msleep(100); - /* Check for BRB port occupancy */ - val = REG_RD(bp, BRB1_REG_PORT_NUM_OCC_BLOCKS_0 + port*4); - if (val) - DP(NETIF_MSG_IFDOWN, - "BRB1 is not empty %d blocks are occupied\n", val); + bp->link_params.req_line_speed = cmd->speed; + bp->link_params.req_duplex = cmd->duplex; + bp->port.advertising = advertising; + } - /* TODO: Close Doorbell port? */ + DP(NETIF_MSG_LINK, "req_line_speed %d\n" + DP_LEVEL " req_duplex %d advertising 0x%x\n", + bp->link_params.req_line_speed, bp->link_params.req_duplex, + bp->port.advertising); + + if (netif_running(dev)) { + bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_link_set(bp); + } + + return 0; } -static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) +#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) +#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) + +static int bnx2x_get_regs_len(struct net_device *dev) { - DP(BNX2X_MSG_MCP, "function %d reset_code %x\n", - BP_FUNC(bp), reset_code); + struct bnx2x *bp = netdev_priv(dev); + int regdump_len = 0; + int i; - switch (reset_code) { - case FW_MSG_CODE_DRV_UNLOAD_COMMON: - bnx2x_reset_port(bp); - bnx2x_reset_func(bp); - bnx2x_reset_common(bp); - break; + if (CHIP_IS_E1(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E1_ONLINE(reg_addrs[i].info)) + regdump_len += reg_addrs[i].size; - case FW_MSG_CODE_DRV_UNLOAD_PORT: - bnx2x_reset_port(bp); - bnx2x_reset_func(bp); - break; + for (i = 0; i < WREGS_COUNT_E1; i++) + if (IS_E1_ONLINE(wreg_addrs_e1[i].info)) + regdump_len += wreg_addrs_e1[i].size * + (1 + wreg_addrs_e1[i].read_regs_count); - case FW_MSG_CODE_DRV_UNLOAD_FUNCTION: - bnx2x_reset_func(bp); - break; + } else { /* E1H */ + for (i = 0; i < REGS_COUNT; i++) + if (IS_E1H_ONLINE(reg_addrs[i].info)) + regdump_len += reg_addrs[i].size; - default: - BNX2X_ERR("Unknown reset_code (0x%x) from MCP\n", reset_code); - break; + for (i = 0; i < WREGS_COUNT_E1H; i++) + if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) + regdump_len += wreg_addrs_e1h[i].size * + (1 + wreg_addrs_e1h[i].read_regs_count); } + regdump_len *= 4; + regdump_len += sizeof(struct dump_hdr); + + return regdump_len; } -void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) +static void bnx2x_get_regs(struct net_device *dev, + struct ethtool_regs *regs, void *_p) { - int port = BP_PORT(bp); - u32 reset_code = 0; - int i, cnt, rc; + u32 *p = _p, i, j; + struct bnx2x *bp = netdev_priv(dev); + struct dump_hdr dump_hdr = {0}; - /* Wait until tx fastpath tasks complete */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; + regs->version = 0; + memset(p, 0, regs->len); - cnt = 1000; - while (bnx2x_has_tx_work_unload(fp)) { + if (!netif_running(bp->dev)) + return; - bnx2x_tx_int(fp); - if (!cnt) { - BNX2X_ERR("timeout waiting for queue[%d]\n", - i); -#ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); - return -EBUSY; -#else - break; -#endif - } - cnt--; - msleep(1); - } - } - /* Give HW time to discard old tx messages */ - msleep(1); + dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1; + dump_hdr.dump_sign = dump_sign_all; + dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR); + dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR); + dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR); + dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR); + dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE; - if (CHIP_IS_E1(bp)) { - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); + memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); + p += dump_hdr.hdr_size + 1; - bnx2x_set_eth_mac_addr_e1(bp, 0); + if (CHIP_IS_E1(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E1_ONLINE(reg_addrs[i].info)) + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(bp, + reg_addrs[i].addr + j*4); - for (i = 0; i < config->hdr.length; i++) - CAM_INVALIDATE(config->config_table[i]); + } else { /* E1H */ + for (i = 0; i < REGS_COUNT; i++) + if (IS_E1H_ONLINE(reg_addrs[i].info)) + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(bp, + reg_addrs[i].addr + j*4); + } +} - config->hdr.length = i; - if (CHIP_REV_IS_SLOW(bp)) - config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port); - else - config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port); - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; +#define PHY_FW_VER_LEN 10 - bp->set_mac_pending++; - smp_wmb(); +static void bnx2x_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct bnx2x *bp = netdev_priv(dev); + u8 phy_fw_ver[PHY_FW_VER_LEN]; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mcast_config)), - U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0); + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); - } else { /* E1H */ - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); + phy_fw_ver[0] = '\0'; + if (bp->port.pmf) { + bnx2x_acquire_phy_lock(bp); + bnx2x_get_ext_phy_fw_version(&bp->link_params, + (bp->state != BNX2X_STATE_CLOSED), + phy_fw_ver, PHY_FW_VER_LEN); + bnx2x_release_phy_lock(bp); + } - bnx2x_set_eth_mac_addr_e1h(bp, 0); + strncpy(info->fw_version, bp->fw_ver, 32); + snprintf(info->fw_version + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver), + "bc %d.%d.%d%s%s", + (bp->common.bc_ver & 0xff0000) >> 16, + (bp->common.bc_ver & 0xff00) >> 8, + (bp->common.bc_ver & 0xff), + ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver); + strcpy(info->bus_info, pci_name(bp->pdev)); + info->n_stats = BNX2X_NUM_STATS; + info->testinfo_len = BNX2X_NUM_TESTS; + info->eedump_len = bp->common.flash_size; + info->regdump_len = bnx2x_get_regs_len(dev); +} - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); +static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct bnx2x *bp = netdev_priv(dev); - REG_WR(bp, MISC_REG_E1HMF_MODE, 0); - } -#ifdef BCM_CNIC - /* Clear iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { - bnx2x_set_iscsi_eth_mac_addr(bp, 0); - bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; + if (bp->flags & NO_WOL_FLAG) { + wol->supported = 0; + wol->wolopts = 0; + } else { + wol->supported = WAKE_MAGIC; + if (bp->wol) + wol->wolopts = WAKE_MAGIC; + else + wol->wolopts = 0; } - mutex_unlock(&bp->cnic_mutex); -#endif + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} - if (unload_mode == UNLOAD_NORMAL) - reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; +static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct bnx2x *bp = netdev_priv(dev); + + if (wol->wolopts & ~WAKE_MAGIC) + return -EINVAL; + + if (wol->wolopts & WAKE_MAGIC) { + if (bp->flags & NO_WOL_FLAG) + return -EINVAL; + + bp->wol = 1; + } else + bp->wol = 0; - else if (bp->flags & NO_WOL_FLAG) - reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP; + return 0; +} - else if (bp->wol) { - u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u8 *mac_addr = bp->dev->dev_addr; - u32 val; - /* The mac address is written to entries 1-4 to - preserve entry 0 which is used by the PMF */ - u8 entry = (BP_E1HVN(bp) + 1)*8; +static u32 bnx2x_get_msglevel(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); - val = (mac_addr[0] << 8) | mac_addr[1]; - EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry, val); + return bp->msg_enable; +} - val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | - (mac_addr[4] << 8) | mac_addr[5]; - EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val); +static void bnx2x_set_msglevel(struct net_device *dev, u32 level) +{ + struct bnx2x *bp = netdev_priv(dev); - reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN; + if (capable(CAP_NET_ADMIN)) + bp->msg_enable = level; +} - } else - reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; +static int bnx2x_nway_reset(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); - /* Close multi and leading connections - Completions for ramrods are collected in a synchronous way */ - for_each_nondefault_queue(bp, i) - if (bnx2x_stop_multi(bp, i)) - goto unload_error; + if (!bp->port.pmf) + return 0; - rc = bnx2x_stop_leading(bp); - if (rc) { - BNX2X_ERR("Stop leading failed!\n"); -#ifdef BNX2X_STOP_ON_ERROR - return -EBUSY; -#else - goto unload_error; -#endif + if (netif_running(dev)) { + bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_link_set(bp); } -unload_error: - if (!BP_NOMCP(bp)) - reset_code = bnx2x_fw_command(bp, reset_code); - else { - DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]--; - load_count[1 + port]--; - DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 0) - reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; - else if (load_count[1 + port] == 0) - reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; - else - reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; - } + return 0; +} - if ((reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) || - (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT)) - bnx2x__link_reset(bp); +static u32 bnx2x_get_link(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); - /* Reset the chip */ - bnx2x_reset_chip(bp, reset_code); + if (bp->flags & MF_FUNC_DIS) + return 0; - /* Report UNLOAD_DONE to MCP */ - if (!BP_NOMCP(bp)) - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + return bp->link_vars.link_up; +} + +static int bnx2x_get_eeprom_len(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + return bp->common.flash_size; } -void bnx2x_disable_close_the_gate(struct bnx2x *bp) +static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) { - u32 val; + int port = BP_PORT(bp); + int count, i; + u32 val = 0; - DP(NETIF_MSG_HW, "Disabling \"close the gates\"\n"); + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; + if (CHIP_REV_IS_SLOW(bp)) + count *= 100; - if (CHIP_IS_E1(bp)) { - int port = BP_PORT(bp); - u32 addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : - MISC_REG_AEU_MASK_ATTN_FUNC_0; + /* request access to nvram interface */ + REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB, + (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port)); - val = REG_RD(bp, addr); - val &= ~(0x300); - REG_WR(bp, addr, val); - } else if (CHIP_IS_E1H(bp)) { - val = REG_RD(bp, MISC_REG_AEU_GENERAL_MASK); - val &= ~(MISC_AEU_GENERAL_MASK_REG_AEU_PXP_CLOSE_MASK | - MISC_AEU_GENERAL_MASK_REG_AEU_NIG_CLOSE_MASK); - REG_WR(bp, MISC_REG_AEU_GENERAL_MASK, val); + for (i = 0; i < count*10; i++) { + val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB); + if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) + break; + + udelay(5); } -} + if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) { + DP(BNX2X_MSG_NVM, "cannot get access to nvram interface\n"); + return -EBUSY; + } -/* Close gates #2, #3 and #4: */ -static void bnx2x_set_234_gates(struct bnx2x *bp, bool close) + return 0; +} + +static int bnx2x_release_nvram_lock(struct bnx2x *bp) { - u32 val, addr; + int port = BP_PORT(bp); + int count, i; + u32 val = 0; - /* Gates #2 and #4a are closed/opened for "not E1" only */ - if (!CHIP_IS_E1(bp)) { - /* #4 */ - val = REG_RD(bp, PXP_REG_HST_DISCARD_DOORBELLS); - REG_WR(bp, PXP_REG_HST_DISCARD_DOORBELLS, - close ? (val | 0x1) : (val & (~(u32)1))); - /* #2 */ - val = REG_RD(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES); - REG_WR(bp, PXP_REG_HST_DISCARD_INTERNAL_WRITES, - close ? (val | 0x1) : (val & (~(u32)1))); + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; + if (CHIP_REV_IS_SLOW(bp)) + count *= 100; + + /* relinquish nvram interface */ + REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB, + (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port)); + + for (i = 0; i < count*10; i++) { + val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB); + if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) + break; + + udelay(5); } - /* #3 */ - addr = BP_PORT(bp) ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; - val = REG_RD(bp, addr); - REG_WR(bp, addr, (!close) ? (val | 0x1) : (val & (~(u32)1))); + if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) { + DP(BNX2X_MSG_NVM, "cannot free access to nvram interface\n"); + return -EBUSY; + } - DP(NETIF_MSG_HW, "%s gates #2, #3 and #4\n", - close ? "closing" : "opening"); - mmiowb(); + return 0; } -#define SHARED_MF_CLP_MAGIC 0x80000000 /* `magic' bit */ - -static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val) +static void bnx2x_enable_nvram_access(struct bnx2x *bp) { - /* Do some magic... */ - u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb); - *magic_val = val & SHARED_MF_CLP_MAGIC; - MF_CFG_WR(bp, shared_mf_config.clp_mb, val | SHARED_MF_CLP_MAGIC); + u32 val; + + val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE); + + /* enable both bits, even on read */ + REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE, + (val | MCPR_NVM_ACCESS_ENABLE_EN | + MCPR_NVM_ACCESS_ENABLE_WR_EN)); } -/* Restore the value of the `magic' bit. - * - * @param pdev Device handle. - * @param magic_val Old value of the `magic' bit. - */ -static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val) +static void bnx2x_disable_nvram_access(struct bnx2x *bp) { - /* Restore the `magic' bit value... */ - /* u32 val = SHMEM_RD(bp, mf_cfg.shared_mf_config.clp_mb); - SHMEM_WR(bp, mf_cfg.shared_mf_config.clp_mb, - (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); */ - u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb); - MF_CFG_WR(bp, shared_mf_config.clp_mb, - (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); + u32 val; + + val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE); + + /* disable both bits, even after read */ + REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE, + (val & ~(MCPR_NVM_ACCESS_ENABLE_EN | + MCPR_NVM_ACCESS_ENABLE_WR_EN))); } -/* Prepares for MCP reset: takes care of CLP configurations. - * - * @param bp - * @param magic_val Old value of 'magic' bit. - */ -static void bnx2x_reset_mcp_prep(struct bnx2x *bp, u32 *magic_val) +static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val, + u32 cmd_flags) { - u32 shmem; - u32 validity_offset; - - DP(NETIF_MSG_HW, "Starting\n"); + int count, i, rc; + u32 val; - /* Set `magic' bit in order to save MF config */ - if (!CHIP_IS_E1(bp)) - bnx2x_clp_reset_prep(bp, magic_val); + /* build the command word */ + cmd_flags |= MCPR_NVM_COMMAND_DOIT; - /* Get shmem offset */ - shmem = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); - validity_offset = offsetof(struct shmem_region, validity_map[0]); + /* need to clear DONE bit separately */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE); - /* Clear validity map flags */ - if (shmem > 0) - REG_WR(bp, shmem + validity_offset, 0); -} + /* address of the NVRAM to read from */ + REG_WR(bp, MCP_REG_MCPR_NVM_ADDR, + (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE)); -#define MCP_TIMEOUT 5000 /* 5 seconds (in ms) */ -#define MCP_ONE_TIMEOUT 100 /* 100 ms */ + /* issue a read command */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); -/* Waits for MCP_ONE_TIMEOUT or MCP_ONE_TIMEOUT*10, - * depending on the HW type. - * - * @param bp - */ -static inline void bnx2x_mcp_wait_one(struct bnx2x *bp) -{ - /* special handling for emulation and FPGA, - wait 10 times longer */ + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; if (CHIP_REV_IS_SLOW(bp)) - msleep(MCP_ONE_TIMEOUT*10); - else - msleep(MCP_ONE_TIMEOUT); + count *= 100; + + /* wait for completion */ + *ret_val = 0; + rc = -EBUSY; + for (i = 0; i < count; i++) { + udelay(5); + val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND); + + if (val & MCPR_NVM_COMMAND_DONE) { + val = REG_RD(bp, MCP_REG_MCPR_NVM_READ); + /* we read nvram data in cpu order + * but ethtool sees it as an array of bytes + * converting to big-endian will do the work */ + *ret_val = cpu_to_be32(val); + rc = 0; + break; + } + } + + return rc; } -static int bnx2x_reset_mcp_comp(struct bnx2x *bp, u32 magic_val) +static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf, + int buf_size) { - u32 shmem, cnt, validity_offset, val; - int rc = 0; + int rc; + u32 cmd_flags; + __be32 val; - msleep(100); + if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { + DP(BNX2X_MSG_NVM, + "Invalid parameter: offset 0x%x buf_size 0x%x\n", + offset, buf_size); + return -EINVAL; + } - /* Get shmem offset */ - shmem = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); - if (shmem == 0) { - BNX2X_ERR("Shmem 0 return failure\n"); - rc = -ENOTTY; - goto exit_lbl; + if (offset + buf_size > bp->common.flash_size) { + DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +" + " buf_size (0x%x) > flash_size (0x%x)\n", + offset, buf_size, bp->common.flash_size); + return -EINVAL; } - validity_offset = offsetof(struct shmem_region, validity_map[0]); + /* request access to nvram interface */ + rc = bnx2x_acquire_nvram_lock(bp); + if (rc) + return rc; - /* Wait for MCP to come up */ - for (cnt = 0; cnt < (MCP_TIMEOUT / MCP_ONE_TIMEOUT); cnt++) { - /* TBD: its best to check validity map of last port. - * currently checks on port 0. - */ - val = REG_RD(bp, shmem + validity_offset); - DP(NETIF_MSG_HW, "shmem 0x%x validity map(0x%x)=0x%x\n", shmem, - shmem + validity_offset, val); + /* enable access to nvram interface */ + bnx2x_enable_nvram_access(bp); - /* check that shared memory is valid. */ - if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - == (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - break; + /* read the first word(s) */ + cmd_flags = MCPR_NVM_COMMAND_FIRST; + while ((buf_size > sizeof(u32)) && (rc == 0)) { + rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags); + memcpy(ret_buf, &val, 4); - bnx2x_mcp_wait_one(bp); + /* advance to the next dword */ + offset += sizeof(u32); + ret_buf += sizeof(u32); + buf_size -= sizeof(u32); + cmd_flags = 0; } - DP(NETIF_MSG_HW, "Cnt=%d Shmem validity map 0x%x\n", cnt, val); - - /* Check that shared memory is valid. This indicates that MCP is up. */ - if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != - (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) { - BNX2X_ERR("Shmem signature not present. MCP is not up !!\n"); - rc = -ENOTTY; - goto exit_lbl; + if (rc == 0) { + cmd_flags |= MCPR_NVM_COMMAND_LAST; + rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags); + memcpy(ret_buf, &val, 4); } -exit_lbl: - /* Restore the `magic' bit value */ - if (!CHIP_IS_E1(bp)) - bnx2x_clp_reset_done(bp, magic_val); + /* disable access to nvram interface */ + bnx2x_disable_nvram_access(bp); + bnx2x_release_nvram_lock(bp); + + return rc; +} + +static int bnx2x_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *eebuf) +{ + struct bnx2x *bp = netdev_priv(dev); + int rc; + + if (!netif_running(dev)) + return -EAGAIN; + + DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n" + DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", + eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, + eeprom->len, eeprom->len); + + /* parameters already validated in ethtool_get_eeprom */ + + rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); return rc; } -static void bnx2x_pxp_prep(struct bnx2x *bp) +static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, + u32 cmd_flags) { - if (!CHIP_IS_E1(bp)) { - REG_WR(bp, PXP2_REG_RD_START_INIT, 0); - REG_WR(bp, PXP2_REG_RQ_RBC_DONE, 0); - REG_WR(bp, PXP2_REG_RQ_CFG_DONE, 0); - mmiowb(); + int count, i, rc; + + /* build the command word */ + cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR; + + /* need to clear DONE bit separately */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE); + + /* write the data */ + REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val); + + /* address of the NVRAM to write to */ + REG_WR(bp, MCP_REG_MCPR_NVM_ADDR, + (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE)); + + /* issue the write command */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); + + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; + if (CHIP_REV_IS_SLOW(bp)) + count *= 100; + + /* wait for completion */ + rc = -EBUSY; + for (i = 0; i < count; i++) { + udelay(5); + val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND); + if (val & MCPR_NVM_COMMAND_DONE) { + rc = 0; + break; + } } + + return rc; } -/* - * Reset the whole chip except for: - * - PCIE core - * - PCI Glue, PSWHST, PXP/PXP2 RF (all controlled by - * one reset bit) - * - IGU - * - MISC (including AEU) - * - GRC - * - RBCN, RBCP - */ -static void bnx2x_process_kill_chip_reset(struct bnx2x *bp) +#define BYTE_OFFSET(offset) (8 * (offset & 0x03)) + +static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf, + int buf_size) { - u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2; + int rc; + u32 cmd_flags; + u32 align_offset; + __be32 val; + + if (offset + buf_size > bp->common.flash_size) { + DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +" + " buf_size (0x%x) > flash_size (0x%x)\n", + offset, buf_size, bp->common.flash_size); + return -EINVAL; + } - not_reset_mask1 = - MISC_REGISTERS_RESET_REG_1_RST_HC | - MISC_REGISTERS_RESET_REG_1_RST_PXPV | - MISC_REGISTERS_RESET_REG_1_RST_PXP; + /* request access to nvram interface */ + rc = bnx2x_acquire_nvram_lock(bp); + if (rc) + return rc; - not_reset_mask2 = - MISC_REGISTERS_RESET_REG_2_RST_MDIO | - MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE | - MISC_REGISTERS_RESET_REG_2_RST_EMAC1_HARD_CORE | - MISC_REGISTERS_RESET_REG_2_RST_MISC_CORE | - MISC_REGISTERS_RESET_REG_2_RST_RBCN | - MISC_REGISTERS_RESET_REG_2_RST_GRC | - MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE | - MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B; + /* enable access to nvram interface */ + bnx2x_enable_nvram_access(bp); - reset_mask1 = 0xffffffff; + cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST); + align_offset = (offset & ~0x03); + rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags); - if (CHIP_IS_E1(bp)) - reset_mask2 = 0xffff; - else - reset_mask2 = 0x1ffff; + if (rc == 0) { + val &= ~(0xff << BYTE_OFFSET(offset)); + val |= (*data_buf << BYTE_OFFSET(offset)); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, - reset_mask1 & (~not_reset_mask1)); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - reset_mask2 & (~not_reset_mask2)); + /* nvram data is returned as an array of bytes + * convert it back to cpu order */ + val = be32_to_cpu(val); - barrier(); - mmiowb(); + rc = bnx2x_nvram_write_dword(bp, align_offset, val, + cmd_flags); + } - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, reset_mask2); - mmiowb(); + /* disable access to nvram interface */ + bnx2x_disable_nvram_access(bp); + bnx2x_release_nvram_lock(bp); + + return rc; } -static int bnx2x_process_kill(struct bnx2x *bp) +static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf, + int buf_size) { - int cnt = 1000; - u32 val = 0; - u32 sr_cnt, blk_cnt, port_is_idle_0, port_is_idle_1, pgl_exp_rom2; + int rc; + u32 cmd_flags; + u32 val; + u32 written_so_far; + if (buf_size == 1) /* ethtool */ + return bnx2x_nvram_write1(bp, offset, data_buf, buf_size); - /* Empty the Tetris buffer, wait for 1s */ - do { - sr_cnt = REG_RD(bp, PXP2_REG_RD_SR_CNT); - blk_cnt = REG_RD(bp, PXP2_REG_RD_BLK_CNT); - port_is_idle_0 = REG_RD(bp, PXP2_REG_RD_PORT_IS_IDLE_0); - port_is_idle_1 = REG_RD(bp, PXP2_REG_RD_PORT_IS_IDLE_1); - pgl_exp_rom2 = REG_RD(bp, PXP2_REG_PGL_EXP_ROM2); - if ((sr_cnt == 0x7e) && (blk_cnt == 0xa0) && - ((port_is_idle_0 & 0x1) == 0x1) && - ((port_is_idle_1 & 0x1) == 0x1) && - (pgl_exp_rom2 == 0xffffffff)) - break; - msleep(1); - } while (cnt-- > 0); + if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { + DP(BNX2X_MSG_NVM, + "Invalid parameter: offset 0x%x buf_size 0x%x\n", + offset, buf_size); + return -EINVAL; + } - if (cnt <= 0) { - DP(NETIF_MSG_HW, "Tetris buffer didn't get empty or there" - " are still" - " outstanding read requests after 1s!\n"); - DP(NETIF_MSG_HW, "sr_cnt=0x%08x, blk_cnt=0x%08x," - " port_is_idle_0=0x%08x," - " port_is_idle_1=0x%08x, pgl_exp_rom2=0x%08x\n", - sr_cnt, blk_cnt, port_is_idle_0, port_is_idle_1, - pgl_exp_rom2); - return -EAGAIN; + if (offset + buf_size > bp->common.flash_size) { + DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +" + " buf_size (0x%x) > flash_size (0x%x)\n", + offset, buf_size, bp->common.flash_size); + return -EINVAL; } - barrier(); + /* request access to nvram interface */ + rc = bnx2x_acquire_nvram_lock(bp); + if (rc) + return rc; - /* Close gates #2, #3 and #4 */ - bnx2x_set_234_gates(bp, true); + /* enable access to nvram interface */ + bnx2x_enable_nvram_access(bp); - /* TBD: Indicate that "process kill" is in progress to MCP */ + written_so_far = 0; + cmd_flags = MCPR_NVM_COMMAND_FIRST; + while ((written_so_far < buf_size) && (rc == 0)) { + if (written_so_far == (buf_size - sizeof(u32))) + cmd_flags |= MCPR_NVM_COMMAND_LAST; + else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0) + cmd_flags |= MCPR_NVM_COMMAND_LAST; + else if ((offset % NVRAM_PAGE_SIZE) == 0) + cmd_flags |= MCPR_NVM_COMMAND_FIRST; - /* Clear "unprepared" bit */ - REG_WR(bp, MISC_REG_UNPREPARED, 0); - barrier(); + memcpy(&val, data_buf, 4); - /* Make sure all is written to the chip before the reset */ - mmiowb(); + rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags); - /* Wait for 1ms to empty GLUE and PCI-E core queues, - * PSWHST, GRC and PSWRD Tetris buffer. - */ - msleep(1); + /* advance to the next dword */ + offset += sizeof(u32); + data_buf += sizeof(u32); + written_so_far += sizeof(u32); + cmd_flags = 0; + } - /* Prepare to chip reset: */ - /* MCP */ - bnx2x_reset_mcp_prep(bp, &val); + /* disable access to nvram interface */ + bnx2x_disable_nvram_access(bp); + bnx2x_release_nvram_lock(bp); - /* PXP */ - bnx2x_pxp_prep(bp); - barrier(); + return rc; +} - /* reset the chip */ - bnx2x_process_kill_chip_reset(bp); - barrier(); +static int bnx2x_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *eebuf) +{ + struct bnx2x *bp = netdev_priv(dev); + int port = BP_PORT(bp); + int rc = 0; - /* Recover after reset: */ - /* MCP */ - if (bnx2x_reset_mcp_comp(bp, val)) + if (!netif_running(dev)) return -EAGAIN; - /* PXP */ - bnx2x_pxp_prep(bp); + DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n" + DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", + eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, + eeprom->len, eeprom->len); - /* Open the gates #2, #3 and #4 */ - bnx2x_set_234_gates(bp, false); + /* parameters already validated in ethtool_set_eeprom */ - /* TBD: IGU/AEU preparation bring back the AEU/IGU to a - * reset state, re-enable attentions. */ + /* PHY eeprom can be accessed only by the PMF */ + if ((eeprom->magic >= 0x50485900) && (eeprom->magic <= 0x504859FF) && + !bp->port.pmf) + return -EINVAL; - return 0; -} + if (eeprom->magic == 0x50485950) { + /* 'PHYP' (0x50485950): prepare phy for FW upgrade */ + bnx2x_stats_handle(bp, STATS_EVENT_STOP); -static int bnx2x_leader_reset(struct bnx2x *bp) -{ - int rc = 0; - /* Try to recover after the failure */ - if (bnx2x_process_kill(bp)) { - printk(KERN_ERR "%s: Something bad had happen! Aii!\n", - bp->dev->name); - rc = -EAGAIN; - goto exit_leader_reset; - } + bnx2x_acquire_phy_lock(bp); + rc |= bnx2x_link_reset(&bp->link_params, + &bp->link_vars, 0); + if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, + MISC_REGISTERS_GPIO_HIGH, port); + bnx2x_release_phy_lock(bp); + bnx2x_link_report(bp); - /* Clear "reset is in progress" bit and update the driver state */ - bnx2x_set_reset_done(bp); - bp->recovery_state = BNX2X_RECOVERY_DONE; + } else if (eeprom->magic == 0x50485952) { + /* 'PHYR' (0x50485952): re-init link after FW upgrade */ + if (bp->state == BNX2X_STATE_OPEN) { + bnx2x_acquire_phy_lock(bp); + rc |= bnx2x_link_reset(&bp->link_params, + &bp->link_vars, 1); + + rc |= bnx2x_phy_init(&bp->link_params, + &bp->link_vars); + bnx2x_release_phy_lock(bp); + bnx2x_calc_fc_adv(bp); + } + } else if (eeprom->magic == 0x53985943) { + /* 'PHYC' (0x53985943): PHY FW upgrade completed */ + if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) { + u8 ext_phy_addr = + XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); + + /* DSP Remove Download Mode */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, + MISC_REGISTERS_GPIO_LOW, port); + + bnx2x_acquire_phy_lock(bp); + + bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); + + /* wait 0.5 sec to allow it to run */ + msleep(500); + bnx2x_ext_phy_hw_reset(bp, port); + msleep(500); + bnx2x_release_phy_lock(bp); + } + } else + rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); -exit_leader_reset: - bp->is_leader = 0; - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESERVED_08); - smp_wmb(); return rc; } -/* Assumption: runs under rtnl lock. This together with the fact - * that it's called only from bnx2x_reset_task() ensure that it - * will never be called when netif_running(bp->dev) is false. - */ -static void bnx2x_parity_recover(struct bnx2x *bp) +static int bnx2x_get_coalesce(struct net_device *dev, + struct ethtool_coalesce *coal) { - DP(NETIF_MSG_HW, "Handling parity\n"); - while (1) { - switch (bp->recovery_state) { - case BNX2X_RECOVERY_INIT: - DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n"); - /* Try to get a LEADER_LOCK HW lock */ - if (bnx2x_trylock_hw_lock(bp, - HW_LOCK_RESOURCE_RESERVED_08)) - bp->is_leader = 1; + struct bnx2x *bp = netdev_priv(dev); - /* Stop the driver */ - /* If interface has been removed - break */ - if (bnx2x_nic_unload(bp, UNLOAD_RECOVERY)) - return; + memset(coal, 0, sizeof(struct ethtool_coalesce)); - bp->recovery_state = BNX2X_RECOVERY_WAIT; - /* Ensure "is_leader" and "recovery_state" - * update values are seen on other CPUs - */ - smp_wmb(); - break; + coal->rx_coalesce_usecs = bp->rx_ticks; + coal->tx_coalesce_usecs = bp->tx_ticks; - case BNX2X_RECOVERY_WAIT: - DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_WAIT\n"); - if (bp->is_leader) { - u32 load_counter = bnx2x_get_load_cnt(bp); - if (load_counter) { - /* Wait until all other functions get - * down. - */ - schedule_delayed_work(&bp->reset_task, - HZ/10); - return; - } else { - /* If all other functions got down - - * try to bring the chip back to - * normal. In any case it's an exit - * point for a leader. - */ - if (bnx2x_leader_reset(bp) || - bnx2x_nic_load(bp, LOAD_NORMAL)) { - printk(KERN_ERR"%s: Recovery " - "has failed. Power cycle is " - "needed.\n", bp->dev->name); - /* Disconnect this device */ - netif_device_detach(bp->dev); - /* Block ifup for all function - * of this ASIC until - * "process kill" or power - * cycle. - */ - bnx2x_set_reset_in_progress(bp); - /* Shut down the power */ - bnx2x_set_power_state(bp, - PCI_D3hot); - return; - } + return 0; +} - return; - } - } else { /* non-leader */ - if (!bnx2x_reset_is_done(bp)) { - /* Try to get a LEADER_LOCK HW lock as - * long as a former leader may have - * been unloaded by the user or - * released a leadership by another - * reason. - */ - if (bnx2x_trylock_hw_lock(bp, - HW_LOCK_RESOURCE_RESERVED_08)) { - /* I'm a leader now! Restart a - * switch case. - */ - bp->is_leader = 1; - break; - } +static int bnx2x_set_coalesce(struct net_device *dev, + struct ethtool_coalesce *coal) +{ + struct bnx2x *bp = netdev_priv(dev); - schedule_delayed_work(&bp->reset_task, - HZ/10); - return; + bp->rx_ticks = (u16)coal->rx_coalesce_usecs; + if (bp->rx_ticks > BNX2X_MAX_COALESCE_TOUT) + bp->rx_ticks = BNX2X_MAX_COALESCE_TOUT; - } else { /* A leader has completed - * the "process kill". It's an exit - * point for a non-leader. - */ - bnx2x_nic_load(bp, LOAD_NORMAL); - bp->recovery_state = - BNX2X_RECOVERY_DONE; - smp_wmb(); - return; - } - } - default: - return; - } - } + bp->tx_ticks = (u16)coal->tx_coalesce_usecs; + if (bp->tx_ticks > BNX2X_MAX_COALESCE_TOUT) + bp->tx_ticks = BNX2X_MAX_COALESCE_TOUT; + + if (netif_running(dev)) + bnx2x_update_coalesce(bp); + + return 0; } -/* bnx2x_nic_unload() flushes the bnx2x_wq, thus reset task is - * scheduled on a general queue in order to prevent a dead lock. - */ -static void bnx2x_reset_task(struct work_struct *work) +static void bnx2x_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ering) { - struct bnx2x *bp = container_of(work, struct bnx2x, reset_task.work); + struct bnx2x *bp = netdev_priv(dev); -#ifdef BNX2X_STOP_ON_ERROR - BNX2X_ERR("reset task called but STOP_ON_ERROR defined" - " so reset not done to allow debug dump,\n" - KERN_ERR " you will need to reboot when done\n"); - return; -#endif + ering->rx_max_pending = MAX_RX_AVAIL; + ering->rx_mini_max_pending = 0; + ering->rx_jumbo_max_pending = 0; - rtnl_lock(); + ering->rx_pending = bp->rx_ring_size; + ering->rx_mini_pending = 0; + ering->rx_jumbo_pending = 0; - if (!netif_running(bp->dev)) - goto reset_task_exit; + ering->tx_max_pending = MAX_TX_AVAIL; + ering->tx_pending = bp->tx_ring_size; +} - if (unlikely(bp->recovery_state != BNX2X_RECOVERY_DONE)) - bnx2x_parity_recover(bp); - else { +static int bnx2x_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ering) +{ + struct bnx2x *bp = netdev_priv(dev); + int rc = 0; + + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + return -EAGAIN; + } + + if ((ering->rx_pending > MAX_RX_AVAIL) || + (ering->tx_pending > MAX_TX_AVAIL) || + (ering->tx_pending <= MAX_SKB_FRAGS + 4)) + return -EINVAL; + + bp->rx_ring_size = ering->rx_pending; + bp->tx_ring_size = ering->tx_pending; + + if (netif_running(dev)) { bnx2x_nic_unload(bp, UNLOAD_NORMAL); - bnx2x_nic_load(bp, LOAD_NORMAL); + rc = bnx2x_nic_load(bp, LOAD_NORMAL); } -reset_task_exit: - rtnl_unlock(); + return rc; } -/* end of nic load/unload */ +static void bnx2x_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *epause) +{ + struct bnx2x *bp = netdev_priv(dev); -/* - * Init service functions - */ + epause->autoneg = (bp->link_params.req_flow_ctrl == + BNX2X_FLOW_CTRL_AUTO) && + (bp->link_params.req_line_speed == SPEED_AUTO_NEG); -static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func) + epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) == + BNX2X_FLOW_CTRL_RX); + epause->tx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) == + BNX2X_FLOW_CTRL_TX); + + DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n" + DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", + epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); +} + +static int bnx2x_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *epause) { - switch (func) { - case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0; - case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1; - case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2; - case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3; - case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4; - case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5; - case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6; - case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7; - default: - BNX2X_ERR("Unsupported function index: %d\n", func); - return (u32)(-1); + struct bnx2x *bp = netdev_priv(dev); + + if (IS_E1HMF(bp)) + return 0; + + DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n" + DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", + epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); + + bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + + if (epause->rx_pause) + bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX; + + if (epause->tx_pause) + bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX; + + if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) + bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + if (epause->autoneg) { + if (!(bp->port.supported & SUPPORTED_Autoneg)) { + DP(NETIF_MSG_LINK, "autoneg not supported\n"); + return -EINVAL; + } + + if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) + bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + } + + DP(NETIF_MSG_LINK, + "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl); + + if (netif_running(dev)) { + bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_link_set(bp); } + + return 0; } -static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) +static int bnx2x_set_flags(struct net_device *dev, u32 data) { - u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val; + struct bnx2x *bp = netdev_priv(dev); + int changed = 0; + int rc = 0; - /* Flush all outstanding writes */ - mmiowb(); + if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH)) + return -EINVAL; - /* Pretend to be function 0 */ - REG_WR(bp, reg, 0); - /* Flush the GRC transaction (in the chip) */ - new_val = REG_RD(bp, reg); - if (new_val != 0) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n", - new_val); - BUG(); + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + return -EAGAIN; } - /* From now we are in the "like-E1" mode */ - bnx2x_int_disable(bp); + /* TPA requires Rx CSUM offloading */ + if ((data & ETH_FLAG_LRO) && bp->rx_csum) { + if (!disable_tpa) { + if (!(dev->features & NETIF_F_LRO)) { + dev->features |= NETIF_F_LRO; + bp->flags |= TPA_ENABLE_FLAG; + changed = 1; + } + } else + rc = -EINVAL; + } else if (dev->features & NETIF_F_LRO) { + dev->features &= ~NETIF_F_LRO; + bp->flags &= ~TPA_ENABLE_FLAG; + changed = 1; + } - /* Flush all outstanding writes */ - mmiowb(); + if (data & ETH_FLAG_RXHASH) + dev->features |= NETIF_F_RXHASH; + else + dev->features &= ~NETIF_F_RXHASH; - /* Restore the original funtion settings */ - REG_WR(bp, reg, orig_func); - new_val = REG_RD(bp, reg); - if (new_val != orig_func) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n", - orig_func, new_val); - BUG(); + if (changed && netif_running(dev)) { + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + rc = bnx2x_nic_load(bp, LOAD_NORMAL); } + + return rc; } -static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func) +static u32 bnx2x_get_rx_csum(struct net_device *dev) { - if (CHIP_IS_E1H(bp)) - bnx2x_undi_int_disable_e1h(bp, func); - else - bnx2x_int_disable(bp); + struct bnx2x *bp = netdev_priv(dev); + + return bp->rx_csum; } -static void __devinit bnx2x_undi_unload(struct bnx2x *bp) +static int bnx2x_set_rx_csum(struct net_device *dev, u32 data) { - u32 val; + struct bnx2x *bp = netdev_priv(dev); + int rc = 0; - /* Check if there is any driver already loaded */ - val = REG_RD(bp, MISC_REG_UNPREPARED); - if (val == 0x1) { - /* Check if it is the UNDI driver - * UNDI driver initializes CID offset for normal bell to 0x7 - */ - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); - if (val == 0x7) { - u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - /* save our func */ - int func = BP_FUNC(bp); - u32 swap_en; - u32 swap_val; + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + return -EAGAIN; + } - /* clear the UNDI indication */ - REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); + bp->rx_csum = data; - BNX2X_DEV_INFO("UNDI is active! reset device\n"); + /* Disable TPA, when Rx CSUM is disabled. Otherwise all + TPA'ed packets will be discarded due to wrong TCP CSUM */ + if (!data) { + u32 flags = ethtool_op_get_flags(dev); - /* try unload UNDI on port 0 */ - bp->func = 0; - bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); - reset_code = bnx2x_fw_command(bp, reset_code); + rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO)); + } - /* if UNDI is loaded on the other port */ - if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { + return rc; +} - /* send "DONE" for previous unload */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); +static int bnx2x_set_tso(struct net_device *dev, u32 data) +{ + if (data) { + dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); + dev->features |= NETIF_F_TSO6; + } else { + dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN); + dev->features &= ~NETIF_F_TSO6; + } - /* unload UNDI on port 1 */ - bp->func = 1; - bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); - reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + return 0; +} - bnx2x_fw_command(bp, reset_code); - } +static const struct { + char string[ETH_GSTRING_LEN]; +} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { + { "register_test (offline)" }, + { "memory_test (offline)" }, + { "loopback_test (offline)" }, + { "nvram_test (online)" }, + { "interrupt_test (online)" }, + { "link_test (online)" }, + { "idle check (online)" } +}; - /* now it's safe to release the lock */ - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); +static int bnx2x_test_registers(struct bnx2x *bp) +{ + int idx, i, rc = -ENODEV; + u32 wr_val = 0; + int port = BP_PORT(bp); + static const struct { + u32 offset0; + u32 offset1; + u32 mask; + } reg_tbl[] = { +/* 0 */ { BRB1_REG_PAUSE_LOW_THRESHOLD_0, 4, 0x000003ff }, + { DORQ_REG_DB_ADDR0, 4, 0xffffffff }, + { HC_REG_AGG_INT_0, 4, 0x000003ff }, + { PBF_REG_MAC_IF0_ENABLE, 4, 0x00000001 }, + { PBF_REG_P0_INIT_CRD, 4, 0x000007ff }, + { PRS_REG_CID_PORT_0, 4, 0x00ffffff }, + { PXP2_REG_PSWRQ_CDU0_L2P, 4, 0x000fffff }, + { PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, + { PXP2_REG_PSWRQ_TM0_L2P, 4, 0x000fffff }, + { PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR, 8, 0x0003ffff }, +/* 10 */ { PXP2_REG_PSWRQ_TSDM0_L2P, 4, 0x000fffff }, + { QM_REG_CONNNUM_0, 4, 0x000fffff }, + { TM_REG_LIN0_MAX_ACTIVE_CID, 4, 0x0003ffff }, + { SRC_REG_KEYRSS0_0, 40, 0xffffffff }, + { SRC_REG_KEYRSS0_7, 40, 0xffffffff }, + { XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 }, + { XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 }, + { XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff }, + { NIG_REG_LLH0_T_BIT, 4, 0x00000001 }, + { NIG_REG_EMAC0_IN_EN, 4, 0x00000001 }, +/* 20 */ { NIG_REG_BMAC0_IN_EN, 4, 0x00000001 }, + { NIG_REG_XCM0_OUT_EN, 4, 0x00000001 }, + { NIG_REG_BRB0_OUT_EN, 4, 0x00000001 }, + { NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 }, + { NIG_REG_LLH0_ACPI_PAT_6_LEN, 68, 0x000000ff }, + { NIG_REG_LLH0_ACPI_PAT_0_CRC, 68, 0xffffffff }, + { NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff }, + { NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff }, + { NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 }, + { NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff }, +/* 30 */ { NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff }, + { NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff }, + { NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 }, + { NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 }, + { NIG_REG_STATUS_INTERRUPT_PORT0, 4, 0x07ffffff }, + { NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 }, + { NIG_REG_SERDES0_CTRL_PHY_ADDR, 16, 0x0000001f }, + + { 0xffffffff, 0, 0x00000000 } + }; - bnx2x_undi_int_disable(bp, func); + if (!netif_running(bp->dev)) + return rc; - /* close input traffic and wait for it */ - /* Do not rcv packets to BRB */ - REG_WR(bp, - (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : - NIG_REG_LLH0_BRB1_DRV_MASK), 0x0); - /* Do not direct rcv packets that are not for MCP to - * the BRB */ - REG_WR(bp, - (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_NOT_MCP : - NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); - /* clear AEU */ - REG_WR(bp, - (BP_PORT(bp) ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : - MISC_REG_AEU_MASK_ATTN_FUNC_0), 0); - msleep(10); + /* Repeat the test twice: + First by writing 0x00000000, second by writing 0xffffffff */ + for (idx = 0; idx < 2; idx++) { - /* save NIG port swap info */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_en = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - /* reset device */ - REG_WR(bp, - GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, - 0xd3ffffff); - REG_WR(bp, - GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - 0x1403); - /* take the NIG out of reset and restore swap values */ - REG_WR(bp, - GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, - MISC_REGISTERS_RESET_REG_1_RST_NIG); - REG_WR(bp, NIG_REG_PORT_SWAP, swap_val); - REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en); + switch (idx) { + case 0: + wr_val = 0; + break; + case 1: + wr_val = 0xffffffff; + break; + } - /* send unload done to the MCP */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { + u32 offset, mask, save_val, val; - /* restore our func and fw_seq */ - bp->func = func; - bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); + offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; + mask = reg_tbl[i].mask; - } else - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); + save_val = REG_RD(bp, offset); + + REG_WR(bp, offset, (wr_val & mask)); + val = REG_RD(bp, offset); + + /* Restore the original register's value */ + REG_WR(bp, offset, save_val); + + /* verify value is as expected */ + if ((val & mask) != (wr_val & mask)) { + DP(NETIF_MSG_PROBE, + "offset 0x%x: val 0x%x != 0x%x mask 0x%x\n", + offset, val, wr_val, mask); + goto test_reg_exit; + } + } } + + rc = 0; + +test_reg_exit: + return rc; } -static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) +static int bnx2x_test_memory(struct bnx2x *bp) { - u32 val, val2, val3, val4, id; - u16 pmc; + int i, j, rc = -ENODEV; + u32 val; + static const struct { + u32 offset; + int size; + } mem_tbl[] = { + { CCM_REG_XX_DESCR_TABLE, CCM_REG_XX_DESCR_TABLE_SIZE }, + { CFC_REG_ACTIVITY_COUNTER, CFC_REG_ACTIVITY_COUNTER_SIZE }, + { CFC_REG_LINK_LIST, CFC_REG_LINK_LIST_SIZE }, + { DMAE_REG_CMD_MEM, DMAE_REG_CMD_MEM_SIZE }, + { TCM_REG_XX_DESCR_TABLE, TCM_REG_XX_DESCR_TABLE_SIZE }, + { UCM_REG_XX_DESCR_TABLE, UCM_REG_XX_DESCR_TABLE_SIZE }, + { XCM_REG_XX_DESCR_TABLE, XCM_REG_XX_DESCR_TABLE_SIZE }, + + { 0xffffffff, 0 } + }; + static const struct { + char *name; + u32 offset; + u32 e1_mask; + u32 e1h_mask; + } prty_tbl[] = { + { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 }, + { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 }, + { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 }, + { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 }, + { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 }, + { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 }, + + { NULL, 0xffffffff, 0, 0 } + }; - /* Get the chip revision id and number. */ - /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ - val = REG_RD(bp, MISC_REG_CHIP_NUM); - id = ((val & 0xffff) << 16); - val = REG_RD(bp, MISC_REG_CHIP_REV); - id |= ((val & 0xf) << 12); - val = REG_RD(bp, MISC_REG_CHIP_METAL); - id |= ((val & 0xff) << 4); - val = REG_RD(bp, MISC_REG_BOND_ID); - id |= (val & 0xf); - bp->common.chip_id = id; - bp->link_params.chip_id = bp->common.chip_id; - BNX2X_DEV_INFO("chip ID is 0x%x\n", id); + if (!netif_running(bp->dev)) + return rc; - val = (REG_RD(bp, 0x2874) & 0x55); - if ((bp->common.chip_id & 0x1) || - (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) { - bp->flags |= ONE_PORT_FLAG; - BNX2X_DEV_INFO("single port device\n"); + /* Go through all the memories */ + for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) + for (j = 0; j < mem_tbl[i].size; j++) + REG_RD(bp, mem_tbl[i].offset + j*4); + + /* Check the parity status */ + for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { + val = REG_RD(bp, prty_tbl[i].offset); + if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || + (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) { + DP(NETIF_MSG_HW, + "%s is 0x%x\n", prty_tbl[i].name, val); + goto test_mem_exit; + } } - val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4); - bp->common.flash_size = (NVRAM_1MB_SIZE << - (val & MCPR_NVM_CFG4_FLASH_SIZE)); - BNX2X_DEV_INFO("flash_size 0x%x (%d)\n", - bp->common.flash_size, bp->common.flash_size); + rc = 0; - bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); - bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); - bp->link_params.shmem_base = bp->common.shmem_base; - BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", - bp->common.shmem_base, bp->common.shmem2_base); +test_mem_exit: + return rc; +} - if (!bp->common.shmem_base || - (bp->common.shmem_base < 0xA0000) || - (bp->common.shmem_base >= 0xC0000)) { - BNX2X_DEV_INFO("MCP not active\n"); - bp->flags |= NO_MCP_FLAG; - return; +static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up) +{ + int cnt = 1000; + + if (link_up) + while (bnx2x_link_test(bp) && cnt--) + msleep(10); +} + +static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) +{ + unsigned int pkt_size, num_pkts, i; + struct sk_buff *skb; + unsigned char *packet; + struct bnx2x_fastpath *fp_rx = &bp->fp[0]; + struct bnx2x_fastpath *fp_tx = &bp->fp[0]; + u16 tx_start_idx, tx_idx; + u16 rx_start_idx, rx_idx; + u16 pkt_prod, bd_prod; + struct sw_tx_bd *tx_buf; + struct eth_tx_start_bd *tx_start_bd; + struct eth_tx_parse_bd *pbd = NULL; + dma_addr_t mapping; + union eth_rx_cqe *cqe; + u8 cqe_fp_flags; + struct sw_rx_bd *rx_buf; + u16 len; + int rc = -ENODEV; + + /* check the loopback mode */ + switch (loopback_mode) { + case BNX2X_PHY_LOOPBACK: + if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10) + return -EINVAL; + break; + case BNX2X_MAC_LOOPBACK: + bp->link_params.loopback_mode = LOOPBACK_BMAC; + bnx2x_phy_init(&bp->link_params, &bp->link_vars); + break; + default: + return -EINVAL; } - val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); - if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - BNX2X_ERROR("BAD MCP validity signature\n"); + /* prepare the loopback packet */ + pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ? + bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN); + skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); + if (!skb) { + rc = -ENOMEM; + goto test_loopback_exit; + } + packet = skb_put(skb, pkt_size); + memcpy(packet, bp->dev->dev_addr, ETH_ALEN); + memset(packet + ETH_ALEN, 0, ETH_ALEN); + memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN)); + for (i = ETH_HLEN; i < pkt_size; i++) + packet[i] = (unsigned char) (i & 0xff); + + /* send the loopback packet */ + num_pkts = 0; + tx_start_idx = le16_to_cpu(*fp_tx->tx_cons_sb); + rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb); + + pkt_prod = fp_tx->tx_pkt_prod++; + tx_buf = &fp_tx->tx_buf_ring[TX_BD(pkt_prod)]; + tx_buf->first_bd = fp_tx->tx_bd_prod; + tx_buf->skb = skb; + tx_buf->flags = 0; + + bd_prod = TX_BD(fp_tx->tx_bd_prod); + tx_start_bd = &fp_tx->tx_desc_ring[bd_prod].start_bd; + mapping = dma_map_single(&bp->pdev->dev, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */ + tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); + tx_start_bd->vlan = cpu_to_le16(pkt_prod); + tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; + tx_start_bd->general_data = ((UNICAST_ADDRESS << + ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1); + + /* turn on parsing and get a BD */ + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd; + + memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); - bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); - BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config); + wmb(); - bp->link_params.hw_led_mode = ((bp->common.hw_config & - SHARED_HW_CFG_LED_MODE_MASK) >> - SHARED_HW_CFG_LED_MODE_SHIFT); + fp_tx->tx_db.data.prod += 2; + barrier(); + DOORBELL(bp, fp_tx->index, fp_tx->tx_db.raw); - bp->link_params.feature_config_flags = 0; - val = SHMEM_RD(bp, dev_info.shared_feature_config.config); - if (val & SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED) - bp->link_params.feature_config_flags |= - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED; - else - bp->link_params.feature_config_flags &= - ~FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED; + mmiowb(); - val = SHMEM_RD(bp, dev_info.bc_rev) >> 8; - bp->common.bc_ver = val; - BNX2X_DEV_INFO("bc_ver %X\n", val); - if (val < BNX2X_BC_VER) { - /* for now only warn - * later we might need to enforce this */ - BNX2X_ERROR("This driver needs bc_ver %X but found %X, " - "please upgrade BC\n", BNX2X_BC_VER, val); - } - bp->link_params.feature_config_flags |= - (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ? - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + num_pkts++; + fp_tx->tx_bd_prod += 2; /* start + pbd */ - if (BP_E1HVN(bp) == 0) { - pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc); - bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG; - } else { - /* no WOL capability for E1HVN != 0 */ - bp->flags |= NO_WOL_FLAG; - } - BNX2X_DEV_INFO("%sWoL capable\n", - (bp->flags & NO_WOL_FLAG) ? "not " : ""); + udelay(100); - val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num); - val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]); - val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]); - val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]); + tx_idx = le16_to_cpu(*fp_tx->tx_cons_sb); + if (tx_idx != tx_start_idx + num_pkts) + goto test_loopback_exit; - dev_info(&bp->pdev->dev, "part number %X-%X-%X-%X\n", - val, val2, val3, val4); -} + rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); + if (rx_idx != rx_start_idx + num_pkts) + goto test_loopback_exit; -static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, - u32 switch_cfg) -{ - int port = BP_PORT(bp); - u32 ext_phy_type; + cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)]; + cqe_fp_flags = cqe->fast_path_cqe.type_error_flags; + if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS)) + goto test_loopback_rx_exit; - switch (switch_cfg) { - case SWITCH_CFG_1G: - BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg); + len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); + if (len != pkt_size) + goto test_loopback_rx_exit; - ext_phy_type = - SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", - ext_phy_type); + rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)]; + skb = rx_buf->skb; + skb_reserve(skb, cqe->fast_path_cqe.placement_offset); + for (i = ETH_HLEN; i < pkt_size; i++) + if (*(skb->data + i) != (unsigned char) (i & 0xff)) + goto test_loopback_rx_exit; - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + rc = 0; - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n", - ext_phy_type); +test_loopback_rx_exit: - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + fp_rx->rx_bd_cons = NEXT_RX_IDX(fp_rx->rx_bd_cons); + fp_rx->rx_bd_prod = NEXT_RX_IDX(fp_rx->rx_bd_prod); + fp_rx->rx_comp_cons = NEXT_RCQ_IDX(fp_rx->rx_comp_cons); + fp_rx->rx_comp_prod = NEXT_RCQ_IDX(fp_rx->rx_comp_prod); - default: - BNX2X_ERR("NVRAM config error. " - "BAD SerDes ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); - return; - } + /* Update producers */ + bnx2x_update_rx_prod(bp, fp_rx, fp_rx->rx_bd_prod, fp_rx->rx_comp_prod, + fp_rx->rx_sge_prod); - bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + - port*0x10); - BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - break; +test_loopback_exit: + bp->link_params.loopback_mode = LOOPBACK_NONE; - case SWITCH_CFG_10G: - BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg); + return rc; +} - ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", - ext_phy_type); +static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) +{ + int rc = 0, res; - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + if (BP_NOMCP(bp)) + return rc; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", - ext_phy_type); + if (!netif_running(bp->dev)) + return BNX2X_LOOPBACK_FAILED; - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + bnx2x_netif_stop(bp, 1); + bnx2x_acquire_phy_lock(bp); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", - ext_phy_type); + res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up); + if (res) { + DP(NETIF_MSG_PROBE, " PHY loopback failed (res %d)\n", res); + rc |= BNX2X_PHY_LOOPBACK_FAILED; + } - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up); + if (res) { + DP(NETIF_MSG_PROBE, " MAC loopback failed (res %d)\n", res); + rc |= BNX2X_MAC_LOOPBACK_FAILED; + } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", - ext_phy_type); + bnx2x_release_phy_lock(bp); + bnx2x_netif_start(bp); - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + return rc; +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", - ext_phy_type); +#define CRC32_RESIDUAL 0xdebb20e3 + +static int bnx2x_test_nvram(struct bnx2x *bp) +{ + static const struct { + int offset; + int size; + } nvram_tbl[] = { + { 0, 0x14 }, /* bootstrap */ + { 0x14, 0xec }, /* dir */ + { 0x100, 0x350 }, /* manuf_info */ + { 0x450, 0xf0 }, /* feature_info */ + { 0x640, 0x64 }, /* upgrade_key_info */ + { 0x6a4, 0x64 }, + { 0x708, 0x70 }, /* manuf_key_info */ + { 0x778, 0x70 }, + { 0, 0 } + }; + __be32 buf[0x350 / 4]; + u8 *data = (u8 *)buf; + int i, rc; + u32 magic, crc; - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + if (BP_NOMCP(bp)) + return 0; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n", - ext_phy_type); + rc = bnx2x_nvram_read(bp, 0, data, 4); + if (rc) { + DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc); + goto test_nvram_exit; + } - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + magic = be32_to_cpu(buf[0]); + if (magic != 0x669955aa) { + DP(NETIF_MSG_PROBE, "magic value (0x%08x)\n", magic); + rc = -ENODEV; + goto test_nvram_exit; + } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n", - ext_phy_type); + for (i = 0; nvram_tbl[i].size; i++) { - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + rc = bnx2x_nvram_read(bp, nvram_tbl[i].offset, data, + nvram_tbl[i].size); + if (rc) { + DP(NETIF_MSG_PROBE, + "nvram_tbl[%d] read data (rc %d)\n", i, rc); + goto test_nvram_exit; + } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n", - ext_phy_type); + crc = ether_crc_le(nvram_tbl[i].size, data); + if (crc != CRC32_RESIDUAL) { + DP(NETIF_MSG_PROBE, + "nvram_tbl[%d] crc value (0x%08x)\n", i, crc); + rc = -ENODEV; + goto test_nvram_exit; + } + } - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; +test_nvram_exit: + return rc; +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n", - ext_phy_type); +static int bnx2x_test_intr(struct bnx2x *bp) +{ + struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); + int i, rc; - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + if (!netif_running(bp->dev)) + return -ENODEV; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", - bp->link_params.ext_phy_config); - break; + config->hdr.length = 0; + if (CHIP_IS_E1(bp)) + /* use last unicast entries */ + config->hdr.offset = (BP_PORT(bp) ? 63 : 31); + else + config->hdr.offset = BP_FUNC(bp); + config->hdr.client_id = bp->fp->cl_id; + config->hdr.reserved1 = 0; - default: - BNX2X_ERR("NVRAM config error. " - "BAD XGXS ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); - return; + bp->set_mac_pending++; + smp_wmb(); + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + U64_HI(bnx2x_sp_mapping(bp, mac_config)), + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + if (rc == 0) { + for (i = 0; i < 10; i++) { + if (!bp->set_mac_pending) + break; + smp_rmb(); + msleep_interruptible(10); } + if (i == 10) + rc = -ENODEV; + } - bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + - port*0x18); - BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); + return rc; +} - break; +static void bnx2x_self_test(struct net_device *dev, + struct ethtool_test *etest, u64 *buf) +{ + struct bnx2x *bp = netdev_priv(dev); - default: - BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", - bp->port.link_config); + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + etest->flags |= ETH_TEST_FL_FAILED; return; } - bp->link_params.phy_addr = bp->port.phy_addr; - /* mask what we support according to speed_cap_mask */ - if (!(bp->link_params.speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) - bp->port.supported &= ~SUPPORTED_10baseT_Half; + memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS); - if (!(bp->link_params.speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL)) - bp->port.supported &= ~SUPPORTED_10baseT_Full; + if (!netif_running(dev)) + return; - if (!(bp->link_params.speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) - bp->port.supported &= ~SUPPORTED_100baseT_Half; + /* offline tests are not supported in MF mode */ + if (IS_E1HMF(bp)) + etest->flags &= ~ETH_TEST_FL_OFFLINE; - if (!(bp->link_params.speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL)) - bp->port.supported &= ~SUPPORTED_100baseT_Full; + if (etest->flags & ETH_TEST_FL_OFFLINE) { + int port = BP_PORT(bp); + u32 val; + u8 link_up; - if (!(bp->link_params.speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) - bp->port.supported &= ~(SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); + /* save current value of input enable for TX port IF */ + val = REG_RD(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4); + /* disable input for TX port IF */ + REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0); - if (!(bp->link_params.speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - bp->port.supported &= ~SUPPORTED_2500baseX_Full; + link_up = (bnx2x_link_test(bp) == 0); + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + bnx2x_nic_load(bp, LOAD_DIAG); + /* wait until link state is restored */ + bnx2x_wait_for_link(bp, link_up); - if (!(bp->link_params.speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) - bp->port.supported &= ~SUPPORTED_10000baseT_Full; + if (bnx2x_test_registers(bp) != 0) { + buf[0] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + if (bnx2x_test_memory(bp) != 0) { + buf[1] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + buf[2] = bnx2x_test_loopback(bp, link_up); + if (buf[2] != 0) + etest->flags |= ETH_TEST_FL_FAILED; - BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported); + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + + /* restore input for TX port IF */ + REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val); + + bnx2x_nic_load(bp, LOAD_NORMAL); + /* wait until link state is restored */ + bnx2x_wait_for_link(bp, link_up); + } + if (bnx2x_test_nvram(bp) != 0) { + buf[3] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + if (bnx2x_test_intr(bp) != 0) { + buf[4] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + if (bp->port.pmf) + if (bnx2x_link_test(bp) != 0) { + buf[5] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + +#ifdef BNX2X_EXTRA_DEBUG + bnx2x_panic_dump(bp); +#endif } -static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) -{ - bp->link_params.req_duplex = DUPLEX_FULL; +static const struct { + long offset; + int size; + u8 string[ETH_GSTRING_LEN]; +} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = { +/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" }, + { Q_STATS_OFFSET32(error_bytes_received_hi), + 8, "[%d]: rx_error_bytes" }, + { Q_STATS_OFFSET32(total_unicast_packets_received_hi), + 8, "[%d]: rx_ucast_packets" }, + { Q_STATS_OFFSET32(total_multicast_packets_received_hi), + 8, "[%d]: rx_mcast_packets" }, + { Q_STATS_OFFSET32(total_broadcast_packets_received_hi), + 8, "[%d]: rx_bcast_packets" }, + { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" }, + { Q_STATS_OFFSET32(rx_err_discard_pkt), + 4, "[%d]: rx_phy_ip_err_discards"}, + { Q_STATS_OFFSET32(rx_skb_alloc_failed), + 4, "[%d]: rx_skb_alloc_discard" }, + { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" }, + +/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" }, + { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), + 8, "[%d]: tx_ucast_packets" }, + { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi), + 8, "[%d]: tx_mcast_packets" }, + { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + 8, "[%d]: tx_bcast_packets" } +}; - switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) { - case PORT_FEATURE_LINK_SPEED_AUTO: - if (bp->port.supported & SUPPORTED_Autoneg) { - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; - } else { - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); +static const struct { + long offset; + int size; + u32 flags; +#define STATS_FLAGS_PORT 1 +#define STATS_FLAGS_FUNC 2 +#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT) + u8 string[ETH_GSTRING_LEN]; +} bnx2x_stats_arr[BNX2X_NUM_STATS] = { +/* 1 */ { STATS_OFFSET32(total_bytes_received_hi), + 8, STATS_FLAGS_BOTH, "rx_bytes" }, + { STATS_OFFSET32(error_bytes_received_hi), + 8, STATS_FLAGS_BOTH, "rx_error_bytes" }, + { STATS_OFFSET32(total_unicast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_ucast_packets" }, + { STATS_OFFSET32(total_multicast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_mcast_packets" }, + { STATS_OFFSET32(total_broadcast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_bcast_packets" }, + { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi), + 8, STATS_FLAGS_PORT, "rx_crc_errors" }, + { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi), + 8, STATS_FLAGS_PORT, "rx_align_errors" }, + { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi), + 8, STATS_FLAGS_PORT, "rx_undersize_packets" }, + { STATS_OFFSET32(etherstatsoverrsizepkts_hi), + 8, STATS_FLAGS_PORT, "rx_oversize_packets" }, +/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi), + 8, STATS_FLAGS_PORT, "rx_fragments" }, + { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), + 8, STATS_FLAGS_PORT, "rx_jabbers" }, + { STATS_OFFSET32(no_buff_discard_hi), + 8, STATS_FLAGS_BOTH, "rx_discards" }, + { STATS_OFFSET32(mac_filter_discard), + 4, STATS_FLAGS_PORT, "rx_filtered_packets" }, + { STATS_OFFSET32(xxoverflow_discard), + 4, STATS_FLAGS_PORT, "rx_fw_discards" }, + { STATS_OFFSET32(brb_drop_hi), + 8, STATS_FLAGS_PORT, "rx_brb_discard" }, + { STATS_OFFSET32(brb_truncate_hi), + 8, STATS_FLAGS_PORT, "rx_brb_truncate" }, + { STATS_OFFSET32(pause_frames_received_hi), + 8, STATS_FLAGS_PORT, "rx_pause_frames" }, + { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi), + 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" }, + { STATS_OFFSET32(nig_timer_max), + 4, STATS_FLAGS_PORT, "rx_constant_pause_events" }, +/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt), + 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"}, + { STATS_OFFSET32(rx_skb_alloc_failed), + 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" }, + { STATS_OFFSET32(hw_csum_err), + 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" }, + + { STATS_OFFSET32(total_bytes_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_bytes" }, + { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), + 8, STATS_FLAGS_PORT, "tx_error_bytes" }, + { STATS_OFFSET32(total_unicast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_ucast_packets" }, + { STATS_OFFSET32(total_multicast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_mcast_packets" }, + { STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_bcast_packets" }, + { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi), + 8, STATS_FLAGS_PORT, "tx_mac_errors" }, + { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi), + 8, STATS_FLAGS_PORT, "tx_carrier_errors" }, +/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi), + 8, STATS_FLAGS_PORT, "tx_single_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi), + 8, STATS_FLAGS_PORT, "tx_multi_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi), + 8, STATS_FLAGS_PORT, "tx_deferred" }, + { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi), + 8, STATS_FLAGS_PORT, "tx_excess_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi), + 8, STATS_FLAGS_PORT, "tx_late_collisions" }, + { STATS_OFFSET32(tx_stat_etherstatscollisions_hi), + 8, STATS_FLAGS_PORT, "tx_total_collisions" }, + { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi), + 8, STATS_FLAGS_PORT, "tx_64_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi), + 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi), + 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi), + 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" }, +/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi), + 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" }, + { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi), + 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" }, + { STATS_OFFSET32(etherstatspktsover1522octets_hi), + 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" }, + { STATS_OFFSET32(pause_frames_sent_hi), + 8, STATS_FLAGS_PORT, "tx_pause_frames" } +}; - if ((ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) { - /* force 10G, no AN */ - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = - (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - break; - } - BNX2X_ERR("NVRAM config error. " - "Invalid link_config 0x%x" - " Autoneg not supported\n", - bp->port.link_config); - return; - } - break; +#define IS_PORT_STAT(i) \ + ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) +#define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) +#define IS_E1HMF_MODE_STAT(bp) \ + (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) - case PORT_FEATURE_LINK_SPEED_10M_FULL: - if (bp->port.supported & SUPPORTED_10baseT_Full) { - bp->link_params.req_line_speed = SPEED_10; - bp->port.advertising = (ADVERTISED_10baseT_Full | - ADVERTISED_TP); +static int bnx2x_get_sset_count(struct net_device *dev, int stringset) +{ + struct bnx2x *bp = netdev_priv(dev); + int i, num_stats; + + switch (stringset) { + case ETH_SS_STATS: + if (is_multi(bp)) { + num_stats = BNX2X_NUM_Q_STATS * bp->num_queues; + if (!IS_E1HMF_MODE_STAT(bp)) + num_stats += BNX2X_NUM_STATS; } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; + if (IS_E1HMF_MODE_STAT(bp)) { + num_stats = 0; + for (i = 0; i < BNX2X_NUM_STATS; i++) + if (IS_FUNC_STAT(i)) + num_stats++; + } else + num_stats = BNX2X_NUM_STATS; } - break; + return num_stats; - case PORT_FEATURE_LINK_SPEED_10M_HALF: - if (bp->port.supported & SUPPORTED_10baseT_Half) { - bp->link_params.req_line_speed = SPEED_10; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_10baseT_Half | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } - break; + case ETH_SS_TEST: + return BNX2X_NUM_TESTS; - case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->port.supported & SUPPORTED_100baseT_Full) { - bp->link_params.req_line_speed = SPEED_100; - bp->port.advertising = (ADVERTISED_100baseT_Full | - ADVERTISED_TP); + default: + return -EINVAL; + } +} + +static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) +{ + struct bnx2x *bp = netdev_priv(dev); + int i, j, k; + + switch (stringset) { + case ETH_SS_STATS: + if (is_multi(bp)) { + k = 0; + for_each_queue(bp, i) { + for (j = 0; j < BNX2X_NUM_Q_STATS; j++) + sprintf(buf + (k + j)*ETH_GSTRING_LEN, + bnx2x_q_stats_arr[j].string, i); + k += BNX2X_NUM_Q_STATS; + } + if (IS_E1HMF_MODE_STAT(bp)) + break; + for (j = 0; j < BNX2X_NUM_STATS; j++) + strcpy(buf + (k + j)*ETH_GSTRING_LEN, + bnx2x_stats_arr[j].string); } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; + for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { + if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + continue; + strcpy(buf + j*ETH_GSTRING_LEN, + bnx2x_stats_arr[i].string); + j++; + } } break; - case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->port.supported & SUPPORTED_100baseT_Half) { - bp->link_params.req_line_speed = SPEED_100; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_100baseT_Half | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } + case ETH_SS_TEST: + memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr)); break; + } +} - case PORT_FEATURE_LINK_SPEED_1G: - if (bp->port.supported & SUPPORTED_1000baseT_Full) { - bp->link_params.req_line_speed = SPEED_1000; - bp->port.advertising = (ADVERTISED_1000baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); +static void bnx2x_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *buf) +{ + struct bnx2x *bp = netdev_priv(dev); + u32 *hw_stats, *offset; + int i, j, k; + + if (is_multi(bp)) { + k = 0; + for_each_queue(bp, i) { + hw_stats = (u32 *)&bp->fp[i].eth_q_stats; + for (j = 0; j < BNX2X_NUM_Q_STATS; j++) { + if (bnx2x_q_stats_arr[j].size == 0) { + /* skip this counter */ + buf[k + j] = 0; + continue; + } + offset = (hw_stats + + bnx2x_q_stats_arr[j].offset); + if (bnx2x_q_stats_arr[j].size == 4) { + /* 4-byte counter */ + buf[k + j] = (u64) *offset; + continue; + } + /* 8-byte counter */ + buf[k + j] = HILO_U64(*offset, *(offset + 1)); + } + k += BNX2X_NUM_Q_STATS; + } + if (IS_E1HMF_MODE_STAT(bp)) return; + hw_stats = (u32 *)&bp->eth_stats; + for (j = 0; j < BNX2X_NUM_STATS; j++) { + if (bnx2x_stats_arr[j].size == 0) { + /* skip this counter */ + buf[k + j] = 0; + continue; + } + offset = (hw_stats + bnx2x_stats_arr[j].offset); + if (bnx2x_stats_arr[j].size == 4) { + /* 4-byte counter */ + buf[k + j] = (u64) *offset; + continue; + } + /* 8-byte counter */ + buf[k + j] = HILO_U64(*offset, *(offset + 1)); } - break; + } else { + hw_stats = (u32 *)&bp->eth_stats; + for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { + if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + continue; + if (bnx2x_stats_arr[i].size == 0) { + /* skip this counter */ + buf[j] = 0; + j++; + continue; + } + offset = (hw_stats + bnx2x_stats_arr[i].offset); + if (bnx2x_stats_arr[i].size == 4) { + /* 4-byte counter */ + buf[j] = (u64) *offset; + j++; + continue; + } + /* 8-byte counter */ + buf[j] = HILO_U64(*offset, *(offset + 1)); + j++; + } + } +} + +static int bnx2x_phys_id(struct net_device *dev, u32 data) +{ + struct bnx2x *bp = netdev_priv(dev); + int i; + + if (!netif_running(dev)) + return 0; + + if (!bp->port.pmf) + return 0; + + if (data == 0) + data = 2; + + for (i = 0; i < (data * 2); i++) { + if ((i % 2) == 0) + bnx2x_set_led(&bp->link_params, LED_MODE_OPER, + SPEED_1000); + else + bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0); + + msleep_interruptible(500); + if (signal_pending(current)) + break; + } + + if (bp->link_vars.link_up) + bnx2x_set_led(&bp->link_params, LED_MODE_OPER, + bp->link_vars.line_speed); + + return 0; +} + +static const struct ethtool_ops bnx2x_ethtool_ops = { + .get_settings = bnx2x_get_settings, + .set_settings = bnx2x_set_settings, + .get_drvinfo = bnx2x_get_drvinfo, + .get_regs_len = bnx2x_get_regs_len, + .get_regs = bnx2x_get_regs, + .get_wol = bnx2x_get_wol, + .set_wol = bnx2x_set_wol, + .get_msglevel = bnx2x_get_msglevel, + .set_msglevel = bnx2x_set_msglevel, + .nway_reset = bnx2x_nway_reset, + .get_link = bnx2x_get_link, + .get_eeprom_len = bnx2x_get_eeprom_len, + .get_eeprom = bnx2x_get_eeprom, + .set_eeprom = bnx2x_set_eeprom, + .get_coalesce = bnx2x_get_coalesce, + .set_coalesce = bnx2x_set_coalesce, + .get_ringparam = bnx2x_get_ringparam, + .set_ringparam = bnx2x_set_ringparam, + .get_pauseparam = bnx2x_get_pauseparam, + .set_pauseparam = bnx2x_set_pauseparam, + .get_rx_csum = bnx2x_get_rx_csum, + .set_rx_csum = bnx2x_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_hw_csum, + .set_flags = bnx2x_set_flags, + .get_flags = ethtool_op_get_flags, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = bnx2x_set_tso, + .self_test = bnx2x_self_test, + .get_sset_count = bnx2x_get_sset_count, + .get_strings = bnx2x_get_strings, + .phys_id = bnx2x_phys_id, + .get_ethtool_stats = bnx2x_get_ethtool_stats, +}; + +/* end of ethtool_ops */ + +/**************************************************************************** +* General service functions +****************************************************************************/ - case PORT_FEATURE_LINK_SPEED_2_5G: - if (bp->port.supported & SUPPORTED_2500baseX_Full) { - bp->link_params.req_line_speed = SPEED_2500; - bp->port.advertising = (ADVERTISED_2500baseX_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } +static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) +{ + u16 pmcsr; + + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); + + switch (state) { + case PCI_D0: + pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, + ((pmcsr & ~PCI_PM_CTRL_STATE_MASK) | + PCI_PM_CTRL_PME_STATUS)); + + if (pmcsr & PCI_PM_CTRL_STATE_MASK) + /* delay required during transition out of D3hot */ + msleep(20); break; - case PORT_FEATURE_LINK_SPEED_10G_CX4: - case PORT_FEATURE_LINK_SPEED_10G_KX4: - case PORT_FEATURE_LINK_SPEED_10G_KR: - if (bp->port.supported & SUPPORTED_10000baseT_Full) { - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } + case PCI_D3hot: + /* If there are other clients above don't + shut down the power */ + if (atomic_read(&bp->pdev->enable_cnt) != 1) + return 0; + /* Don't shut down the power for emulation and FPGA */ + if (CHIP_REV_IS_SLOW(bp)) + return 0; + + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= 3; + + if (bp->wol) + pmcsr |= PCI_PM_CTRL_PME_ENABLE; + + pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, + pmcsr); + + /* No more memory access after this point until + * device is brought back to D0. + */ break; default: - BNX2X_ERROR("NVRAM config error. " - "BAD link speed link_config 0x%x\n", - bp->port.link_config); - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; - break; + return -EINVAL; } - - bp->link_params.req_flow_ctrl = (bp->port.link_config & - PORT_FEATURE_FLOW_CONTROL_MASK); - if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - !(bp->port.supported & SUPPORTED_Autoneg)) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x" - " advertising 0x%x\n", - bp->link_params.req_line_speed, - bp->link_params.req_duplex, - bp->link_params.req_flow_ctrl, bp->port.advertising); + return 0; } -static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) +static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) { - mac_hi = cpu_to_be16(mac_hi); - mac_lo = cpu_to_be32(mac_lo); - memcpy(mac_buf, &mac_hi, sizeof(mac_hi)); - memcpy(mac_buf + sizeof(mac_hi), &mac_lo, sizeof(mac_lo)); + u16 rx_cons_sb; + + /* Tell compiler that status block fields can change */ + barrier(); + rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); + if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) + rx_cons_sb++; + return (fp->rx_comp_cons != rx_cons_sb); } -static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) +/* + * net_device service functions + */ + +static int bnx2x_poll(struct napi_struct *napi, int budget) { - int port = BP_PORT(bp); - u32 val, val2; - u32 config; - u16 i; - u32 ext_phy_type; + int work_done = 0; + struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath, + napi); + struct bnx2x *bp = fp->bp; - bp->link_params.bp = bp; - bp->link_params.port = port; + while (1) { +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) { + napi_complete(napi); + return 0; + } +#endif - bp->link_params.lane_config = - SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); - bp->link_params.ext_phy_config = - SHMEM_RD(bp, - dev_info.port_hw_config[port].external_phy_config); - /* BCM8727_NOC => BCM8727 no over current */ - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) { - bp->link_params.ext_phy_config &= - ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; - bp->link_params.ext_phy_config |= - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727; - bp->link_params.feature_config_flags |= - FEATURE_CONFIG_BCM8727_NOC; + if (bnx2x_has_tx_work(fp)) + bnx2x_tx_int(fp); + + if (bnx2x_has_rx_work(fp)) { + work_done += bnx2x_rx_int(fp, budget - work_done); + + /* must not complete if we consumed full budget */ + if (work_done >= budget) + break; + } + + /* Fall out from the NAPI loop if needed */ + if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { + bnx2x_update_fpsb_idx(fp); + /* bnx2x_has_rx_work() reads the status block, thus we need + * to ensure that status block indices have been actually read + * (bnx2x_update_fpsb_idx) prior to this check + * (bnx2x_has_rx_work) so that we won't write the "newer" + * value of the status block to IGU (if there was a DMA right + * after bnx2x_has_rx_work and if there is no rmb, the memory + * reading (bnx2x_update_fpsb_idx) may be postponed to right + * before bnx2x_ack_sb). In this case there will never be + * another interrupt until there is another update of the + * status block, while there is still unhandled work. + */ + rmb(); + + if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { + napi_complete(napi); + /* Re-enable interrupts */ + bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, + le16_to_cpu(fp->fp_c_idx), + IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, + le16_to_cpu(fp->fp_u_idx), + IGU_INT_ENABLE, 1); + break; + } + } } - bp->link_params.speed_cap_mask = - SHMEM_RD(bp, - dev_info.port_hw_config[port].speed_capability_mask); + return work_done; +} - bp->port.link_config = - SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); - /* Get the 4 lanes xgxs config rx and tx */ - for (i = 0; i < 2; i++) { - val = SHMEM_RD(bp, - dev_info.port_hw_config[port].xgxs_config_rx[i<<1]); - bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff); - bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff); +/* we split the first BD into headers and data BDs + * to ease the pain of our fellow microcode engineers + * we use one mapping for both BDs + * So far this has only been observed to happen + * in Other Operating Systems(TM) + */ +static noinline u16 bnx2x_tx_split(struct bnx2x *bp, + struct bnx2x_fastpath *fp, + struct sw_tx_bd *tx_buf, + struct eth_tx_start_bd **tx_bd, u16 hlen, + u16 bd_prod, int nbd) +{ + struct eth_tx_start_bd *h_tx_bd = *tx_bd; + struct eth_tx_bd *d_tx_bd; + dma_addr_t mapping; + int old_len = le16_to_cpu(h_tx_bd->nbytes); - val = SHMEM_RD(bp, - dev_info.port_hw_config[port].xgxs_config_tx[i<<1]); - bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff); - bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff); - } + /* first fix first BD */ + h_tx_bd->nbd = cpu_to_le16(nbd); + h_tx_bd->nbytes = cpu_to_le16(hlen); - /* If the device is capable of WoL, set the default state according - * to the HW - */ - config = SHMEM_RD(bp, dev_info.port_feature_config[port].config); - bp->wol = (!(bp->flags & NO_WOL_FLAG) && - (config & PORT_FEATURE_WOL_ENABLED)); + DP(NETIF_MSG_TX_QUEUED, "TSO split header size is %d " + "(%x:%x) nbd %d\n", h_tx_bd->nbytes, h_tx_bd->addr_hi, + h_tx_bd->addr_lo, h_tx_bd->nbd); - BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x" - " speed_cap_mask 0x%08x link_config 0x%08x\n", - bp->link_params.lane_config, - bp->link_params.ext_phy_config, - bp->link_params.speed_cap_mask, bp->port.link_config); + /* now get a new data BD + * (after the pbd) and fill it */ + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + d_tx_bd = &fp->tx_desc_ring[bd_prod].reg_bd; - bp->link_params.switch_cfg |= (bp->port.link_config & - PORT_FEATURE_CONNECTED_SWITCH_MASK); - bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); + mapping = HILO_U64(le32_to_cpu(h_tx_bd->addr_hi), + le32_to_cpu(h_tx_bd->addr_lo)) + hlen; - bnx2x_link_settings_requested(bp); + d_tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + d_tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + d_tx_bd->nbytes = cpu_to_le16(old_len - hlen); - /* - * If connected directly, work with the internal PHY, otherwise, work - * with the external PHY - */ - ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) - bp->mdio.prtad = bp->link_params.phy_addr; + /* this marks the BD as one that has no individual mapping */ + tx_buf->flags |= BNX2X_TSO_SPLIT_BD; - else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) - bp->mdio.prtad = - XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); + DP(NETIF_MSG_TX_QUEUED, + "TSO split data size is %d (%x:%x)\n", + d_tx_bd->nbytes, d_tx_bd->addr_hi, d_tx_bd->addr_lo); - val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); - val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); - bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); - memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); + /* update tx_bd */ + *tx_bd = (struct eth_tx_start_bd *)d_tx_bd; -#ifdef BCM_CNIC - val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_upper); - val = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_lower); - bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); -#endif + return bd_prod; } -static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) +static inline u16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) { - int func = BP_FUNC(bp); - u32 val, val2; - int rc = 0; + if (fix > 0) + csum = (u16) ~csum_fold(csum_sub(csum, + csum_partial(t_header - fix, fix, 0))); - bnx2x_get_common_hwinfo(bp); + else if (fix < 0) + csum = (u16) ~csum_fold(csum_add(csum, + csum_partial(t_header, -fix, 0))); - bp->e1hov = 0; - bp->e1hmf = 0; - if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { - bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + return swab16(csum); +} - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[FUNC_0].e1hov_tag) & - FUNC_MF_CFG_E1HOV_TAG_MASK); - if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) - bp->e1hmf = 1; - BNX2X_DEV_INFO("%s function mode\n", - IS_E1HMF(bp) ? "multi" : "single"); +static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) +{ + u32 rc; + + if (skb->ip_summed != CHECKSUM_PARTIAL) + rc = XMIT_PLAIN; + + else { + if (skb->protocol == htons(ETH_P_IPV6)) { + rc = XMIT_CSUM_V6; + if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) + rc |= XMIT_CSUM_TCP; - if (IS_E1HMF(bp)) { - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func]. - e1hov_tag) & - FUNC_MF_CFG_E1HOV_TAG_MASK); - if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - bp->e1hov = val; - BNX2X_DEV_INFO("E1HOV for func %d is %d " - "(0x%04x)\n", - func, bp->e1hov, bp->e1hov); - } else { - BNX2X_ERROR("No valid E1HOV for func %d," - " aborting\n", func); - rc = -EPERM; - } } else { - if (BP_E1HVN(bp)) { - BNX2X_ERROR("VN %d in single function mode," - " aborting\n", BP_E1HVN(bp)); - rc = -EPERM; - } + rc = XMIT_CSUM_V4; + if (ip_hdr(skb)->protocol == IPPROTO_TCP) + rc |= XMIT_CSUM_TCP; } } - if (!BP_NOMCP(bp)) { - bnx2x_get_port_hwinfo(bp); + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) + rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP); - bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); - BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); - } + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6); - if (IS_E1HMF(bp)) { - val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper); - val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower); - if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && - (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { - bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); - bp->dev->dev_addr[1] = (u8)(val2 & 0xff); - bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff); - bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff); - bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff); - bp->dev->dev_addr[5] = (u8)(val & 0xff); - memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, - ETH_ALEN); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, - ETH_ALEN); + return rc; +} + +#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) +/* check if packet requires linearization (packet is too fragmented) + no need to check fragmentation if page size > 8K (there will be no + violation to FW restrictions) */ +static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, + u32 xmit_type) +{ + int to_copy = 0; + int hlen = 0; + int first_bd_sz = 0; + + /* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */ + if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) { + + if (xmit_type & XMIT_GSO) { + unsigned short lso_mss = skb_shinfo(skb)->gso_size; + /* Check if LSO packet needs to be copied: + 3 = 1 (for headers BD) + 2 (for PBD and last BD) */ + int wnd_size = MAX_FETCH_BD - 3; + /* Number of windows to check */ + int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size; + int wnd_idx = 0; + int frag_idx = 0; + u32 wnd_sum = 0; + + /* Headers length */ + hlen = (int)(skb_transport_header(skb) - skb->data) + + tcp_hdrlen(skb); + + /* Amount of data (w/o headers) on linear part of SKB*/ + first_bd_sz = skb_headlen(skb) - hlen; + + wnd_sum = first_bd_sz; + + /* Calculate the first sum - it's special */ + for (frag_idx = 0; frag_idx < wnd_size - 1; frag_idx++) + wnd_sum += + skb_shinfo(skb)->frags[frag_idx].size; + + /* If there was data on linear skb data - check it */ + if (first_bd_sz > 0) { + if (unlikely(wnd_sum < lso_mss)) { + to_copy = 1; + goto exit_lbl; + } + + wnd_sum -= first_bd_sz; + } + + /* Others are easier: run through the frag list and + check all windows */ + for (wnd_idx = 0; wnd_idx <= num_wnds; wnd_idx++) { + wnd_sum += + skb_shinfo(skb)->frags[wnd_idx + wnd_size - 1].size; + + if (unlikely(wnd_sum < lso_mss)) { + to_copy = 1; + break; + } + wnd_sum -= + skb_shinfo(skb)->frags[wnd_idx].size; + } + } else { + /* in non-LSO too fragmented packet should always + be linearized */ + to_copy = 1; } + } - return rc; +exit_lbl: + if (unlikely(to_copy)) + DP(NETIF_MSG_TX_QUEUED, + "Linearization IS REQUIRED for %s packet. " + "num_frags %d hlen %d first_bd_sz %d\n", + (xmit_type & XMIT_GSO) ? "LSO" : "non-LSO", + skb_shinfo(skb)->nr_frags, hlen, first_bd_sz); + + return to_copy; +} +#endif + +/* called with netif_tx_lock + * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call + * netif_wake_queue() + */ +static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + struct bnx2x_fastpath *fp; + struct netdev_queue *txq; + struct sw_tx_bd *tx_buf; + struct eth_tx_start_bd *tx_start_bd; + struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; + struct eth_tx_parse_bd *pbd = NULL; + u16 pkt_prod, bd_prod; + int nbd, fp_index; + dma_addr_t mapping; + u32 xmit_type = bnx2x_xmit_type(bp, skb); + int i; + u8 hlen = 0; + __le16 pkt_size = 0; + struct ethhdr *eth; + u8 mac_type = UNICAST_ADDRESS; + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return NETDEV_TX_BUSY; +#endif + + fp_index = skb_get_queue_mapping(skb); + txq = netdev_get_tx_queue(dev, fp_index); + + fp = &bp->fp[fp_index]; + + if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) { + fp->eth_q_stats.driver_xoff++; + netif_tx_stop_queue(txq); + BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); + return NETDEV_TX_BUSY; } - if (BP_NOMCP(bp)) { - /* only supposed to happen on emulation/FPGA */ - BNX2X_ERROR("warning: random MAC workaround active\n"); - random_ether_addr(bp->dev->dev_addr); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); + DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)" + " gso type %x xmit_type %x\n", + skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, + ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); + + eth = (struct ethhdr *)skb->data; + + /* set flag according to packet type (UNICAST_ADDRESS is default)*/ + if (unlikely(is_multicast_ether_addr(eth->h_dest))) { + if (is_broadcast_ether_addr(eth->h_dest)) + mac_type = BROADCAST_ADDRESS; + else + mac_type = MULTICAST_ADDRESS; + } + +#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) + /* First, check if we need to linearize the skb (due to FW + restrictions). No need to check fragmentation if page size > 8K + (there will be no violation to FW restrictions) */ + if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) { + /* Statistics of linearization */ + bp->lin_cnt++; + if (skb_linearize(skb) != 0) { + DP(NETIF_MSG_TX_QUEUED, "SKB linearization failed - " + "silently dropping this SKB\n"); + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } } +#endif - return rc; -} + /* + Please read carefully. First we use one BD which we mark as start, + then we have a parsing info BD (used for TSO or xsum), + and only then we have the rest of the TSO BDs. + (don't forget to mark the last one as last, + and to unmap only AFTER you write to the BD ...) + And above all, all pdb sizes are in words - NOT DWORDS! + */ + + pkt_prod = fp->tx_pkt_prod++; + bd_prod = TX_BD(fp->tx_bd_prod); + + /* get a tx_buf and first BD */ + tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)]; + tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; + + tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; + tx_start_bd->general_data = (mac_type << + ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT); + /* header nbd */ + tx_start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); + + /* remember the first BD of the packet */ + tx_buf->first_bd = fp->tx_bd_prod; + tx_buf->skb = skb; + tx_buf->flags = 0; + + DP(NETIF_MSG_TX_QUEUED, + "sending pkt %u @%p next_idx %u bd %u @%p\n", + pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); -static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp) -{ - int cnt, i, block_end, rodi; - char vpd_data[BNX2X_VPD_LEN+1]; - char str_id_reg[VENDOR_ID_LEN+1]; - char str_id_cap[VENDOR_ID_LEN+1]; - u8 len; +#ifdef BCM_VLAN + if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && + (bp->flags & HW_VLAN_TX_FLAG)) { + tx_start_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; + } else +#endif + tx_start_bd->vlan = cpu_to_le16(pkt_prod); - cnt = pci_read_vpd(bp->pdev, 0, BNX2X_VPD_LEN, vpd_data); - memset(bp->fw_ver, 0, sizeof(bp->fw_ver)); + /* turn on parsing and get a BD */ + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + pbd = &fp->tx_desc_ring[bd_prod].parse_bd; - if (cnt < BNX2X_VPD_LEN) - goto out_not_found; + memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); - i = pci_vpd_find_tag(vpd_data, 0, BNX2X_VPD_LEN, - PCI_VPD_LRDT_RO_DATA); - if (i < 0) - goto out_not_found; + if (xmit_type & XMIT_CSUM) { + hlen = (skb_network_header(skb) - skb->data) / 2; + /* for now NS flag is not used in Linux */ + pbd->global_data = + (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << + ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); - block_end = i + PCI_VPD_LRDT_TAG_SIZE + - pci_vpd_lrdt_size(&vpd_data[i]); + pbd->ip_hlen = (skb_transport_header(skb) - + skb_network_header(skb)) / 2; - i += PCI_VPD_LRDT_TAG_SIZE; + hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2; - if (block_end > BNX2X_VPD_LEN) - goto out_not_found; + pbd->total_hlen = cpu_to_le16(hlen); + hlen = hlen*2; - rodi = pci_vpd_find_info_keyword(vpd_data, i, block_end, - PCI_VPD_RO_KEYWORD_MFR_ID); - if (rodi < 0) - goto out_not_found; + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; - len = pci_vpd_info_field_size(&vpd_data[rodi]); + if (xmit_type & XMIT_CSUM_V4) + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IP_CSUM; + else + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IPV6; - if (len != VENDOR_ID_LEN) - goto out_not_found; + if (xmit_type & XMIT_CSUM_TCP) { + pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); - rodi += PCI_VPD_INFO_FLD_HDR_SIZE; + } else { + s8 fix = SKB_CS_OFF(skb); /* signed! */ - /* vendor specific info */ - snprintf(str_id_reg, VENDOR_ID_LEN + 1, "%04x", PCI_VENDOR_ID_DELL); - snprintf(str_id_cap, VENDOR_ID_LEN + 1, "%04X", PCI_VENDOR_ID_DELL); - if (!strncmp(str_id_reg, &vpd_data[rodi], VENDOR_ID_LEN) || - !strncmp(str_id_cap, &vpd_data[rodi], VENDOR_ID_LEN)) { + pbd->global_data |= ETH_TX_PARSE_BD_UDP_CS_FLG; - rodi = pci_vpd_find_info_keyword(vpd_data, i, block_end, - PCI_VPD_RO_KEYWORD_VENDOR0); - if (rodi >= 0) { - len = pci_vpd_info_field_size(&vpd_data[rodi]); + DP(NETIF_MSG_TX_QUEUED, + "hlen %d fix %d csum before fix %x\n", + le16_to_cpu(pbd->total_hlen), fix, SKB_CS(skb)); - rodi += PCI_VPD_INFO_FLD_HDR_SIZE; + /* HW bug: fixup the CSUM */ + pbd->tcp_pseudo_csum = + bnx2x_csum_fix(skb_transport_header(skb), + SKB_CS(skb), fix); - if (len < 32 && (len + rodi) <= BNX2X_VPD_LEN) { - memcpy(bp->fw_ver, &vpd_data[rodi], len); - bp->fw_ver[len] = ' '; - } + DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", + pbd->tcp_pseudo_csum); } - return; } -out_not_found: - return; -} -static int __devinit bnx2x_init_bp(struct bnx2x *bp) -{ - int func = BP_FUNC(bp); - int timer_interval; - int rc; + mapping = dma_map_single(&bp->pdev->dev, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); - /* Disable interrupt handling until HW is initialized */ - atomic_set(&bp->intr_sem, 1); - smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ + tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */ + tx_start_bd->nbd = cpu_to_le16(nbd); + tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); + pkt_size = tx_start_bd->nbytes; - mutex_init(&bp->port.phy_mutex); - mutex_init(&bp->fw_mb_mutex); - spin_lock_init(&bp->stats_lock); -#ifdef BCM_CNIC - mutex_init(&bp->cnic_mutex); -#endif + DP(NETIF_MSG_TX_QUEUED, "first bd @%p addr (%x:%x) nbd %d" + " nbytes %d flags %x vlan %x\n", + tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo, + le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes), + tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan)); - INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); - INIT_DELAYED_WORK(&bp->reset_task, bnx2x_reset_task); + if (xmit_type & XMIT_GSO) { - rc = bnx2x_get_hwinfo(bp); + DP(NETIF_MSG_TX_QUEUED, + "TSO packet len %d hlen %d total len %d tso size %d\n", + skb->len, hlen, skb_headlen(skb), + skb_shinfo(skb)->gso_size); - bnx2x_read_fwinfo(bp); - /* need to reset chip if undi was active */ - if (!BP_NOMCP(bp)) - bnx2x_undi_unload(bp); + tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO; - if (CHIP_REV_IS_FPGA(bp)) - dev_err(&bp->pdev->dev, "FPGA detected\n"); + if (unlikely(skb_headlen(skb) > hlen)) + bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, + hlen, bd_prod, ++nbd); - if (BP_NOMCP(bp) && (func == 0)) - dev_err(&bp->pdev->dev, "MCP disabled, " - "must load devices in order!\n"); + pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); + pbd->tcp_flags = pbd_tcp_flags(skb); - /* Set multi queue mode */ - if ((multi_mode != ETH_RSS_MODE_DISABLED) && - ((int_mode == INT_MODE_INTx) || (int_mode == INT_MODE_MSI))) { - dev_err(&bp->pdev->dev, "Multi disabled since int_mode " - "requested is not MSI-X\n"); - multi_mode = ETH_RSS_MODE_DISABLED; + if (xmit_type & XMIT_GSO_V4) { + pbd->ip_id = swab16(ip_hdr(skb)->id); + pbd->tcp_pseudo_csum = + swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + } else + pbd->tcp_pseudo_csum = + swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN; } - bp->multi_mode = multi_mode; - bp->int_mode = int_mode; + tx_data_bd = (struct eth_tx_bd *)tx_start_bd; - bp->dev->features |= NETIF_F_GRO; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - /* Set TPA flags */ - if (disable_tpa) { - bp->flags &= ~TPA_ENABLE_FLAG; - bp->dev->features &= ~NETIF_F_LRO; - } else { - bp->flags |= TPA_ENABLE_FLAG; - bp->dev->features |= NETIF_F_LRO; + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + tx_data_bd = &fp->tx_desc_ring[bd_prod].reg_bd; + if (total_pkt_bd == NULL) + total_pkt_bd = &fp->tx_desc_ring[bd_prod].reg_bd; + + mapping = dma_map_page(&bp->pdev->dev, frag->page, + frag->page_offset, + frag->size, DMA_TO_DEVICE); + + tx_data_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + tx_data_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + tx_data_bd->nbytes = cpu_to_le16(frag->size); + le16_add_cpu(&pkt_size, frag->size); + + DP(NETIF_MSG_TX_QUEUED, + "frag %d bd @%p addr (%x:%x) nbytes %d\n", + i, tx_data_bd, tx_data_bd->addr_hi, tx_data_bd->addr_lo, + le16_to_cpu(tx_data_bd->nbytes)); } - bp->disable_tpa = disable_tpa; - if (CHIP_IS_E1(bp)) - bp->dropless_fc = 0; - else - bp->dropless_fc = dropless_fc; + DP(NETIF_MSG_TX_QUEUED, "last bd @%p\n", tx_data_bd); - bp->mrrs = mrrs; + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - bp->tx_ring_size = MAX_TX_AVAIL; - bp->rx_ring_size = MAX_RX_AVAIL; + /* now send a tx doorbell, counting the next BD + * if the packet contains or ends with it + */ + if (TX_BD_POFF(bd_prod) < nbd) + nbd++; - bp->rx_csum = 1; + if (total_pkt_bd != NULL) + total_pkt_bd->total_pkt_bytes = pkt_size; - /* make sure that the numbers are in the right granularity */ - bp->tx_ticks = (50 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); - bp->rx_ticks = (25 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); + if (pbd) + DP(NETIF_MSG_TX_QUEUED, + "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" + " tcp_flags %x xsum %x seq %u hlen %u\n", + pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id, + pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum, + pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen)); - timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ); - bp->current_interval = (poll ? poll : timer_interval); + DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); - init_timer(&bp->timer); - bp->timer.expires = jiffies + bp->current_interval; - bp->timer.data = (unsigned long) bp; - bp->timer.function = bnx2x_timer; + /* + * Make sure that the BD data is updated before updating the producer + * since FW might read the BD right after the producer is updated. + * This is only applicable for weak-ordered memory model archs such + * as IA-64. The following barrier is also mandatory since FW will + * assumes packets must have BDs. + */ + wmb(); - return rc; -} + fp->tx_db.data.prod += nbd; + barrier(); + DOORBELL(bp, fp->index, fp->tx_db.raw); + mmiowb(); -/**************************************************************************** -* General service functions -****************************************************************************/ + fp->tx_bd_prod += nbd; + + if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { + netif_tx_stop_queue(txq); + + /* paired memory barrier is in bnx2x_tx_int(), we have to keep + * ordering of set_bit() in netif_tx_stop_queue() and read of + * fp->bd_tx_cons */ + smp_mb(); + + fp->eth_q_stats.driver_xoff++; + if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) + netif_tx_wake_queue(txq); + } + fp->tx_pkt++; + + return NETDEV_TX_OK; +} /* called with rtnl_lock */ static int bnx2x_open(struct net_device *dev) @@ -6849,7 +12591,7 @@ static int bnx2x_close(struct net_device *dev) } /* called with netif_tx_lock from dev_mcast.c */ -void bnx2x_set_rx_mode(struct net_device *dev) +static void bnx2x_set_rx_mode(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); u32 rx_mode = BNX2X_RX_MODE_NORMAL; @@ -6969,6 +12711,25 @@ void bnx2x_set_rx_mode(struct net_device *dev) bnx2x_set_storm_rx_mode(bp); } +/* called with rtnl_lock */ +static int bnx2x_change_mac_addr(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + struct bnx2x *bp = netdev_priv(dev); + + if (!is_valid_ether_addr((u8 *)(addr->sa_data))) + return -EINVAL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + if (netif_running(dev)) { + if (CHIP_IS_E1(bp)) + bnx2x_set_eth_mac_addr_e1(bp, 1); + else + bnx2x_set_eth_mac_addr_e1h(bp, 1); + } + + return 0; +} /* called with rtnl_lock */ static int bnx2x_mdio_read(struct net_device *netdev, int prtad, @@ -7044,6 +12805,71 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return mdio_mii_ioctl(&bp->mdio, mdio, cmd); } +/* called with rtnl_lock */ +static int bnx2x_change_mtu(struct net_device *dev, int new_mtu) +{ + struct bnx2x *bp = netdev_priv(dev); + int rc = 0; + + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + return -EAGAIN; + } + + if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) || + ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE)) + return -EINVAL; + + /* This does not race with packet allocation + * because the actual alloc size is + * only updated as part of load + */ + dev->mtu = new_mtu; + + if (netif_running(dev)) { + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + rc = bnx2x_nic_load(bp, LOAD_NORMAL); + } + + return rc; +} + +static void bnx2x_tx_timeout(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + +#ifdef BNX2X_STOP_ON_ERROR + if (!bp->panic) + bnx2x_panic(); +#endif + /* This allows the netif to be shutdown gracefully before resetting */ + schedule_delayed_work(&bp->reset_task, 0); +} + +#ifdef BCM_VLAN +/* called with rtnl_lock */ +static void bnx2x_vlan_rx_register(struct net_device *dev, + struct vlan_group *vlgrp) +{ + struct bnx2x *bp = netdev_priv(dev); + + bp->vlgrp = vlgrp; + + /* Set flags according to the required capabilities */ + bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); + + if (dev->features & NETIF_F_HW_VLAN_TX) + bp->flags |= HW_VLAN_TX_FLAG; + + if (dev->features & NETIF_F_HW_VLAN_RX) + bp->flags |= HW_VLAN_RX_FLAG; + + if (netif_running(dev)) + bnx2x_set_client_config(bp); +} + +#endif + #ifdef CONFIG_NET_POLL_CONTROLLER static void poll_bnx2x(struct net_device *dev) { @@ -7192,7 +13018,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->watchdog_timeo = TX_TIMEOUT; dev->netdev_ops = &bnx2x_netdev_ops; - bnx2x_set_ethtool_ops(dev); + dev->ethtool_ops = &bnx2x_ethtool_ops; dev->features |= NETIF_F_SG; dev->features |= NETIF_F_HW_CSUM; if (bp->flags & USING_DAC_FLAG) @@ -7545,6 +13371,73 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2x *bp; + + if (!dev) { + dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n"); + return -ENODEV; + } + bp = netdev_priv(dev); + + rtnl_lock(); + + pci_save_state(pdev); + + if (!netif_running(dev)) { + rtnl_unlock(); + return 0; + } + + netif_device_detach(dev); + + bnx2x_nic_unload(bp, UNLOAD_CLOSE); + + bnx2x_set_power_state(bp, pci_choose_state(pdev, state)); + + rtnl_unlock(); + + return 0; +} + +static int bnx2x_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2x *bp; + int rc; + + if (!dev) { + dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n"); + return -ENODEV; + } + bp = netdev_priv(dev); + + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + return -EAGAIN; + } + + rtnl_lock(); + + pci_restore_state(pdev); + + if (!netif_running(dev)) { + rtnl_unlock(); + return 0; + } + + bnx2x_set_power_state(bp, PCI_D0); + netif_device_attach(dev); + + rc = bnx2x_nic_load(bp, LOAD_OPEN); + + rtnl_unlock(); + + return rc; +} + static int bnx2x_eeh_nic_unload(struct bnx2x *bp) { int i; @@ -7866,7 +13759,7 @@ static int bnx2x_cnic_ctl_send_bh(struct bnx2x *bp, struct cnic_ctl_info *ctl) /* * for commands that have no data */ -int bnx2x_cnic_notify(struct bnx2x *bp, int cmd) +static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd) { struct cnic_ctl_info ctl = {0}; @@ -7934,7 +13827,7 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) return rc; } -void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) +static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) { struct cnic_eth_dev *cp = &bp->cnic_eth_dev; diff --git a/trunk/drivers/net/bnx2x/bnx2x_reg.h b/trunk/drivers/net/bnx2x_reg.h similarity index 100% rename from trunk/drivers/net/bnx2x/bnx2x_reg.h rename to trunk/drivers/net/bnx2x_reg.h diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c index c746b331771d..3662d6e446a9 100644 --- a/trunk/drivers/net/bonding/bond_alb.c +++ b/trunk/drivers/net/bonding/bond_alb.c @@ -682,7 +682,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon client_info->ntt = 0; } - if (bond->vlgrp) { + if (!list_empty(&bond->vlan_list)) { if (!vlan_get_tag(skb, &client_info->vlan_id)) client_info->tag = 1; } @@ -815,7 +815,7 @@ static int rlb_initialize(struct bonding *bond) /*initialize packet type*/ pk_type->type = cpu_to_be16(ETH_P_ARP); - pk_type->dev = bond->dev; + pk_type->dev = NULL; pk_type->func = rlb_arp_recv; /* register to receive ARPs */ @@ -904,7 +904,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) skb->priority = TC_PRIO_CONTROL; skb->dev = slave->dev; - if (bond->vlgrp) { + if (!list_empty(&bond->vlan_list)) { struct vlan_entry *vlan; vlan = bond_next_vlan(bond, diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 2cc4cfc31892..20f45cbf961a 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -424,7 +424,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, { unsigned short uninitialized_var(vlan_id); - /* Test vlan_list not vlgrp to catch and handle 802.1p tags */ if (!list_empty(&bond->vlan_list) && !(slave_dev->features & NETIF_F_HW_VLAN_TX) && vlan_get_tag(skb, &vlan_id) == 0) { @@ -488,9 +487,7 @@ static void bond_vlan_rx_register(struct net_device *bond_dev, struct slave *slave; int i; - write_lock(&bond->lock); bond->vlgrp = grp; - write_unlock(&bond->lock); bond_for_each_slave(bond, slave, i) { struct net_device *slave_dev = slave->dev; @@ -570,8 +567,10 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla struct vlan_entry *vlan; const struct net_device_ops *slave_ops = slave_dev->netdev_ops; - if (!bond->vlgrp) - return; + write_lock_bh(&bond->lock); + + if (list_empty(&bond->vlan_list)) + goto out; if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && slave_ops->ndo_vlan_rx_register) @@ -579,10 +578,13 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || !(slave_ops->ndo_vlan_rx_add_vid)) - return; + goto out; list_for_each_entry(vlan, &bond->vlan_list, vlan_list) slave_ops->ndo_vlan_rx_add_vid(slave_dev, vlan->vlan_id); + +out: + write_unlock_bh(&bond->lock); } static void bond_del_vlans_from_slave(struct bonding *bond, @@ -592,16 +594,16 @@ static void bond_del_vlans_from_slave(struct bonding *bond, struct vlan_entry *vlan; struct net_device *vlan_dev; - if (!bond->vlgrp) - return; + write_lock_bh(&bond->lock); + + if (list_empty(&bond->vlan_list)) + goto out; if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || !(slave_ops->ndo_vlan_rx_kill_vid)) goto unreg; list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - if (!vlan->vlan_id) - continue; /* Save and then restore vlan_dev in the grp array, * since the slave's driver might clear it. */ @@ -614,6 +616,9 @@ static void bond_del_vlans_from_slave(struct bonding *bond, if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && slave_ops->ndo_vlan_rx_register) slave_ops->ndo_vlan_rx_register(slave_dev, NULL); + +out: + write_unlock_bh(&bond->lock); } /*------------------------------- Link status -------------------------------*/ @@ -1438,7 +1443,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* no need to lock since we're protected by rtnl_lock */ if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); - if (bond->vlgrp) { + if (!list_empty(&bond->vlan_list)) { pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", bond_dev->name, slave_dev->name, bond_dev->name); return -EPERM; @@ -1937,7 +1942,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) */ memset(bond_dev->dev_addr, 0, bond_dev->addr_len); - if (!bond->vlgrp) { + if (list_empty(&bond->vlan_list)) { bond_dev->features |= NETIF_F_VLAN_CHALLENGED; } else { pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", @@ -2129,9 +2134,9 @@ static int bond_release_all(struct net_device *bond_dev) */ memset(bond_dev->dev_addr, 0, bond_dev->addr_len); - if (!bond->vlgrp) { + if (list_empty(&bond->vlan_list)) bond_dev->features |= NETIF_F_VLAN_CHALLENGED; - } else { + else { pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", bond_dev->name, bond_dev->name); pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", @@ -2564,7 +2569,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) if (!targets[i]) break; pr_debug("basa: target %x\n", targets[i]); - if (!bond->vlgrp) { + if (list_empty(&bond->vlan_list)) { pr_debug("basa: empty vlan: arp_send\n"); bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond->master_ip, 0); @@ -2653,9 +2658,6 @@ static void bond_send_gratuitous_arp(struct bonding *bond) bond->master_ip, 0); } - if (!bond->vlgrp) - return; - list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); if (vlan->vlan_ip) { @@ -3588,8 +3590,6 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - if (!bond->vlgrp) - continue; vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); if (vlan_dev == event_dev) { switch (event) { @@ -4686,7 +4686,6 @@ static void bond_work_cancel_all(struct bonding *bond) static void bond_uninit(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); - struct vlan_entry *vlan, *tmp; bond_netpoll_cleanup(bond_dev); @@ -4700,11 +4699,6 @@ static void bond_uninit(struct net_device *bond_dev) bond_remove_proc_entry(bond); __hw_addr_flush(&bond->mc_list); - - list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) { - list_del(&vlan->vlan_list); - kfree(vlan); - } } /*------------------------- Module initialization ---------------------------*/ diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index c311aed9bd02..1a9976487099 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -313,26 +313,19 @@ static ssize_t bonding_store_mode(struct device *d, bond->dev->name, (int)strlen(buf) - 1, buf); ret = -EINVAL; goto out; - } - if ((new_value == BOND_MODE_ALB || - new_value == BOND_MODE_TLB) && - bond->params.arp_interval) { - pr_err("%s: %s mode is incompatible with arp monitoring.\n", - bond->dev->name, bond_mode_tbl[new_value].modename); - ret = -EINVAL; - goto out; - } - if (bond->params.mode == BOND_MODE_8023AD) - bond_unset_master_3ad_flags(bond); + } else { + if (bond->params.mode == BOND_MODE_8023AD) + bond_unset_master_3ad_flags(bond); - if (bond->params.mode == BOND_MODE_ALB) - bond_unset_master_alb_flags(bond); + if (bond->params.mode == BOND_MODE_ALB) + bond_unset_master_alb_flags(bond); - bond->params.mode = new_value; - bond_set_mode_ops(bond, bond->params.mode); - pr_info("%s: setting mode to %s (%d).\n", - bond->dev->name, bond_mode_tbl[new_value].modename, - new_value); + bond->params.mode = new_value; + bond_set_mode_ops(bond, bond->params.mode); + pr_info("%s: setting mode to %s (%d).\n", + bond->dev->name, bond_mode_tbl[new_value].modename, + new_value); + } out: return ret; } @@ -517,13 +510,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, ret = -EINVAL; goto out; } - if (bond->params.mode == BOND_MODE_ALB || - bond->params.mode == BOND_MODE_TLB) { - pr_info("%s: ARP monitoring cannot be used with ALB/TLB. Only MII monitoring is supported on %s.\n", - bond->dev->name, bond->dev->name); - ret = -EINVAL; - goto out; - } + pr_info("%s: Setting ARP monitoring interval to %d.\n", bond->dev->name, new_value); bond->params.arp_interval = new_value; diff --git a/trunk/drivers/net/caif/caif_spi.c b/trunk/drivers/net/caif/caif_spi.c index f5058ff2b210..6c948037fc78 100644 --- a/trunk/drivers/net/caif/caif_spi.c +++ b/trunk/drivers/net/caif/caif_spi.c @@ -165,9 +165,6 @@ static ssize_t dbgfs_state(struct file *file, char __user *user_buf, len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), "Next RX len: %d\n", cfspi->rx_npck_len); - if (len > DEBUGFS_BUF_SIZE) - len = DEBUGFS_BUF_SIZE; - size = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); diff --git a/trunk/drivers/net/can/Kconfig b/trunk/drivers/net/can/Kconfig index 9d9e45394433..2c5227c02fa0 100644 --- a/trunk/drivers/net/can/Kconfig +++ b/trunk/drivers/net/can/Kconfig @@ -73,15 +73,6 @@ config CAN_JANZ_ICAN3 This driver can also be built as a module. If so, the module will be called janz-ican3.ko. -config HAVE_CAN_FLEXCAN - bool - -config CAN_FLEXCAN - tristate "Support for Freescale FLEXCAN based chips" - depends on CAN_DEV && HAVE_CAN_FLEXCAN - ---help--- - Say Y here if you want to support for Freescale FlexCAN. - source "drivers/net/can/mscan/Kconfig" source "drivers/net/can/sja1000/Kconfig" diff --git a/trunk/drivers/net/can/Makefile b/trunk/drivers/net/can/Makefile index 00575373bbd0..9047cd066fea 100644 --- a/trunk/drivers/net/can/Makefile +++ b/trunk/drivers/net/can/Makefile @@ -16,6 +16,5 @@ obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o obj-$(CONFIG_CAN_MCP251X) += mcp251x.o obj-$(CONFIG_CAN_BFIN) += bfin_can.o obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o -obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/trunk/drivers/net/can/flexcan.c b/trunk/drivers/net/can/flexcan.c deleted file mode 100644 index ef443a090ba7..000000000000 --- a/trunk/drivers/net/can/flexcan.c +++ /dev/null @@ -1,1030 +0,0 @@ -/* - * flexcan.c - FLEXCAN CAN controller driver - * - * Copyright (c) 2005-2006 Varma Electronics Oy - * Copyright (c) 2009 Sascha Hauer, Pengutronix - * Copyright (c) 2010 Marc Kleine-Budde, Pengutronix - * - * Based on code originally by Andrey Volkov - * - * LICENCE: - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DRV_NAME "flexcan" - -/* 8 for RX fifo and 2 error handling */ -#define FLEXCAN_NAPI_WEIGHT (8 + 2) - -/* FLEXCAN module configuration register (CANMCR) bits */ -#define FLEXCAN_MCR_MDIS BIT(31) -#define FLEXCAN_MCR_FRZ BIT(30) -#define FLEXCAN_MCR_FEN BIT(29) -#define FLEXCAN_MCR_HALT BIT(28) -#define FLEXCAN_MCR_NOT_RDY BIT(27) -#define FLEXCAN_MCR_WAK_MSK BIT(26) -#define FLEXCAN_MCR_SOFTRST BIT(25) -#define FLEXCAN_MCR_FRZ_ACK BIT(24) -#define FLEXCAN_MCR_SUPV BIT(23) -#define FLEXCAN_MCR_SLF_WAK BIT(22) -#define FLEXCAN_MCR_WRN_EN BIT(21) -#define FLEXCAN_MCR_LPM_ACK BIT(20) -#define FLEXCAN_MCR_WAK_SRC BIT(19) -#define FLEXCAN_MCR_DOZE BIT(18) -#define FLEXCAN_MCR_SRX_DIS BIT(17) -#define FLEXCAN_MCR_BCC BIT(16) -#define FLEXCAN_MCR_LPRIO_EN BIT(13) -#define FLEXCAN_MCR_AEN BIT(12) -#define FLEXCAN_MCR_MAXMB(x) ((x) & 0xf) -#define FLEXCAN_MCR_IDAM_A (0 << 8) -#define FLEXCAN_MCR_IDAM_B (1 << 8) -#define FLEXCAN_MCR_IDAM_C (2 << 8) -#define FLEXCAN_MCR_IDAM_D (3 << 8) - -/* FLEXCAN control register (CANCTRL) bits */ -#define FLEXCAN_CTRL_PRESDIV(x) (((x) & 0xff) << 24) -#define FLEXCAN_CTRL_RJW(x) (((x) & 0x03) << 22) -#define FLEXCAN_CTRL_PSEG1(x) (((x) & 0x07) << 19) -#define FLEXCAN_CTRL_PSEG2(x) (((x) & 0x07) << 16) -#define FLEXCAN_CTRL_BOFF_MSK BIT(15) -#define FLEXCAN_CTRL_ERR_MSK BIT(14) -#define FLEXCAN_CTRL_CLK_SRC BIT(13) -#define FLEXCAN_CTRL_LPB BIT(12) -#define FLEXCAN_CTRL_TWRN_MSK BIT(11) -#define FLEXCAN_CTRL_RWRN_MSK BIT(10) -#define FLEXCAN_CTRL_SMP BIT(7) -#define FLEXCAN_CTRL_BOFF_REC BIT(6) -#define FLEXCAN_CTRL_TSYN BIT(5) -#define FLEXCAN_CTRL_LBUF BIT(4) -#define FLEXCAN_CTRL_LOM BIT(3) -#define FLEXCAN_CTRL_PROPSEG(x) ((x) & 0x07) -#define FLEXCAN_CTRL_ERR_BUS (FLEXCAN_CTRL_ERR_MSK) -#define FLEXCAN_CTRL_ERR_STATE \ - (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \ - FLEXCAN_CTRL_BOFF_MSK) -#define FLEXCAN_CTRL_ERR_ALL \ - (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) - -/* FLEXCAN error and status register (ESR) bits */ -#define FLEXCAN_ESR_TWRN_INT BIT(17) -#define FLEXCAN_ESR_RWRN_INT BIT(16) -#define FLEXCAN_ESR_BIT1_ERR BIT(15) -#define FLEXCAN_ESR_BIT0_ERR BIT(14) -#define FLEXCAN_ESR_ACK_ERR BIT(13) -#define FLEXCAN_ESR_CRC_ERR BIT(12) -#define FLEXCAN_ESR_FRM_ERR BIT(11) -#define FLEXCAN_ESR_STF_ERR BIT(10) -#define FLEXCAN_ESR_TX_WRN BIT(9) -#define FLEXCAN_ESR_RX_WRN BIT(8) -#define FLEXCAN_ESR_IDLE BIT(7) -#define FLEXCAN_ESR_TXRX BIT(6) -#define FLEXCAN_EST_FLT_CONF_SHIFT (4) -#define FLEXCAN_ESR_FLT_CONF_MASK (0x3 << FLEXCAN_EST_FLT_CONF_SHIFT) -#define FLEXCAN_ESR_FLT_CONF_ACTIVE (0x0 << FLEXCAN_EST_FLT_CONF_SHIFT) -#define FLEXCAN_ESR_FLT_CONF_PASSIVE (0x1 << FLEXCAN_EST_FLT_CONF_SHIFT) -#define FLEXCAN_ESR_BOFF_INT BIT(2) -#define FLEXCAN_ESR_ERR_INT BIT(1) -#define FLEXCAN_ESR_WAK_INT BIT(0) -#define FLEXCAN_ESR_ERR_BUS \ - (FLEXCAN_ESR_BIT1_ERR | FLEXCAN_ESR_BIT0_ERR | \ - FLEXCAN_ESR_ACK_ERR | FLEXCAN_ESR_CRC_ERR | \ - FLEXCAN_ESR_FRM_ERR | FLEXCAN_ESR_STF_ERR) -#define FLEXCAN_ESR_ERR_STATE \ - (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT) -#define FLEXCAN_ESR_ERR_ALL \ - (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) - -/* FLEXCAN interrupt flag register (IFLAG) bits */ -#define FLEXCAN_TX_BUF_ID 8 -#define FLEXCAN_IFLAG_BUF(x) BIT(x) -#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) -#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) -#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) -#define FLEXCAN_IFLAG_DEFAULT \ - (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \ - FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID)) - -/* FLEXCAN message buffers */ -#define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24) -#define FLEXCAN_MB_CNT_SRR BIT(22) -#define FLEXCAN_MB_CNT_IDE BIT(21) -#define FLEXCAN_MB_CNT_RTR BIT(20) -#define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16) -#define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff) - -#define FLEXCAN_MB_CODE_MASK (0xf0ffffff) - -/* Structure of the message buffer */ -struct flexcan_mb { - u32 can_ctrl; - u32 can_id; - u32 data[2]; -}; - -/* Structure of the hardware registers */ -struct flexcan_regs { - u32 mcr; /* 0x00 */ - u32 ctrl; /* 0x04 */ - u32 timer; /* 0x08 */ - u32 _reserved1; /* 0x0c */ - u32 rxgmask; /* 0x10 */ - u32 rx14mask; /* 0x14 */ - u32 rx15mask; /* 0x18 */ - u32 ecr; /* 0x1c */ - u32 esr; /* 0x20 */ - u32 imask2; /* 0x24 */ - u32 imask1; /* 0x28 */ - u32 iflag2; /* 0x2c */ - u32 iflag1; /* 0x30 */ - u32 _reserved2[19]; - struct flexcan_mb cantxfg[64]; -}; - -struct flexcan_priv { - struct can_priv can; - struct net_device *dev; - struct napi_struct napi; - - void __iomem *base; - u32 reg_esr; - u32 reg_ctrl_default; - - struct clk *clk; - struct flexcan_platform_data *pdata; -}; - -static struct can_bittiming_const flexcan_bittiming_const = { - .name = DRV_NAME, - .tseg1_min = 4, - .tseg1_max = 16, - .tseg2_min = 2, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 256, - .brp_inc = 1, -}; - -/* - * Swtich transceiver on or off - */ -static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on) -{ - if (priv->pdata && priv->pdata->transceiver_switch) - priv->pdata->transceiver_switch(on); -} - -static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, - u32 reg_esr) -{ - return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && - (reg_esr & FLEXCAN_ESR_ERR_BUS); -} - -static inline void flexcan_chip_enable(struct flexcan_priv *priv) -{ - struct flexcan_regs __iomem *regs = priv->base; - u32 reg; - - reg = readl(®s->mcr); - reg &= ~FLEXCAN_MCR_MDIS; - writel(reg, ®s->mcr); - - udelay(10); -} - -static inline void flexcan_chip_disable(struct flexcan_priv *priv) -{ - struct flexcan_regs __iomem *regs = priv->base; - u32 reg; - - reg = readl(®s->mcr); - reg |= FLEXCAN_MCR_MDIS; - writel(reg, ®s->mcr); -} - -static int flexcan_get_berr_counter(const struct net_device *dev, - struct can_berr_counter *bec) -{ - const struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - u32 reg = readl(®s->ecr); - - bec->txerr = (reg >> 0) & 0xff; - bec->rxerr = (reg >> 8) & 0xff; - - return 0; -} - -static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - const struct flexcan_priv *priv = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct flexcan_regs __iomem *regs = priv->base; - struct can_frame *cf = (struct can_frame *)skb->data; - u32 can_id; - u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16); - - if (can_dropped_invalid_skb(dev, skb)) - return NETDEV_TX_OK; - - netif_stop_queue(dev); - - if (cf->can_id & CAN_EFF_FLAG) { - can_id = cf->can_id & CAN_EFF_MASK; - ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; - } else { - can_id = (cf->can_id & CAN_SFF_MASK) << 18; - } - - if (cf->can_id & CAN_RTR_FLAG) - ctrl |= FLEXCAN_MB_CNT_RTR; - - if (cf->can_dlc > 0) { - u32 data = be32_to_cpup((__be32 *)&cf->data[0]); - writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]); - } - if (cf->can_dlc > 3) { - u32 data = be32_to_cpup((__be32 *)&cf->data[4]); - writel(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]); - } - - writel(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id); - writel(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); - - kfree_skb(skb); - - /* tx_packets is incremented in flexcan_irq */ - stats->tx_bytes += cf->can_dlc; - - return NETDEV_TX_OK; -} - -static void do_bus_err(struct net_device *dev, - struct can_frame *cf, u32 reg_esr) -{ - struct flexcan_priv *priv = netdev_priv(dev); - int rx_errors = 0, tx_errors = 0; - - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; - - if (reg_esr & FLEXCAN_ESR_BIT1_ERR) { - dev_dbg(dev->dev.parent, "BIT1_ERR irq\n"); - cf->data[2] |= CAN_ERR_PROT_BIT1; - tx_errors = 1; - } - if (reg_esr & FLEXCAN_ESR_BIT0_ERR) { - dev_dbg(dev->dev.parent, "BIT0_ERR irq\n"); - cf->data[2] |= CAN_ERR_PROT_BIT0; - tx_errors = 1; - } - if (reg_esr & FLEXCAN_ESR_ACK_ERR) { - dev_dbg(dev->dev.parent, "ACK_ERR irq\n"); - cf->can_id |= CAN_ERR_ACK; - cf->data[3] |= CAN_ERR_PROT_LOC_ACK; - tx_errors = 1; - } - if (reg_esr & FLEXCAN_ESR_CRC_ERR) { - dev_dbg(dev->dev.parent, "CRC_ERR irq\n"); - cf->data[2] |= CAN_ERR_PROT_BIT; - cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; - rx_errors = 1; - } - if (reg_esr & FLEXCAN_ESR_FRM_ERR) { - dev_dbg(dev->dev.parent, "FRM_ERR irq\n"); - cf->data[2] |= CAN_ERR_PROT_FORM; - rx_errors = 1; - } - if (reg_esr & FLEXCAN_ESR_STF_ERR) { - dev_dbg(dev->dev.parent, "STF_ERR irq\n"); - cf->data[2] |= CAN_ERR_PROT_STUFF; - rx_errors = 1; - } - - priv->can.can_stats.bus_error++; - if (rx_errors) - dev->stats.rx_errors++; - if (tx_errors) - dev->stats.tx_errors++; -} - -static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr) -{ - struct sk_buff *skb; - struct can_frame *cf; - - skb = alloc_can_err_skb(dev, &cf); - if (unlikely(!skb)) - return 0; - - do_bus_err(dev, cf, reg_esr); - netif_receive_skb(skb); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += cf->can_dlc; - - return 1; -} - -static void do_state(struct net_device *dev, - struct can_frame *cf, enum can_state new_state) -{ - struct flexcan_priv *priv = netdev_priv(dev); - struct can_berr_counter bec; - - flexcan_get_berr_counter(dev, &bec); - - switch (priv->can.state) { - case CAN_STATE_ERROR_ACTIVE: - /* - * from: ERROR_ACTIVE - * to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF - * => : there was a warning int - */ - if (new_state >= CAN_STATE_ERROR_WARNING && - new_state <= CAN_STATE_BUS_OFF) { - dev_dbg(dev->dev.parent, "Error Warning IRQ\n"); - priv->can.can_stats.error_warning++; - - cf->can_id |= CAN_ERR_CRTL; - cf->data[1] = (bec.txerr > bec.rxerr) ? - CAN_ERR_CRTL_TX_WARNING : - CAN_ERR_CRTL_RX_WARNING; - } - case CAN_STATE_ERROR_WARNING: /* fallthrough */ - /* - * from: ERROR_ACTIVE, ERROR_WARNING - * to : ERROR_PASSIVE, BUS_OFF - * => : error passive int - */ - if (new_state >= CAN_STATE_ERROR_PASSIVE && - new_state <= CAN_STATE_BUS_OFF) { - dev_dbg(dev->dev.parent, "Error Passive IRQ\n"); - priv->can.can_stats.error_passive++; - - cf->can_id |= CAN_ERR_CRTL; - cf->data[1] = (bec.txerr > bec.rxerr) ? - CAN_ERR_CRTL_TX_PASSIVE : - CAN_ERR_CRTL_RX_PASSIVE; - } - break; - case CAN_STATE_BUS_OFF: - dev_err(dev->dev.parent, - "BUG! hardware recovered automatically from BUS_OFF\n"); - break; - default: - break; - } - - /* process state changes depending on the new state */ - switch (new_state) { - case CAN_STATE_ERROR_ACTIVE: - dev_dbg(dev->dev.parent, "Error Active\n"); - cf->can_id |= CAN_ERR_PROT; - cf->data[2] = CAN_ERR_PROT_ACTIVE; - break; - case CAN_STATE_BUS_OFF: - cf->can_id |= CAN_ERR_BUSOFF; - can_bus_off(dev); - break; - default: - break; - } -} - -static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) -{ - struct flexcan_priv *priv = netdev_priv(dev); - struct sk_buff *skb; - struct can_frame *cf; - enum can_state new_state; - int flt; - - flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; - if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { - if (likely(!(reg_esr & (FLEXCAN_ESR_TX_WRN | - FLEXCAN_ESR_RX_WRN)))) - new_state = CAN_STATE_ERROR_ACTIVE; - else - new_state = CAN_STATE_ERROR_WARNING; - } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) - new_state = CAN_STATE_ERROR_PASSIVE; - else - new_state = CAN_STATE_BUS_OFF; - - /* state hasn't changed */ - if (likely(new_state == priv->can.state)) - return 0; - - skb = alloc_can_err_skb(dev, &cf); - if (unlikely(!skb)) - return 0; - - do_state(dev, cf, new_state); - priv->can.state = new_state; - netif_receive_skb(skb); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += cf->can_dlc; - - return 1; -} - -static void flexcan_read_fifo(const struct net_device *dev, - struct can_frame *cf) -{ - const struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - struct flexcan_mb __iomem *mb = ®s->cantxfg[0]; - u32 reg_ctrl, reg_id; - - reg_ctrl = readl(&mb->can_ctrl); - reg_id = readl(&mb->can_id); - if (reg_ctrl & FLEXCAN_MB_CNT_IDE) - cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; - else - cf->can_id = (reg_id >> 18) & CAN_SFF_MASK; - - if (reg_ctrl & FLEXCAN_MB_CNT_RTR) - cf->can_id |= CAN_RTR_FLAG; - cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); - - *(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0])); - *(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1])); - - /* mark as read */ - writel(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); - readl(®s->timer); -} - -static int flexcan_read_frame(struct net_device *dev) -{ - struct net_device_stats *stats = &dev->stats; - struct can_frame *cf; - struct sk_buff *skb; - - skb = alloc_can_skb(dev, &cf); - if (unlikely(!skb)) { - stats->rx_dropped++; - return 0; - } - - flexcan_read_fifo(dev, cf); - netif_receive_skb(skb); - - stats->rx_packets++; - stats->rx_bytes += cf->can_dlc; - - return 1; -} - -static int flexcan_poll(struct napi_struct *napi, int quota) -{ - struct net_device *dev = napi->dev; - const struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - u32 reg_iflag1, reg_esr; - int work_done = 0; - - /* - * The error bits are cleared on read, - * use saved value from irq handler. - */ - reg_esr = readl(®s->esr) | priv->reg_esr; - - /* handle state changes */ - work_done += flexcan_poll_state(dev, reg_esr); - - /* handle RX-FIFO */ - reg_iflag1 = readl(®s->iflag1); - while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE && - work_done < quota) { - work_done += flexcan_read_frame(dev); - reg_iflag1 = readl(®s->iflag1); - } - - /* report bus errors */ - if (flexcan_has_and_handle_berr(priv, reg_esr) && work_done < quota) - work_done += flexcan_poll_bus_err(dev, reg_esr); - - if (work_done < quota) { - napi_complete(napi); - /* enable IRQs */ - writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); - writel(priv->reg_ctrl_default, ®s->ctrl); - } - - return work_done; -} - -static irqreturn_t flexcan_irq(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct net_device_stats *stats = &dev->stats; - struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - u32 reg_iflag1, reg_esr; - - reg_iflag1 = readl(®s->iflag1); - reg_esr = readl(®s->esr); - writel(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */ - - /* - * schedule NAPI in case of: - * - rx IRQ - * - state change IRQ - * - bus error IRQ and bus error reporting is activated - */ - if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) || - (reg_esr & FLEXCAN_ESR_ERR_STATE) || - flexcan_has_and_handle_berr(priv, reg_esr)) { - /* - * The error bits are cleared on read, - * save them for later use. - */ - priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS; - writel(FLEXCAN_IFLAG_DEFAULT & ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, - ®s->imask1); - writel(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, - ®s->ctrl); - napi_schedule(&priv->napi); - } - - /* FIFO overflow */ - if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { - writel(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1); - dev->stats.rx_over_errors++; - dev->stats.rx_errors++; - } - - /* transmission complete interrupt */ - if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { - /* tx_bytes is incremented in flexcan_start_xmit */ - stats->tx_packets++; - writel((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); - netif_wake_queue(dev); - } - - return IRQ_HANDLED; -} - -static void flexcan_set_bittiming(struct net_device *dev) -{ - const struct flexcan_priv *priv = netdev_priv(dev); - const struct can_bittiming *bt = &priv->can.bittiming; - struct flexcan_regs __iomem *regs = priv->base; - u32 reg; - - reg = readl(®s->ctrl); - reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | - FLEXCAN_CTRL_RJW(0x3) | - FLEXCAN_CTRL_PSEG1(0x7) | - FLEXCAN_CTRL_PSEG2(0x7) | - FLEXCAN_CTRL_PROPSEG(0x7) | - FLEXCAN_CTRL_LPB | - FLEXCAN_CTRL_SMP | - FLEXCAN_CTRL_LOM); - - reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | - FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | - FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | - FLEXCAN_CTRL_RJW(bt->sjw - 1) | - FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); - - if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) - reg |= FLEXCAN_CTRL_LPB; - if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) - reg |= FLEXCAN_CTRL_LOM; - if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) - reg |= FLEXCAN_CTRL_SMP; - - dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg); - writel(reg, ®s->ctrl); - - /* print chip status */ - dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, - readl(®s->mcr), readl(®s->ctrl)); -} - -/* - * flexcan_chip_start - * - * this functions is entered with clocks enabled - * - */ -static int flexcan_chip_start(struct net_device *dev) -{ - struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - unsigned int i; - int err; - u32 reg_mcr, reg_ctrl; - - /* enable module */ - flexcan_chip_enable(priv); - - /* soft reset */ - writel(FLEXCAN_MCR_SOFTRST, ®s->mcr); - udelay(10); - - reg_mcr = readl(®s->mcr); - if (reg_mcr & FLEXCAN_MCR_SOFTRST) { - dev_err(dev->dev.parent, - "Failed to softreset can module (mcr=0x%08x)\n", - reg_mcr); - err = -ENODEV; - goto out; - } - - flexcan_set_bittiming(dev); - - /* - * MCR - * - * enable freeze - * enable fifo - * halt now - * only supervisor access - * enable warning int - * choose format C - * - */ - reg_mcr = readl(®s->mcr); - reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | - FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | - FLEXCAN_MCR_IDAM_C; - dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr); - writel(reg_mcr, ®s->mcr); - - /* - * CTRL - * - * disable timer sync feature - * - * disable auto busoff recovery - * transmit lowest buffer first - * - * enable tx and rx warning interrupt - * enable bus off interrupt - * (== FLEXCAN_CTRL_ERR_STATE) - * - * _note_: we enable the "error interrupt" - * (FLEXCAN_CTRL_ERR_MSK), too. Otherwise we don't get any - * warning or bus passive interrupts. - */ - reg_ctrl = readl(®s->ctrl); - reg_ctrl &= ~FLEXCAN_CTRL_TSYN; - reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | - FLEXCAN_CTRL_ERR_STATE | FLEXCAN_CTRL_ERR_MSK; - - /* save for later use */ - priv->reg_ctrl_default = reg_ctrl; - dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); - writel(reg_ctrl, ®s->ctrl); - - for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) { - writel(0, ®s->cantxfg[i].can_ctrl); - writel(0, ®s->cantxfg[i].can_id); - writel(0, ®s->cantxfg[i].data[0]); - writel(0, ®s->cantxfg[i].data[1]); - - /* put MB into rx queue */ - writel(FLEXCAN_MB_CNT_CODE(0x4), ®s->cantxfg[i].can_ctrl); - } - - /* acceptance mask/acceptance code (accept everything) */ - writel(0x0, ®s->rxgmask); - writel(0x0, ®s->rx14mask); - writel(0x0, ®s->rx15mask); - - flexcan_transceiver_switch(priv, 1); - - /* synchronize with the can bus */ - reg_mcr = readl(®s->mcr); - reg_mcr &= ~FLEXCAN_MCR_HALT; - writel(reg_mcr, ®s->mcr); - - priv->can.state = CAN_STATE_ERROR_ACTIVE; - - /* enable FIFO interrupts */ - writel(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); - - /* print chip status */ - dev_dbg(dev->dev.parent, "%s: reading mcr=0x%08x ctrl=0x%08x\n", - __func__, readl(®s->mcr), readl(®s->ctrl)); - - return 0; - - out: - flexcan_chip_disable(priv); - return err; -} - -/* - * flexcan_chip_stop - * - * this functions is entered with clocks enabled - * - */ -static void flexcan_chip_stop(struct net_device *dev) -{ - struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - u32 reg; - - /* Disable all interrupts */ - writel(0, ®s->imask1); - - /* Disable + halt module */ - reg = readl(®s->mcr); - reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT; - writel(reg, ®s->mcr); - - flexcan_transceiver_switch(priv, 0); - priv->can.state = CAN_STATE_STOPPED; - - return; -} - -static int flexcan_open(struct net_device *dev) -{ - struct flexcan_priv *priv = netdev_priv(dev); - int err; - - clk_enable(priv->clk); - - err = open_candev(dev); - if (err) - goto out; - - err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); - if (err) - goto out_close; - - /* start chip and queuing */ - err = flexcan_chip_start(dev); - if (err) - goto out_close; - napi_enable(&priv->napi); - netif_start_queue(dev); - - return 0; - - out_close: - close_candev(dev); - out: - clk_disable(priv->clk); - - return err; -} - -static int flexcan_close(struct net_device *dev) -{ - struct flexcan_priv *priv = netdev_priv(dev); - - netif_stop_queue(dev); - napi_disable(&priv->napi); - flexcan_chip_stop(dev); - - free_irq(dev->irq, dev); - clk_disable(priv->clk); - - close_candev(dev); - - return 0; -} - -static int flexcan_set_mode(struct net_device *dev, enum can_mode mode) -{ - int err; - - switch (mode) { - case CAN_MODE_START: - err = flexcan_chip_start(dev); - if (err) - return err; - - netif_wake_queue(dev); - break; - - default: - return -EOPNOTSUPP; - } - - return 0; -} - -static const struct net_device_ops flexcan_netdev_ops = { - .ndo_open = flexcan_open, - .ndo_stop = flexcan_close, - .ndo_start_xmit = flexcan_start_xmit, -}; - -static int __devinit register_flexcandev(struct net_device *dev) -{ - struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - u32 reg, err; - - clk_enable(priv->clk); - - /* select "bus clock", chip must be disabled */ - flexcan_chip_disable(priv); - reg = readl(®s->ctrl); - reg |= FLEXCAN_CTRL_CLK_SRC; - writel(reg, ®s->ctrl); - - flexcan_chip_enable(priv); - - /* set freeze, halt and activate FIFO, restrict register access */ - reg = readl(®s->mcr); - reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | - FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; - writel(reg, ®s->mcr); - - /* - * Currently we only support newer versions of this core - * featuring a RX FIFO. Older cores found on some Coldfire - * derivates are not yet supported. - */ - reg = readl(®s->mcr); - if (!(reg & FLEXCAN_MCR_FEN)) { - dev_err(dev->dev.parent, - "Could not enable RX FIFO, unsupported core\n"); - err = -ENODEV; - goto out; - } - - err = register_candev(dev); - - out: - /* disable core and turn off clocks */ - flexcan_chip_disable(priv); - clk_disable(priv->clk); - - return err; -} - -static void __devexit unregister_flexcandev(struct net_device *dev) -{ - unregister_candev(dev); -} - -static int __devinit flexcan_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct flexcan_priv *priv; - struct resource *mem; - struct clk *clk; - void __iomem *base; - resource_size_t mem_size; - int err, irq; - - clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "no clock defined\n"); - err = PTR_ERR(clk); - goto failed_clock; - } - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!mem || irq <= 0) { - err = -ENODEV; - goto failed_get; - } - - mem_size = resource_size(mem); - if (!request_mem_region(mem->start, mem_size, pdev->name)) { - err = -EBUSY; - goto failed_req; - } - - base = ioremap(mem->start, mem_size); - if (!base) { - err = -ENOMEM; - goto failed_map; - } - - dev = alloc_candev(sizeof(struct flexcan_priv), 0); - if (!dev) { - err = -ENOMEM; - goto failed_alloc; - } - - dev->netdev_ops = &flexcan_netdev_ops; - dev->irq = irq; - dev->flags |= IFF_ECHO; /* we support local echo in hardware */ - - priv = netdev_priv(dev); - priv->can.clock.freq = clk_get_rate(clk); - priv->can.bittiming_const = &flexcan_bittiming_const; - priv->can.do_set_mode = flexcan_set_mode; - priv->can.do_get_berr_counter = flexcan_get_berr_counter; - priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | - CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES | - CAN_CTRLMODE_BERR_REPORTING; - priv->base = base; - priv->dev = dev; - priv->clk = clk; - priv->pdata = pdev->dev.platform_data; - - netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); - - dev_set_drvdata(&pdev->dev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - - err = register_flexcandev(dev); - if (err) { - dev_err(&pdev->dev, "registering netdev failed\n"); - goto failed_register; - } - - dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", - priv->base, dev->irq); - - return 0; - - failed_register: - free_candev(dev); - failed_alloc: - iounmap(base); - failed_map: - release_mem_region(mem->start, mem_size); - failed_req: - clk_put(clk); - failed_get: - failed_clock: - return err; -} - -static int __devexit flexcan_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct flexcan_priv *priv = netdev_priv(dev); - struct resource *mem; - - unregister_flexcandev(dev); - platform_set_drvdata(pdev, NULL); - free_candev(dev); - iounmap(priv->base); - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); - - clk_put(priv->clk); - - return 0; -} - -static struct platform_driver flexcan_driver = { - .driver.name = DRV_NAME, - .probe = flexcan_probe, - .remove = __devexit_p(flexcan_remove), -}; - -static int __init flexcan_init(void) -{ - pr_info("%s netdevice driver\n", DRV_NAME); - return platform_driver_register(&flexcan_driver); -} - -static void __exit flexcan_exit(void) -{ - platform_driver_unregister(&flexcan_driver); - pr_info("%s: driver removed\n", DRV_NAME); -} - -module_init(flexcan_init); -module_exit(flexcan_exit); - -MODULE_AUTHOR("Sascha Hauer , " - "Marc Kleine-Budde "); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("CAN port driver for flexcan based chip"); diff --git a/trunk/drivers/net/cnic.c b/trunk/drivers/net/cnic.c index 09610323a948..5ecf0bcf372d 100644 --- a/trunk/drivers/net/cnic.c +++ b/trunk/drivers/net/cnic.c @@ -40,9 +40,9 @@ #include "cnic_if.h" #include "bnx2.h" -#include "bnx2x/bnx2x_reg.h" -#include "bnx2x/bnx2x_fw_defs.h" -#include "bnx2x/bnx2x_hsi.h" +#include "bnx2x_reg.h" +#include "bnx2x_fw_defs.h" +#include "bnx2x_hsi.h" #include "../scsi/bnx2i/57xx_iscsi_constants.h" #include "../scsi/bnx2i/57xx_iscsi_hsi.h" #include "cnic.h" diff --git a/trunk/drivers/net/davinci_emac.c b/trunk/drivers/net/davinci_emac.c index 2fe709f98cc4..25e14d2da755 100644 --- a/trunk/drivers/net/davinci_emac.c +++ b/trunk/drivers/net/davinci_emac.c @@ -298,11 +298,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_CTRL_EWCTL (0x4) #define EMAC_CTRL_EWINTTCNT (0x8) -/* EMAC DM644x control module masks */ -#define EMAC_DM644X_EWINTCNT_MASK 0x1FFFF -#define EMAC_DM644X_INTMIN_INTVL 0x1 -#define EMAC_DM644X_INTMAX_INTVL (EMAC_DM644X_EWINTCNT_MASK) - /* EMAC MDIO related */ /* Mask & Control defines */ #define MDIO_CONTROL_CLKDIV (0xFF) @@ -323,20 +318,8 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define MDIO_CONTROL (0x04) /* EMAC DM646X control module registers */ -#define EMAC_DM646X_CMINTCTRL 0x0C -#define EMAC_DM646X_CMRXINTEN 0x14 -#define EMAC_DM646X_CMTXINTEN 0x18 -#define EMAC_DM646X_CMRXINTMAX 0x70 -#define EMAC_DM646X_CMTXINTMAX 0x74 - -/* EMAC DM646X control module masks */ -#define EMAC_DM646X_INTPACEEN (0x3 << 16) -#define EMAC_DM646X_INTPRESCALE_MASK (0x7FF << 0) -#define EMAC_DM646X_CMINTMAX_CNT 63 -#define EMAC_DM646X_CMINTMIN_CNT 2 -#define EMAC_DM646X_CMINTMAX_INTVL (1000 / EMAC_DM646X_CMINTMIN_CNT) -#define EMAC_DM646X_CMINTMIN_INTVL ((1000 / EMAC_DM646X_CMINTMAX_CNT) + 1) - +#define EMAC_DM646X_CMRXINTEN (0x14) +#define EMAC_DM646X_CMTXINTEN (0x18) /* EMAC EOI codes for C0 */ #define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01) @@ -485,8 +468,6 @@ struct emac_priv { u32 duplex; /* Link duplex: 0=Half, 1=Full */ u32 rx_buf_size; u32 isr_count; - u32 coal_intvl; - u32 bus_freq_mhz; u8 rmii_en; u8 version; u32 mac_hash1; @@ -564,11 +545,9 @@ static void emac_dump_regs(struct emac_priv *priv) /* Print important registers in EMAC */ dev_info(emac_dev, "EMAC Basic registers\n"); - if (priv->version == EMAC_VERSION_1) { - dev_info(emac_dev, "EMAC: EWCTL: %08X, EWINTTCNT: %08X\n", - emac_ctrl_read(EMAC_CTRL_EWCTL), - emac_ctrl_read(EMAC_CTRL_EWINTTCNT)); - } + dev_info(emac_dev, "EMAC: EWCTL: %08X, EWINTTCNT: %08X\n", + emac_ctrl_read(EMAC_CTRL_EWCTL), + emac_ctrl_read(EMAC_CTRL_EWINTTCNT)); dev_info(emac_dev, "EMAC: TXID: %08X %s, RXID: %08X %s\n", emac_read(EMAC_TXIDVER), ((emac_read(EMAC_TXCONTROL)) ? "enabled" : "disabled"), @@ -711,103 +690,6 @@ static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) } -/** - * emac_get_coalesce : Get interrupt coalesce settings for this device - * @ndev : The DaVinci EMAC network adapter - * @coal : ethtool coalesce settings structure - * - * Fetch the current interrupt coalesce settings - * - */ -static int emac_get_coalesce(struct net_device *ndev, - struct ethtool_coalesce *coal) -{ - struct emac_priv *priv = netdev_priv(ndev); - - coal->rx_coalesce_usecs = priv->coal_intvl; - return 0; - -} - -/** - * emac_set_coalesce : Set interrupt coalesce settings for this device - * @ndev : The DaVinci EMAC network adapter - * @coal : ethtool coalesce settings structure - * - * Set interrupt coalesce parameters - * - */ -static int emac_set_coalesce(struct net_device *ndev, - struct ethtool_coalesce *coal) -{ - struct emac_priv *priv = netdev_priv(ndev); - u32 int_ctrl, num_interrupts = 0; - u32 prescale = 0, addnl_dvdr = 1, coal_intvl = 0; - - if (!coal->rx_coalesce_usecs) - return -EINVAL; - - coal_intvl = coal->rx_coalesce_usecs; - - switch (priv->version) { - case EMAC_VERSION_2: - int_ctrl = emac_ctrl_read(EMAC_DM646X_CMINTCTRL); - prescale = priv->bus_freq_mhz * 4; - - if (coal_intvl < EMAC_DM646X_CMINTMIN_INTVL) - coal_intvl = EMAC_DM646X_CMINTMIN_INTVL; - - if (coal_intvl > EMAC_DM646X_CMINTMAX_INTVL) { - /* - * Interrupt pacer works with 4us Pulse, we can - * throttle further by dilating the 4us pulse. - */ - addnl_dvdr = EMAC_DM646X_INTPRESCALE_MASK / prescale; - - if (addnl_dvdr > 1) { - prescale *= addnl_dvdr; - if (coal_intvl > (EMAC_DM646X_CMINTMAX_INTVL - * addnl_dvdr)) - coal_intvl = (EMAC_DM646X_CMINTMAX_INTVL - * addnl_dvdr); - } else { - addnl_dvdr = 1; - coal_intvl = EMAC_DM646X_CMINTMAX_INTVL; - } - } - - num_interrupts = (1000 * addnl_dvdr) / coal_intvl; - - int_ctrl |= EMAC_DM646X_INTPACEEN; - int_ctrl &= (~EMAC_DM646X_INTPRESCALE_MASK); - int_ctrl |= (prescale & EMAC_DM646X_INTPRESCALE_MASK); - emac_ctrl_write(EMAC_DM646X_CMINTCTRL, int_ctrl); - - emac_ctrl_write(EMAC_DM646X_CMRXINTMAX, num_interrupts); - emac_ctrl_write(EMAC_DM646X_CMTXINTMAX, num_interrupts); - - break; - default: - int_ctrl = emac_ctrl_read(EMAC_CTRL_EWINTTCNT); - int_ctrl &= (~EMAC_DM644X_EWINTCNT_MASK); - prescale = coal_intvl * priv->bus_freq_mhz; - if (prescale > EMAC_DM644X_EWINTCNT_MASK) { - prescale = EMAC_DM644X_EWINTCNT_MASK; - coal_intvl = prescale / priv->bus_freq_mhz; - } - emac_ctrl_write(EMAC_CTRL_EWINTTCNT, (int_ctrl | prescale)); - - break; - } - - printk(KERN_INFO"Set coalesce to %d usecs.\n", coal_intvl); - priv->coal_intvl = coal_intvl; - - return 0; - -} - - /** * ethtool_ops: DaVinci EMAC Ethtool structure * @@ -819,8 +701,6 @@ static const struct ethtool_ops ethtool_ops = { .get_settings = emac_get_settings, .set_settings = emac_set_settings, .get_link = ethtool_op_get_link, - .get_coalesce = emac_get_coalesce, - .set_coalesce = emac_set_coalesce, }; /** @@ -2268,7 +2148,7 @@ static int emac_poll(struct napi_struct *napi, int budget) struct net_device *ndev = priv->ndev; struct device *emac_dev = &ndev->dev; u32 status = 0; - u32 num_tx_pkts = 0, num_rx_pkts = 0; + u32 num_pkts = 0; /* Check interrupt vectors and call packet processing */ status = emac_read(EMAC_MACINVECTOR); @@ -2279,19 +2159,27 @@ static int emac_poll(struct napi_struct *napi, int budget) mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC; if (status & mask) { - num_tx_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH, + num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH, EMAC_DEF_TX_MAX_SERVICE); } /* TX processing */ + if (num_pkts) + return budget; + mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC; if (priv->version == EMAC_VERSION_2) mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC; if (status & mask) { - num_rx_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget); + num_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget); } /* RX processing */ + if (num_pkts < budget) { + napi_complete(napi); + emac_int_enable(priv); + } + mask = EMAC_DM644X_MAC_IN_VECTOR_HOST_INT; if (priv->version == EMAC_VERSION_2) mask = EMAC_DM646X_MAC_IN_VECTOR_HOST_INT; @@ -2322,12 +2210,9 @@ static int emac_poll(struct napi_struct *napi, int budget) dev_err(emac_dev, "RX Host error %s on ch=%d\n", &emac_rxhost_errcodes[cause][0], ch); } - } else if (num_rx_pkts < budget) { - napi_complete(napi); - emac_int_enable(priv); - } + } /* Host error processing */ - return num_rx_pkts; + return num_pkts; } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -2552,14 +2437,6 @@ static int emac_dev_open(struct net_device *ndev) /* Start/Enable EMAC hardware */ emac_hw_enable(priv); - /* Enable Interrupt pacing if configured */ - if (priv->coal_intvl != 0) { - struct ethtool_coalesce coal; - - coal.rx_coalesce_usecs = (priv->coal_intvl << 4); - emac_set_coalesce(ndev, &coal); - } - /* find the first phy */ priv->phydev = NULL; if (priv->phy_mask) { @@ -2800,9 +2677,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) priv->int_enable = pdata->interrupt_enable; priv->int_disable = pdata->interrupt_disable; - priv->coal_intvl = 0; - priv->bus_freq_mhz = (u32)(emac_bus_frequency / 1000000); - emac_dev = &ndev->dev; /* Get EMAC platform data */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/trunk/drivers/net/dnet.c b/trunk/drivers/net/dnet.c index 7c075756611a..4ea7141f525d 100644 --- a/trunk/drivers/net/dnet.c +++ b/trunk/drivers/net/dnet.c @@ -854,7 +854,7 @@ static int __devinit dnet_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof(*bp)); if (!dev) { dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); - goto err_out_release_mem; + goto err_out; } /* TODO: Actually, we have some interesting features... */ @@ -911,8 +911,7 @@ static int __devinit dnet_probe(struct platform_device *pdev) if (err) dev_warn(&pdev->dev, "Cannot register PHY board fixup.\n"); - err = dnet_mii_init(bp); - if (err) + if (dnet_mii_init(bp) != 0) goto err_out_unregister_netdev; dev_info(&pdev->dev, "Dave DNET at 0x%p (0x%08x) irq %d %pM\n", @@ -937,8 +936,6 @@ static int __devinit dnet_probe(struct platform_device *pdev) iounmap(bp->regs); err_out_free_dev: free_netdev(dev); -err_out_release_mem: - release_mem_region(mem_base, mem_size); err_out: return err; } diff --git a/trunk/drivers/net/e1000/e1000.h b/trunk/drivers/net/e1000/e1000.h index 99288b95aead..65298a6d9af7 100644 --- a/trunk/drivers/net/e1000/e1000.h +++ b/trunk/drivers/net/e1000/e1000.h @@ -324,20 +324,18 @@ enum e1000_state_t { extern struct net_device *e1000_get_hw_dev(struct e1000_hw *hw); #define e_dbg(format, arg...) \ netdev_dbg(e1000_get_hw_dev(hw), format, ## arg) -#define e_err(msglvl, format, arg...) \ - netif_err(adapter, msglvl, adapter->netdev, format, ## arg) -#define e_info(msglvl, format, arg...) \ - netif_info(adapter, msglvl, adapter->netdev, format, ## arg) -#define e_warn(msglvl, format, arg...) \ - netif_warn(adapter, msglvl, adapter->netdev, format, ## arg) -#define e_notice(msglvl, format, arg...) \ - netif_notice(adapter, msglvl, adapter->netdev, format, ## arg) +#define e_err(format, arg...) \ + netdev_err(adapter->netdev, format, ## arg) +#define e_info(format, arg...) \ + netdev_info(adapter->netdev, format, ## arg) +#define e_warn(format, arg...) \ + netdev_warn(adapter->netdev, format, ## arg) +#define e_notice(format, arg...) \ + netdev_notice(adapter->netdev, format, ## arg) #define e_dev_info(format, arg...) \ dev_info(&adapter->pdev->dev, format, ## arg) #define e_dev_warn(format, arg...) \ dev_warn(&adapter->pdev->dev, format, ## arg) -#define e_dev_err(format, arg...) \ - dev_err(&adapter->pdev->dev, format, ## arg) extern char e1000_driver_name[]; extern const char e1000_driver_version[]; diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index f4d0922ec65b..d5ff029aa7b2 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -346,7 +346,7 @@ static int e1000_set_tso(struct net_device *netdev, u32 data) netdev->features &= ~NETIF_F_TSO6; - e_info(probe, "TSO is %s\n", data ? "Enabled" : "Disabled"); + e_info("TSO is %s\n", data ? "Enabled" : "Disabled"); adapter->tso_force = true; return 0; } @@ -714,9 +714,9 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, int reg, writel(write & test[i], address); read = readl(address); if (read != (write & test[i] & mask)) { - e_err(drv, "pattern test reg %04X failed: " - "got 0x%08X expected 0x%08X\n", - reg, read, (write & test[i] & mask)); + e_info("pattern test reg %04X failed: " + "got 0x%08X expected 0x%08X\n", + reg, read, (write & test[i] & mask)); *data = reg; return true; } @@ -734,7 +734,7 @@ static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, int reg, writel(write & mask, address); read = readl(address); if ((read & mask) != (write & mask)) { - e_err(drv, "set/check reg %04X test failed: " + e_err("set/check reg %04X test failed: " "got 0x%08X expected 0x%08X\n", reg, (read & mask), (write & mask)); *data = reg; @@ -779,7 +779,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) ew32(STATUS, toggle); after = er32(STATUS) & toggle; if (value != after) { - e_err(drv, "failed STATUS register test got: " + e_err("failed STATUS register test got: " "0x%08X expected: 0x%08X\n", after, value); *data = 1; return 1; @@ -894,8 +894,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) *data = 1; return -1; } - e_info(hw, "testing %s interrupt\n", (shared_int ? - "shared" : "unshared")); + e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); @@ -1562,7 +1561,7 @@ static void e1000_diag_test(struct net_device *netdev, u8 forced_speed_duplex = hw->forced_speed_duplex; u8 autoneg = hw->autoneg; - e_info(hw, "offline testing starting\n"); + e_info("offline testing starting\n"); /* Link test performed before hardware reset so autoneg doesn't * interfere with test result */ @@ -1602,7 +1601,7 @@ static void e1000_diag_test(struct net_device *netdev, if (if_running) dev_open(netdev); } else { - e_info(hw, "online testing starting\n"); + e_info("online testing starting\n"); /* Online tests */ if (e1000_link_test(adapter, &data[4])) eth_test->flags |= ETH_TEST_FL_FAILED; @@ -1695,8 +1694,8 @@ static void e1000_get_wol(struct net_device *netdev, wol->supported &= ~WAKE_UCAST; if (adapter->wol & E1000_WUFC_EX) - e_err(drv, "Interface does not support directed " - "(unicast) frame wake-up packets\n"); + e_err("Interface does not support " + "directed (unicast) frame wake-up packets\n"); break; default: break; @@ -1727,8 +1726,8 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) switch (hw->device_id) { case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: if (wol->wolopts & WAKE_UCAST) { - e_err(drv, "Interface does not support directed " - "(unicast) frame wake-up packets\n"); + e_err("Interface does not support " + "directed (unicast) frame wake-up packets\n"); return -EOPNOTSUPP; } break; diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 02833af8a0b1..68a80893dce1 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -275,7 +275,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter) err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name, netdev); if (err) { - e_err(probe, "Unable to allocate interrupt Error: %d\n", err); + e_err("Unable to allocate interrupt Error: %d\n", err); } return err; @@ -657,7 +657,7 @@ void e1000_reset(struct e1000_adapter *adapter) ew32(WUC, 0); if (e1000_init_hw(hw)) - e_dev_err("Hardware Error\n"); + e_err("Hardware Error\n"); e1000_update_mng_vlan(adapter); /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */ @@ -925,7 +925,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* initialize eeprom parameters */ if (e1000_init_eeprom_params(hw)) { - e_err(probe, "EEPROM initialization failed\n"); + e_err("EEPROM initialization failed\n"); goto err_eeprom; } @@ -936,7 +936,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* make sure the EEPROM is good */ if (e1000_validate_eeprom_checksum(hw) < 0) { - e_err(probe, "The EEPROM Checksum Is Not Valid\n"); + e_err("The EEPROM Checksum Is Not Valid\n"); e1000_dump_eeprom(adapter); /* * set MAC address to all zeroes to invalidate and temporary @@ -950,14 +950,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } else { /* copy the MAC address out of the EEPROM */ if (e1000_read_mac_addr(hw)) - e_err(probe, "EEPROM Read Error\n"); + e_err("EEPROM Read Error\n"); } /* don't block initalization here due to bad MAC address */ memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len); memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len); if (!is_valid_ether_addr(netdev->perm_addr)) - e_err(probe, "Invalid MAC Address\n"); + e_err("Invalid MAC Address\n"); e1000_get_bus_info(hw); @@ -1047,7 +1047,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, goto err_register; /* print bus type/speed/width info */ - e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", + e_info("(PCI%s:%dMHz:%d-bit) %pM\n", ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), ((hw->bus_speed == e1000_bus_speed_133) ? 133 : (hw->bus_speed == e1000_bus_speed_120) ? 120 : @@ -1059,7 +1059,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); - e_info(probe, "Intel(R) PRO/1000 Network Connection\n"); + e_info("Intel(R) PRO/1000 Network Connection\n"); cards_found++; return 0; @@ -1159,7 +1159,7 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) /* identify the MAC */ if (e1000_set_mac_type(hw)) { - e_err(probe, "Unknown MAC Type\n"); + e_err("Unknown MAC Type\n"); return -EIO; } @@ -1192,7 +1192,7 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) adapter->num_rx_queues = 1; if (e1000_alloc_queues(adapter)) { - e_err(probe, "Unable to allocate memory for queues\n"); + e_err("Unable to allocate memory for queues\n"); return -ENOMEM; } @@ -1386,8 +1386,7 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, size = sizeof(struct e1000_buffer) * txdr->count; txdr->buffer_info = vmalloc(size); if (!txdr->buffer_info) { - e_err(probe, "Unable to allocate memory for the Tx descriptor " - "ring\n"); + e_err("Unable to allocate memory for the Tx descriptor ring\n"); return -ENOMEM; } memset(txdr->buffer_info, 0, size); @@ -1402,8 +1401,7 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, if (!txdr->desc) { setup_tx_desc_die: vfree(txdr->buffer_info); - e_err(probe, "Unable to allocate memory for the Tx descriptor " - "ring\n"); + e_err("Unable to allocate memory for the Tx descriptor ring\n"); return -ENOMEM; } @@ -1411,7 +1409,7 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) { void *olddesc = txdr->desc; dma_addr_t olddma = txdr->dma; - e_err(tx_err, "txdr align check failed: %u bytes at %p\n", + e_err("txdr align check failed: %u bytes at %p\n", txdr->size, txdr->desc); /* Try again, without freeing the previous */ txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, @@ -1429,7 +1427,7 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, txdr->dma); dma_free_coherent(&pdev->dev, txdr->size, olddesc, olddma); - e_err(probe, "Unable to allocate aligned memory " + e_err("Unable to allocate aligned memory " "for the transmit descriptor ring\n"); vfree(txdr->buffer_info); return -ENOMEM; @@ -1462,7 +1460,7 @@ int e1000_setup_all_tx_resources(struct e1000_adapter *adapter) for (i = 0; i < adapter->num_tx_queues; i++) { err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]); if (err) { - e_err(probe, "Allocation for Tx Queue %u failed\n", i); + e_err("Allocation for Tx Queue %u failed\n", i); for (i-- ; i >= 0; i--) e1000_free_tx_resources(adapter, &adapter->tx_ring[i]); @@ -1582,8 +1580,7 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, size = sizeof(struct e1000_buffer) * rxdr->count; rxdr->buffer_info = vmalloc(size); if (!rxdr->buffer_info) { - e_err(probe, "Unable to allocate memory for the Rx descriptor " - "ring\n"); + e_err("Unable to allocate memory for the Rx descriptor ring\n"); return -ENOMEM; } memset(rxdr->buffer_info, 0, size); @@ -1599,8 +1596,7 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, GFP_KERNEL); if (!rxdr->desc) { - e_err(probe, "Unable to allocate memory for the Rx descriptor " - "ring\n"); + e_err("Unable to allocate memory for the Rx descriptor ring\n"); setup_rx_desc_die: vfree(rxdr->buffer_info); return -ENOMEM; @@ -1610,7 +1606,7 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) { void *olddesc = rxdr->desc; dma_addr_t olddma = rxdr->dma; - e_err(rx_err, "rxdr align check failed: %u bytes at %p\n", + e_err("rxdr align check failed: %u bytes at %p\n", rxdr->size, rxdr->desc); /* Try again, without freeing the previous */ rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, @@ -1619,8 +1615,8 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, if (!rxdr->desc) { dma_free_coherent(&pdev->dev, rxdr->size, olddesc, olddma); - e_err(probe, "Unable to allocate memory for the Rx " - "descriptor ring\n"); + e_err("Unable to allocate memory for the Rx descriptor " + "ring\n"); goto setup_rx_desc_die; } @@ -1630,8 +1626,8 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, rxdr->dma); dma_free_coherent(&pdev->dev, rxdr->size, olddesc, olddma); - e_err(probe, "Unable to allocate aligned memory for " - "the Rx descriptor ring\n"); + e_err("Unable to allocate aligned memory for the Rx " + "descriptor ring\n"); goto setup_rx_desc_die; } else { /* Free old allocation, new allocation was successful */ @@ -1663,7 +1659,7 @@ int e1000_setup_all_rx_resources(struct e1000_adapter *adapter) for (i = 0; i < adapter->num_rx_queues; i++) { err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]); if (err) { - e_err(probe, "Allocation for Rx Queue %u failed\n", i); + e_err("Allocation for Rx Queue %u failed\n", i); for (i-- ; i >= 0; i--) e1000_free_rx_resources(adapter, &adapter->rx_ring[i]); @@ -2114,7 +2110,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC); if (!mcarray) { - e_err(probe, "memory allocation failed\n"); + e_err("memory allocation failed\n"); return; } @@ -2652,8 +2648,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, break; default: if (unlikely(net_ratelimit())) - e_warn(drv, "checksum_partial proto=%x!\n", - skb->protocol); + e_warn("checksum_partial proto=%x!\n", skb->protocol); break; } @@ -2997,8 +2992,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, /* fall through */ pull_size = min((unsigned int)4, skb->data_len); if (!__pskb_pull_tail(skb, pull_size)) { - e_err(drv, "__pskb_pull_tail " - "failed.\n"); + e_err("__pskb_pull_tail failed.\n"); dev_kfree_skb_any(skb); return NETDEV_TX_OK; } @@ -3146,7 +3140,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { - e_err(probe, "Invalid MTU setting\n"); + e_err("Invalid MTU setting\n"); return -EINVAL; } @@ -3154,7 +3148,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) switch (hw->mac_type) { case e1000_undefined ... e1000_82542_rev2_1: if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) { - e_err(probe, "Jumbo Frames not supported.\n"); + e_err("Jumbo Frames not supported.\n"); return -EINVAL; } break; @@ -3506,7 +3500,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, !(er32(STATUS) & E1000_STATUS_TXOFF)) { /* detected Tx unit hang */ - e_err(drv, "Detected Tx Unit Hang\n" + e_err("Detected Tx Unit Hang\n" " Tx Queue <%lu>\n" " TDH <%x>\n" " TDT <%x>\n" @@ -3755,7 +3749,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, /* eth type trans needs skb->data to point to something */ if (!pskb_may_pull(skb, ETH_HLEN)) { - e_err(drv, "pskb_may_pull failed.\n"); + e_err("pskb_may_pull failed.\n"); dev_kfree_skb(skb); goto next_desc; } @@ -3880,7 +3874,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, if (adapter->discarding) { /* All receives must fit into a single buffer */ - e_dbg("Receive packet consumed multiple buffers\n"); + e_info("Receive packet consumed multiple buffers\n"); /* recycle */ buffer_info->skb = skb; if (status & E1000_RXD_STAT_EOP) @@ -3992,8 +3986,8 @@ e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, /* Fix for errata 23, can't cross 64kB boundary */ if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { struct sk_buff *oldskb = skb; - e_err(rx_err, "skb align check failed: %u bytes at " - "%p\n", bufsz, skb->data); + e_err("skb align check failed: %u bytes at %p\n", + bufsz, skb->data); /* Try again, without freeing the previous */ skb = netdev_alloc_skb_ip_align(netdev, bufsz); /* Failed allocation, critical failure */ @@ -4101,8 +4095,8 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, /* Fix for errata 23, can't cross 64kB boundary */ if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { struct sk_buff *oldskb = skb; - e_err(rx_err, "skb align check failed: %u bytes at " - "%p\n", bufsz, skb->data); + e_err("skb align check failed: %u bytes at %p\n", + bufsz, skb->data); /* Try again, without freeing the previous */ skb = netdev_alloc_skb_ip_align(netdev, bufsz); /* Failed allocation, critical failure */ @@ -4147,8 +4141,8 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, if (!e1000_check_64k_bound(adapter, (void *)(unsigned long)buffer_info->dma, adapter->rx_buffer_len)) { - e_err(rx_err, "dma align check failed: %u bytes at " - "%p\n", adapter->rx_buffer_len, + e_err("dma align check failed: %u bytes at %p\n", + adapter->rx_buffer_len, (void *)(unsigned long)buffer_info->dma); dev_kfree_skb(skb); buffer_info->skb = NULL; @@ -4361,7 +4355,7 @@ void e1000_pci_set_mwi(struct e1000_hw *hw) int ret_val = pci_set_mwi(adapter->pdev); if (ret_val) - e_err(probe, "Error in setting MWI\n"); + e_err("Error in setting MWI\n"); } void e1000_pci_clear_mwi(struct e1000_hw *hw) @@ -4492,7 +4486,7 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) /* Fiber NICs only allow 1000 gbps Full duplex */ if ((hw->media_type == e1000_media_type_fiber) && spddplx != (SPEED_1000 + DUPLEX_FULL)) { - e_err(probe, "Unsupported Speed/Duplex configuration\n"); + e_err("Unsupported Speed/Duplex configuration\n"); return -EINVAL; } @@ -4515,7 +4509,7 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) break; case SPEED_1000 + DUPLEX_HALF: /* not supported */ default: - e_err(probe, "Unsupported Speed/Duplex configuration\n"); + e_err("Unsupported Speed/Duplex configuration\n"); return -EINVAL; } return 0; diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index afd01295fbec..6aa795a6160b 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -5650,6 +5650,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) goto err_sw_init; + err = -EIO; + memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops)); memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops)); memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops)); diff --git a/trunk/drivers/net/ethoc.c b/trunk/drivers/net/ethoc.c index 6d653c459c1f..38c282e6565b 100644 --- a/trunk/drivers/net/ethoc.c +++ b/trunk/drivers/net/ethoc.c @@ -632,7 +632,7 @@ static void ethoc_mdio_poll(struct net_device *dev) { } -static int __devinit ethoc_mdio_probe(struct net_device *dev) +static int ethoc_mdio_probe(struct net_device *dev) { struct ethoc *priv = netdev_priv(dev); struct phy_device *phy; @@ -871,7 +871,7 @@ static const struct net_device_ops ethoc_netdev_ops = { * ethoc_probe() - initialize OpenCores ethernet MAC * pdev: platform device */ -static int __devinit ethoc_probe(struct platform_device *pdev) +static int ethoc_probe(struct platform_device *pdev) { struct net_device *netdev = NULL; struct resource *res = NULL; @@ -1080,7 +1080,7 @@ static int __devinit ethoc_probe(struct platform_device *pdev) * ethoc_remove() - shutdown OpenCores ethernet MAC * @pdev: platform device */ -static int __devexit ethoc_remove(struct platform_device *pdev) +static int ethoc_remove(struct platform_device *pdev) { struct net_device *netdev = platform_get_drvdata(pdev); struct ethoc *priv = netdev_priv(netdev); @@ -1121,7 +1121,7 @@ static int ethoc_resume(struct platform_device *pdev) static struct platform_driver ethoc_driver = { .probe = ethoc_probe, - .remove = __devexit_p(ethoc_remove), + .remove = ethoc_remove, .suspend = ethoc_suspend, .resume = ethoc_resume, .driver = { diff --git a/trunk/drivers/net/fec.c b/trunk/drivers/net/fec.c index 768b840aeb6b..391a553a3add 100644 --- a/trunk/drivers/net/fec.c +++ b/trunk/drivers/net/fec.c @@ -118,8 +118,6 @@ static unsigned char fec_mac_default[] = { #define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */ #define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */ -#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII) - /* The FEC stores dest/src/type, data, and checksum for receive packets. */ #define PKT_MAXBUF_SIZE 1518 @@ -1215,7 +1213,8 @@ fec_restart(struct net_device *dev, int duplex) writel(0, fep->hwp + FEC_R_DES_ACTIVE); /* Enable interrupts we wish to service */ - writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); + writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII, + fep->hwp + FEC_IMASK); } static void @@ -1234,8 +1233,8 @@ fec_stop(struct net_device *dev) /* Whack a reset. We should wait for this. */ writel(1, fep->hwp + FEC_ECNTRL); udelay(10); + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); - writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); } static int __devinit diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 4da05b1b445c..9ef6a9d5fbcb 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -89,10 +89,8 @@ #define DEV_HAS_MSI_X 0x0000080 /* device supports MSI-X */ #define DEV_HAS_POWER_CNTRL 0x0000100 /* device supports power savings */ #define DEV_HAS_STATISTICS_V1 0x0000200 /* device supports hw statistics version 1 */ -#define DEV_HAS_STATISTICS_V2 0x0000400 /* device supports hw statistics version 2 */ -#define DEV_HAS_STATISTICS_V3 0x0000800 /* device supports hw statistics version 3 */ -#define DEV_HAS_STATISTICS_V12 0x0000600 /* device supports hw statistics version 1 and 2 */ -#define DEV_HAS_STATISTICS_V123 0x0000e00 /* device supports hw statistics version 1, 2, and 3 */ +#define DEV_HAS_STATISTICS_V2 0x0000600 /* device supports hw statistics version 2 */ +#define DEV_HAS_STATISTICS_V3 0x0000e00 /* device supports hw statistics version 3 */ #define DEV_HAS_TEST_EXTENDED 0x0001000 /* device supports extended diagnostic test */ #define DEV_HAS_MGMT_UNIT 0x0002000 /* device supports management unit */ #define DEV_HAS_CORRECT_MACADDR 0x0004000 /* device supports correct mac address order */ @@ -6069,111 +6067,111 @@ static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = { }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0372), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0373), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x03E5), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x03E6), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x03EE), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x03EF), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0450), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0451), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0452), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0453), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x054C), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x054D), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x054E), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x054F), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x07DC), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x07DD), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x07DE), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x07DF), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V12|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0760), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0761), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0762), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0763), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0AB0), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0AB1), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0AB2), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0AB3), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, }, { /* MCP89 Ethernet Controller */ PCI_DEVICE(0x10DE, 0x0D7D), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V123|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX, + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX, }, {0,}, }; diff --git a/trunk/drivers/net/igb/e1000_82575.c b/trunk/drivers/net/igb/e1000_82575.c index cc58227af424..06251a9e9f1b 100644 --- a/trunk/drivers/net/igb/e1000_82575.c +++ b/trunk/drivers/net/igb/e1000_82575.c @@ -70,35 +70,6 @@ static const u16 e1000_82580_rxpbs_table[] = #define E1000_82580_RXPBS_TABLE_SIZE \ (sizeof(e1000_82580_rxpbs_table)/sizeof(u16)) -/** - * igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO - * @hw: pointer to the HW structure - * - * Called to determine if the I2C pins are being used for I2C or as an - * external MDIO interface since the two options are mutually exclusive. - **/ -static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw) -{ - u32 reg = 0; - bool ext_mdio = false; - - switch (hw->mac.type) { - case e1000_82575: - case e1000_82576: - reg = rd32(E1000_MDIC); - ext_mdio = !!(reg & E1000_MDIC_DEST); - break; - case e1000_82580: - case e1000_i350: - reg = rd32(E1000_MDICNFG); - ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO); - break; - default: - break; - } - return ext_mdio; -} - static s32 igb_get_invariants_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; @@ -173,6 +144,13 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) wr32(E1000_CTRL_EXT, ctrl_ext); + /* + * if using i2c make certain the MDICNFG register is cleared to prevent + * communications from being misrouted to the mdic registers + */ + if ((ctrl_ext & E1000_CTRL_I2C_ENA) && (hw->mac.type == e1000_82580)) + wr32(E1000_MDICNFG, 0); + /* Set mta register count */ mac->mta_reg_count = 128; /* Set rar entry count */ @@ -251,20 +229,18 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) phy->reset_delay_us = 100; /* PHY function pointers */ - if (igb_sgmii_active_82575(hw)) - phy->ops.reset = igb_phy_hw_reset_sgmii_82575; - else - phy->ops.reset = igb_phy_hw_reset; - - if (igb_sgmii_active_82575(hw) && !igb_sgmii_uses_mdio_82575(hw)) { - phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; - phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; + if (igb_sgmii_active_82575(hw)) { + phy->ops.reset = igb_phy_hw_reset_sgmii_82575; + phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; + phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; } else if (hw->mac.type >= e1000_82580) { - phy->ops.read_reg = igb_read_phy_reg_82580; - phy->ops.write_reg = igb_write_phy_reg_82580; + phy->ops.reset = igb_phy_hw_reset; + phy->ops.read_reg = igb_read_phy_reg_82580; + phy->ops.write_reg = igb_write_phy_reg_82580; } else { - phy->ops.read_reg = igb_read_phy_reg_igp; - phy->ops.write_reg = igb_write_phy_reg_igp; + phy->ops.reset = igb_phy_hw_reset; + phy->ops.read_reg = igb_read_phy_reg_igp; + phy->ops.write_reg = igb_write_phy_reg_igp; } /* set lan id */ @@ -424,7 +400,6 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) s32 ret_val = 0; u16 phy_id; u32 ctrl_ext; - u32 mdic; /* * For SGMII PHYs, we try the list of possible addresses until @@ -439,29 +414,6 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) goto out; } - if (igb_sgmii_uses_mdio_82575(hw)) { - switch (hw->mac.type) { - case e1000_82575: - case e1000_82576: - mdic = rd32(E1000_MDIC); - mdic &= E1000_MDIC_PHY_MASK; - phy->addr = mdic >> E1000_MDIC_PHY_SHIFT; - break; - case e1000_82580: - case e1000_i350: - mdic = rd32(E1000_MDICNFG); - mdic &= E1000_MDICNFG_PHY_MASK; - phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT; - break; - default: - ret_val = -E1000_ERR_PHY; - goto out; - break; - } - ret_val = igb_get_phy_id(hw); - goto out; - } - /* Power on sgmii phy if it is disabled */ ctrl_ext = rd32(E1000_CTRL_EXT); wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); @@ -1548,43 +1500,6 @@ static s32 igb_write_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 data) return ret_val; } -/** - * igb_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits - * @hw: pointer to the HW structure - * - * This resets the the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on - * the values found in the EEPROM. This addresses an issue in which these - * bits are not restored from EEPROM after reset. - **/ -static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw) -{ - s32 ret_val = 0; - u32 mdicnfg; - u16 nvm_data; - - if (hw->mac.type != e1000_82580) - goto out; - if (!igb_sgmii_active_82575(hw)) - goto out; - - ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + - NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, - &nvm_data); - if (ret_val) { - hw_dbg("NVM Read Error\n"); - goto out; - } - - mdicnfg = rd32(E1000_MDICNFG); - if (nvm_data & NVM_WORD24_EXT_MDIO) - mdicnfg |= E1000_MDICNFG_EXT_MDIO; - if (nvm_data & NVM_WORD24_COM_MDIO) - mdicnfg |= E1000_MDICNFG_COM_MDIO; - wr32(E1000_MDICNFG, mdicnfg); -out: - return ret_val; -} - /** * igb_reset_hw_82580 - Reset hardware * @hw: pointer to the HW structure @@ -1660,10 +1575,6 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw) wr32(E1000_IMC, 0xffffffff); icr = rd32(E1000_ICR); - ret_val = igb_reset_mdicnfg_82580(hw); - if (ret_val) - hw_dbg("Could not reset MDICNFG based on EEPROM\n"); - /* Install any alternate MAC address into RAR0 */ ret_val = igb_check_alt_mac_addr(hw); diff --git a/trunk/drivers/net/igb/e1000_defines.h b/trunk/drivers/net/igb/e1000_defines.h index bbd2ec308eb0..90bc29d7e182 100644 --- a/trunk/drivers/net/igb/e1000_defines.h +++ b/trunk/drivers/net/igb/e1000_defines.h @@ -468,11 +468,6 @@ #define E1000_TIMINCA_16NS_SHIFT 24 -#define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */ -#define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */ -#define E1000_MDICNFG_PHY_MASK 0x03E00000 -#define E1000_MDICNFG_PHY_SHIFT 21 - /* PCI Express Control */ #define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 #define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 @@ -570,10 +565,6 @@ #define NVM_82580_LAN_FUNC_OFFSET(a) (a ? (0x40 + (0x40 * a)) : 0) -/* Mask bits for fields in Word 0x24 of the NVM */ -#define NVM_WORD24_COM_MDIO 0x0008 /* MDIO interface shared */ -#define NVM_WORD24_EXT_MDIO 0x0004 /* MDIO accesses routed external */ - /* Mask bits for fields in Word 0x0f of the NVM */ #define NVM_WORD0F_PAUSE_MASK 0x3000 #define NVM_WORD0F_ASM_DIR 0x2000 @@ -707,17 +698,12 @@ #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 /* MDI Control */ -#define E1000_MDIC_DATA_MASK 0x0000FFFF -#define E1000_MDIC_REG_MASK 0x001F0000 #define E1000_MDIC_REG_SHIFT 16 -#define E1000_MDIC_PHY_MASK 0x03E00000 #define E1000_MDIC_PHY_SHIFT 21 #define E1000_MDIC_OP_WRITE 0x04000000 #define E1000_MDIC_OP_READ 0x08000000 #define E1000_MDIC_READY 0x10000000 -#define E1000_MDIC_INT_EN 0x20000000 #define E1000_MDIC_ERROR 0x40000000 -#define E1000_MDIC_DEST 0x80000000 /* SerDes Control */ #define E1000_GEN_CTL_READY 0x80000000 diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index 667b527b0312..94656179441d 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -1722,15 +1722,6 @@ static int __devinit igb_probe(struct pci_dev *pdev, u16 eeprom_apme_mask = IGB_EEPROM_APME; u32 part_num; - /* Catch broken hardware that put the wrong VF device ID in - * the PCIe SR-IOV capability. - */ - if (pdev->is_virtfn) { - WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n", - pci_name(pdev), pdev->vendor, pdev->device); - return -EINVAL; - } - err = pci_enable_device_mem(pdev); if (err) return err; diff --git a/trunk/drivers/net/igbvf/netdev.c b/trunk/drivers/net/igbvf/netdev.c index 048595bc79ad..5e2b2a8c56c6 100644 --- a/trunk/drivers/net/igbvf/netdev.c +++ b/trunk/drivers/net/igbvf/netdev.c @@ -2751,7 +2751,7 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "PF still in reset state, assigning new address." " Is the PF interface up?\n"); - dev_hw_addr_random(adapter->netdev, hw->mac.addr); + random_ether_addr(hw->mac.addr); } else { err = hw->mac.ops.read_mac_addr(hw); if (err) { diff --git a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c index dcebc82c6f4d..da54b38bb480 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c @@ -54,14 +54,14 @@ struct ixgbe_stats { sizeof(((struct ixgbe_adapter *)0)->m), \ offsetof(struct ixgbe_adapter, m) #define IXGBE_NETDEV_STAT(m) NETDEV_STATS, \ - sizeof(((struct rtnl_link_stats64 *)0)->m), \ - offsetof(struct rtnl_link_stats64, m) + sizeof(((struct net_device *)0)->m), \ + offsetof(struct net_device, m) - offsetof(struct net_device, stats) static struct ixgbe_stats ixgbe_gstrings_stats[] = { - {"rx_packets", IXGBE_NETDEV_STAT(rx_packets)}, - {"tx_packets", IXGBE_NETDEV_STAT(tx_packets)}, - {"rx_bytes", IXGBE_NETDEV_STAT(rx_bytes)}, - {"tx_bytes", IXGBE_NETDEV_STAT(tx_bytes)}, + {"rx_packets", IXGBE_NETDEV_STAT(stats.rx_packets)}, + {"tx_packets", IXGBE_NETDEV_STAT(stats.tx_packets)}, + {"rx_bytes", IXGBE_NETDEV_STAT(stats.rx_bytes)}, + {"tx_bytes", IXGBE_NETDEV_STAT(stats.tx_bytes)}, {"rx_pkts_nic", IXGBE_STAT(stats.gprc)}, {"tx_pkts_nic", IXGBE_STAT(stats.gptc)}, {"rx_bytes_nic", IXGBE_STAT(stats.gorc)}, @@ -69,27 +69,27 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"lsc_int", IXGBE_STAT(lsc_int)}, {"tx_busy", IXGBE_STAT(tx_busy)}, {"non_eop_descs", IXGBE_STAT(non_eop_descs)}, - {"rx_errors", IXGBE_NETDEV_STAT(rx_errors)}, - {"tx_errors", IXGBE_NETDEV_STAT(tx_errors)}, - {"rx_dropped", IXGBE_NETDEV_STAT(rx_dropped)}, - {"tx_dropped", IXGBE_NETDEV_STAT(tx_dropped)}, - {"multicast", IXGBE_NETDEV_STAT(multicast)}, + {"rx_errors", IXGBE_NETDEV_STAT(stats.rx_errors)}, + {"tx_errors", IXGBE_NETDEV_STAT(stats.tx_errors)}, + {"rx_dropped", IXGBE_NETDEV_STAT(stats.rx_dropped)}, + {"tx_dropped", IXGBE_NETDEV_STAT(stats.tx_dropped)}, + {"multicast", IXGBE_NETDEV_STAT(stats.multicast)}, {"broadcast", IXGBE_STAT(stats.bprc)}, {"rx_no_buffer_count", IXGBE_STAT(stats.rnbc[0]) }, - {"collisions", IXGBE_NETDEV_STAT(collisions)}, - {"rx_over_errors", IXGBE_NETDEV_STAT(rx_over_errors)}, - {"rx_crc_errors", IXGBE_NETDEV_STAT(rx_crc_errors)}, - {"rx_frame_errors", IXGBE_NETDEV_STAT(rx_frame_errors)}, + {"collisions", IXGBE_NETDEV_STAT(stats.collisions)}, + {"rx_over_errors", IXGBE_NETDEV_STAT(stats.rx_over_errors)}, + {"rx_crc_errors", IXGBE_NETDEV_STAT(stats.rx_crc_errors)}, + {"rx_frame_errors", IXGBE_NETDEV_STAT(stats.rx_frame_errors)}, {"hw_rsc_aggregated", IXGBE_STAT(rsc_total_count)}, {"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)}, {"fdir_match", IXGBE_STAT(stats.fdirmatch)}, {"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, - {"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)}, - {"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)}, - {"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)}, - {"tx_carrier_errors", IXGBE_NETDEV_STAT(tx_carrier_errors)}, - {"tx_fifo_errors", IXGBE_NETDEV_STAT(tx_fifo_errors)}, - {"tx_heartbeat_errors", IXGBE_NETDEV_STAT(tx_heartbeat_errors)}, + {"rx_fifo_errors", IXGBE_NETDEV_STAT(stats.rx_fifo_errors)}, + {"rx_missed_errors", IXGBE_NETDEV_STAT(stats.rx_missed_errors)}, + {"tx_aborted_errors", IXGBE_NETDEV_STAT(stats.tx_aborted_errors)}, + {"tx_carrier_errors", IXGBE_NETDEV_STAT(stats.tx_carrier_errors)}, + {"tx_fifo_errors", IXGBE_NETDEV_STAT(stats.tx_fifo_errors)}, + {"tx_heartbeat_errors", IXGBE_NETDEV_STAT(stats.tx_heartbeat_errors)}, {"tx_timeout_count", IXGBE_STAT(tx_timeout_count)}, {"tx_restart_queue", IXGBE_STAT(restart_queue)}, {"rx_long_length_errors", IXGBE_STAT(stats.roc)}, diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 7d6a415bcf88..920375951454 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -4783,7 +4783,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) #ifdef CONFIG_IXGBE_DCB /* Default traffic class to use for FCoE */ adapter->fcoe.tc = IXGBE_FCOE_DEFTC; - adapter->fcoe.up = IXGBE_FCOE_DEFTC; #endif #endif /* IXGBE_FCOE */ } @@ -6148,26 +6147,21 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) struct ixgbe_adapter *adapter = netdev_priv(dev); int txq = smp_processor_id(); -#ifdef IXGBE_FCOE - if ((skb->protocol == htons(ETH_P_FCOE)) || - (skb->protocol == htons(ETH_P_FIP))) { - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); - txq += adapter->ring_feature[RING_F_FCOE].mask; - return txq; - } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - txq = adapter->fcoe.up; - return txq; - } - } -#endif - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { while (unlikely(txq >= dev->real_num_tx_queues)) txq -= dev->real_num_tx_queues; return txq; } +#ifdef IXGBE_FCOE + if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + ((skb->protocol == htons(ETH_P_FCOE)) || + (skb->protocol == htons(ETH_P_FIP)))) { + txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); + txq += adapter->ring_feature[RING_F_FCOE].mask; + return txq; + } +#endif if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { if (skb->priority == TC_PRIO_CONTROL) txq = adapter->ring_feature[RING_F_DCB].indices-1; @@ -6211,15 +6205,18 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, tx_ring = adapter->tx_ring[skb->queue_mapping]; #ifdef IXGBE_FCOE - /* for FCoE with DCB, we force the priority to what - * was specified by the switch */ - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED && - (skb->protocol == htons(ETH_P_FCOE) || - skb->protocol == htons(ETH_P_FIP))) { - tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK - << IXGBE_TX_FLAGS_VLAN_SHIFT); - tx_flags |= ((adapter->fcoe.up << 13) - << IXGBE_TX_FLAGS_VLAN_SHIFT); + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { +#ifdef CONFIG_IXGBE_DCB + /* for FCoE with DCB, we force the priority to what + * was specified by the switch */ + if ((skb->protocol == htons(ETH_P_FCOE)) || + (skb->protocol == htons(ETH_P_FIP))) { + tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK + << IXGBE_TX_FLAGS_VLAN_SHIFT); + tx_flags |= ((adapter->fcoe.up << 13) + << IXGBE_TX_FLAGS_VLAN_SHIFT); + } +#endif /* flag for FCoE offloads */ if (skb->protocol == htons(ETH_P_FCOE)) tx_flags |= IXGBE_TX_FLAGS_FCOE; @@ -6539,15 +6536,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, #endif u32 part_num, eec; - /* Catch broken hardware that put the wrong VF device ID in - * the PCIe SR-IOV capability. - */ - if (pdev->is_virtfn) { - WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n", - pci_name(pdev), pdev->vendor, pdev->device); - return -EINVAL; - } - err = pci_enable_device_mem(pdev); if (err) return err; @@ -6561,8 +6549,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (err) { - dev_err(&pdev->dev, - "No usable DMA configuration, aborting\n"); + e_dev_err("No usable DMA configuration, " + "aborting\n"); goto err_dma; } } @@ -6572,8 +6560,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, err = pci_request_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM), ixgbe_driver_name); if (err) { - dev_err(&pdev->dev, - "pci_request_selected_regions failed 0x%x\n", err); + e_dev_err("pci_request_selected_regions failed 0x%x\n", err); goto err_pci_reg; } diff --git a/trunk/drivers/net/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ixgbevf/ixgbevf_main.c index 4867440ecfa8..af491352b5e0 100644 --- a/trunk/drivers/net/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ixgbevf/ixgbevf_main.c @@ -2229,7 +2229,7 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) if (err) { dev_info(&pdev->dev, "PF still in reset state, assigning new address\n"); - dev_hw_addr_random(adapter->netdev, hw->mac.addr); + random_ether_addr(hw->mac.addr); } else { err = hw->mac.ops.init_hw(hw); if (err) { diff --git a/trunk/drivers/net/ks8842.c b/trunk/drivers/net/ks8842.c index 928b2b83cef5..634dad1c8b48 100644 --- a/trunk/drivers/net/ks8842.c +++ b/trunk/drivers/net/ks8842.c @@ -30,19 +30,11 @@ #include #include #include -#include -#include -#include #define DRV_NAME "ks8842" /* Timberdale specific Registers */ -#define REG_TIMB_RST 0x1c -#define REG_TIMB_FIFO 0x20 -#define REG_TIMB_ISR 0x24 -#define REG_TIMB_IER 0x28 -#define REG_TIMB_IAR 0x2C -#define REQ_TIMB_DMA_RESUME 0x30 +#define REG_TIMB_RST 0x1c /* KS8842 registers */ @@ -85,15 +77,6 @@ #define IRQ_RX_ERROR 0x0080 #define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \ IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR) -/* When running via timberdale in DMA mode, the RX interrupt should be - enabled in the KS8842, but not in the FPGA IP, since the IP handles - RX DMA internally. - TX interrupts are not needed it is handled by the FPGA the driver is - notified via DMA callbacks. -*/ -#define ENABLED_IRQS_DMA_IP (IRQ_LINK_CHANGE | IRQ_RX_STOPPED | \ - IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR) -#define ENABLED_IRQS_DMA (ENABLED_IRQS_DMA_IP | IRQ_RX) #define REG_ISR 0x02 #define REG_RXSR 0x04 #define RXSR_VALID 0x8000 @@ -136,28 +119,6 @@ #define MICREL_KS884X 0x01 /* 0=Timeberdale(FPGA), 1=Micrel */ #define KS884X_16BIT 0x02 /* 1=16bit, 0=32bit */ -#define DMA_BUFFER_SIZE 2048 - -struct ks8842_tx_dma_ctl { - struct dma_chan *chan; - struct dma_async_tx_descriptor *adesc; - void *buf; - struct scatterlist sg; - int channel; -}; - -struct ks8842_rx_dma_ctl { - struct dma_chan *chan; - struct dma_async_tx_descriptor *adesc; - struct sk_buff *skb; - struct scatterlist sg; - struct tasklet_struct tasklet; - int channel; -}; - -#define KS8842_USE_DMA(adapter) (((adapter)->dma_tx.channel != -1) && \ - ((adapter)->dma_rx.channel != -1)) - struct ks8842_adapter { void __iomem *hw_addr; int irq; @@ -166,19 +127,8 @@ struct ks8842_adapter { spinlock_t lock; /* spinlock to be interrupt safe */ struct work_struct timeout_work; struct net_device *netdev; - struct device *dev; - struct ks8842_tx_dma_ctl dma_tx; - struct ks8842_rx_dma_ctl dma_rx; }; -static void ks8842_dma_rx_cb(void *data); -static void ks8842_dma_tx_cb(void *data); - -static inline void ks8842_resume_dma(struct ks8842_adapter *adapter) -{ - iowrite32(1, adapter->hw_addr + REQ_TIMB_DMA_RESUME); -} - static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank) { iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK); @@ -332,6 +282,10 @@ static void ks8842_reset_hw(struct ks8842_adapter *adapter) /* restart port auto-negotiation */ ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4); + if (!(adapter->conf_flags & MICREL_KS884X)) + /* only advertise 10Mbps */ + ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4); + /* Enable the transmitter */ ks8842_enable_tx(adapter); @@ -342,19 +296,8 @@ static void ks8842_reset_hw(struct ks8842_adapter *adapter) ks8842_write16(adapter, 18, 0xffff, REG_ISR); /* enable interrupts */ - if (KS8842_USE_DMA(adapter)) { - /* When running in DMA Mode the RX interrupt is not enabled in - timberdale because RX data is received by DMA callbacks - it must still be enabled in the KS8842 because it indicates - to timberdale when there is RX data for it's DMA FIFOs */ - iowrite16(ENABLED_IRQS_DMA_IP, adapter->hw_addr + REG_TIMB_IER); - ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER); - } else { - if (!(adapter->conf_flags & MICREL_KS884X)) - iowrite16(ENABLED_IRQS, - adapter->hw_addr + REG_TIMB_IER); - ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); - } + ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); + /* enable the switch */ ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE); } @@ -427,53 +370,6 @@ static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter) return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff; } -static int ks8842_tx_frame_dma(struct sk_buff *skb, struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - struct ks8842_tx_dma_ctl *ctl = &adapter->dma_tx; - u8 *buf = ctl->buf; - - if (ctl->adesc) { - netdev_dbg(netdev, "%s: TX ongoing\n", __func__); - /* transfer ongoing */ - return NETDEV_TX_BUSY; - } - - sg_dma_len(&ctl->sg) = skb->len + sizeof(u32); - - /* copy data to the TX buffer */ - /* the control word, enable IRQ, port 1 and the length */ - *buf++ = 0x00; - *buf++ = 0x01; /* Port 1 */ - *buf++ = skb->len & 0xff; - *buf++ = (skb->len >> 8) & 0xff; - skb_copy_from_linear_data(skb, buf, skb->len); - - dma_sync_single_range_for_device(adapter->dev, - sg_dma_address(&ctl->sg), 0, sg_dma_len(&ctl->sg), - DMA_TO_DEVICE); - - /* make sure the length is a multiple of 4 */ - if (sg_dma_len(&ctl->sg) % 4) - sg_dma_len(&ctl->sg) += 4 - sg_dma_len(&ctl->sg) % 4; - - ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan, - &ctl->sg, 1, DMA_TO_DEVICE, - DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); - if (!ctl->adesc) - return NETDEV_TX_BUSY; - - ctl->adesc->callback_param = netdev; - ctl->adesc->callback = ks8842_dma_tx_cb; - ctl->adesc->tx_submit(ctl->adesc); - - netdev->stats.tx_bytes += skb->len; - - dev_kfree_skb(skb); - - return NETDEV_TX_OK; -} - static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev) { struct ks8842_adapter *adapter = netdev_priv(netdev); @@ -525,121 +421,6 @@ static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } -static void ks8842_update_rx_err_counters(struct net_device *netdev, u32 status) -{ - netdev_dbg(netdev, "RX error, status: %x\n", status); - - netdev->stats.rx_errors++; - if (status & RXSR_TOO_LONG) - netdev->stats.rx_length_errors++; - if (status & RXSR_CRC_ERROR) - netdev->stats.rx_crc_errors++; - if (status & RXSR_RUNT) - netdev->stats.rx_frame_errors++; -} - -static void ks8842_update_rx_counters(struct net_device *netdev, u32 status, - int len) -{ - netdev_dbg(netdev, "RX packet, len: %d\n", len); - - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += len; - if (status & RXSR_MULTICAST) - netdev->stats.multicast++; -} - -static int __ks8842_start_new_rx_dma(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx; - struct scatterlist *sg = &ctl->sg; - int err; - - ctl->skb = netdev_alloc_skb(netdev, DMA_BUFFER_SIZE); - if (ctl->skb) { - sg_init_table(sg, 1); - sg_dma_address(sg) = dma_map_single(adapter->dev, - ctl->skb->data, DMA_BUFFER_SIZE, DMA_FROM_DEVICE); - err = dma_mapping_error(adapter->dev, sg_dma_address(sg)); - if (unlikely(err)) { - sg_dma_address(sg) = 0; - goto out; - } - - sg_dma_len(sg) = DMA_BUFFER_SIZE; - - ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan, - sg, 1, DMA_FROM_DEVICE, - DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP); - - if (!ctl->adesc) - goto out; - - ctl->adesc->callback_param = netdev; - ctl->adesc->callback = ks8842_dma_rx_cb; - ctl->adesc->tx_submit(ctl->adesc); - } else { - err = -ENOMEM; - sg_dma_address(sg) = 0; - goto out; - } - - return err; -out: - if (sg_dma_address(sg)) - dma_unmap_single(adapter->dev, sg_dma_address(sg), - DMA_BUFFER_SIZE, DMA_FROM_DEVICE); - sg_dma_address(sg) = 0; - if (ctl->skb) - dev_kfree_skb(ctl->skb); - - ctl->skb = NULL; - - printk(KERN_ERR DRV_NAME": Failed to start RX DMA: %d\n", err); - return err; -} - -static void ks8842_rx_frame_dma_tasklet(unsigned long arg) -{ - struct net_device *netdev = (struct net_device *)arg; - struct ks8842_adapter *adapter = netdev_priv(netdev); - struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx; - struct sk_buff *skb = ctl->skb; - dma_addr_t addr = sg_dma_address(&ctl->sg); - u32 status; - - ctl->adesc = NULL; - - /* kick next transfer going */ - __ks8842_start_new_rx_dma(netdev); - - /* now handle the data we got */ - dma_unmap_single(adapter->dev, addr, DMA_BUFFER_SIZE, DMA_FROM_DEVICE); - - status = *((u32 *)skb->data); - - netdev_dbg(netdev, "%s - rx_data: status: %x\n", - __func__, status & 0xffff); - - /* check the status */ - if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { - int len = (status >> 16) & 0x7ff; - - ks8842_update_rx_counters(netdev, status, len); - - /* reserve 4 bytes which is the status word */ - skb_reserve(skb, 4); - skb_put(skb, len); - - skb->protocol = eth_type_trans(skb, netdev); - netif_rx(skb); - } else { - ks8842_update_rx_err_counters(netdev, status); - dev_kfree_skb(skb); - } -} - static void ks8842_rx_frame(struct net_device *netdev, struct ks8842_adapter *adapter) { @@ -663,9 +444,13 @@ static void ks8842_rx_frame(struct net_device *netdev, if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len); + netdev_dbg(netdev, "%s, got package, len: %d\n", __func__, len); if (skb) { - ks8842_update_rx_counters(netdev, status, len); + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += len; + if (status & RXSR_MULTICAST) + netdev->stats.multicast++; if (adapter->conf_flags & KS884X_16BIT) { u16 *data16 = (u16 *)skb_put(skb, len); @@ -691,8 +476,16 @@ static void ks8842_rx_frame(struct net_device *netdev, netif_rx(skb); } else netdev->stats.rx_dropped++; - } else - ks8842_update_rx_err_counters(netdev, status); + } else { + netdev_dbg(netdev, "RX error, status: %x\n", status); + netdev->stats.rx_errors++; + if (status & RXSR_TOO_LONG) + netdev->stats.rx_length_errors++; + if (status & RXSR_CRC_ERROR) + netdev->stats.rx_crc_errors++; + if (status & RXSR_RUNT) + netdev->stats.rx_frame_errors++; + } /* set high watermark to 3K */ ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR); @@ -747,30 +540,18 @@ void ks8842_tasklet(unsigned long arg) isr = ks8842_read16(adapter, 18, REG_ISR); netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr); - /* when running in DMA mode, do not ack RX interrupts, it is handled - internally by timberdale, otherwise it's DMA FIFO:s would stop - */ - if (KS8842_USE_DMA(adapter)) - isr &= ~IRQ_RX; - /* Ack */ ks8842_write16(adapter, 18, isr, REG_ISR); - if (!(adapter->conf_flags & MICREL_KS884X)) - /* Ack in the timberdale IP as well */ - iowrite32(0x1, adapter->hw_addr + REG_TIMB_IAR); - if (!netif_running(netdev)) return; if (isr & IRQ_LINK_CHANGE) ks8842_update_link_status(netdev, adapter); - /* should not get IRQ_RX when running DMA mode */ - if (isr & (IRQ_RX | IRQ_RX_ERROR) && !KS8842_USE_DMA(adapter)) + if (isr & (IRQ_RX | IRQ_RX_ERROR)) ks8842_handle_rx(netdev, adapter); - /* should only happen when in PIO mode */ if (isr & IRQ_TX) ks8842_handle_tx(netdev, adapter); @@ -789,17 +570,8 @@ void ks8842_tasklet(unsigned long arg) /* re-enable interrupts, put back the bank selection register */ spin_lock_irqsave(&adapter->lock, flags); - if (KS8842_USE_DMA(adapter)) - ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER); - else - ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); + ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); - - /* Make sure timberdale continues DMA operations, they are stopped while - we are handling the ks8842 because we might change bank */ - if (KS8842_USE_DMA(adapter)) - ks8842_resume_dma(adapter); - spin_unlock_irqrestore(&adapter->lock, flags); } @@ -815,12 +587,8 @@ static irqreturn_t ks8842_irq(int irq, void *devid) netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr); if (isr) { - if (KS8842_USE_DMA(adapter)) - /* disable all but RX IRQ, since the FPGA relies on it*/ - ks8842_write16(adapter, 18, IRQ_RX, REG_IER); - else - /* disable IRQ */ - ks8842_write16(adapter, 18, 0x00, REG_IER); + /* disable IRQ */ + ks8842_write16(adapter, 18, 0x00, REG_IER); /* schedule tasklet */ tasklet_schedule(&adapter->tasklet); @@ -830,151 +598,9 @@ static irqreturn_t ks8842_irq(int irq, void *devid) iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); - /* After an interrupt, tell timberdale to continue DMA operations. - DMA is disabled while we are handling the ks8842 because we might - change bank */ - ks8842_resume_dma(adapter); - return ret; } -static void ks8842_dma_rx_cb(void *data) -{ - struct net_device *netdev = data; - struct ks8842_adapter *adapter = netdev_priv(netdev); - - netdev_dbg(netdev, "RX DMA finished\n"); - /* schedule tasklet */ - if (adapter->dma_rx.adesc) - tasklet_schedule(&adapter->dma_rx.tasklet); -} - -static void ks8842_dma_tx_cb(void *data) -{ - struct net_device *netdev = data; - struct ks8842_adapter *adapter = netdev_priv(netdev); - struct ks8842_tx_dma_ctl *ctl = &adapter->dma_tx; - - netdev_dbg(netdev, "TX DMA finished\n"); - - if (!ctl->adesc) - return; - - netdev->stats.tx_packets++; - ctl->adesc = NULL; - - if (netif_queue_stopped(netdev)) - netif_wake_queue(netdev); -} - -static void ks8842_stop_dma(struct ks8842_adapter *adapter) -{ - struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx; - struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx; - - tx_ctl->adesc = NULL; - if (tx_ctl->chan) - tx_ctl->chan->device->device_control(tx_ctl->chan, - DMA_TERMINATE_ALL, 0); - - rx_ctl->adesc = NULL; - if (rx_ctl->chan) - rx_ctl->chan->device->device_control(rx_ctl->chan, - DMA_TERMINATE_ALL, 0); - - if (sg_dma_address(&rx_ctl->sg)) - dma_unmap_single(adapter->dev, sg_dma_address(&rx_ctl->sg), - DMA_BUFFER_SIZE, DMA_FROM_DEVICE); - sg_dma_address(&rx_ctl->sg) = 0; - - dev_kfree_skb(rx_ctl->skb); - rx_ctl->skb = NULL; -} - -static void ks8842_dealloc_dma_bufs(struct ks8842_adapter *adapter) -{ - struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx; - struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx; - - ks8842_stop_dma(adapter); - - if (tx_ctl->chan) - dma_release_channel(tx_ctl->chan); - tx_ctl->chan = NULL; - - if (rx_ctl->chan) - dma_release_channel(rx_ctl->chan); - rx_ctl->chan = NULL; - - tasklet_kill(&rx_ctl->tasklet); - - if (sg_dma_address(&tx_ctl->sg)) - dma_unmap_single(adapter->dev, sg_dma_address(&tx_ctl->sg), - DMA_BUFFER_SIZE, DMA_TO_DEVICE); - sg_dma_address(&tx_ctl->sg) = 0; - - kfree(tx_ctl->buf); - tx_ctl->buf = NULL; -} - -static bool ks8842_dma_filter_fn(struct dma_chan *chan, void *filter_param) -{ - return chan->chan_id == (long)filter_param; -} - -static int ks8842_alloc_dma_bufs(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx; - struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx; - int err; - - dma_cap_mask_t mask; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_cap_set(DMA_PRIVATE, mask); - - sg_init_table(&tx_ctl->sg, 1); - - tx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn, - (void *)(long)tx_ctl->channel); - if (!tx_ctl->chan) { - err = -ENODEV; - goto err; - } - - /* allocate DMA buffer */ - tx_ctl->buf = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL); - if (!tx_ctl->buf) { - err = -ENOMEM; - goto err; - } - - sg_dma_address(&tx_ctl->sg) = dma_map_single(adapter->dev, - tx_ctl->buf, DMA_BUFFER_SIZE, DMA_TO_DEVICE); - err = dma_mapping_error(adapter->dev, - sg_dma_address(&tx_ctl->sg)); - if (err) { - sg_dma_address(&tx_ctl->sg) = 0; - goto err; - } - - rx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn, - (void *)(long)rx_ctl->channel); - if (!rx_ctl->chan) { - err = -ENODEV; - goto err; - } - - tasklet_init(&rx_ctl->tasklet, ks8842_rx_frame_dma_tasklet, - (unsigned long)netdev); - - return 0; -err: - ks8842_dealloc_dma_bufs(adapter); - return err; -} /* Netdevice operations */ @@ -985,25 +611,6 @@ static int ks8842_open(struct net_device *netdev) netdev_dbg(netdev, "%s - entry\n", __func__); - if (KS8842_USE_DMA(adapter)) { - err = ks8842_alloc_dma_bufs(netdev); - - if (!err) { - /* start RX dma */ - err = __ks8842_start_new_rx_dma(netdev); - if (err) - ks8842_dealloc_dma_bufs(adapter); - } - - if (err) { - printk(KERN_WARNING DRV_NAME - ": Failed to initiate DMA, running PIO\n"); - ks8842_dealloc_dma_bufs(adapter); - adapter->dma_rx.channel = -1; - adapter->dma_tx.channel = -1; - } - } - /* reset the HW */ ks8842_reset_hw(adapter); @@ -1029,9 +636,6 @@ static int ks8842_close(struct net_device *netdev) cancel_work_sync(&adapter->timeout_work); - if (KS8842_USE_DMA(adapter)) - ks8842_dealloc_dma_bufs(adapter); - /* free the irq */ free_irq(adapter->irq, netdev); @@ -1049,17 +653,6 @@ static netdev_tx_t ks8842_xmit_frame(struct sk_buff *skb, netdev_dbg(netdev, "%s: entry\n", __func__); - if (KS8842_USE_DMA(adapter)) { - unsigned long flags; - ret = ks8842_tx_frame_dma(skb, netdev); - /* for now only allow one transfer at the time */ - spin_lock_irqsave(&adapter->lock, flags); - if (adapter->dma_tx.adesc) - netif_stop_queue(netdev); - spin_unlock_irqrestore(&adapter->lock, flags); - return ret; - } - ret = ks8842_tx_frame(skb, netdev); if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8) @@ -1095,10 +688,6 @@ static void ks8842_tx_timeout_work(struct work_struct *work) netdev_dbg(netdev, "%s: entry\n", __func__); spin_lock_irqsave(&adapter->lock, flags); - - if (KS8842_USE_DMA(adapter)) - ks8842_stop_dma(adapter); - /* disable interrupts */ ks8842_write16(adapter, 18, 0, REG_IER); ks8842_write16(adapter, 18, 0xFFFF, REG_ISR); @@ -1112,9 +701,6 @@ static void ks8842_tx_timeout_work(struct work_struct *work) ks8842_write_mac_addr(adapter, netdev->dev_addr); ks8842_update_link_status(netdev, adapter); - - if (KS8842_USE_DMA(adapter)) - __ks8842_start_new_rx_dma(netdev); } static void ks8842_tx_timeout(struct net_device *netdev) @@ -1174,19 +760,6 @@ static int __devinit ks8842_probe(struct platform_device *pdev) goto err_get_irq; } - adapter->dev = (pdev->dev.parent) ? pdev->dev.parent : &pdev->dev; - - /* DMA is only supported when accessed via timberdale */ - if (!(adapter->conf_flags & MICREL_KS884X) && pdata && - (pdata->tx_dma_channel != -1) && - (pdata->rx_dma_channel != -1)) { - adapter->dma_rx.channel = pdata->rx_dma_channel; - adapter->dma_tx.channel = pdata->tx_dma_channel; - } else { - adapter->dma_rx.channel = -1; - adapter->dma_tx.channel = -1; - } - tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev); spin_lock_init(&adapter->lock); diff --git a/trunk/drivers/net/ksz884x.c b/trunk/drivers/net/ksz884x.c index 8b32cc107f0f..b3c010b85658 100644 --- a/trunk/drivers/net/ksz884x.c +++ b/trunk/drivers/net/ksz884x.c @@ -6894,12 +6894,13 @@ static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port) i = j = num = got_num = 0; while (j < MAC_ADDR_LEN) { if (macaddr[i]) { - int digit; - got_num = 1; - digit = hex_to_bin(macaddr[i]); - if (digit >= 0) - num = num * 16 + digit; + if ('0' <= macaddr[i] && macaddr[i] <= '9') + num = num * 16 + macaddr[i] - '0'; + else if ('A' <= macaddr[i] && macaddr[i] <= 'F') + num = num * 16 + 10 + macaddr[i] - 'A'; + else if ('a' <= macaddr[i] && macaddr[i] <= 'f') + num = num * 16 + 10 + macaddr[i] - 'a'; else if (':' == macaddr[i]) got_num = 2; else diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 0ef0eb0db945..1b28aaec0a5a 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -158,8 +158,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) const struct macvlan_dev *vlan; const struct macvlan_dev *src; struct net_device *dev; - unsigned int len = 0; - int ret = NET_RX_DROP; + unsigned int len; port = macvlan_port_get_rcu(skb->dev); if (is_multicast_ether_addr(eth->h_dest)) { @@ -196,16 +195,14 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) } len = skb->len + ETH_HLEN; skb = skb_share_check(skb, GFP_ATOMIC); + macvlan_count_rx(vlan, len, skb != NULL, 0); if (!skb) - goto out; + return NULL; skb->dev = dev; skb->pkt_type = PACKET_HOST; - ret = vlan->receive(skb); - -out: - macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0); + vlan->receive(skb); return NULL; } @@ -518,7 +515,7 @@ static const struct net_device_ops macvlan_netdev_ops = { .ndo_validate_addr = eth_validate_addr, }; -void macvlan_common_setup(struct net_device *dev) +static void macvlan_setup(struct net_device *dev) { ether_setup(dev); @@ -527,12 +524,6 @@ void macvlan_common_setup(struct net_device *dev) dev->destructor = free_netdev; dev->header_ops = &macvlan_hard_header_ops, dev->ethtool_ops = &macvlan_ethtool_ops; -} -EXPORT_SYMBOL_GPL(macvlan_common_setup); - -static void macvlan_setup(struct net_device *dev) -{ - macvlan_common_setup(dev); dev->tx_queue_len = 0; } @@ -744,6 +735,7 @@ int macvlan_link_register(struct rtnl_link_ops *ops) /* common fields */ ops->priv_size = sizeof(struct macvlan_dev); ops->get_tx_queues = macvlan_get_tx_queues; + ops->setup = macvlan_setup; ops->validate = macvlan_validate; ops->maxtype = IFLA_MACVLAN_MAX; ops->policy = macvlan_policy; @@ -757,7 +749,6 @@ EXPORT_SYMBOL_GPL(macvlan_link_register); static struct rtnl_link_ops macvlan_link_ops = { .kind = "macvlan", - .setup = macvlan_setup, .newlink = macvlan_newlink, .dellink = macvlan_dellink, }; diff --git a/trunk/drivers/net/macvtap.c b/trunk/drivers/net/macvtap.c index 3b1c54a9c6ef..2b4d59b58b2c 100644 --- a/trunk/drivers/net/macvtap.c +++ b/trunk/drivers/net/macvtap.c @@ -180,18 +180,11 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb) { struct macvtap_queue *q = macvtap_get_queue(dev, skb); if (!q) - goto drop; - - if (skb_queue_len(&q->sk.sk_receive_queue) >= dev->tx_queue_len) - goto drop; + return -ENOLINK; skb_queue_tail(&q->sk.sk_receive_queue, skb); wake_up_interruptible_poll(sk_sleep(&q->sk), POLLIN | POLLRDNORM | POLLRDBAND); - return NET_RX_SUCCESS; - -drop: - kfree_skb(skb); - return NET_RX_DROP; + return 0; } /* @@ -242,15 +235,8 @@ static void macvtap_dellink(struct net_device *dev, macvlan_dellink(dev, head); } -static void macvtap_setup(struct net_device *dev) -{ - macvlan_common_setup(dev); - dev->tx_queue_len = TUN_READQ_SIZE; -} - static struct rtnl_link_ops macvtap_link_ops __read_mostly = { .kind = "macvtap", - .setup = macvtap_setup, .newlink = macvtap_newlink, .dellink = macvtap_dellink, }; diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index 2d488abcf62d..2fcdb1e1b99d 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -2675,8 +2675,7 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) * Detect hardware parameters. */ msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; - msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? - pd->tx_csum_limit : 9 * 1024; + msp->tx_csum_limit = pd->tx_csum_limit ? pd->tx_csum_limit : 9 * 1024; infer_hw_params(msp); platform_set_drvdata(pdev, msp); diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index 6168a130f33f..54ebb65ada18 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -5,8 +5,6 @@ * See LICENSE.qla3xxx for copyright and licensing details. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -38,16 +36,14 @@ #include "qla3xxx.h" -#define DRV_NAME "qla3xxx" -#define DRV_STRING "QLogic ISP3XXX Network Driver" +#define DRV_NAME "qla3xxx" +#define DRV_STRING "QLogic ISP3XXX Network Driver" #define DRV_VERSION "v2.03.00-k5" +#define PFX DRV_NAME " " static const char ql3xxx_driver_name[] = DRV_NAME; static const char ql3xxx_driver_version[] = DRV_VERSION; -#define TIMED_OUT_MSG \ -"Timed out waiting for management port to get free before issuing command\n" - MODULE_AUTHOR("QLogic Corporation"); MODULE_DESCRIPTION("QLogic ISP3XXX Network Driver " DRV_VERSION " "); MODULE_LICENSE("GPL"); @@ -77,24 +73,24 @@ MODULE_DEVICE_TABLE(pci, ql3xxx_pci_tbl); /* * These are the known PHY's which are used */ -enum PHY_DEVICE_TYPE { +typedef enum { PHY_TYPE_UNKNOWN = 0, PHY_VITESSE_VSC8211, PHY_AGERE_ET1011C, MAX_PHY_DEV_TYPES -}; - -struct PHY_DEVICE_INFO { - const enum PHY_DEVICE_TYPE phyDevice; - const u32 phyIdOUI; - const u16 phyIdModel; - const char *name; -}; - -static const struct PHY_DEVICE_INFO PHY_DEVICES[] = { - {PHY_TYPE_UNKNOWN, 0x000000, 0x0, "PHY_TYPE_UNKNOWN"}, - {PHY_VITESSE_VSC8211, 0x0003f1, 0xb, "PHY_VITESSE_VSC8211"}, - {PHY_AGERE_ET1011C, 0x00a0bc, 0x1, "PHY_AGERE_ET1011C"}, +} PHY_DEVICE_et; + +typedef struct { + PHY_DEVICE_et phyDevice; + u32 phyIdOUI; + u16 phyIdModel; + char *name; +} PHY_DEVICE_INFO_t; + +static const PHY_DEVICE_INFO_t PHY_DEVICES[] = + {{PHY_TYPE_UNKNOWN, 0x000000, 0x0, "PHY_TYPE_UNKNOWN"}, + {PHY_VITESSE_VSC8211, 0x0003f1, 0xb, "PHY_VITESSE_VSC8211"}, + {PHY_AGERE_ET1011C, 0x00a0bc, 0x1, "PHY_AGERE_ET1011C"}, }; @@ -104,8 +100,7 @@ static const struct PHY_DEVICE_INFO PHY_DEVICES[] = { static int ql_sem_spinlock(struct ql3_adapter *qdev, u32 sem_mask, u32 sem_bits) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; u32 value; unsigned int seconds = 3; @@ -116,22 +111,20 @@ static int ql_sem_spinlock(struct ql3_adapter *qdev, if ((value & (sem_mask >> 16)) == sem_bits) return 0; ssleep(1); - } while (--seconds); + } while(--seconds); return -1; } static void ql_sem_unlock(struct ql3_adapter *qdev, u32 sem_mask) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; writel(sem_mask, &port_regs->CommonRegs.semaphoreReg); readl(&port_regs->CommonRegs.semaphoreReg); } static int ql_sem_lock(struct ql3_adapter *qdev, u32 sem_mask, u32 sem_bits) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; u32 value; writel((sem_mask | sem_bits), &port_regs->CommonRegs.semaphoreReg); @@ -146,28 +139,32 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) { int i = 0; - while (i < 10) { - if (i) - ssleep(1); - - if (ql_sem_lock(qdev, - QL_DRVR_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) - * 2) << 1)) { - netdev_printk(KERN_DEBUG, qdev->ndev, - "driver lock acquired\n"); + while (1) { + if (!ql_sem_lock(qdev, + QL_DRVR_SEM_MASK, + (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) + * 2) << 1)) { + if (i < 10) { + ssleep(1); + i++; + } else { + printk(KERN_ERR PFX "%s: Timed out waiting for " + "driver lock...\n", + qdev->ndev->name); + return 0; + } + } else { + printk(KERN_DEBUG PFX + "%s: driver lock acquired.\n", + qdev->ndev->name); return 1; } } - - netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); - return 0; } static void ql_set_register_page(struct ql3_adapter *qdev, u32 page) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; writel(((ISP_CONTROL_NP_MASK << 16) | page), &port_regs->CommonRegs.ispControlStatus); @@ -175,7 +172,8 @@ static void ql_set_register_page(struct ql3_adapter *qdev, u32 page) qdev->current_page = page; } -static u32 ql_read_common_reg_l(struct ql3_adapter *qdev, u32 __iomem *reg) +static u32 ql_read_common_reg_l(struct ql3_adapter *qdev, + u32 __iomem * reg) { u32 value; unsigned long hw_flags; @@ -187,7 +185,8 @@ static u32 ql_read_common_reg_l(struct ql3_adapter *qdev, u32 __iomem *reg) return value; } -static u32 ql_read_common_reg(struct ql3_adapter *qdev, u32 __iomem *reg) +static u32 ql_read_common_reg(struct ql3_adapter *qdev, + u32 __iomem * reg) { return readl(reg); } @@ -200,7 +199,7 @@ static u32 ql_read_page0_reg_l(struct ql3_adapter *qdev, u32 __iomem *reg) spin_lock_irqsave(&qdev->hw_lock, hw_flags); if (qdev->current_page != 0) - ql_set_register_page(qdev, 0); + ql_set_register_page(qdev,0); value = readl(reg); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); @@ -210,7 +209,7 @@ static u32 ql_read_page0_reg_l(struct ql3_adapter *qdev, u32 __iomem *reg) static u32 ql_read_page0_reg(struct ql3_adapter *qdev, u32 __iomem *reg) { if (qdev->current_page != 0) - ql_set_register_page(qdev, 0); + ql_set_register_page(qdev,0); return readl(reg); } @@ -244,7 +243,7 @@ static void ql_write_page0_reg(struct ql3_adapter *qdev, u32 __iomem *reg, u32 value) { if (qdev->current_page != 0) - ql_set_register_page(qdev, 0); + ql_set_register_page(qdev,0); writel(value, reg); readl(reg); } @@ -256,7 +255,7 @@ static void ql_write_page1_reg(struct ql3_adapter *qdev, u32 __iomem *reg, u32 value) { if (qdev->current_page != 1) - ql_set_register_page(qdev, 1); + ql_set_register_page(qdev,1); writel(value, reg); readl(reg); } @@ -268,15 +267,14 @@ static void ql_write_page2_reg(struct ql3_adapter *qdev, u32 __iomem *reg, u32 value) { if (qdev->current_page != 2) - ql_set_register_page(qdev, 2); + ql_set_register_page(qdev,2); writel(value, reg); readl(reg); } static void ql_disable_interrupts(struct ql3_adapter *qdev) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; ql_write_common_reg_l(qdev, &port_regs->CommonRegs.ispInterruptMaskReg, (ISP_IMR_ENABLE_INT << 16)); @@ -285,8 +283,7 @@ static void ql_disable_interrupts(struct ql3_adapter *qdev) static void ql_enable_interrupts(struct ql3_adapter *qdev) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; ql_write_common_reg_l(qdev, &port_regs->CommonRegs.ispInterruptMaskReg, ((0xff << 16) | ISP_IMR_ENABLE_INT)); @@ -311,7 +308,8 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, lrg_buf_cb->skb = netdev_alloc_skb(qdev->ndev, qdev->lrg_buffer_len); if (unlikely(!lrg_buf_cb->skb)) { - netdev_err(qdev->ndev, "failed netdev_alloc_skb()\n"); + printk(KERN_ERR PFX "%s: failed netdev_alloc_skb().\n", + qdev->ndev->name); qdev->lrg_buf_skb_check++; } else { /* @@ -325,10 +323,9 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); err = pci_dma_mapping_error(qdev->pdev, map); - if (err) { - netdev_err(qdev->ndev, - "PCI mapping failed with error: %d\n", - err); + if(err) { + printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", + qdev->ndev->name, err); dev_kfree_skb(lrg_buf_cb->skb); lrg_buf_cb->skb = NULL; @@ -353,11 +350,10 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, static struct ql_rcv_buf_cb *ql_get_from_lrg_buf_free_list(struct ql3_adapter *qdev) { - struct ql_rcv_buf_cb *lrg_buf_cb = qdev->lrg_buf_free_head; + struct ql_rcv_buf_cb *lrg_buf_cb; - if (lrg_buf_cb != NULL) { - qdev->lrg_buf_free_head = lrg_buf_cb->next; - if (qdev->lrg_buf_free_head == NULL) + if ((lrg_buf_cb = qdev->lrg_buf_free_head) != NULL) { + if ((qdev->lrg_buf_free_head = lrg_buf_cb->next) == NULL) qdev->lrg_buf_free_tail = NULL; qdev->lrg_buf_free_count--; } @@ -378,13 +374,13 @@ static void eeprom_readword(struct ql3_adapter *qdev, u32 eepromAddr, static void fm93c56a_select(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + qdev->mem_map_registers; qdev->eeprom_cmd_data = AUBURN_EEPROM_CS_1; - ql_write_nvram_reg(qdev, spir, ISP_NVRAM_MASK | qdev->eeprom_cmd_data); - ql_write_nvram_reg(qdev, spir, - ((ISP_NVRAM_MASK << 16) | qdev->eeprom_cmd_data)); + ql_write_nvram_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev->eeprom_cmd_data); + ql_write_nvram_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, + ((ISP_NVRAM_MASK << 16) | qdev->eeprom_cmd_data)); } /* @@ -397,40 +393,51 @@ static void fm93c56a_cmd(struct ql3_adapter *qdev, u32 cmd, u32 eepromAddr) u32 dataBit; u32 previousBit; struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + qdev->mem_map_registers; /* Clock in a zero, then do the start bit */ - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_DO_1)); - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_DO_1 | AUBURN_EEPROM_CLK_RISE)); - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_DO_1 | AUBURN_EEPROM_CLK_FALL)); + ql_write_nvram_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev->eeprom_cmd_data | + AUBURN_EEPROM_DO_1); + ql_write_nvram_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | AUBURN_EEPROM_DO_1 | + AUBURN_EEPROM_CLK_RISE); + ql_write_nvram_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | AUBURN_EEPROM_DO_1 | + AUBURN_EEPROM_CLK_FALL); mask = 1 << (FM93C56A_CMD_BITS - 1); /* Force the previous data bit to be different */ previousBit = 0xffff; for (i = 0; i < FM93C56A_CMD_BITS; i++) { - dataBit = (cmd & mask) - ? AUBURN_EEPROM_DO_1 - : AUBURN_EEPROM_DO_0; + dataBit = + (cmd & mask) ? AUBURN_EEPROM_DO_1 : AUBURN_EEPROM_DO_0; if (previousBit != dataBit) { - /* If the bit changed, change the DO state to match */ - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | - qdev->eeprom_cmd_data | dataBit)); + /* + * If the bit changed, then change the DO state to + * match + */ + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | dataBit); previousBit = dataBit; } - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - dataBit | AUBURN_EEPROM_CLK_RISE)); - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - dataBit | AUBURN_EEPROM_CLK_FALL)); + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_RISE); + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_FALL); cmd = cmd << 1; } @@ -438,24 +445,33 @@ static void fm93c56a_cmd(struct ql3_adapter *qdev, u32 cmd, u32 eepromAddr) /* Force the previous data bit to be different */ previousBit = 0xffff; for (i = 0; i < addrBits; i++) { - dataBit = (eepromAddr & mask) ? AUBURN_EEPROM_DO_1 - : AUBURN_EEPROM_DO_0; + dataBit = + (eepromAddr & mask) ? AUBURN_EEPROM_DO_1 : + AUBURN_EEPROM_DO_0; if (previousBit != dataBit) { /* * If the bit changed, then change the DO state to * match */ - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | - qdev->eeprom_cmd_data | dataBit)); + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | dataBit); previousBit = dataBit; } - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - dataBit | AUBURN_EEPROM_CLK_RISE)); - ql_write_nvram_reg(qdev, spir, - (ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - dataBit | AUBURN_EEPROM_CLK_FALL)); + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_RISE); + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev-> + eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_FALL); eepromAddr = eepromAddr << 1; } } @@ -466,11 +482,10 @@ static void fm93c56a_cmd(struct ql3_adapter *qdev, u32 cmd, u32 eepromAddr) static void fm93c56a_deselect(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; - + qdev->mem_map_registers; qdev->eeprom_cmd_data = AUBURN_EEPROM_CS_0; - ql_write_nvram_reg(qdev, spir, ISP_NVRAM_MASK | qdev->eeprom_cmd_data); + ql_write_nvram_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev->eeprom_cmd_data); } /* @@ -482,23 +497,29 @@ static void fm93c56a_datain(struct ql3_adapter *qdev, unsigned short *value) u32 data = 0; u32 dataBit; struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + qdev->mem_map_registers; /* Read the data bits */ /* The first bit is a dummy. Clock right over it. */ for (i = 0; i < dataBits; i++) { - ql_write_nvram_reg(qdev, spir, - ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_CLK_RISE); - ql_write_nvram_reg(qdev, spir, - ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_CLK_FALL); - dataBit = (ql_read_common_reg(qdev, spir) & - AUBURN_EEPROM_DI_1) ? 1 : 0; + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev->eeprom_cmd_data | + AUBURN_EEPROM_CLK_RISE); + ql_write_nvram_reg(qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg, + ISP_NVRAM_MASK | qdev->eeprom_cmd_data | + AUBURN_EEPROM_CLK_FALL); + dataBit = + (ql_read_common_reg + (qdev, + &port_regs->CommonRegs. + serialPortInterfaceReg) & AUBURN_EEPROM_DI_1) ? 1 : 0; data = (data << 1) | dataBit; } - *value = (u16)data; + *value = (u16) data; } /* @@ -530,12 +551,13 @@ static int ql_get_nvram_params(struct ql3_adapter *qdev) spin_lock_irqsave(&qdev->hw_lock, hw_flags); - pEEPROMData = (u16 *)&qdev->nvram_data; + pEEPROMData = (u16 *) & qdev->nvram_data; qdev->eeprom_cmd_data = 0; - if (ql_sem_spinlock(qdev, QL_NVRAM_SEM_MASK, + if(ql_sem_spinlock(qdev, QL_NVRAM_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 2) << 10)) { - pr_err("%s: Failed ql_sem_spinlock()\n", __func__); + printk(KERN_ERR PFX"%s: Failed ql_sem_spinlock().\n", + __func__); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); return -1; } @@ -548,8 +570,8 @@ static int ql_get_nvram_params(struct ql3_adapter *qdev) ql_sem_unlock(qdev, QL_NVRAM_SEM_MASK); if (checksum != 0) { - netdev_err(qdev->ndev, "checksum should be zero, is %x!!\n", - checksum); + printk(KERN_ERR PFX "%s: checksum should be zero, is %x!!\n", + qdev->ndev->name, checksum); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); return -1; } @@ -565,7 +587,7 @@ static const u32 PHYAddr[2] = { static int ql_wait_for_mii_ready(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 temp; int count = 1000; @@ -582,7 +604,7 @@ static int ql_wait_for_mii_ready(struct ql3_adapter *qdev) static void ql_mii_enable_scan_mode(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 scanControl; if (qdev->numPorts > 1) { @@ -610,7 +632,7 @@ static u8 ql_mii_disable_scan_mode(struct ql3_adapter *qdev) { u8 ret; struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; /* See if scan mode is enabled before we turn it off */ if (ql_read_page0_reg(qdev, &port_regs->macMIIMgmtControlReg) & @@ -640,13 +662,17 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, u16 regAddr, u16 value, u32 phyAddr) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u8 scanWasEnabled; scanWasEnabled = ql_mii_disable_scan_mode(qdev); if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s Timed out waiting for management port to " + "get free before issuing command.\n", + qdev->ndev->name); return -1; } @@ -657,7 +683,11 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, /* Wait for write to complete 9/10/04 SJP */ if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Timed out waiting for management port to " + "get free before issuing command.\n", + qdev->ndev->name); return -1; } @@ -668,17 +698,21 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, } static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr, - u16 *value, u32 phyAddr) + u16 * value, u32 phyAddr) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u8 scanWasEnabled; u32 temp; scanWasEnabled = ql_mii_disable_scan_mode(qdev); if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Timed out waiting for management port to " + "get free before issuing command.\n", + qdev->ndev->name); return -1; } @@ -693,7 +727,11 @@ static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr, /* Wait for the read to complete */ if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Timed out waiting for management port to " + "get free after issuing command.\n", + qdev->ndev->name); return -1; } @@ -709,12 +747,16 @@ static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr, static int ql_mii_write_reg(struct ql3_adapter *qdev, u16 regAddr, u16 value) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; ql_mii_disable_scan_mode(qdev); if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Timed out waiting for management port to " + "get free before issuing command.\n", + qdev->ndev->name); return -1; } @@ -725,7 +767,11 @@ static int ql_mii_write_reg(struct ql3_adapter *qdev, u16 regAddr, u16 value) /* Wait for write to complete. */ if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Timed out waiting for management port to " + "get free before issuing command.\n", + qdev->ndev->name); return -1; } @@ -738,12 +784,16 @@ static int ql_mii_read_reg(struct ql3_adapter *qdev, u16 regAddr, u16 *value) { u32 temp; struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; ql_mii_disable_scan_mode(qdev); if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Timed out waiting for management port to " + "get free before issuing command.\n", + qdev->ndev->name); return -1; } @@ -758,7 +808,11 @@ static int ql_mii_read_reg(struct ql3_adapter *qdev, u16 regAddr, u16 *value) /* Wait for the read to complete */ if (ql_wait_for_mii_ready(qdev)) { - netif_warn(qdev, link, qdev->ndev, TIMED_OUT_MSG); + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Timed out waiting for management port to " + "get free before issuing command.\n", + qdev->ndev->name); return -1; } @@ -844,7 +898,7 @@ static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev) static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr) { - netdev_info(qdev->ndev, "enabling Agere specific PHY\n"); + printk(KERN_INFO "%s: enabling Agere specific PHY\n", qdev->ndev->name); /* power down device bit 11 = 1 */ ql_mii_write_reg_ex(qdev, 0x00, 0x1940, miiAddr); /* enable diagnostic mode bit 2 = 1 */ @@ -864,8 +918,7 @@ static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr) /* point to hidden reg 0x2806 */ ql_mii_write_reg_ex(qdev, 0x10, 0x2806, miiAddr); /* Write new PHYAD w/bit 5 set */ - ql_mii_write_reg_ex(qdev, 0x11, - 0x0020 | (PHYAddr[qdev->mac_index] >> 8), miiAddr); + ql_mii_write_reg_ex(qdev, 0x11, 0x0020 | (PHYAddr[qdev->mac_index] >> 8), miiAddr); /* * Disable diagnostic mode bit 2 = 0 * Power up device bit 11 = 0 @@ -876,19 +929,21 @@ static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr) ql_mii_write_reg(qdev, 0x1c, 0xfaf0); } -static enum PHY_DEVICE_TYPE getPhyType(struct ql3_adapter *qdev, - u16 phyIdReg0, u16 phyIdReg1) +static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev, + u16 phyIdReg0, u16 phyIdReg1) { - enum PHY_DEVICE_TYPE result = PHY_TYPE_UNKNOWN; + PHY_DEVICE_et result = PHY_TYPE_UNKNOWN; u32 oui; u16 model; int i; - if (phyIdReg0 == 0xffff) + if (phyIdReg0 == 0xffff) { return result; + } - if (phyIdReg1 == 0xffff) + if (phyIdReg1 == 0xffff) { return result; + } /* oui is split between two registers */ oui = (phyIdReg0 << 6) | ((phyIdReg1 & PHY_OUI_1_MASK) >> 10); @@ -896,13 +951,15 @@ static enum PHY_DEVICE_TYPE getPhyType(struct ql3_adapter *qdev, model = (phyIdReg1 & PHY_MODEL_MASK) >> 4; /* Scan table for this PHY */ - for (i = 0; i < MAX_PHY_DEV_TYPES; i++) { - if ((oui == PHY_DEVICES[i].phyIdOUI) && - (model == PHY_DEVICES[i].phyIdModel)) { - netdev_info(qdev->ndev, "Phy: %s\n", - PHY_DEVICES[i].name); + for(i = 0; i < MAX_PHY_DEV_TYPES; i++) { + if ((oui == PHY_DEVICES[i].phyIdOUI) && (model == PHY_DEVICES[i].phyIdModel)) + { result = PHY_DEVICES[i].phyDevice; - break; + + printk(KERN_INFO "%s: Phy: %s\n", + qdev->ndev->name, PHY_DEVICES[i].name); + + break; } } @@ -913,8 +970,9 @@ static int ql_phy_get_speed(struct ql3_adapter *qdev) { u16 reg; - switch (qdev->phyType) { - case PHY_AGERE_ET1011C: { + switch(qdev->phyType) { + case PHY_AGERE_ET1011C: + { if (ql_mii_read_reg(qdev, 0x1A, ®) < 0) return 0; @@ -922,20 +980,20 @@ static int ql_phy_get_speed(struct ql3_adapter *qdev) break; } default: - if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, ®) < 0) - return 0; + if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, ®) < 0) + return 0; - reg = (((reg & 0x18) >> 3) & 3); + reg = (((reg & 0x18) >> 3) & 3); } - switch (reg) { - case 2: + switch(reg) { + case 2: return SPEED_1000; - case 1: + case 1: return SPEED_100; - case 0: + case 0: return SPEED_10; - default: + default: return -1; } } @@ -944,15 +1002,17 @@ static int ql_is_full_dup(struct ql3_adapter *qdev) { u16 reg; - switch (qdev->phyType) { - case PHY_AGERE_ET1011C: { + switch(qdev->phyType) { + case PHY_AGERE_ET1011C: + { if (ql_mii_read_reg(qdev, 0x1A, ®)) return 0; return ((reg & 0x0080) && (reg & 0x1000)) != 0; } case PHY_VITESSE_VSC8211: - default: { + default: + { if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, ®) < 0) return 0; return (reg & PHY_AUX_DUPLEX_STAT) != 0; @@ -980,15 +1040,17 @@ static int PHY_Setup(struct ql3_adapter *qdev) /* Determine the PHY we are using by reading the ID's */ err = ql_mii_read_reg(qdev, PHY_ID_0_REG, ®1); - if (err != 0) { - netdev_err(qdev->ndev, "Could not read from reg PHY_ID_0_REG\n"); - return err; + if(err != 0) { + printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG\n", + qdev->ndev->name); + return err; } err = ql_mii_read_reg(qdev, PHY_ID_1_REG, ®2); - if (err != 0) { - netdev_err(qdev->ndev, "Could not read from reg PHY_ID_1_REG\n"); - return err; + if(err != 0) { + printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG\n", + qdev->ndev->name); + return err; } /* Check if we have a Agere PHY */ @@ -996,22 +1058,24 @@ static int PHY_Setup(struct ql3_adapter *qdev) /* Determine which MII address we should be using determined by the index of the card */ - if (qdev->mac_index == 0) + if (qdev->mac_index == 0) { miiAddr = MII_AGERE_ADDR_1; - else + } else { miiAddr = MII_AGERE_ADDR_2; + } - err = ql_mii_read_reg_ex(qdev, PHY_ID_0_REG, ®1, miiAddr); - if (err != 0) { - netdev_err(qdev->ndev, - "Could not read from reg PHY_ID_0_REG after Agere detected\n"); + err =ql_mii_read_reg_ex(qdev, PHY_ID_0_REG, ®1, miiAddr); + if(err != 0) { + printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n", + qdev->ndev->name); return err; } err = ql_mii_read_reg_ex(qdev, PHY_ID_1_REG, ®2, miiAddr); - if (err != 0) { - netdev_err(qdev->ndev, "Could not read from reg PHY_ID_1_REG after Agere detected\n"); - return err; + if(err != 0) { + printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n", + qdev->ndev->name); + return err; } /* We need to remember to initialize the Agere PHY */ @@ -1026,7 +1090,7 @@ static int PHY_Setup(struct ql3_adapter *qdev) /* need this here so address gets changed */ phyAgereSpecificInit(qdev, miiAddr); } else if (qdev->phyType == PHY_TYPE_UNKNOWN) { - netdev_err(qdev->ndev, "PHY is unknown\n"); + printk(KERN_ERR "%s: PHY is unknown\n", qdev->ndev->name); return -EIO; } @@ -1039,7 +1103,7 @@ static int PHY_Setup(struct ql3_adapter *qdev) static void ql_mac_enable(struct ql3_adapter *qdev, u32 enable) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 value; if (enable) @@ -1059,7 +1123,7 @@ static void ql_mac_enable(struct ql3_adapter *qdev, u32 enable) static void ql_mac_cfg_soft_reset(struct ql3_adapter *qdev, u32 enable) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 value; if (enable) @@ -1079,7 +1143,7 @@ static void ql_mac_cfg_soft_reset(struct ql3_adapter *qdev, u32 enable) static void ql_mac_cfg_gig(struct ql3_adapter *qdev, u32 enable) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 value; if (enable) @@ -1099,7 +1163,7 @@ static void ql_mac_cfg_gig(struct ql3_adapter *qdev, u32 enable) static void ql_mac_cfg_full_dup(struct ql3_adapter *qdev, u32 enable) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 value; if (enable) @@ -1119,7 +1183,7 @@ static void ql_mac_cfg_full_dup(struct ql3_adapter *qdev, u32 enable) static void ql_mac_cfg_pause(struct ql3_adapter *qdev, u32 enable) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 value; if (enable) @@ -1141,7 +1205,7 @@ static void ql_mac_cfg_pause(struct ql3_adapter *qdev, u32 enable) static int ql_is_fiber(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 bitToCheck = 0; u32 temp; @@ -1171,7 +1235,7 @@ static int ql_is_auto_cfg(struct ql3_adapter *qdev) static int ql_is_auto_neg_complete(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 bitToCheck = 0; u32 temp; @@ -1186,11 +1250,18 @@ static int ql_is_auto_neg_complete(struct ql3_adapter *qdev) temp = ql_read_page0_reg(qdev, &port_regs->portStatus); if (temp & bitToCheck) { - netif_info(qdev, link, qdev->ndev, "Auto-Negotiate complete\n"); + if (netif_msg_link(qdev)) + printk(KERN_INFO PFX + "%s: Auto-Negotiate complete.\n", + qdev->ndev->name); return 1; + } else { + if (netif_msg_link(qdev)) + printk(KERN_WARNING PFX + "%s: Auto-Negotiate incomplete.\n", + qdev->ndev->name); + return 0; } - netif_info(qdev, link, qdev->ndev, "Auto-Negotiate incomplete\n"); - return 0; } /* @@ -1207,7 +1278,7 @@ static int ql_is_neg_pause(struct ql3_adapter *qdev) static int ql_auto_neg_error(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 bitToCheck = 0; u32 temp; @@ -1245,7 +1316,7 @@ static int ql_is_link_full_dup(struct ql3_adapter *qdev) static int ql_link_down_detect(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 bitToCheck = 0; u32 temp; @@ -1269,7 +1340,7 @@ static int ql_link_down_detect(struct ql3_adapter *qdev) static int ql_link_down_detect_clear(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; switch (qdev->mac_index) { case 0: @@ -1299,7 +1370,7 @@ static int ql_link_down_detect_clear(struct ql3_adapter *qdev) static int ql_this_adapter_controls_port(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 bitToCheck = 0; u32 temp; @@ -1316,13 +1387,16 @@ static int ql_this_adapter_controls_port(struct ql3_adapter *qdev) temp = ql_read_page0_reg(qdev, &port_regs->portStatus); if (temp & bitToCheck) { - netif_printk(qdev, link, KERN_DEBUG, qdev->ndev, - "not link master\n"); + if (netif_msg_link(qdev)) + printk(KERN_DEBUG PFX + "%s: is not link master.\n", qdev->ndev->name); return 0; + } else { + if (netif_msg_link(qdev)) + printk(KERN_DEBUG PFX + "%s: is link master.\n", qdev->ndev->name); + return 1; } - - netif_printk(qdev, link, KERN_DEBUG, qdev->ndev, "link master\n"); - return 1; } static void ql_phy_reset_ex(struct ql3_adapter *qdev) @@ -1336,20 +1410,19 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev) u16 reg; u16 portConfiguration; - if (qdev->phyType == PHY_AGERE_ET1011C) + if(qdev->phyType == PHY_AGERE_ET1011C) { + /* turn off external loopback */ ql_mii_write_reg(qdev, 0x13, 0x0000); - /* turn off external loopback */ + } - if (qdev->mac_index == 0) - portConfiguration = - qdev->nvram_data.macCfg_port0.portConfiguration; + if(qdev->mac_index == 0) + portConfiguration = qdev->nvram_data.macCfg_port0.portConfiguration; else - portConfiguration = - qdev->nvram_data.macCfg_port1.portConfiguration; + portConfiguration = qdev->nvram_data.macCfg_port1.portConfiguration; /* Some HBA's in the field are set to 0 and they need to be reinterpreted with a default value */ - if (portConfiguration == 0) + if(portConfiguration == 0) portConfiguration = PORT_CONFIG_DEFAULT; /* Set the 1000 advertisements */ @@ -1357,8 +1430,8 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev) PHYAddr[qdev->mac_index]); reg &= ~PHY_GIG_ALL_PARAMS; - if (portConfiguration & PORT_CONFIG_1000MB_SPEED) { - if (portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) + if(portConfiguration & PORT_CONFIG_1000MB_SPEED) { + if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) reg |= PHY_GIG_ADV_1000F; else reg |= PHY_GIG_ADV_1000H; @@ -1372,27 +1445,29 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev) PHYAddr[qdev->mac_index]); reg &= ~PHY_NEG_ALL_PARAMS; - if (portConfiguration & PORT_CONFIG_SYM_PAUSE_ENABLED) + if(portConfiguration & PORT_CONFIG_SYM_PAUSE_ENABLED) reg |= PHY_NEG_ASY_PAUSE | PHY_NEG_SYM_PAUSE; - if (portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) { - if (portConfiguration & PORT_CONFIG_100MB_SPEED) + if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) { + if(portConfiguration & PORT_CONFIG_100MB_SPEED) reg |= PHY_NEG_ADV_100F; - if (portConfiguration & PORT_CONFIG_10MB_SPEED) + if(portConfiguration & PORT_CONFIG_10MB_SPEED) reg |= PHY_NEG_ADV_10F; } - if (portConfiguration & PORT_CONFIG_HALF_DUPLEX_ENABLED) { - if (portConfiguration & PORT_CONFIG_100MB_SPEED) + if(portConfiguration & PORT_CONFIG_HALF_DUPLEX_ENABLED) { + if(portConfiguration & PORT_CONFIG_100MB_SPEED) reg |= PHY_NEG_ADV_100H; - if (portConfiguration & PORT_CONFIG_10MB_SPEED) + if(portConfiguration & PORT_CONFIG_10MB_SPEED) reg |= PHY_NEG_ADV_10H; } - if (portConfiguration & PORT_CONFIG_1000MB_SPEED) + if(portConfiguration & + PORT_CONFIG_1000MB_SPEED) { reg |= 1; + } ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, reg, PHYAddr[qdev->mac_index]); @@ -1417,7 +1492,7 @@ static void ql_phy_init_ex(struct ql3_adapter *qdev) static u32 ql_get_link_state(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; u32 bitToCheck = 0; u32 temp, linkState; @@ -1429,22 +1504,22 @@ static u32 ql_get_link_state(struct ql3_adapter *qdev) bitToCheck = PORT_STATUS_UP1; break; } - temp = ql_read_page0_reg(qdev, &port_regs->portStatus); - if (temp & bitToCheck) + if (temp & bitToCheck) { linkState = LS_UP; - else + } else { linkState = LS_DOWN; - + } return linkState; } static int ql_port_start(struct ql3_adapter *qdev) { - if (ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, + if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 2) << 7)) { - netdev_err(qdev->ndev, "Could not get hw lock for GIO\n"); + printk(KERN_ERR "%s: Could not get hw lock for GIO\n", + qdev->ndev->name); return -1; } @@ -1462,16 +1537,19 @@ static int ql_port_start(struct ql3_adapter *qdev) static int ql_finish_auto_neg(struct ql3_adapter *qdev) { - if (ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, + if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 2) << 7)) return -1; if (!ql_auto_neg_error(qdev)) { - if (test_bit(QL_LINK_MASTER, &qdev->flags)) { + if (test_bit(QL_LINK_MASTER,&qdev->flags)) { /* configure the MAC */ - netif_printk(qdev, link, KERN_DEBUG, qdev->ndev, - "Configuring link\n"); + if (netif_msg_link(qdev)) + printk(KERN_DEBUG PFX + "%s: Configuring link.\n", + qdev->ndev-> + name); ql_mac_cfg_soft_reset(qdev, 1); ql_mac_cfg_gig(qdev, (ql_get_link_speed @@ -1486,32 +1564,43 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev) ql_mac_cfg_soft_reset(qdev, 0); /* enable the MAC */ - netif_printk(qdev, link, KERN_DEBUG, qdev->ndev, - "Enabling mac\n"); + if (netif_msg_link(qdev)) + printk(KERN_DEBUG PFX + "%s: Enabling mac.\n", + qdev->ndev-> + name); ql_mac_enable(qdev, 1); } qdev->port_link_state = LS_UP; netif_start_queue(qdev->ndev); netif_carrier_on(qdev->ndev); - netif_info(qdev, link, qdev->ndev, - "Link is up at %d Mbps, %s duplex\n", - ql_get_link_speed(qdev), - ql_is_link_full_dup(qdev) ? "full" : "half"); + if (netif_msg_link(qdev)) + printk(KERN_INFO PFX + "%s: Link is up at %d Mbps, %s duplex.\n", + qdev->ndev->name, + ql_get_link_speed(qdev), + ql_is_link_full_dup(qdev) + ? "full" : "half"); } else { /* Remote error detected */ - if (test_bit(QL_LINK_MASTER, &qdev->flags)) { - netif_printk(qdev, link, KERN_DEBUG, qdev->ndev, - "Remote error detected. Calling ql_port_start()\n"); + if (test_bit(QL_LINK_MASTER,&qdev->flags)) { + if (netif_msg_link(qdev)) + printk(KERN_DEBUG PFX + "%s: Remote error detected. " + "Calling ql_port_start().\n", + qdev->ndev-> + name); /* * ql_port_start() is shared code and needs * to lock the PHY on it's own. */ ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - if (ql_port_start(qdev)) /* Restart port */ + if(ql_port_start(qdev)) {/* Restart port */ return -1; - return 0; + } else + return 0; } } ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); @@ -1530,28 +1619,33 @@ static void ql_link_state_machine_work(struct work_struct *work) curr_link_state = ql_get_link_state(qdev); - if (test_bit(QL_RESET_ACTIVE, &qdev->flags)) { - netif_info(qdev, link, qdev->ndev, - "Reset in progress, skip processing link state\n"); + if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) { + if (netif_msg_link(qdev)) + printk(KERN_INFO PFX + "%s: Reset in progress, skip processing link " + "state.\n", qdev->ndev->name); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); /* Restart timer on 2 second interval. */ - mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); + mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);\ return; } switch (qdev->port_link_state) { default: - if (test_bit(QL_LINK_MASTER, &qdev->flags)) + if (test_bit(QL_LINK_MASTER,&qdev->flags)) { ql_port_start(qdev); + } qdev->port_link_state = LS_DOWN; /* Fall Through */ case LS_DOWN: if (curr_link_state == LS_UP) { - netif_info(qdev, link, qdev->ndev, "Link is up\n"); + if (netif_msg_link(qdev)) + printk(KERN_INFO PFX "%s: Link is up.\n", + qdev->ndev->name); if (ql_is_auto_neg_complete(qdev)) ql_finish_auto_neg(qdev); @@ -1568,7 +1662,9 @@ static void ql_link_state_machine_work(struct work_struct *work) * back up */ if (curr_link_state == LS_DOWN) { - netif_info(qdev, link, qdev->ndev, "Link is down\n"); + if (netif_msg_link(qdev)) + printk(KERN_INFO PFX "%s: Link is down.\n", + qdev->ndev->name); qdev->port_link_state = LS_DOWN; } if (ql_link_down_detect(qdev)) @@ -1587,9 +1683,9 @@ static void ql_link_state_machine_work(struct work_struct *work) static void ql_get_phy_owner(struct ql3_adapter *qdev) { if (ql_this_adapter_controls_port(qdev)) - set_bit(QL_LINK_MASTER, &qdev->flags); + set_bit(QL_LINK_MASTER,&qdev->flags); else - clear_bit(QL_LINK_MASTER, &qdev->flags); + clear_bit(QL_LINK_MASTER,&qdev->flags); } /* @@ -1599,7 +1695,7 @@ static void ql_init_scan_mode(struct ql3_adapter *qdev) { ql_mii_enable_scan_mode(qdev); - if (test_bit(QL_LINK_OPTICAL, &qdev->flags)) { + if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { if (ql_this_adapter_controls_port(qdev)) ql_petbi_init_ex(qdev); } else { @@ -1609,18 +1705,18 @@ static void ql_init_scan_mode(struct ql3_adapter *qdev) } /* - * MII_Setup needs to be called before taking the PHY out of reset - * so that the management interface clock speed can be set properly. - * It would be better if we had a way to disable MDC until after the - * PHY is out of reset, but we don't have that capability. + * MII_Setup needs to be called before taking the PHY out of reset so that the + * management interface clock speed can be set properly. It would be better if + * we had a way to disable MDC until after the PHY is out of reset, but we + * don't have that capability. */ static int ql_mii_setup(struct ql3_adapter *qdev) { u32 reg; struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; - if (ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, + if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 2) << 7)) return -1; @@ -1639,24 +1735,24 @@ static int ql_mii_setup(struct ql3_adapter *qdev) return 0; } -#define SUPPORTED_OPTICAL_MODES (SUPPORTED_1000baseT_Full | \ - SUPPORTED_FIBRE | \ - SUPPORTED_Autoneg) -#define SUPPORTED_TP_MODES (SUPPORTED_10baseT_Half | \ - SUPPORTED_10baseT_Full | \ - SUPPORTED_100baseT_Half | \ - SUPPORTED_100baseT_Full | \ - SUPPORTED_1000baseT_Half | \ - SUPPORTED_1000baseT_Full | \ - SUPPORTED_Autoneg | \ - SUPPORTED_TP); \ - static u32 ql_supported_modes(struct ql3_adapter *qdev) { - if (test_bit(QL_LINK_OPTICAL, &qdev->flags)) - return SUPPORTED_OPTICAL_MODES; + u32 supported; - return SUPPORTED_TP_MODES; + if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { + supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE + | SUPPORTED_Autoneg; + } else { + supported = SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full + | SUPPORTED_1000baseT_Half + | SUPPORTED_1000baseT_Full + | SUPPORTED_Autoneg | SUPPORTED_TP; + } + + return supported; } static int ql_get_auto_cfg_status(struct ql3_adapter *qdev) @@ -1664,9 +1760,9 @@ static int ql_get_auto_cfg_status(struct ql3_adapter *qdev) int status; unsigned long hw_flags; spin_lock_irqsave(&qdev->hw_lock, hw_flags); - if (ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | - (qdev->mac_index) * 2) << 7)) { + if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, + (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * + 2) << 7)) { spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); return 0; } @@ -1681,9 +1777,9 @@ static u32 ql_get_speed(struct ql3_adapter *qdev) u32 status; unsigned long hw_flags; spin_lock_irqsave(&qdev->hw_lock, hw_flags); - if (ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | - (qdev->mac_index) * 2) << 7)) { + if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, + (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * + 2) << 7)) { spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); return 0; } @@ -1698,9 +1794,9 @@ static int ql_get_full_dup(struct ql3_adapter *qdev) int status; unsigned long hw_flags; spin_lock_irqsave(&qdev->hw_lock, hw_flags); - if (ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | - (qdev->mac_index) * 2) << 7)) { + if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, + (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * + 2) << 7)) { spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); return 0; } @@ -1710,6 +1806,7 @@ static int ql_get_full_dup(struct ql3_adapter *qdev) return status; } + static int ql_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) { struct ql3_adapter *qdev = netdev_priv(ndev); @@ -1717,7 +1814,7 @@ static int ql_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) ecmd->transceiver = XCVR_INTERNAL; ecmd->supported = ql_supported_modes(qdev); - if (test_bit(QL_LINK_OPTICAL, &qdev->flags)) { + if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { ecmd->port = PORT_FIBRE; } else { ecmd->port = PORT_TP; @@ -1758,11 +1855,10 @@ static void ql_get_pauseparam(struct net_device *ndev, struct ethtool_pauseparam *pause) { struct ql3_adapter *qdev = netdev_priv(ndev); - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; u32 reg; - if (qdev->mac_index == 0) + if(qdev->mac_index == 0) reg = ql_read_page0_reg(qdev, &port_regs->mac0ConfigReg); else reg = ql_read_page0_reg(qdev, &port_regs->mac1ConfigReg); @@ -1789,12 +1885,12 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) while (lrg_buf_cb) { if (!lrg_buf_cb->skb) { - lrg_buf_cb->skb = - netdev_alloc_skb(qdev->ndev, - qdev->lrg_buffer_len); + lrg_buf_cb->skb = netdev_alloc_skb(qdev->ndev, + qdev->lrg_buffer_len); if (unlikely(!lrg_buf_cb->skb)) { - netdev_printk(KERN_DEBUG, qdev->ndev, - "Failed netdev_alloc_skb()\n"); + printk(KERN_DEBUG PFX + "%s: Failed netdev_alloc_skb().\n", + qdev->ndev->name); break; } else { /* @@ -1809,10 +1905,9 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) PCI_DMA_FROMDEVICE); err = pci_dma_mapping_error(qdev->pdev, map); - if (err) { - netdev_err(qdev->ndev, - "PCI mapping failed with error: %d\n", - err); + if(err) { + printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", + qdev->ndev->name, err); dev_kfree_skb(lrg_buf_cb->skb); lrg_buf_cb->skb = NULL; break; @@ -1820,9 +1915,9 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) lrg_buf_cb->buf_phy_addr_low = - cpu_to_le32(LS_64BITS(map)); + cpu_to_le32(LS_64BITS(map)); lrg_buf_cb->buf_phy_addr_high = - cpu_to_le32(MS_64BITS(map)); + cpu_to_le32(MS_64BITS(map)); dma_unmap_addr_set(lrg_buf_cb, mapaddr, map); dma_unmap_len_set(lrg_buf_cb, maplen, qdev->lrg_buffer_len - @@ -1842,9 +1937,7 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) */ static void ql_update_small_bufq_prod_index(struct ql3_adapter *qdev) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; if (qdev->small_buf_release_cnt >= 16) { while (qdev->small_buf_release_cnt >= 16) { qdev->small_buf_q_producer_index++; @@ -1868,8 +1961,7 @@ static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev) struct bufq_addr_element *lrg_buf_q_ele; int i; struct ql_rcv_buf_cb *lrg_buf_cb; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; if ((qdev->lrg_buf_free_count >= 8) && (qdev->lrg_buf_release_cnt >= 16)) { @@ -1897,8 +1989,7 @@ static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev) qdev->lrg_buf_q_producer_index++; - if (qdev->lrg_buf_q_producer_index == - qdev->num_lbufq_entries) + if (qdev->lrg_buf_q_producer_index == qdev->num_lbufq_entries) qdev->lrg_buf_q_producer_index = 0; if (qdev->lrg_buf_q_producer_index == @@ -1920,26 +2011,23 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, int i; int retval = 0; - if (mac_rsp->flags & OB_MAC_IOCB_RSP_S) { - netdev_warn(qdev->ndev, - "Frame too short but it was padded and sent\n"); + if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) { + printk(KERN_WARNING "Frame short but, frame was padded and sent.\n"); } tx_cb = &qdev->tx_buf[mac_rsp->transaction_id]; /* Check the transmit response flags for any errors */ - if (mac_rsp->flags & OB_MAC_IOCB_RSP_S) { - netdev_err(qdev->ndev, - "Frame too short to be legal, frame not sent\n"); + if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) { + printk(KERN_ERR "Frame too short to be legal, frame not sent.\n"); qdev->ndev->stats.tx_errors++; retval = -EIO; goto frame_not_sent; } - if (tx_cb->seg_count == 0) { - netdev_err(qdev->ndev, "tx_cb->seg_count == 0: %d\n", - mac_rsp->transaction_id); + if(tx_cb->seg_count == 0) { + printk(KERN_ERR "tx_cb->seg_count == 0: %d\n", mac_rsp->transaction_id); qdev->ndev->stats.tx_errors++; retval = -EIO; @@ -1985,7 +2073,7 @@ static struct ql_rcv_buf_cb *ql_get_lbuf(struct ql3_adapter *qdev) qdev->lrg_buf_release_cnt++; if (++qdev->lrg_buf_index == qdev->num_large_buffers) qdev->lrg_buf_index = 0; - return lrg_buf_cb; + return(lrg_buf_cb); } /* @@ -2089,11 +2177,12 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, if (checksum & (IB_IP_IOCB_RSP_3032_ICE | IB_IP_IOCB_RSP_3032_CE)) { - netdev_err(ndev, - "%s: Bad checksum for this %s packet, checksum = %x\n", - __func__, - ((checksum & IB_IP_IOCB_RSP_3032_TCP) ? - "TCP" : "UDP"), checksum); + printk(KERN_ERR + "%s: Bad checksum for this %s packet, checksum = %x.\n", + __func__, + ((checksum & + IB_IP_IOCB_RSP_3032_TCP) ? "TCP" : + "UDP"),checksum); } else if ((checksum & IB_IP_IOCB_RSP_3032_TCP) || (checksum & IB_IP_IOCB_RSP_3032_UDP && !(checksum & IB_IP_IOCB_RSP_3032_NUC))) { @@ -2126,8 +2215,8 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev, net_rsp = qdev->rsp_current; rmb(); /* - * Fix 4032 chip's undocumented "feature" where bit-8 is set - * if the inbound completion is for a VLAN. + * Fix 4032 chipe undocumented "feature" where bit-8 is set if the + * inbound completion is for a VLAN. */ if (qdev->device_id == QL3032_DEVICE_ID) net_rsp->opcode &= 0x7f; @@ -2153,18 +2242,22 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev, net_rsp); (*rx_cleaned)++; break; - default: { - u32 *tmp = (u32 *)net_rsp; - netdev_err(ndev, - "Hit default case, not handled!\n" - " dropping the packet, opcode = %x\n" - "0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", - net_rsp->opcode, - (unsigned long int)tmp[0], - (unsigned long int)tmp[1], - (unsigned long int)tmp[2], - (unsigned long int)tmp[3]); - } + default: + { + u32 *tmp = (u32 *) net_rsp; + printk(KERN_ERR PFX + "%s: Hit default case, not " + "handled!\n" + " dropping the packet, opcode = " + "%x.\n", + ndev->name, net_rsp->opcode); + printk(KERN_ERR PFX + "0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", + (unsigned long int)tmp[0], + (unsigned long int)tmp[1], + (unsigned long int)tmp[2], + (unsigned long int)tmp[3]); + } } qdev->rsp_consumer_index++; @@ -2187,8 +2280,7 @@ static int ql_poll(struct napi_struct *napi, int budget) struct ql3_adapter *qdev = container_of(napi, struct ql3_adapter, napi); int rx_cleaned = 0, tx_cleaned = 0; unsigned long hw_flags; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, budget); @@ -2211,14 +2303,15 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) struct net_device *ndev = dev_id; struct ql3_adapter *qdev = netdev_priv(ndev); - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; u32 value; int handled = 1; u32 var; - value = ql_read_common_reg_l(qdev, - &port_regs->CommonRegs.ispControlStatus); + port_regs = qdev->mem_map_registers; + + value = + ql_read_common_reg_l(qdev, &port_regs->CommonRegs.ispControlStatus); if (value & (ISP_CONTROL_FE | ISP_CONTROL_RI)) { spin_lock(&qdev->adapter_lock); @@ -2226,7 +2319,7 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) netif_carrier_off(qdev->ndev); ql_disable_interrupts(qdev); qdev->port_link_state = LS_DOWN; - set_bit(QL_RESET_ACTIVE, &qdev->flags) ; + set_bit(QL_RESET_ACTIVE,&qdev->flags) ; if (value & ISP_CONTROL_FE) { /* @@ -2235,53 +2328,69 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) var = ql_read_page0_reg_l(qdev, &port_regs->PortFatalErrStatus); - netdev_warn(ndev, - "Resetting chip. PortFatalErrStatus register = 0x%x\n", - var); - set_bit(QL_RESET_START, &qdev->flags) ; + printk(KERN_WARNING PFX + "%s: Resetting chip. PortFatalErrStatus " + "register = 0x%x\n", ndev->name, var); + set_bit(QL_RESET_START,&qdev->flags) ; } else { /* * Soft Reset Requested. */ - set_bit(QL_RESET_PER_SCSI, &qdev->flags) ; - netdev_err(ndev, - "Another function issued a reset to the chip. ISR value = %x\n", - value); + set_bit(QL_RESET_PER_SCSI,&qdev->flags) ; + printk(KERN_ERR PFX + "%s: Another function issued a reset to the " + "chip. ISR value = %x.\n", ndev->name, value); } queue_delayed_work(qdev->workqueue, &qdev->reset_work, 0); spin_unlock(&qdev->adapter_lock); } else if (value & ISP_IMR_DISABLE_CMPL_INT) { ql_disable_interrupts(qdev); - if (likely(napi_schedule_prep(&qdev->napi))) + if (likely(napi_schedule_prep(&qdev->napi))) { __napi_schedule(&qdev->napi); - } else + } + } else { return IRQ_NONE; + } return IRQ_RETVAL(handled); } /* - * Get the total number of segments needed for the given number of fragments. - * This is necessary because outbound address lists (OAL) will be used when - * more than two frags are given. Each address list has 5 addr/len pairs. - * The 5th pair in each OAL is used to point to the next OAL if more frags - * are coming. That is why the frags:segment count ratio is not linear. + * Get the total number of segments needed for the + * given number of fragments. This is necessary because + * outbound address lists (OAL) will be used when more than + * two frags are given. Each address list has 5 addr/len + * pairs. The 5th pair in each AOL is used to point to + * the next AOL if more frags are coming. + * That is why the frags:segment count ratio is not linear. */ -static int ql_get_seg_count(struct ql3_adapter *qdev, unsigned short frags) +static int ql_get_seg_count(struct ql3_adapter *qdev, + unsigned short frags) { if (qdev->device_id == QL3022_DEVICE_ID) return 1; - if (frags <= 2) - return frags + 1; - else if (frags <= 6) - return frags + 2; - else if (frags <= 10) - return frags + 3; - else if (frags <= 14) - return frags + 4; - else if (frags <= 18) - return frags + 5; + switch(frags) { + case 0: return 1; /* just the skb->data seg */ + case 1: return 2; /* skb->data + 1 frag */ + case 2: return 3; /* skb->data + 2 frags */ + case 3: return 5; /* skb->data + 1 frag + 1 AOL containting 2 frags */ + case 4: return 6; + case 5: return 7; + case 6: return 8; + case 7: return 10; + case 8: return 11; + case 9: return 12; + case 10: return 13; + case 11: return 15; + case 12: return 16; + case 13: return 17; + case 14: return 18; + case 15: return 20; + case 16: return 21; + case 17: return 22; + case 18: return 23; + } return -1; } @@ -2304,8 +2413,8 @@ static void ql_hw_csum_setup(const struct sk_buff *skb, } /* - * Map the buffers for this transmit. - * This will return NETDEV_TX_BUSY or NETDEV_TX_OK based on success. + * Map the buffers for this transmit. This will return + * NETDEV_TX_BUSY or NETDEV_TX_OK based on success. */ static int ql_send_map(struct ql3_adapter *qdev, struct ob_mac_iocb_req *mac_iocb_ptr, @@ -2328,9 +2437,9 @@ static int ql_send_map(struct ql3_adapter *qdev, map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); err = pci_dma_mapping_error(qdev->pdev, map); - if (err) { - netdev_err(qdev->ndev, "PCI mapping failed with error: %d\n", - err); + if(err) { + printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", + qdev->ndev->name, err); return NETDEV_TX_BUSY; } @@ -2346,67 +2455,65 @@ static int ql_send_map(struct ql3_adapter *qdev, if (seg_cnt == 1) { /* Terminate the last segment. */ oal_entry->len |= cpu_to_le32(OAL_LAST_ENTRY); - return NETDEV_TX_OK; - } - oal = tx_cb->oal; - for (completed_segs = 0; - completed_segs < frag_cnt; - completed_segs++, seg++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[completed_segs]; - oal_entry++; - /* - * Check for continuation requirements. - * It's strange but necessary. - * Continuation entry points to outbound address list. - */ - if ((seg == 2 && seg_cnt > 3) || - (seg == 7 && seg_cnt > 8) || - (seg == 12 && seg_cnt > 13) || - (seg == 17 && seg_cnt > 18)) { - map = pci_map_single(qdev->pdev, oal, - sizeof(struct oal), - PCI_DMA_TODEVICE); + } else { + oal = tx_cb->oal; + for (completed_segs=0; completed_segsfrags[completed_segs]; + oal_entry++; + if ((seg == 2 && seg_cnt > 3) || /* Check for continuation */ + (seg == 7 && seg_cnt > 8) || /* requirements. It's strange */ + (seg == 12 && seg_cnt > 13) || /* but necessary. */ + (seg == 17 && seg_cnt > 18)) { + /* Continuation entry points to outbound address list. */ + map = pci_map_single(qdev->pdev, oal, + sizeof(struct oal), + PCI_DMA_TODEVICE); + + err = pci_dma_mapping_error(qdev->pdev, map); + if(err) { + + printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", + qdev->ndev->name, err); + goto map_error; + } + + oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); + oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); + oal_entry->len = + cpu_to_le32(sizeof(struct oal) | + OAL_CONT_ENTRY); + dma_unmap_addr_set(&tx_cb->map[seg], mapaddr, + map); + dma_unmap_len_set(&tx_cb->map[seg], maplen, + sizeof(struct oal)); + oal_entry = (struct oal_entry *)oal; + oal++; + seg++; + } + + map = + pci_map_page(qdev->pdev, frag->page, + frag->page_offset, frag->size, + PCI_DMA_TODEVICE); err = pci_dma_mapping_error(qdev->pdev, map); - if (err) { - netdev_err(qdev->ndev, - "PCI mapping outbound address list with error: %d\n", - err); + if(err) { + printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", + qdev->ndev->name, err); goto map_error; } oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); - oal_entry->len = cpu_to_le32(sizeof(struct oal) | - OAL_CONT_ENTRY); + oal_entry->len = cpu_to_le32(frag->size); dma_unmap_addr_set(&tx_cb->map[seg], mapaddr, map); dma_unmap_len_set(&tx_cb->map[seg], maplen, - sizeof(struct oal)); - oal_entry = (struct oal_entry *)oal; - oal++; - seg++; - } - - map = pci_map_page(qdev->pdev, frag->page, - frag->page_offset, frag->size, - PCI_DMA_TODEVICE); - - err = pci_dma_mapping_error(qdev->pdev, map); - if (err) { - netdev_err(qdev->ndev, - "PCI mapping frags failed with error: %d\n", - err); - goto map_error; + frag->size); } + /* Terminate the last segment. */ + oal_entry->len |= cpu_to_le32(OAL_LAST_ENTRY); + } - oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); - oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); - oal_entry->len = cpu_to_le32(frag->size); - dma_unmap_addr_set(&tx_cb->map[seg], mapaddr, map); - dma_unmap_len_set(&tx_cb->map[seg], maplen, frag->size); - } - /* Terminate the last segment. */ - oal_entry->len |= cpu_to_le32(OAL_LAST_ENTRY); return NETDEV_TX_OK; map_error: @@ -2418,18 +2525,13 @@ static int ql_send_map(struct ql3_adapter *qdev, seg = 1; oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low; oal = tx_cb->oal; - for (i = 0; i < completed_segs; i++, seg++) { + for (i=0; i 3) || - (seg == 7 && seg_cnt > 8) || - (seg == 12 && seg_cnt > 13) || - (seg == 17 && seg_cnt > 18)) { + if((seg == 2 && seg_cnt > 3) || /* Check for continuation */ + (seg == 7 && seg_cnt > 8) || /* requirements. It's strange */ + (seg == 12 && seg_cnt > 13) || /* but necessary. */ + (seg == 17 && seg_cnt > 18)) { pci_unmap_single(qdev->pdev, dma_unmap_addr(&tx_cb->map[seg], mapaddr), dma_unmap_len(&tx_cb->map[seg], maplen), @@ -2468,20 +2570,19 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) { struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct ql_tx_buf_cb *tx_cb; u32 tot_len = skb->len; struct ob_mac_iocb_req *mac_iocb_ptr; - if (unlikely(atomic_read(&qdev->tx_count) < 2)) + if (unlikely(atomic_read(&qdev->tx_count) < 2)) { return NETDEV_TX_BUSY; + } - tx_cb = &qdev->tx_buf[qdev->req_producer_index]; - tx_cb->seg_count = ql_get_seg_count(qdev, - skb_shinfo(skb)->nr_frags); - if (tx_cb->seg_count == -1) { - netdev_err(ndev, "%s: invalid segment count!\n", __func__); + tx_cb = &qdev->tx_buf[qdev->req_producer_index] ; + if((tx_cb->seg_count = ql_get_seg_count(qdev, + (skb_shinfo(skb)->nr_frags))) == -1) { + printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__); return NETDEV_TX_OK; } @@ -2497,8 +2598,8 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb, skb->ip_summed == CHECKSUM_PARTIAL) ql_hw_csum_setup(skb, mac_iocb_ptr); - if (ql_send_map(qdev, mac_iocb_ptr, tx_cb, skb) != NETDEV_TX_OK) { - netdev_err(ndev, "%s: Could not map the segments!\n", __func__); + if(ql_send_map(qdev,mac_iocb_ptr,tx_cb,skb) != NETDEV_TX_OK) { + printk(KERN_ERR PFX"%s: Could not map the segments!\n",__func__); return NETDEV_TX_BUSY; } @@ -2511,9 +2612,9 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb, &port_regs->CommonRegs.reqQProducerIndex, qdev->req_producer_index); - netif_printk(qdev, tx_queued, KERN_DEBUG, ndev, - "tx queued, slot %d, len %d\n", - qdev->req_producer_index, skb->len); + if (netif_msg_tx_queued(qdev)) + printk(KERN_DEBUG PFX "%s: tx queued, slot %d, len %d\n", + ndev->name, qdev->req_producer_index, skb->len); atomic_dec(&qdev->tx_count); return NETDEV_TX_OK; @@ -2531,7 +2632,8 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) if ((qdev->req_q_virt_addr == NULL) || LS_64BITS(qdev->req_q_phy_addr) & (qdev->req_q_size - 1)) { - netdev_err(qdev->ndev, "reqQ failed\n"); + printk(KERN_ERR PFX "%s: reqQ failed.\n", + qdev->ndev->name); return -ENOMEM; } @@ -2544,22 +2646,25 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) if ((qdev->rsp_q_virt_addr == NULL) || LS_64BITS(qdev->rsp_q_phy_addr) & (qdev->rsp_q_size - 1)) { - netdev_err(qdev->ndev, "rspQ allocation failed\n"); + printk(KERN_ERR PFX + "%s: rspQ allocation failed\n", + qdev->ndev->name); pci_free_consistent(qdev->pdev, (size_t) qdev->req_q_size, qdev->req_q_virt_addr, qdev->req_q_phy_addr); return -ENOMEM; } - set_bit(QL_ALLOC_REQ_RSP_Q_DONE, &qdev->flags); + set_bit(QL_ALLOC_REQ_RSP_Q_DONE,&qdev->flags); return 0; } static void ql_free_net_req_rsp_queues(struct ql3_adapter *qdev) { - if (!test_bit(QL_ALLOC_REQ_RSP_Q_DONE, &qdev->flags)) { - netdev_info(qdev->ndev, "Already done\n"); + if (!test_bit(QL_ALLOC_REQ_RSP_Q_DONE,&qdev->flags)) { + printk(KERN_INFO PFX + "%s: Already done.\n", qdev->ndev->name); return; } @@ -2575,34 +2680,34 @@ static void ql_free_net_req_rsp_queues(struct ql3_adapter *qdev) qdev->rsp_q_virt_addr = NULL; - clear_bit(QL_ALLOC_REQ_RSP_Q_DONE, &qdev->flags); + clear_bit(QL_ALLOC_REQ_RSP_Q_DONE,&qdev->flags); } static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) { /* Create Large Buffer Queue */ qdev->lrg_buf_q_size = - qdev->num_lbufq_entries * sizeof(struct lrg_buf_q_entry); + qdev->num_lbufq_entries * sizeof(struct lrg_buf_q_entry); if (qdev->lrg_buf_q_size < PAGE_SIZE) qdev->lrg_buf_q_alloc_size = PAGE_SIZE; else qdev->lrg_buf_q_alloc_size = qdev->lrg_buf_q_size * 2; - qdev->lrg_buf = - kmalloc(qdev->num_large_buffers * sizeof(struct ql_rcv_buf_cb), - GFP_KERNEL); + qdev->lrg_buf = kmalloc(qdev->num_large_buffers * sizeof(struct ql_rcv_buf_cb),GFP_KERNEL); if (qdev->lrg_buf == NULL) { - netdev_err(qdev->ndev, "qdev->lrg_buf alloc failed\n"); + printk(KERN_ERR PFX + "%s: qdev->lrg_buf alloc failed.\n", qdev->ndev->name); return -ENOMEM; } qdev->lrg_buf_q_alloc_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->lrg_buf_q_alloc_size, - &qdev->lrg_buf_q_alloc_phy_addr); + pci_alloc_consistent(qdev->pdev, + qdev->lrg_buf_q_alloc_size, + &qdev->lrg_buf_q_alloc_phy_addr); if (qdev->lrg_buf_q_alloc_virt_addr == NULL) { - netdev_err(qdev->ndev, "lBufQ failed\n"); + printk(KERN_ERR PFX + "%s: lBufQ failed\n", qdev->ndev->name); return -ENOMEM; } qdev->lrg_buf_q_virt_addr = qdev->lrg_buf_q_alloc_virt_addr; @@ -2610,19 +2715,21 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) /* Create Small Buffer Queue */ qdev->small_buf_q_size = - NUM_SBUFQ_ENTRIES * sizeof(struct lrg_buf_q_entry); + NUM_SBUFQ_ENTRIES * sizeof(struct lrg_buf_q_entry); if (qdev->small_buf_q_size < PAGE_SIZE) qdev->small_buf_q_alloc_size = PAGE_SIZE; else qdev->small_buf_q_alloc_size = qdev->small_buf_q_size * 2; qdev->small_buf_q_alloc_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->small_buf_q_alloc_size, - &qdev->small_buf_q_alloc_phy_addr); + pci_alloc_consistent(qdev->pdev, + qdev->small_buf_q_alloc_size, + &qdev->small_buf_q_alloc_phy_addr); if (qdev->small_buf_q_alloc_virt_addr == NULL) { - netdev_err(qdev->ndev, "Small Buffer Queue allocation failed\n"); + printk(KERN_ERR PFX + "%s: Small Buffer Queue allocation failed.\n", + qdev->ndev->name); pci_free_consistent(qdev->pdev, qdev->lrg_buf_q_alloc_size, qdev->lrg_buf_q_alloc_virt_addr, qdev->lrg_buf_q_alloc_phy_addr); @@ -2631,17 +2738,18 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) qdev->small_buf_q_virt_addr = qdev->small_buf_q_alloc_virt_addr; qdev->small_buf_q_phy_addr = qdev->small_buf_q_alloc_phy_addr; - set_bit(QL_ALLOC_BUFQS_DONE, &qdev->flags); + set_bit(QL_ALLOC_BUFQS_DONE,&qdev->flags); return 0; } static void ql_free_buffer_queues(struct ql3_adapter *qdev) { - if (!test_bit(QL_ALLOC_BUFQS_DONE, &qdev->flags)) { - netdev_info(qdev->ndev, "Already done\n"); + if (!test_bit(QL_ALLOC_BUFQS_DONE,&qdev->flags)) { + printk(KERN_INFO PFX + "%s: Already done.\n", qdev->ndev->name); return; } - kfree(qdev->lrg_buf); + if(qdev->lrg_buf) kfree(qdev->lrg_buf); pci_free_consistent(qdev->pdev, qdev->lrg_buf_q_alloc_size, qdev->lrg_buf_q_alloc_virt_addr, @@ -2656,7 +2764,7 @@ static void ql_free_buffer_queues(struct ql3_adapter *qdev) qdev->small_buf_q_virt_addr = NULL; - clear_bit(QL_ALLOC_BUFQS_DONE, &qdev->flags); + clear_bit(QL_ALLOC_BUFQS_DONE,&qdev->flags); } static int ql_alloc_small_buffers(struct ql3_adapter *qdev) @@ -2666,16 +2774,18 @@ static int ql_alloc_small_buffers(struct ql3_adapter *qdev) /* Currently we allocate on one of memory and use it for smallbuffers */ qdev->small_buf_total_size = - (QL_ADDR_ELE_PER_BUFQ_ENTRY * NUM_SBUFQ_ENTRIES * - QL_SMALL_BUFFER_SIZE); + (QL_ADDR_ELE_PER_BUFQ_ENTRY * NUM_SBUFQ_ENTRIES * + QL_SMALL_BUFFER_SIZE); qdev->small_buf_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->small_buf_total_size, - &qdev->small_buf_phy_addr); + pci_alloc_consistent(qdev->pdev, + qdev->small_buf_total_size, + &qdev->small_buf_phy_addr); if (qdev->small_buf_virt_addr == NULL) { - netdev_err(qdev->ndev, "Failed to get small buffer memory\n"); + printk(KERN_ERR PFX + "%s: Failed to get small buffer memory.\n", + qdev->ndev->name); return -ENOMEM; } @@ -2694,14 +2804,15 @@ static int ql_alloc_small_buffers(struct ql3_adapter *qdev) small_buf_q_entry++; } qdev->small_buf_index = 0; - set_bit(QL_ALLOC_SMALL_BUF_DONE, &qdev->flags); + set_bit(QL_ALLOC_SMALL_BUF_DONE,&qdev->flags); return 0; } static void ql_free_small_buffers(struct ql3_adapter *qdev) { - if (!test_bit(QL_ALLOC_SMALL_BUF_DONE, &qdev->flags)) { - netdev_info(qdev->ndev, "Already done\n"); + if (!test_bit(QL_ALLOC_SMALL_BUF_DONE,&qdev->flags)) { + printk(KERN_INFO PFX + "%s: Already done.\n", qdev->ndev->name); return; } if (qdev->small_buf_virt_addr != NULL) { @@ -2763,9 +2874,11 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) qdev->lrg_buffer_len); if (unlikely(!skb)) { /* Better luck next round */ - netdev_err(qdev->ndev, - "large buff alloc failed for %d bytes at index %d\n", - qdev->lrg_buffer_len * 2, i); + printk(KERN_ERR PFX + "%s: large buff alloc failed, " + "for %d bytes at index %d.\n", + qdev->ndev->name, + qdev->lrg_buffer_len * 2, i); ql_free_large_buffers(qdev); return -ENOMEM; } else { @@ -2786,10 +2899,9 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) PCI_DMA_FROMDEVICE); err = pci_dma_mapping_error(qdev->pdev, map); - if (err) { - netdev_err(qdev->ndev, - "PCI mapping failed with error: %d\n", - err); + if(err) { + printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", + qdev->ndev->name, err); ql_free_large_buffers(qdev); return -ENOMEM; } @@ -2814,8 +2926,10 @@ static void ql_free_send_free_list(struct ql3_adapter *qdev) tx_cb = &qdev->tx_buf[0]; for (i = 0; i < NUM_REQ_Q_ENTRIES; i++) { - kfree(tx_cb->oal); - tx_cb->oal = NULL; + if (tx_cb->oal) { + kfree(tx_cb->oal); + tx_cb->oal = NULL; + } tx_cb++; } } @@ -2824,7 +2938,8 @@ static int ql_create_send_free_list(struct ql3_adapter *qdev) { struct ql_tx_buf_cb *tx_cb; int i; - struct ob_mac_iocb_req *req_q_curr = qdev->req_q_virt_addr; + struct ob_mac_iocb_req *req_q_curr = + qdev->req_q_virt_addr; /* Create free list of transmit buffers */ for (i = 0; i < NUM_REQ_Q_ENTRIES; i++) { @@ -2845,22 +2960,23 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) if (qdev->ndev->mtu == NORMAL_MTU_SIZE) { qdev->num_lbufq_entries = NUM_LBUFQ_ENTRIES; qdev->lrg_buffer_len = NORMAL_MTU_SIZE; - } else if (qdev->ndev->mtu == JUMBO_MTU_SIZE) { + } + else if (qdev->ndev->mtu == JUMBO_MTU_SIZE) { /* * Bigger buffers, so less of them. */ qdev->num_lbufq_entries = JUMBO_NUM_LBUFQ_ENTRIES; qdev->lrg_buffer_len = JUMBO_MTU_SIZE; } else { - netdev_err(qdev->ndev, "Invalid mtu size: %d. Only %d and %d are accepted.\n", - qdev->ndev->mtu, NORMAL_MTU_SIZE, JUMBO_MTU_SIZE); + printk(KERN_ERR PFX + "%s: Invalid mtu size. Only 1500 and 9000 are accepted.\n", + qdev->ndev->name); return -ENOMEM; } - qdev->num_large_buffers = - qdev->num_lbufq_entries * QL_ADDR_ELE_PER_BUFQ_ENTRY; + qdev->num_large_buffers = qdev->num_lbufq_entries * QL_ADDR_ELE_PER_BUFQ_ENTRY; qdev->lrg_buffer_len += VLAN_ETH_HLEN + VLAN_ID_LEN + QL_HEADER_SPACE; qdev->max_frame_size = - (qdev->lrg_buffer_len - QL_HEADER_SPACE) + ETHERNET_CRC_SIZE; + (qdev->lrg_buffer_len - QL_HEADER_SPACE) + ETHERNET_CRC_SIZE; /* * First allocate a page of shared memory and use it for shadow @@ -2868,44 +2984,51 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) * Network Completion Queue Producer Index Register */ qdev->shadow_reg_virt_addr = - pci_alloc_consistent(qdev->pdev, - PAGE_SIZE, &qdev->shadow_reg_phy_addr); + pci_alloc_consistent(qdev->pdev, + PAGE_SIZE, &qdev->shadow_reg_phy_addr); if (qdev->shadow_reg_virt_addr != NULL) { qdev->preq_consumer_index = (u16 *) qdev->shadow_reg_virt_addr; qdev->req_consumer_index_phy_addr_high = - MS_64BITS(qdev->shadow_reg_phy_addr); + MS_64BITS(qdev->shadow_reg_phy_addr); qdev->req_consumer_index_phy_addr_low = - LS_64BITS(qdev->shadow_reg_phy_addr); + LS_64BITS(qdev->shadow_reg_phy_addr); qdev->prsp_producer_index = - (__le32 *) (((u8 *) qdev->preq_consumer_index) + 8); + (__le32 *) (((u8 *) qdev->preq_consumer_index) + 8); qdev->rsp_producer_index_phy_addr_high = - qdev->req_consumer_index_phy_addr_high; + qdev->req_consumer_index_phy_addr_high; qdev->rsp_producer_index_phy_addr_low = - qdev->req_consumer_index_phy_addr_low + 8; + qdev->req_consumer_index_phy_addr_low + 8; } else { - netdev_err(qdev->ndev, "shadowReg Alloc failed\n"); + printk(KERN_ERR PFX + "%s: shadowReg Alloc failed.\n", qdev->ndev->name); return -ENOMEM; } if (ql_alloc_net_req_rsp_queues(qdev) != 0) { - netdev_err(qdev->ndev, "ql_alloc_net_req_rsp_queues failed\n"); + printk(KERN_ERR PFX + "%s: ql_alloc_net_req_rsp_queues failed.\n", + qdev->ndev->name); goto err_req_rsp; } if (ql_alloc_buffer_queues(qdev) != 0) { - netdev_err(qdev->ndev, "ql_alloc_buffer_queues failed\n"); + printk(KERN_ERR PFX + "%s: ql_alloc_buffer_queues failed.\n", + qdev->ndev->name); goto err_buffer_queues; } if (ql_alloc_small_buffers(qdev) != 0) { - netdev_err(qdev->ndev, "ql_alloc_small_buffers failed\n"); + printk(KERN_ERR PFX + "%s: ql_alloc_small_buffers failed\n", qdev->ndev->name); goto err_small_buffers; } if (ql_alloc_large_buffers(qdev) != 0) { - netdev_err(qdev->ndev, "ql_alloc_large_buffers failed\n"); + printk(KERN_ERR PFX + "%s: ql_alloc_large_buffers failed\n", qdev->ndev->name); goto err_small_buffers; } @@ -2953,7 +3076,7 @@ static int ql_init_misc_registers(struct ql3_adapter *qdev) struct ql3xxx_local_ram_registers __iomem *local_ram = (void __iomem *)qdev->mem_map_registers; - if (ql_sem_spinlock(qdev, QL_DDR_RAM_SEM_MASK, + if(ql_sem_spinlock(qdev, QL_DDR_RAM_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 2) << 4)) return -1; @@ -3009,20 +3132,18 @@ static int ql_init_misc_registers(struct ql3_adapter *qdev) static int ql_adapter_initialize(struct ql3_adapter *qdev) { u32 value; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct ql3xxx_host_memory_registers __iomem *hmem_regs = - (void __iomem *)port_regs; + (void __iomem *)port_regs; u32 delay = 10; int status = 0; unsigned long hw_flags = 0; - if (ql_mii_setup(qdev)) + if(ql_mii_setup(qdev)) return -1; /* Bring out PHY out of reset */ - ql_write_common_reg(qdev, spir, + ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, (ISP_SERIAL_PORT_IF_WE | (ISP_SERIAL_PORT_IF_WE << 16))); /* Give the PHY time to come out of reset. */ @@ -3031,13 +3152,13 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) netif_carrier_off(qdev->ndev); /* V2 chip fix for ARS-39168. */ - ql_write_common_reg(qdev, spir, + ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, (ISP_SERIAL_PORT_IF_SDE | (ISP_SERIAL_PORT_IF_SDE << 16))); /* Request Queue Registers */ - *((u32 *)(qdev->preq_consumer_index)) = 0; - atomic_set(&qdev->tx_count, NUM_REQ_Q_ENTRIES); + *((u32 *) (qdev->preq_consumer_index)) = 0; + atomic_set(&qdev->tx_count,NUM_REQ_Q_ENTRIES); qdev->req_producer_index = 0; ql_write_page1_reg(qdev, @@ -3087,9 +3208,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) &hmem_regs->rxLargeQBaseAddrLow, LS_64BITS(qdev->lrg_buf_q_phy_addr)); - ql_write_page1_reg(qdev, - &hmem_regs->rxLargeQLength, - qdev->num_lbufq_entries); + ql_write_page1_reg(qdev, &hmem_regs->rxLargeQLength, qdev->num_lbufq_entries); ql_write_page1_reg(qdev, &hmem_regs->rxLargeBufferLength, @@ -3139,7 +3258,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) if ((value & PORT_STATUS_IC) == 0) { /* Chip has not been configured yet, so let it rip. */ - if (ql_init_misc_registers(qdev)) { + if(ql_init_misc_registers(qdev)) { status = -1; goto out; } @@ -3149,7 +3268,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) value = (0xFFFF << 16) | qdev->nvram_data.extHwConfig; - if (ql_sem_spinlock(qdev, QL_FLASH_SEM_MASK, + if(ql_sem_spinlock(qdev, QL_FLASH_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 2) << 13)) { status = -1; @@ -3172,7 +3291,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) &port_regs->mac0MaxFrameLengthReg, qdev->max_frame_size); - if (ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, + if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * 2) << 7)) { status = -1; @@ -3234,7 +3353,8 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) } while (--delay); if (delay == 0) { - netdev_err(qdev->ndev, "Hw Initialization timeout\n"); + printk(KERN_ERR PFX + "%s: Hw Initialization timeout.\n", qdev->ndev->name); status = -1; goto out; } @@ -3265,8 +3385,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) */ static int ql_adapter_reset(struct ql3_adapter *qdev) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; int status = 0; u16 value; int max_wait_time; @@ -3277,14 +3396,17 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) /* * Issue soft reset to chip. */ - netdev_printk(KERN_DEBUG, qdev->ndev, "Issue soft reset to chip\n"); + printk(KERN_DEBUG PFX + "%s: Issue soft reset to chip.\n", + qdev->ndev->name); ql_write_common_reg(qdev, &port_regs->CommonRegs.ispControlStatus, ((ISP_CONTROL_SR << 16) | ISP_CONTROL_SR)); /* Wait 3 seconds for reset to complete. */ - netdev_printk(KERN_DEBUG, qdev->ndev, - "Wait 10 milliseconds for reset to complete\n"); + printk(KERN_DEBUG PFX + "%s: Wait 10 milliseconds for reset to complete.\n", + qdev->ndev->name); /* Wait until the firmware tells us the Soft Reset is done */ max_wait_time = 5; @@ -3305,8 +3427,8 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) value = ql_read_common_reg(qdev, &port_regs->CommonRegs.ispControlStatus); if (value & ISP_CONTROL_RI) { - netdev_printk(KERN_DEBUG, qdev->ndev, - "clearing RI after reset\n"); + printk(KERN_DEBUG PFX + "ql_adapter_reset: clearing RI after reset.\n"); ql_write_common_reg(qdev, &port_regs->CommonRegs. ispControlStatus, @@ -3326,11 +3448,13 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) */ max_wait_time = 5; do { - value = ql_read_common_reg(qdev, - &port_regs->CommonRegs. - ispControlStatus); - if ((value & ISP_CONTROL_FSR) == 0) + value = + ql_read_common_reg(qdev, + &port_regs->CommonRegs. + ispControlStatus); + if ((value & ISP_CONTROL_FSR) == 0) { break; + } ssleep(1); } while ((--max_wait_time)); } @@ -3344,8 +3468,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) static void ql_set_mac_info(struct ql3_adapter *qdev) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; u32 value, port_status; u8 func_number; @@ -3361,9 +3484,9 @@ static void ql_set_mac_info(struct ql3_adapter *qdev) qdev->mb_bit_mask = FN0_MA_BITS_MASK; qdev->PHYAddr = PORT0_PHY_ADDRESS; if (port_status & PORT_STATUS_SM0) - set_bit(QL_LINK_OPTICAL, &qdev->flags); + set_bit(QL_LINK_OPTICAL,&qdev->flags); else - clear_bit(QL_LINK_OPTICAL, &qdev->flags); + clear_bit(QL_LINK_OPTICAL,&qdev->flags); break; case ISP_CONTROL_FN1_NET: @@ -3372,17 +3495,17 @@ static void ql_set_mac_info(struct ql3_adapter *qdev) qdev->mb_bit_mask = FN1_MA_BITS_MASK; qdev->PHYAddr = PORT1_PHY_ADDRESS; if (port_status & PORT_STATUS_SM1) - set_bit(QL_LINK_OPTICAL, &qdev->flags); + set_bit(QL_LINK_OPTICAL,&qdev->flags); else - clear_bit(QL_LINK_OPTICAL, &qdev->flags); + clear_bit(QL_LINK_OPTICAL,&qdev->flags); break; case ISP_CONTROL_FN0_SCSI: case ISP_CONTROL_FN1_SCSI: default: - netdev_printk(KERN_DEBUG, qdev->ndev, - "Invalid function number, ispControlStatus = 0x%x\n", - value); + printk(KERN_DEBUG PFX + "%s: Invalid function number, ispControlStatus = 0x%x\n", + qdev->ndev->name,value); break; } qdev->numPorts = qdev->nvram_data.version_and_numPorts >> 8; @@ -3393,26 +3516,32 @@ static void ql_display_dev_info(struct net_device *ndev) struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct pci_dev *pdev = qdev->pdev; - netdev_info(ndev, - "%s Adapter %d RevisionID %d found %s on PCI slot %d\n", - DRV_NAME, qdev->index, qdev->chip_rev_id, - qdev->device_id == QL3032_DEVICE_ID ? "QLA3032" : "QLA3022", - qdev->pci_slot); - netdev_info(ndev, "%s Interface\n", - test_bit(QL_LINK_OPTICAL, &qdev->flags) ? "OPTICAL" : "COPPER"); + printk(KERN_INFO PFX + "\n%s Adapter %d RevisionID %d found %s on PCI slot %d.\n", + DRV_NAME, qdev->index, qdev->chip_rev_id, + (qdev->device_id == QL3032_DEVICE_ID) ? "QLA3032" : "QLA3022", + qdev->pci_slot); + printk(KERN_INFO PFX + "%s Interface.\n", + test_bit(QL_LINK_OPTICAL,&qdev->flags) ? "OPTICAL" : "COPPER"); /* * Print PCI bus width/type. */ - netdev_info(ndev, "Bus interface is %s %s\n", - ((qdev->pci_width == 64) ? "64-bit" : "32-bit"), - ((qdev->pci_x) ? "PCI-X" : "PCI")); + printk(KERN_INFO PFX + "Bus interface is %s %s.\n", + ((qdev->pci_width == 64) ? "64-bit" : "32-bit"), + ((qdev->pci_x) ? "PCI-X" : "PCI")); - netdev_info(ndev, "mem IO base address adjusted = 0x%p\n", - qdev->mem_map_registers); - netdev_info(ndev, "Interrupt number = %d\n", pdev->irq); + printk(KERN_INFO PFX + "mem IO base address adjusted = 0x%p\n", + qdev->mem_map_registers); + printk(KERN_INFO PFX "Interrupt number = %d\n", pdev->irq); - netif_info(qdev, probe, ndev, "MAC address %pM\n", ndev->dev_addr); + if (netif_msg_probe(qdev)) + printk(KERN_INFO PFX + "%s: MAC address %pM\n", + ndev->name, ndev->dev_addr); } static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) @@ -3423,16 +3552,17 @@ static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) netif_stop_queue(ndev); netif_carrier_off(ndev); - clear_bit(QL_ADAPTER_UP, &qdev->flags); - clear_bit(QL_LINK_MASTER, &qdev->flags); + clear_bit(QL_ADAPTER_UP,&qdev->flags); + clear_bit(QL_LINK_MASTER,&qdev->flags); ql_disable_interrupts(qdev); free_irq(qdev->pdev->irq, ndev); - if (qdev->msi && test_bit(QL_MSI_ENABLED, &qdev->flags)) { - netdev_info(qdev->ndev, "calling pci_disable_msi()\n"); - clear_bit(QL_MSI_ENABLED, &qdev->flags); + if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) { + printk(KERN_INFO PFX + "%s: calling pci_disable_msi().\n", qdev->ndev->name); + clear_bit(QL_MSI_ENABLED,&qdev->flags); pci_disable_msi(qdev->pdev); } @@ -3446,16 +3576,17 @@ static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) spin_lock_irqsave(&qdev->hw_lock, hw_flags); if (ql_wait_for_drvr_lock(qdev)) { - soft_reset = ql_adapter_reset(qdev); - if (soft_reset) { - netdev_err(ndev, "ql_adapter_reset(%d) FAILED!\n", - qdev->index); + if ((soft_reset = ql_adapter_reset(qdev))) { + printk(KERN_ERR PFX + "%s: ql_adapter_reset(%d) FAILED!\n", + ndev->name, qdev->index); } - netdev_err(ndev, - "Releasing driver lock via chip reset\n"); + printk(KERN_ERR PFX + "%s: Releaseing driver lock via chip reset.\n",ndev->name); } else { - netdev_err(ndev, - "Could not acquire driver lock to do reset!\n"); + printk(KERN_ERR PFX + "%s: Could not acquire driver lock to do " + "reset!\n", ndev->name); retval = -1; } spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); @@ -3472,50 +3603,56 @@ static int ql_adapter_up(struct ql3_adapter *qdev) unsigned long hw_flags; if (ql_alloc_mem_resources(qdev)) { - netdev_err(ndev, "Unable to allocate buffers\n"); + printk(KERN_ERR PFX + "%s Unable to allocate buffers.\n", ndev->name); return -ENOMEM; } if (qdev->msi) { if (pci_enable_msi(qdev->pdev)) { - netdev_err(ndev, - "User requested MSI, but MSI failed to initialize. Continuing without MSI.\n"); + printk(KERN_ERR PFX + "%s: User requested MSI, but MSI failed to " + "initialize. Continuing without MSI.\n", + qdev->ndev->name); qdev->msi = 0; } else { - netdev_info(ndev, "MSI Enabled...\n"); - set_bit(QL_MSI_ENABLED, &qdev->flags); + printk(KERN_INFO PFX "%s: MSI Enabled...\n", qdev->ndev->name); + set_bit(QL_MSI_ENABLED,&qdev->flags); irq_flags &= ~IRQF_SHARED; } } - err = request_irq(qdev->pdev->irq, ql3xxx_isr, - irq_flags, ndev->name, ndev); - if (err) { - netdev_err(ndev, - "Failed to reserve interrupt %d - already in use\n", - qdev->pdev->irq); + if ((err = request_irq(qdev->pdev->irq, + ql3xxx_isr, + irq_flags, ndev->name, ndev))) { + printk(KERN_ERR PFX + "%s: Failed to reserve interrupt %d already in use.\n", + ndev->name, qdev->pdev->irq); goto err_irq; } spin_lock_irqsave(&qdev->hw_lock, hw_flags); - err = ql_wait_for_drvr_lock(qdev); - if (err) { - err = ql_adapter_initialize(qdev); - if (err) { - netdev_err(ndev, "Unable to initialize adapter\n"); + if ((err = ql_wait_for_drvr_lock(qdev))) { + if ((err = ql_adapter_initialize(qdev))) { + printk(KERN_ERR PFX + "%s: Unable to initialize adapter.\n", + ndev->name); goto err_init; } - netdev_err(ndev, "Releasing driver lock\n"); + printk(KERN_ERR PFX + "%s: Releaseing driver lock.\n",ndev->name); ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); } else { - netdev_err(ndev, "Could not acquire driver lock\n"); + printk(KERN_ERR PFX + "%s: Could not acquire driver lock.\n", + ndev->name); goto err_lock; } spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - set_bit(QL_ADAPTER_UP, &qdev->flags); + set_bit(QL_ADAPTER_UP,&qdev->flags); mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); @@ -3529,9 +3666,11 @@ static int ql_adapter_up(struct ql3_adapter *qdev) spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); free_irq(qdev->pdev->irq, ndev); err_irq: - if (qdev->msi && test_bit(QL_MSI_ENABLED, &qdev->flags)) { - netdev_info(ndev, "calling pci_disable_msi()\n"); - clear_bit(QL_MSI_ENABLED, &qdev->flags); + if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) { + printk(KERN_INFO PFX + "%s: calling pci_disable_msi().\n", + qdev->ndev->name); + clear_bit(QL_MSI_ENABLED,&qdev->flags); pci_disable_msi(qdev->pdev); } return err; @@ -3539,9 +3678,10 @@ static int ql_adapter_up(struct ql3_adapter *qdev) static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset) { - if (ql_adapter_down(qdev, reset) || ql_adapter_up(qdev)) { - netdev_err(qdev->ndev, - "Driver up/down cycle failed, closing device\n"); + if( ql_adapter_down(qdev,reset) || ql_adapter_up(qdev)) { + printk(KERN_ERR PFX + "%s: Driver up/down cycle failed, " + "closing device\n",qdev->ndev->name); rtnl_lock(); dev_close(qdev->ndev); rtnl_unlock(); @@ -3558,24 +3698,24 @@ static int ql3xxx_close(struct net_device *ndev) * Wait for device to recover from a reset. * (Rarely happens, but possible.) */ - while (!test_bit(QL_ADAPTER_UP, &qdev->flags)) + while (!test_bit(QL_ADAPTER_UP,&qdev->flags)) msleep(50); - ql_adapter_down(qdev, QL_DO_RESET); + ql_adapter_down(qdev,QL_DO_RESET); return 0; } static int ql3xxx_open(struct net_device *ndev) { struct ql3_adapter *qdev = netdev_priv(ndev); - return ql_adapter_up(qdev); + return (ql_adapter_up(qdev)); } static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) { struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + qdev->mem_map_registers; struct sockaddr *addr = p; unsigned long hw_flags; @@ -3610,7 +3750,7 @@ static void ql3xxx_tx_timeout(struct net_device *ndev) { struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); - netdev_err(ndev, "Resetting...\n"); + printk(KERN_ERR PFX "%s: Resetting...\n", ndev->name); /* * Stop the queues, we've got a problem. */ @@ -3630,12 +3770,11 @@ static void ql_reset_work(struct work_struct *work) u32 value; struct ql_tx_buf_cb *tx_cb; int max_wait_time, i; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; unsigned long hw_flags; - if (test_bit((QL_RESET_PER_SCSI | QL_RESET_START), &qdev->flags)) { - clear_bit(QL_LINK_MASTER, &qdev->flags); + if (test_bit((QL_RESET_PER_SCSI | QL_RESET_START),&qdev->flags)) { + clear_bit(QL_LINK_MASTER,&qdev->flags); /* * Loop through the active list and return the skb. @@ -3644,19 +3783,17 @@ static void ql_reset_work(struct work_struct *work) int j; tx_cb = &qdev->tx_buf[i]; if (tx_cb->skb) { - netdev_printk(KERN_DEBUG, ndev, - "Freeing lost SKB\n"); + printk(KERN_DEBUG PFX + "%s: Freeing lost SKB.\n", + qdev->ndev->name); pci_unmap_single(qdev->pdev, - dma_unmap_addr(&tx_cb->map[0], - mapaddr), + dma_unmap_addr(&tx_cb->map[0], mapaddr), dma_unmap_len(&tx_cb->map[0], maplen), PCI_DMA_TODEVICE); - for (j = 1; j < tx_cb->seg_count; j++) { + for(j=1;jseg_count;j++) { pci_unmap_page(qdev->pdev, - dma_unmap_addr(&tx_cb->map[j], - mapaddr), - dma_unmap_len(&tx_cb->map[j], - maplen), + dma_unmap_addr(&tx_cb->map[j],mapaddr), + dma_unmap_len(&tx_cb->map[j],maplen), PCI_DMA_TODEVICE); } dev_kfree_skb(tx_cb->skb); @@ -3664,7 +3801,8 @@ static void ql_reset_work(struct work_struct *work) } } - netdev_err(ndev, "Clearing NRI after reset\n"); + printk(KERN_ERR PFX + "%s: Clearing NRI after reset.\n", qdev->ndev->name); spin_lock_irqsave(&qdev->hw_lock, hw_flags); ql_write_common_reg(qdev, &port_regs->CommonRegs. @@ -3680,14 +3818,16 @@ static void ql_reset_work(struct work_struct *work) ispControlStatus); if ((value & ISP_CONTROL_SR) == 0) { - netdev_printk(KERN_DEBUG, ndev, - "reset completed\n"); + printk(KERN_DEBUG PFX + "%s: reset completed.\n", + qdev->ndev->name); break; } if (value & ISP_CONTROL_RI) { - netdev_printk(KERN_DEBUG, ndev, - "clearing NRI after reset\n"); + printk(KERN_DEBUG PFX + "%s: clearing NRI after reset.\n", + qdev->ndev->name); ql_write_common_reg(qdev, &port_regs-> CommonRegs. @@ -3708,19 +3848,21 @@ static void ql_reset_work(struct work_struct *work) * Set the reset flags and clear the board again. * Nothing else to do... */ - netdev_err(ndev, - "Timed out waiting for reset to complete\n"); - netdev_err(ndev, "Do a reset\n"); - clear_bit(QL_RESET_PER_SCSI, &qdev->flags); - clear_bit(QL_RESET_START, &qdev->flags); - ql_cycle_adapter(qdev, QL_DO_RESET); + printk(KERN_ERR PFX + "%s: Timed out waiting for reset to " + "complete.\n", ndev->name); + printk(KERN_ERR PFX + "%s: Do a reset.\n", ndev->name); + clear_bit(QL_RESET_PER_SCSI,&qdev->flags); + clear_bit(QL_RESET_START,&qdev->flags); + ql_cycle_adapter(qdev,QL_DO_RESET); return; } - clear_bit(QL_RESET_ACTIVE, &qdev->flags); - clear_bit(QL_RESET_PER_SCSI, &qdev->flags); - clear_bit(QL_RESET_START, &qdev->flags); - ql_cycle_adapter(qdev, QL_NO_RESET); + clear_bit(QL_RESET_ACTIVE,&qdev->flags); + clear_bit(QL_RESET_PER_SCSI,&qdev->flags); + clear_bit(QL_RESET_START,&qdev->flags); + ql_cycle_adapter(qdev,QL_NO_RESET); } } @@ -3734,8 +3876,7 @@ static void ql_tx_timeout_work(struct work_struct *work) static void ql_get_board_info(struct ql3_adapter *qdev) { - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; u32 value; value = ql_read_page0_reg_l(qdev, &port_regs->portStatus); @@ -3774,18 +3915,20 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, { struct net_device *ndev = NULL; struct ql3_adapter *qdev = NULL; - static int cards_found; + static int cards_found = 0; int uninitialized_var(pci_using_dac), err; err = pci_enable_device(pdev); if (err) { - pr_err("%s cannot enable PCI device\n", pci_name(pdev)); + printk(KERN_ERR PFX "%s cannot enable PCI device\n", + pci_name(pdev)); goto err_out; } err = pci_request_regions(pdev, DRV_NAME); if (err) { - pr_err("%s cannot obtain PCI resources\n", pci_name(pdev)); + printk(KERN_ERR PFX "%s cannot obtain PCI resources\n", + pci_name(pdev)); goto err_out_disable_pdev; } @@ -3800,13 +3943,15 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, } if (err) { - pr_err("%s no usable DMA configuration\n", pci_name(pdev)); + printk(KERN_ERR PFX "%s no usable DMA configuration\n", + pci_name(pdev)); goto err_out_free_regions; } ndev = alloc_etherdev(sizeof(struct ql3_adapter)); if (!ndev) { - pr_err("%s could not alloc etherdev\n", pci_name(pdev)); + printk(KERN_ERR PFX "%s could not alloc etherdev\n", + pci_name(pdev)); err = -ENOMEM; goto err_out_free_regions; } @@ -3833,7 +3978,8 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, qdev->mem_map_registers = pci_ioremap_bar(pdev, 1); if (!qdev->mem_map_registers) { - pr_err("%s: cannot map device registers\n", pci_name(pdev)); + printk(KERN_ERR PFX "%s: cannot map device registers\n", + pci_name(pdev)); err = -EIO; goto err_out_free_ndev; } @@ -3852,8 +3998,9 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, /* make sure the EEPROM is good */ if (ql_get_nvram_params(qdev)) { - pr_alert("%s: Adapter #%d, Invalid NVRAM parameters\n", - __func__, qdev->index); + printk(KERN_ALERT PFX + "ql3xxx_probe: Adapter #%d, Invalid NVRAM parameters.\n", + qdev->index); err = -EIO; goto err_out_iounmap; } @@ -3879,12 +4026,14 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, * Set the Maximum Memory Read Byte Count value. We do this to handle * jumbo frames. */ - if (qdev->pci_x) + if (qdev->pci_x) { pci_write_config_word(pdev, (int)0x4e, (u16) 0x0036); + } err = register_netdev(ndev); if (err) { - pr_err("%s: cannot register net device\n", pci_name(pdev)); + printk(KERN_ERR PFX "%s: cannot register net device\n", + pci_name(pdev)); goto err_out_iounmap; } @@ -3903,10 +4052,10 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, qdev->adapter_timer.expires = jiffies + HZ * 2; /* two second delay */ qdev->adapter_timer.data = (unsigned long)qdev; - if (!cards_found) { - pr_alert("%s\n", DRV_STRING); - pr_alert("Driver name: %s, Version: %s\n", - DRV_NAME, DRV_VERSION); + if(!cards_found) { + printk(KERN_ALERT PFX "%s\n", DRV_STRING); + printk(KERN_ALERT PFX "Driver name: %s, Version: %s.\n", + DRV_NAME, DRV_VERSION); } ql_display_dev_info(ndev); diff --git a/trunk/drivers/net/qlcnic/qlcnic.h b/trunk/drivers/net/qlcnic/qlcnic.h index 970389331bbc..e1894775e5aa 100644 --- a/trunk/drivers/net/qlcnic/qlcnic.h +++ b/trunk/drivers/net/qlcnic/qlcnic.h @@ -1074,8 +1074,8 @@ struct qlcnic_eswitch { /* Return codes for Error handling */ #define QL_STATUS_INVALID_PARAM -1 -#define MAX_BW 100 -#define MIN_BW 1 +#define MAX_BW 10000 +#define MIN_BW 100 #define MAX_VLAN_ID 4095 #define MIN_VLAN_ID 2 #define MAX_TX_QUEUES 1 @@ -1083,7 +1083,8 @@ struct qlcnic_eswitch { #define DEFAULT_MAC_LEARN 1 #define IS_VALID_VLAN(vlan) (vlan >= MIN_VLAN_ID && vlan <= MAX_VLAN_ID) -#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW) +#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW \ + && (bw % 100) == 0) #define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) #define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) #define IS_VALID_MODE(mode) (mode == 0 || mode == 1) @@ -1301,6 +1302,8 @@ struct qlcnic_nic_template { int (*get_mac_addr) (struct qlcnic_adapter *, u8*); int (*config_bridged_mode) (struct qlcnic_adapter *, u32); int (*config_led) (struct qlcnic_adapter *, u32, u32); + int (*set_ilb_mode) (struct qlcnic_adapter *); + void (*clear_ilb_mode) (struct qlcnic_adapter *); int (*start_firmware) (struct qlcnic_adapter *); }; diff --git a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c index 9328d59e21e0..7d6558e33dca 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c @@ -678,12 +678,6 @@ static int qlcnic_loopback_test(struct net_device *netdev) int max_sds_rings = adapter->max_sds_rings; int ret; - if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { - dev_warn(&adapter->pdev->dev, "Loopback test not supported" - "for non privilege function\n"); - return 0; - } - if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EIO; @@ -691,13 +685,13 @@ static int qlcnic_loopback_test(struct net_device *netdev) if (ret) goto clear_it; - ret = qlcnic_set_ilb_mode(adapter); + ret = adapter->nic_ops->set_ilb_mode(adapter); if (ret) goto done; ret = qlcnic_do_ilb_test(adapter); - qlcnic_clear_ilb_mode(adapter); + adapter->nic_ops->clear_ilb_mode(adapter); done: qlcnic_diag_free_res(netdev, max_sds_rings); diff --git a/trunk/drivers/net/qlcnic/qlcnic_main.c b/trunk/drivers/net/qlcnic/qlcnic_main.c index b9615bd745ea..f1f7acfbf412 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_main.c +++ b/trunk/drivers/net/qlcnic/qlcnic_main.c @@ -107,6 +107,8 @@ static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); static int qlcnic_start_firmware(struct qlcnic_adapter *); static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); +static void qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *); +static int qlcnicvf_set_ilb_mode(struct qlcnic_adapter *); static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); static int qlcnicvf_start_firmware(struct qlcnic_adapter *); @@ -379,6 +381,8 @@ static struct qlcnic_nic_template qlcnic_ops = { .get_mac_addr = qlcnic_get_mac_address, .config_bridged_mode = qlcnic_config_bridged_mode, .config_led = qlcnic_config_led, + .set_ilb_mode = qlcnic_set_ilb_mode, + .clear_ilb_mode = qlcnic_clear_ilb_mode, .start_firmware = qlcnic_start_firmware }; @@ -386,6 +390,8 @@ static struct qlcnic_nic_template qlcnic_vf_ops = { .get_mac_addr = qlcnic_get_mac_address, .config_bridged_mode = qlcnicvf_config_bridged_mode, .config_led = qlcnicvf_config_led, + .set_ilb_mode = qlcnicvf_set_ilb_mode, + .clear_ilb_mode = qlcnicvf_clear_ilb_mode, .start_firmware = qlcnicvf_start_firmware }; @@ -1176,7 +1182,6 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) ret = qlcnic_fw_create_ctx(adapter); if (ret) { qlcnic_detach(adapter); - netif_device_attach(netdev); return ret; } @@ -2836,6 +2841,18 @@ qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) return -EOPNOTSUPP; } +static int +qlcnicvf_set_ilb_mode(struct qlcnic_adapter *adapter) +{ + return -EOPNOTSUPP; +} + +static void +qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *adapter) +{ + return; +} + static ssize_t qlcnic_store_bridged_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 18bc5b718bbb..b8b85843c614 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -5796,7 +5796,7 @@ static void s2io_vpd_read(struct s2io_nic *nic) { u8 *vpd_data; u8 data; - int i = 0, cnt, len, fail = 0; + int i = 0, cnt, fail = 0; int vpd_addr = 0x80; struct swStat *swstats = &nic->mac_control.stats_info->sw_stat; @@ -5837,28 +5837,20 @@ static void s2io_vpd_read(struct s2io_nic *nic) if (!fail) { /* read serial number of adapter */ - for (cnt = 0; cnt < 252; cnt++) { + for (cnt = 0; cnt < 256; cnt++) { if ((vpd_data[cnt] == 'S') && - (vpd_data[cnt+1] == 'N')) { - len = vpd_data[cnt+2]; - if (len < min(VPD_STRING_LEN, 256-cnt-2)) { - memcpy(nic->serial_num, - &vpd_data[cnt + 3], - len); - memset(nic->serial_num+len, - 0, - VPD_STRING_LEN-len); - break; - } + (vpd_data[cnt+1] == 'N') && + (vpd_data[cnt+2] < VPD_STRING_LEN)) { + memset(nic->serial_num, 0, VPD_STRING_LEN); + memcpy(nic->serial_num, &vpd_data[cnt + 3], + vpd_data[cnt+2]); + break; } } } - if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) { - len = vpd_data[1]; - memcpy(nic->product_name, &vpd_data[3], len); - nic->product_name[len] = 0; - } + if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) + memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); kfree(vpd_data); swstats->mem_freed += 256; } diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 0af033533905..3645fb3673db 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -65,7 +65,7 @@ static int debug_level = ERR_DBG; /* DEBUG message print. */ #define DBG_PRINT(dbg_level, fmt, args...) do { \ - if (dbg_level <= debug_level) \ + if (dbg_level >= debug_level) \ pr_info(fmt, ##args); \ } while (0) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 194e5cf8c763..c762c6ac055b 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -79,7 +79,7 @@ #define SKY2_EEPROM_MAGIC 0x9955aabb -#define RING_NEXT(x, s) (((x)+1) & ((s)-1)) +#define RING_NEXT(x,s) (((x)+1) & ((s)-1)) static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK @@ -172,7 +172,7 @@ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val) udelay(10); } - dev_warn(&hw->pdev->dev, "%s: phy write timeout\n", hw->dev[port]->name); + dev_warn(&hw->pdev->dev,"%s: phy write timeout\n", hw->dev[port]->name); return -ETIMEDOUT; io_error: @@ -1067,7 +1067,7 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) return le; } -static unsigned sky2_get_rx_threshold(struct sky2_port *sky2) +static unsigned sky2_get_rx_threshold(struct sky2_port* sky2) { unsigned size; @@ -1078,7 +1078,7 @@ static unsigned sky2_get_rx_threshold(struct sky2_port *sky2) return (size - 8) / sizeof(u32); } -static unsigned sky2_get_rx_data_size(struct sky2_port *sky2) +static unsigned sky2_get_rx_data_size(struct sky2_port* sky2) { struct rx_ring_info *re; unsigned size; @@ -1102,7 +1102,7 @@ static unsigned sky2_get_rx_data_size(struct sky2_port *sky2) } /* Build description to hardware for one receive segment */ -static void sky2_rx_add(struct sky2_port *sky2, u8 op, +static void sky2_rx_add(struct sky2_port *sky2, u8 op, dma_addr_t map, unsigned len) { struct sky2_rx_le *le; @@ -3014,7 +3014,7 @@ static int __devinit sky2_init(struct sky2_hw *hw) hw->chip_id = sky2_read8(hw, B2_CHIP_ID); hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; - switch (hw->chip_id) { + switch(hw->chip_id) { case CHIP_ID_YUKON_XL: hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY; if (hw->chip_rev < CHIP_REV_YU_XL_A2) @@ -3685,7 +3685,7 @@ static int sky2_set_mac_address(struct net_device *dev, void *p) return 0; } -static inline void sky2_add_filter(u8 filter[8], const u8 *addr) +static void inline sky2_add_filter(u8 filter[8], const u8 *addr) { u32 bit; @@ -3911,7 +3911,7 @@ static int sky2_set_coalesce(struct net_device *dev, return -EINVAL; if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING) return -EINVAL; - if (ecmd->rx_max_coalesced_frames_irq > RX_MAX_PENDING) + if (ecmd->rx_max_coalesced_frames_irq >RX_MAX_PENDING) return -EINVAL; if (ecmd->tx_coalesce_usecs == 0) @@ -4372,7 +4372,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) seq_printf(seq, "%u:", idx); sop = 0; - switch (le->opcode & ~HW_OWNER) { + switch(le->opcode & ~HW_OWNER) { case OP_ADDR64: seq_printf(seq, " %#x:", a); break; @@ -4441,7 +4441,7 @@ static int sky2_device_event(struct notifier_block *unused, if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug) return NOTIFY_DONE; - switch (event) { + switch(event) { case NETDEV_CHANGENAME: if (sky2->debugfs) { sky2->debugfs = debugfs_rename(sky2_debug, sky2->debugfs, @@ -4636,7 +4636,7 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) struct pci_dev *pdev = hw->pdev; int err; - init_waitqueue_head(&hw->msi_wait); + init_waitqueue_head (&hw->msi_wait); sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); @@ -4753,7 +4753,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, * this driver uses software swapping. */ reg &= ~PCI_REV_DESC; - err = pci_write_config_dword(pdev, PCI_DEV_REG2, reg); + err = pci_write_config_dword(pdev,PCI_DEV_REG2, reg); if (err) { dev_err(&pdev->dev, "PCI write config failed\n"); goto err_out_free_regions; diff --git a/trunk/drivers/net/stmmac/common.h b/trunk/drivers/net/stmmac/common.h index 66b9da0260fe..144f76fd3e39 100644 --- a/trunk/drivers/net/stmmac/common.h +++ b/trunk/drivers/net/stmmac/common.h @@ -108,7 +108,6 @@ enum rx_frame_status { /* IPC status */ good_frame = 0, discard_frame = 1, csum_none = 2, - llc_snap = 4, }; enum tx_dma_irq_status { diff --git a/trunk/drivers/net/stmmac/dwmac1000.h b/trunk/drivers/net/stmmac/dwmac1000.h index 8b20b19971cb..d8d0f3553770 100644 --- a/trunk/drivers/net/stmmac/dwmac1000.h +++ b/trunk/drivers/net/stmmac/dwmac1000.h @@ -93,7 +93,7 @@ enum inter_frame_gap { #define GMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */ #define GMAC_CONTROL_DR 0x00000200 /* Disable Retry */ #define GMAC_CONTROL_LUD 0x00000100 /* Link up/down */ -#define GMAC_CONTROL_ACS 0x00000080 /* Automatic Pad/FCS Stripping */ +#define GMAC_CONTROL_ACS 0x00000080 /* Automatic Pad Stripping */ #define GMAC_CONTROL_DC 0x00000010 /* Deferral Check */ #define GMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */ #define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ diff --git a/trunk/drivers/net/stmmac/dwmac1000_core.c b/trunk/drivers/net/stmmac/dwmac1000_core.c index 2b2f5c8caf1c..917b4e16923b 100644 --- a/trunk/drivers/net/stmmac/dwmac1000_core.c +++ b/trunk/drivers/net/stmmac/dwmac1000_core.c @@ -220,8 +220,6 @@ struct mac_device_info *dwmac1000_setup(unsigned long ioaddr) ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff)); mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL); - if (!mac) - return NULL; mac->mac = &dwmac1000_ops; mac->dma = &dwmac1000_dma_ops; diff --git a/trunk/drivers/net/stmmac/dwmac100_core.c b/trunk/drivers/net/stmmac/dwmac100_core.c index 2fb165fa2ba0..6f270a0e151a 100644 --- a/trunk/drivers/net/stmmac/dwmac100_core.c +++ b/trunk/drivers/net/stmmac/dwmac100_core.c @@ -179,8 +179,6 @@ struct mac_device_info *dwmac100_setup(unsigned long ioaddr) struct mac_device_info *mac; mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL); - if (!mac) - return NULL; pr_info("\tDWMAC100\n"); diff --git a/trunk/drivers/net/stmmac/enh_desc.c b/trunk/drivers/net/stmmac/enh_desc.c index f612f986a7e1..3c18ebece043 100644 --- a/trunk/drivers/net/stmmac/enh_desc.c +++ b/trunk/drivers/net/stmmac/enh_desc.c @@ -123,7 +123,7 @@ static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err) */ if (status == 0x0) { CHIP_DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n"); - ret = llc_snap; + ret = good_frame; } else if (status == 0x4) { CHIP_DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n"); ret = good_frame; diff --git a/trunk/drivers/net/stmmac/stmmac_main.c b/trunk/drivers/net/stmmac/stmmac_main.c index bbb7951b9c4c..acf061686940 100644 --- a/trunk/drivers/net/stmmac/stmmac_main.c +++ b/trunk/drivers/net/stmmac/stmmac_main.c @@ -829,6 +829,7 @@ static int stmmac_open(struct net_device *dev) * In case of failure continue without timer. */ if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { pr_warning("stmmaceth: cannot attach the external timer.\n"); + tmrate = 0; priv->tm->freq = 0; priv->tm->timer_start = stmmac_no_timer_started; priv->tm->timer_stop = stmmac_no_timer_stopped; @@ -1216,13 +1217,9 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) priv->dev->stats.rx_errors++; else { struct sk_buff *skb; - int frame_len; + /* Length should omit the CRC */ + int frame_len = priv->hw->desc->get_rx_frame_len(p) - 4; - frame_len = priv->hw->desc->get_rx_frame_len(p); - /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 - * Type frames (LLC/LLC-SNAP) */ - if (unlikely(status != llc_snap)) - frame_len -= ETH_FCS_LEN; #ifdef STMMAC_RX_DEBUG if (frame_len > ETH_FRAME_LEN) pr_debug("\tRX frame size %d, COE status: %d\n", @@ -1561,15 +1558,15 @@ static int stmmac_mac_device_setup(struct net_device *dev) else device = dwmac100_setup(ioaddr); - if (!device) - return -ENOMEM; - if (priv->enh_desc) { device->desc = &enh_desc_ops; pr_info("\tEnhanced descriptor structure\n"); } else device->desc = &ndesc_ops; + if (!device) + return -ENOMEM; + priv->hw = device; priv->wolenabled = priv->hw->pmt; /* PMT supported */ diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index bc3af78a869f..b26a57782939 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -69,10 +69,10 @@ #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 113 +#define TG3_MIN_NUM 112 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "August 2, 2010" +#define DRV_MODULE_RELDATE "July 11, 2010" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -221,9 +221,12 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5720)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752)}, @@ -879,7 +882,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val) unsigned int loops; int ret; - if ((tp->phy_flags & TG3_PHYFLG_IS_FET) && + if ((tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) && (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL)) return 0; @@ -1175,7 +1178,7 @@ static int tg3_mdio_init(struct tg3 *tp) case PHY_ID_BCMAC131: phydev->interface = PHY_INTERFACE_MODE_MII; phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE; - tp->phy_flags |= TG3_PHYFLG_IS_FET; + tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET; break; } @@ -1268,7 +1271,7 @@ static void tg3_ump_link_report(struct tg3 *tp) tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val); val = 0; - if (!(tp->phy_flags & TG3_PHYFLG_MII_SERDES)) { + if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) { if (!tg3_readphy(tp, MII_CTRL1000, ®)) val = reg << 16; if (!tg3_readphy(tp, MII_STAT1000, ®)) @@ -1376,7 +1379,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) if (autoneg == AUTONEG_ENABLE && (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) { - if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv); else flowctrl = mii_resolve_flowctrl_fdx(lcladv, rmtadv); @@ -1490,7 +1493,7 @@ static int tg3_phy_init(struct tg3 *tp) { struct phy_device *phydev; - if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) + if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) return 0; /* Bring the PHY back to a known state. */ @@ -1510,7 +1513,7 @@ static int tg3_phy_init(struct tg3 *tp) switch (phydev->interface) { case PHY_INTERFACE_MODE_GMII: case PHY_INTERFACE_MODE_RGMII: - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { phydev->supported &= (PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause); @@ -1527,7 +1530,7 @@ static int tg3_phy_init(struct tg3 *tp) return -EINVAL; } - tp->phy_flags |= TG3_PHYFLG_IS_CONNECTED; + tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED; phydev->advertising = phydev->supported; @@ -1538,13 +1541,13 @@ static void tg3_phy_start(struct tg3 *tp) { struct phy_device *phydev; - if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) return; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { - tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER; + if (tp->link_config.phy_is_low_power) { + tp->link_config.phy_is_low_power = 0; phydev->speed = tp->link_config.orig_speed; phydev->duplex = tp->link_config.orig_duplex; phydev->autoneg = tp->link_config.orig_autoneg; @@ -1558,7 +1561,7 @@ static void tg3_phy_start(struct tg3 *tp) static void tg3_phy_stop(struct tg3 *tp) { - if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) return; phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); @@ -1566,21 +1569,16 @@ static void tg3_phy_stop(struct tg3 *tp) static void tg3_phy_fini(struct tg3 *tp) { - if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) { phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); - tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED; + tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED; } } -static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) +static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) { - int err; - - err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg); - if (!err) - err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val); - - return err; + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val); } static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable) @@ -1610,10 +1608,10 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable) if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) && - (tp->phy_flags & TG3_PHYFLG_MII_SERDES))) + (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) return; - if (tp->phy_flags & TG3_PHYFLG_IS_FET) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) { tg3_phy_fet_toggle_apd(tp, enable); return; } @@ -1644,10 +1642,10 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable) u32 phy; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || - (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) + (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) return; - if (tp->phy_flags & TG3_PHYFLG_IS_FET) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) { u32 ephy; if (!tg3_readphy(tp, MII_TG3_FET_TEST, &ephy)) { @@ -1683,7 +1681,7 @@ static void tg3_phy_set_wirespeed(struct tg3 *tp) { u32 val; - if (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) + if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) return; if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) && @@ -1742,7 +1740,7 @@ static int tg3_wait_macro_done(struct tg3 *tp) while (limit--) { u32 tmp32; - if (!tg3_readphy(tp, MII_TG3_DSP_CONTROL, &tmp32)) { + if (!tg3_readphy(tp, 0x16, &tmp32)) { if ((tmp32 & 0x1000) == 0) break; } @@ -1768,13 +1766,13 @@ static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp) tg3_writephy(tp, MII_TG3_DSP_ADDRESS, (chan * 0x2000) | 0x0200); - tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0002); + tg3_writephy(tp, 0x16, 0x0002); for (i = 0; i < 6; i++) tg3_writephy(tp, MII_TG3_DSP_RW_PORT, test_pat[chan][i]); - tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0202); + tg3_writephy(tp, 0x16, 0x0202); if (tg3_wait_macro_done(tp)) { *resetp = 1; return -EBUSY; @@ -1782,13 +1780,13 @@ static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp) tg3_writephy(tp, MII_TG3_DSP_ADDRESS, (chan * 0x2000) | 0x0200); - tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0082); + tg3_writephy(tp, 0x16, 0x0082); if (tg3_wait_macro_done(tp)) { *resetp = 1; return -EBUSY; } - tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0802); + tg3_writephy(tp, 0x16, 0x0802); if (tg3_wait_macro_done(tp)) { *resetp = 1; return -EBUSY; @@ -1828,10 +1826,10 @@ static int tg3_phy_reset_chanpat(struct tg3 *tp) tg3_writephy(tp, MII_TG3_DSP_ADDRESS, (chan * 0x2000) | 0x0200); - tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0002); + tg3_writephy(tp, 0x16, 0x0002); for (i = 0; i < 6; i++) tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x000); - tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0202); + tg3_writephy(tp, 0x16, 0x0202); if (tg3_wait_macro_done(tp)) return -EBUSY; } @@ -1877,7 +1875,8 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); /* Block the PHY control access. */ - tg3_phydsp_write(tp, 0x8005, 0x0800); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0800); err = tg3_phy_write_and_check_testpat(tp, &do_phy_reset); if (!err) @@ -1888,10 +1887,11 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) if (err) return err; - tg3_phydsp_write(tp, 0x8005, 0x0000); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0000); tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); - tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000); + tg3_writephy(tp, 0x16, 0x0000); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { @@ -1984,37 +1984,42 @@ static int tg3_phy_reset(struct tg3 *tp) if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) && - (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) + (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) return 0; tg3_phy_apply_otp(tp); - if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) + if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD) tg3_phy_toggle_apd(tp, true); else tg3_phy_toggle_apd(tp, false); out: - if (tp->phy_flags & TG3_PHYFLG_ADC_BUG) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_ADC_BUG) { tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); - tg3_phydsp_write(tp, 0x201f, 0x2aaa); - tg3_phydsp_write(tp, 0x000a, 0x0323); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0323); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); } - if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) { - tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68); - tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68); + if (tp->tg3_flags2 & TG3_FLG2_PHY_5704_A0_BUG) { + tg3_writephy(tp, 0x1c, 0x8d68); + tg3_writephy(tp, 0x1c, 0x8d68); } - if (tp->phy_flags & TG3_PHYFLG_BER_BUG) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_BER_BUG) { tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); - tg3_phydsp_write(tp, 0x000a, 0x310b); - tg3_phydsp_write(tp, 0x201f, 0x9506); - tg3_phydsp_write(tp, 0x401f, 0x14e2); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x310b); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x9506); + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x401f); + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x14e2); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); - } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) { + } else if (tp->tg3_flags2 & TG3_FLG2_PHY_JITTER_BUG) { tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); - if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_ADJUST_TRIM) { tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b); tg3_writephy(tp, MII_TG3_TEST1, MII_TG3_TEST1_TRIM_EN | 0x4); @@ -2199,7 +2204,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) { u32 val; - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { u32 sg_dig_ctrl = tr32(SG_DIG_CTRL); u32 serdes_cfg = tr32(MAC_SERDES_CFG); @@ -2218,7 +2223,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ); udelay(40); return; - } else if (tp->phy_flags & TG3_PHYFLG_IS_FET) { + } else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) { u32 phytest; if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) { u32 phy; @@ -2255,7 +2260,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 && - (tp->phy_flags & TG3_PHYFLG_MII_SERDES))) + (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) return; if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX || @@ -2558,14 +2563,14 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { do_low_power = false; - if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) && - !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { + if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) && + !tp->link_config.phy_is_low_power) { struct phy_device *phydev; u32 phyid, advertising; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; - tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER; + tp->link_config.phy_is_low_power = 1; tp->link_config.orig_speed = phydev->speed; tp->link_config.orig_duplex = phydev->duplex; @@ -2604,14 +2609,14 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) } else { do_low_power = true; - if (!(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { - tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER; + if (tp->link_config.phy_is_low_power == 0) { + tp->link_config.phy_is_low_power = 1; tp->link_config.orig_speed = tp->link_config.speed; tp->link_config.orig_duplex = tp->link_config.duplex; tp->link_config.orig_autoneg = tp->link_config.autoneg; } - if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) { + if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) { tp->link_config.speed = SPEED_10; tp->link_config.duplex = DUPLEX_HALF; tp->link_config.autoneg = AUTONEG_ENABLE; @@ -2644,13 +2649,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) if (device_should_wake) { u32 mac_mode; - if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) { + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { if (do_low_power) { tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); udelay(40); } - if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) mac_mode = MAC_MODE_PORT_MODE_GMII; else mac_mode = MAC_MODE_PORT_MODE_MII; @@ -2818,7 +2823,7 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 break; default: - if (tp->phy_flags & TG3_PHYFLG_IS_FET) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) { *speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 : SPEED_10; *duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL : @@ -2836,7 +2841,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp) u32 new_adv; int i; - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { + if (tp->link_config.phy_is_low_power) { /* Entering low power mode. Disable gigabit and * 100baseT advertisements. */ @@ -2849,7 +2854,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp) tg3_writephy(tp, MII_ADVERTISE, new_adv); } else if (tp->link_config.speed == SPEED_INVALID) { - if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) tp->link_config.advertising &= ~(ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); @@ -2875,7 +2880,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp) new_adv |= MII_TG3_CTRL_ADV_1000_HALF; if (tp->link_config.advertising & ADVERTISED_1000baseT_Full) new_adv |= MII_TG3_CTRL_ADV_1000_FULL; - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY) && + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY) && (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)) new_adv |= (MII_TG3_CTRL_AS_MASTER | @@ -2977,11 +2982,20 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp) /* Set Extended packet length bit */ err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20); - err |= tg3_phydsp_write(tp, 0x0012, 0x1804); - err |= tg3_phydsp_write(tp, 0x0013, 0x1204); - err |= tg3_phydsp_write(tp, 0x8006, 0x0132); - err |= tg3_phydsp_write(tp, 0x8006, 0x0232); - err |= tg3_phydsp_write(tp, 0x201f, 0x0a20); + err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0012); + err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804); + + err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0013); + err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1204); + + err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8006); + err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0132); + + err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8006); + err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0232); + + err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f); + err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0a20); udelay(40); @@ -3006,7 +3020,7 @@ static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask) if ((adv_reg & all_mask) != all_mask) return 0; - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { u32 tg3_ctrl; all_mask = 0; @@ -3134,18 +3148,18 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) { /* 5701 {A0,B0} CRC bug workaround */ tg3_writephy(tp, 0x15, 0x0a75); - tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68); - tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68); - tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68); + tg3_writephy(tp, 0x1c, 0x8c68); + tg3_writephy(tp, 0x1c, 0x8d68); + tg3_writephy(tp, 0x1c, 0x8c68); } /* Clear pending interrupts... */ tg3_readphy(tp, MII_TG3_ISTAT, &dummy); tg3_readphy(tp, MII_TG3_ISTAT, &dummy); - if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) + if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG); - else if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) + else if (!(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)) tg3_writephy(tp, MII_TG3_IMASK, ~0); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || @@ -3161,7 +3175,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) current_speed = SPEED_INVALID; current_duplex = DUPLEX_INVALID; - if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) { + if (tp->tg3_flags2 & TG3_FLG2_CAPACITIVE_COUPLING) { u32 val; tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007); @@ -3237,7 +3251,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) } relink: - if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { + if (current_link_up == 0 || tp->link_config.phy_is_low_power) { u32 tmp; tg3_phy_copper_begin(tp); @@ -3255,7 +3269,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) tp->mac_mode |= MAC_MODE_PORT_MODE_MII; else tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; - } else if (tp->phy_flags & TG3_PHYFLG_IS_FET) + } else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) tp->mac_mode |= MAC_MODE_PORT_MODE_MII; else tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; @@ -3806,7 +3820,7 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) expected_sg_dig_ctrl |= SG_DIG_ASYM_PAUSE; if (sg_dig_ctrl != expected_sg_dig_ctrl) { - if ((tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT) && + if ((tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) && tp->serdes_counter && ((mac_status & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_RCVD_CFG)) == @@ -3823,7 +3837,7 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl); tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } else if (mac_status & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DET)) { sg_dig_status = tr32(SG_DIG_STATUS); @@ -3846,7 +3860,7 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) tg3_setup_flow_control(tp, local_adv, remote_adv); current_link_up = 1; tp->serdes_counter = 0; - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } else if (!(sg_dig_status & SG_DIG_AUTONEG_COMPLETE)) { if (tp->serdes_counter) tp->serdes_counter--; @@ -3873,8 +3887,8 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) !(mac_status & MAC_STATUS_RCVD_CFG)) { tg3_setup_flow_control(tp, 0, 0); current_link_up = 1; - tp->phy_flags |= - TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 |= + TG3_FLG2_PARALLEL_DETECT; tp->serdes_counter = SERDES_PARALLEL_DET_TIMEOUT; } else @@ -3883,7 +3897,7 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) } } else { tp->serdes_counter = SERDES_AN_TIMEOUT_5704S; - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } out: @@ -4100,7 +4114,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) err |= tg3_readphy(tp, MII_BMCR, &bmcr); if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset && - (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) { + (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) { /* do nothing, just check for link up at the end */ } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { u32 adv, new_adv; @@ -4125,7 +4139,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); tp->serdes_counter = SERDES_AN_TIMEOUT_5714S; - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; return err; } @@ -4170,7 +4184,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) else bmsr &= ~BMSR_LSTATUS; } - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } } @@ -4225,7 +4239,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) netif_carrier_on(tp->dev); else { netif_carrier_off(tp->dev); - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } tg3_link_report(tp); } @@ -4249,14 +4263,13 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp) u32 phy1, phy2; /* Select shadow register 0x1f */ - tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x7c00); - tg3_readphy(tp, MII_TG3_MISC_SHDW, &phy1); + tg3_writephy(tp, 0x1c, 0x7c00); + tg3_readphy(tp, 0x1c, &phy1); /* Select expansion interrupt status register */ - tg3_writephy(tp, MII_TG3_DSP_ADDRESS, - MII_TG3_DSP_EXP1_INT_STAT); - tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2); - tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2); + tg3_writephy(tp, 0x17, 0x0f01); + tg3_readphy(tp, 0x15, &phy2); + tg3_readphy(tp, 0x15, &phy2); if ((phy1 & 0x10) && !(phy2 & 0x20)) { /* We have signal detect and not receiving @@ -4267,18 +4280,17 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp) bmcr &= ~BMCR_ANENABLE; bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX; tg3_writephy(tp, MII_BMCR, bmcr); - tp->phy_flags |= TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 |= TG3_FLG2_PARALLEL_DETECT; } } } else if (netif_carrier_ok(tp->dev) && (tp->link_config.autoneg == AUTONEG_ENABLE) && - (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) { + (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) { u32 phy2; /* Select expansion interrupt status register */ - tg3_writephy(tp, MII_TG3_DSP_ADDRESS, - MII_TG3_DSP_EXP1_INT_STAT); - tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2); + tg3_writephy(tp, 0x17, 0x0f01); + tg3_readphy(tp, 0x15, &phy2); if (phy2 & 0x20) { u32 bmcr; @@ -4286,7 +4298,7 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp) tg3_readphy(tp, MII_BMCR, &bmcr); tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANENABLE); - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; } } @@ -4296,9 +4308,9 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) { int err; - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) err = tg3_setup_fiber_phy(tp, force_reset); - else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) + else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) err = tg3_setup_fiber_mii_phy(tp, force_reset); else err = tg3_setup_copper_phy(tp, force_reset); @@ -4377,8 +4389,7 @@ static void tg3_tx_recover(struct tg3 *tp) static inline u32 tg3_tx_avail(struct tg3_napi *tnapi) { - /* Tell compiler to fetch tx indices from memory. */ - barrier(); + smp_mb(); return tnapi->tx_pending - ((tnapi->tx_prod - tnapi->tx_cons) & (TG3_TX_RING_SIZE - 1)); } @@ -5662,13 +5673,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, tnapi->tx_prod = entry; if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) { netif_tx_stop_queue(txq); - - /* netif_tx_stop_queue() must be done before checking - * checking tx index in tg3_tx_avail() below, because in - * tg3_tx(), we update tx index before checking for - * netif_tx_queue_stopped(). - */ - smp_mb(); if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)) netif_tx_wake_queue(txq); } @@ -5714,13 +5718,6 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) /* Estimate the number of fragments in the worst case */ if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) { netif_stop_queue(tp->dev); - - /* netif_tx_stop_queue() must be done before checking - * checking tx index in tg3_tx_avail() below, because in - * tg3_tx(), we update tx index before checking for - * netif_tx_queue_stopped(). - */ - smp_mb(); if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est) return NETDEV_TX_BUSY; @@ -5956,13 +5953,6 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, tnapi->tx_prod = entry; if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) { netif_tx_stop_queue(txq); - - /* netif_tx_stop_queue() must be done before checking - * checking tx index in tg3_tx_avail() below, because in - * tg3_tx(), we update tx index before checking for - * netif_tx_queue_stopped(). - */ - smp_mb(); if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)) netif_tx_wake_queue(txq); } @@ -6939,13 +6929,9 @@ static int tg3_chip_reset(struct tg3 *tp) val = GRC_MISC_CFG_CORECLK_RESET; if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { - /* Force PCIe 1.0a mode */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && - tr32(TG3_PCIE_PHY_TSTCTL) == - (TG3_PCIE_PHY_TSTCTL_PCIE10 | TG3_PCIE_PHY_TSTCTL_PSCRAM)) - tw32(TG3_PCIE_PHY_TSTCTL, TG3_PCIE_PHY_TSTCTL_PSCRAM); - + if (tr32(0x7e2c) == 0x60) { + tw32(0x7e2c, 0x20); + } if (tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) { tw32(GRC_MISC_CFG, (1 << 29)); val |= (1 << 29); @@ -6958,11 +6944,8 @@ static int tg3_chip_reset(struct tg3 *tp) tr32(GRC_VCPU_EXT_CTRL) & ~GRC_VCPU_EXT_CTRL_HALT_CPU); } - /* Manage gphy power for all CPMU absent PCIe devices. */ - if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && - !(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)) + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) val |= GRC_MISC_CFG_KEEP_GPHY_POWER; - tw32(GRC_MISC_CFG, val); /* restore 5701 hardware bug workaround write method */ @@ -7019,7 +7002,8 @@ static int tg3_chip_reset(struct tg3 *tp) * Older PCIe devices only support the 128 byte * MPS setting. Enforce the restriction. */ - if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)) + if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)) val16 &= ~PCI_EXP_DEVCTL_PAYLOAD; pci_write_config_word(tp->pdev, tp->pcie_cap + PCI_EXP_DEVCTL, @@ -7066,10 +7050,10 @@ static int tg3_chip_reset(struct tg3 *tp) tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { tp->mac_mode = MAC_MODE_PORT_MODE_TBI; tw32_f(MAC_MODE, tp->mac_mode); - } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { + } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { tp->mac_mode = MAC_MODE_PORT_MODE_GMII; tw32_f(MAC_MODE, tp->mac_mode); } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { @@ -7092,7 +7076,9 @@ static int tg3_chip_reset(struct tg3 *tp) if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) { val = tr32(0x7c00); tw32(0x7c00, val | (1 << 25)); @@ -7765,7 +7751,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (err) return err; - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { val = tr32(TG3PCI_DMA_RW_CTRL) & ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT; if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) @@ -7928,7 +7916,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) BDINFO_FLAGS_DISABLED); } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) | (TG3_RX_STD_DMA_SZ << 2); else @@ -7945,7 +7935,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->rx_jumbo_pending : 0; tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx); - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { tw32(STD_REPLENISH_LWM, 32); tw32(JMB_REPLENISH_LWM, 16); } @@ -8073,8 +8065,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE); - if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { - tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; + if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { + tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; /* reset to prevent losing 1st rx packet intermittently */ tw32_f(MAC_RX_MODE, RX_MODE_RESET); udelay(10); @@ -8087,7 +8079,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && - !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && + !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) tp->mac_mode |= MAC_MODE_LINK_POLARITY; tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); @@ -8272,16 +8264,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(MAC_LED_CTRL, tp->led_ctrl); tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { tw32_f(MAC_RX_MODE, RX_MODE_RESET); udelay(10); } tw32_f(MAC_RX_MODE, tp->rx_mode); udelay(10); - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && - !(tp->phy_flags & TG3_PHYFLG_SERDES_PREEMPHASIS)) { + !(tp->tg3_flags2 & TG3_FLG2_SERDES_PREEMPHASIS)) { /* Set drive transmission level to 1.2V */ /* only if the signal pre-emphasis bit is not set */ val = tr32(MAC_SERDES_CFG); @@ -8303,12 +8295,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, val); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) { + (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { /* Use hardware link auto-negotiation */ tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG; } - if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && + if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) { u32 tmp; @@ -8320,8 +8312,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) { - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) { - tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER; + if (tp->link_config.phy_is_low_power) { + tp->link_config.phy_is_low_power = 0; tp->link_config.speed = tp->link_config.orig_speed; tp->link_config.duplex = tp->link_config.orig_duplex; tp->link_config.autoneg = tp->link_config.orig_autoneg; @@ -8331,15 +8323,15 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (err) return err; - if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && - !(tp->phy_flags & TG3_PHYFLG_IS_FET)) { + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && + !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)) { u32 tmp; /* Clear CRC stats. */ if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) { tg3_writephy(tp, MII_TG3_TEST1, tmp | MII_TG3_TEST1_CRC_EN); - tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &tmp); + tg3_readphy(tp, 0x14, &tmp); } } } @@ -8507,7 +8499,7 @@ static void tg3_timer(unsigned long __opaque) mac_stat = tr32(MAC_STATUS); phy_event = 0; - if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) { + if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) { if (mac_stat & MAC_STATUS_MI_INTERRUPT) phy_event = 1; } else if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED) @@ -8539,7 +8531,7 @@ static void tg3_timer(unsigned long __opaque) } tg3_setup_phy(tp, 0); } - } else if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) && + } else if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { tg3_serdes_parallel_detect(tp); } @@ -8635,7 +8627,9 @@ static int tg3_test_interrupt(struct tg3 *tp) * Turn off MSI one shot mode. Otherwise this test has no * observable way to know whether the interrupt was delivered. */ - if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); @@ -8678,7 +8672,9 @@ static int tg3_test_interrupt(struct tg3 *tp) if (intr_ok) { /* Reenable MSI one shot mode. */ - if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); @@ -8869,7 +8865,7 @@ static void tg3_ints_fini(struct tg3 *tp) else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) pci_disable_msi(tp->pdev); tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX; - tp->tg3_flags3 &= ~(TG3_FLG3_ENABLE_RSS | TG3_FLG3_ENABLE_TSS); + tp->tg3_flags3 &= ~TG3_FLG3_ENABLE_RSS; } static int tg3_open(struct net_device *dev) @@ -8973,8 +8969,11 @@ static int tg3_open(struct net_device *dev) goto err_out2; } - if (!(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && - (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765 && + (tp->tg3_flags2 & TG3_FLG2_USING_MSI) && + (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)) { u32 val = tr32(PCIE_TRANSACTION_CFG); tw32(PCIE_TRANSACTION_CFG, @@ -9069,7 +9068,7 @@ static u64 calc_crc_errors(struct tg3 *tp) { struct tg3_hw_stats *hw_stats = tp->hw_stats; - if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { u32 val; @@ -9078,7 +9077,7 @@ static u64 calc_crc_errors(struct tg3 *tp) if (!tg3_readphy(tp, MII_TG3_TEST1, &val)) { tg3_writephy(tp, MII_TG3_TEST1, val | MII_TG3_TEST1_CRC_EN); - tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &val); + tg3_readphy(tp, 0x14, &val); } else val = 0; spin_unlock_bh(&tp->lock); @@ -9368,7 +9367,7 @@ static void tg3_get_regs(struct net_device *dev, memset(p, 0, TG3_REGDUMP_LEN); - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if (tp->link_config.phy_is_low_power) return; tg3_full_lock(tp, 0); @@ -9447,7 +9446,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) return -EINVAL; - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if (tp->link_config.phy_is_low_power) return -EAGAIN; offset = eeprom->offset; @@ -9509,7 +9508,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *buf; __be32 start, end; - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if (tp->link_config.phy_is_low_power) return -EAGAIN; if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || @@ -9566,7 +9565,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { struct phy_device *phydev; - if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) return -EAGAIN; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; return phy_ethtool_gset(phydev, cmd); @@ -9574,11 +9573,11 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->supported = (SUPPORTED_Autoneg); - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) cmd->supported |= (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); - if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) { + if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) { cmd->supported |= (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_10baseT_Half | @@ -9609,7 +9608,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { struct phy_device *phydev; - if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) return -EAGAIN; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; return phy_ethtool_sset(phydev, cmd); @@ -9629,11 +9628,11 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ADVERTISED_Pause | ADVERTISED_Asym_Pause; - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) mask |= ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full; - if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) + if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) mask |= ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | ADVERTISED_10baseT_Half | @@ -9654,7 +9653,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->advertising &= mask; } else { - if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { if (cmd->speed != SPEED_1000) return -EINVAL; @@ -9790,11 +9789,11 @@ static int tg3_nway_reset(struct net_device *dev) if (!netif_running(dev)) return -EAGAIN; - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) return -EINVAL; if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { - if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) return -EAGAIN; r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]); } else { @@ -9805,7 +9804,7 @@ static int tg3_nway_reset(struct net_device *dev) tg3_readphy(tp, MII_BMCR, &bmcr); if (!tg3_readphy(tp, MII_BMCR, &bmcr) && ((bmcr & BMCR_ANENABLE) || - (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT))) { + (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) { tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); r = 0; @@ -9940,7 +9939,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam else tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; - if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) { u32 oldadv = phydev->advertising & (ADVERTISED_Pause | ADVERTISED_Asym_Pause); if (oldadv != newadv) { @@ -10269,7 +10268,7 @@ static int tg3_test_link(struct tg3 *tp) if (!netif_running(tp->dev)) return -ENODEV; - if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) max = TG3_SERDES_TIMEOUT_SEC; else max = TG3_COPPER_TIMEOUT_SEC; @@ -10631,7 +10630,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) MAC_MODE_PORT_INT_LPBACK; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) mac_mode |= MAC_MODE_LINK_POLARITY; - if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) mac_mode |= MAC_MODE_PORT_MODE_MII; else mac_mode |= MAC_MODE_PORT_MODE_GMII; @@ -10639,7 +10638,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) } else if (loopback_mode == TG3_PHY_LOOPBACK) { u32 val; - if (tp->phy_flags & TG3_PHYFLG_IS_FET) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) { tg3_phy_fet_toggle_apd(tp, false); val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100; } else @@ -10651,7 +10650,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) udelay(40); mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; - if (tp->phy_flags & TG3_PHYFLG_IS_FET) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) { tg3_writephy(tp, MII_TG3_FET_PTEST, MII_TG3_FET_PTEST_FRC_TX_LINK | MII_TG3_FET_PTEST_FRC_TX_LOCK); @@ -10663,7 +10662,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) mac_mode |= MAC_MODE_PORT_MODE_GMII; /* reset to prevent losing 1st rx packet intermittently */ - if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { tw32_f(MAC_RX_MODE, RX_MODE_RESET); udelay(10); tw32_f(MAC_RX_MODE, tp->rx_mode); @@ -10794,7 +10793,7 @@ static int tg3_test_loopback(struct tg3 *tp) return TG3_LOOPBACK_FAILED; /* Turn off gphy autopowerdown. */ - if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) + if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD) tg3_phy_toggle_apd(tp, false); if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) { @@ -10831,14 +10830,14 @@ static int tg3_test_loopback(struct tg3 *tp) tw32(TG3_CPMU_MUTEX_GNT, CPMU_MUTEX_GNT_DRIVER); } - if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) { if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK)) err |= TG3_PHY_LOOPBACK_FAILED; } /* Re-enable gphy autopowerdown. */ - if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) + if (tp->tg3_flags3 & TG3_FLG3_PHY_ENABLE_APD) tg3_phy_toggle_apd(tp, true); return err; @@ -10849,7 +10848,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, { struct tg3 *tp = netdev_priv(dev); - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if (tp->link_config.phy_is_low_power) tg3_set_power_state(tp, PCI_D0); memset(data, 0, sizeof(u64) * TG3_NUM_TEST); @@ -10881,7 +10880,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, if (!err) tg3_nvram_unlock(tp); - if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) tg3_phy_reset(tp); if (tg3_test_registers(tp) != 0) { @@ -10917,7 +10916,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, if (irq_sync && !err2) tg3_phy_start(tp); } - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if (tp->link_config.phy_is_low_power) tg3_set_power_state(tp, PCI_D3hot); } @@ -10930,7 +10929,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { struct phy_device *phydev; - if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED)) + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) return -EAGAIN; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; return phy_mii_ioctl(phydev, ifr, cmd); @@ -10944,10 +10943,10 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: { u32 mii_regval; - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) break; /* We have no PHY */ - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if (tp->link_config.phy_is_low_power) return -EAGAIN; spin_lock_bh(&tp->lock); @@ -10960,10 +10959,10 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } case SIOCSMIIREG: - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) break; /* We have no PHY */ - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if (tp->link_config.phy_is_low_power) return -EAGAIN; spin_lock_bh(&tp->lock); @@ -12091,9 +12090,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->phy_id = eeprom_phy_id; if (eeprom_phy_serdes) { if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) - tp->phy_flags |= TG3_PHYFLG_PHY_SERDES; + tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; else - tp->phy_flags |= TG3_PHYFLG_MII_SERDES; + tp->tg3_flags2 |= TG3_FLG2_MII_SERDES; } if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) @@ -12177,7 +12176,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)) tp->tg3_flags3 |= TG3_FLG3_ENABLE_APE; - if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES && + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES && !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)) tp->tg3_flags &= ~TG3_FLAG_WOL_CAP; @@ -12186,21 +12185,19 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; if (cfg2 & (1 << 17)) - tp->phy_flags |= TG3_PHYFLG_CAPACITIVE_COUPLING; + tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING; /* serdes signal pre-emphasis in register 0x590 set by */ /* bootcode if bit 18 is set */ if (cfg2 & (1 << 18)) - tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS; + tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) && (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN)) - tp->phy_flags |= TG3_PHYFLG_ENABLE_APD; + tp->tg3_flags3 |= TG3_FLG3_PHY_ENABLE_APD; - if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { u32 cfg3; tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3); @@ -12305,9 +12302,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) if (!err && TG3_KNOWN_PHY_ID(hw_phy_id_masked)) { tp->phy_id = hw_phy_id; if (hw_phy_id_masked == TG3_PHY_ID_BCM8002) - tp->phy_flags |= TG3_PHYFLG_PHY_SERDES; + tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; else - tp->phy_flags &= ~TG3_PHYFLG_PHY_SERDES; + tp->tg3_flags2 &= ~TG3_FLG2_PHY_SERDES; } else { if (tp->phy_id != TG3_PHY_ID_INVALID) { /* Do nothing, phy ID already set up in @@ -12326,11 +12323,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) tp->phy_id = p->phy_id; if (!tp->phy_id || tp->phy_id == TG3_PHY_ID_BCM8002) - tp->phy_flags |= TG3_PHYFLG_PHY_SERDES; + tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; } } - if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && + if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { u32 bmsr, adv_reg, tg3_ctrl, mask; @@ -12348,7 +12345,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); tg3_ctrl = 0; - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF | MII_TG3_CTRL_ADV_1000_FULL); if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || @@ -12363,7 +12360,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) if (!tg3_copper_is_advertising_all(tp, mask)) { tg3_writephy(tp, MII_ADVERTISE, adv_reg); - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl); tg3_writephy(tp, MII_BMCR, @@ -12372,7 +12369,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) tg3_phy_set_wirespeed(tp); tg3_writephy(tp, MII_ADVERTISE, adv_reg); - if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl); } @@ -12385,13 +12382,13 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) err = tg3_init_5401phy_dsp(tp); } - if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) tp->link_config.advertising = (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | ADVERTISED_FIBRE); - if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) tp->link_config.advertising &= ~(ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); @@ -12720,7 +12717,6 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp) { int vlen; u32 apedata; - char *fwtype; if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) || !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) @@ -12736,15 +12732,9 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp) apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION); - if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) - fwtype = "NCSI"; - else - fwtype = "DASH"; - vlen = strlen(tp->fw_ver); - snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " %s v%d.%d.%d.%d", - fwtype, + snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " DASH v%d.%d.%d.%d", (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT, (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT, (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT, @@ -12998,11 +12988,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) tp->pdev_peer = tg3_find_peer(tp); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) - tp->tg3_flags3 |= TG3_FLG3_5717_PLUS; - /* Intentionally exclude ASIC_REV_5906 */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || @@ -13010,7 +12995,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || - (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tp->tg3_flags3 |= TG3_FLG3_5755_PLUS; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || @@ -13040,7 +13027,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } /* Determine TSO capabilities */ - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3; else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) @@ -13076,7 +13065,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX; tp->irq_max = TG3_IRQ_MAX_VECS; } @@ -13091,7 +13082,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG; } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || @@ -13292,7 +13285,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || - (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT; /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). @@ -13350,39 +13345,41 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) - tp->phy_flags |= TG3_PHYFLG_IS_FET; + tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET; /* A few boards don't want Ethernet@WireSpeed phy feature */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) || ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) && (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) || - (tp->phy_flags & TG3_PHYFLG_IS_FET) || - (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) - tp->phy_flags |= TG3_PHYFLG_NO_ETH_WIRE_SPEED; + (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) || + (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) + tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED; if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5703_AX || GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_AX) - tp->phy_flags |= TG3_PHYFLG_ADC_BUG; + tp->tg3_flags2 |= TG3_FLG2_PHY_ADC_BUG; if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) - tp->phy_flags |= TG3_PHYFLG_5704_A0_BUG; + tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG; if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && - !(tp->phy_flags & TG3_PHYFLG_IS_FET) && + !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) { if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 && tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722) - tp->phy_flags |= TG3_PHYFLG_JITTER_BUG; + tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M) - tp->phy_flags |= TG3_PHYFLG_ADJUST_TRIM; + tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM; } else - tp->phy_flags |= TG3_PHYFLG_BER_BUG; + tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && @@ -13495,8 +13492,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795 || - (tp->phy_flags & TG3_PHYFLG_IS_FET)) - tp->phy_flags |= TG3_PHYFLG_10_100_ONLY; + (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)) + tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); if (err) { @@ -13508,13 +13505,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tg3_read_vpd(tp); tg3_read_fw_ver(tp); - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { - tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT; + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { + tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT; } else { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) - tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT; + tp->tg3_flags |= TG3_FLAG_USE_MI_INTERRUPT; else - tp->phy_flags &= ~TG3_PHYFLG_USE_MI_INTERRUPT; + tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT; } /* 5700 {AX,BX} chips have a broken status block link @@ -13532,13 +13529,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) */ if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && - !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) { - tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT; - tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG; + !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { + tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT | + TG3_FLAG_USE_LINKCHG_REG); } /* For all SERDES we poll the MAC status register. */ - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) tp->tg3_flags |= TG3_FLAG_POLL_SERDES; else tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; @@ -13708,7 +13705,9 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val) #endif #endif - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT; goto out; } @@ -13919,7 +13918,9 @@ static int __devinit tg3_test_dma(struct tg3 *tp) tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl); - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) goto out; if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { @@ -14109,6 +14110,7 @@ static void __devinit tg3_init_link_config(struct tg3 *tp) tp->link_config.autoneg = AUTONEG_ENABLE; tp->link_config.active_speed = SPEED_INVALID; tp->link_config.active_duplex = DUPLEX_INVALID; + tp->link_config.phy_is_low_power = 0; tp->link_config.orig_speed = SPEED_INVALID; tp->link_config.orig_duplex = DUPLEX_INVALID; tp->link_config.orig_autoneg = AUTONEG_INVALID; @@ -14116,7 +14118,9 @@ static void __devinit tg3_init_link_config(struct tg3 *tp) static void __devinit tg3_init_bufmgr_config(struct tg3 *tp) { - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { tp->bufmgr_config.mbuf_read_dma_low_water = DEFAULT_MB_RDMA_LOW_WATER_5705; tp->bufmgr_config.mbuf_mac_rx_low_water = @@ -14641,31 +14645,24 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tg3_bus_string(tp, str), dev->dev_addr); - if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) { + if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) { struct phy_device *phydev; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", phydev->drv->name, dev_name(&phydev->dev)); - } else { - char *ethtype; - - if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) - ethtype = "10/100Base-TX"; - else if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) - ethtype = "1000Base-SX"; - else - ethtype = "10/100/1000Base-T"; - + } else netdev_info(dev, "attached PHY is %s (%s Ethernet) " - "(WireSpeed[%d])\n", tg3_phy_string(tp), ethtype, - (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0); - } + "(WireSpeed[%d])\n", tg3_phy_string(tp), + ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" : + ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" : + "10/100/1000Base-T")), + (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0); netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n", (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, - (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) != 0, + (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); netdev_info(dev, "dma_rwctrl[%08x] dma_mask[%d-bit]\n", diff --git a/trunk/drivers/net/tg3.h b/trunk/drivers/net/tg3.h index 4937bd190964..0432399ca741 100644 --- a/trunk/drivers/net/tg3.h +++ b/trunk/drivers/net/tg3.h @@ -1844,10 +1844,6 @@ #define TG3_PCIE_LNKCTL_L1_PLL_PD_DIS 0x00000080 /* 0x7d58 --> 0x7e70 unused */ -#define TG3_PCIE_PHY_TSTCTL 0x00007e2c -#define TG3_PCIE_PHY_TSTCTL_PCIE10 0x00000040 -#define TG3_PCIE_PHY_TSTCTL_PSCRAM 0x00000020 - #define TG3_PCIE_EIDLE_DELAY 0x00007e70 #define TG3_PCIE_EIDLE_DELAY_MASK 0x0000001f #define TG3_PCIE_EIDLE_DELAY_13_CLKS 0x0000000c @@ -2057,9 +2053,8 @@ #define MII_TG3_EXT_STAT 0x11 /* Extended status register */ #define MII_TG3_EXT_STAT_LPASS 0x0100 -#define MII_TG3_RXR_COUNTERS 0x14 /* Local/Remote Receiver Counts */ #define MII_TG3_DSP_RW_PORT 0x15 /* DSP coefficient read/write port */ -#define MII_TG3_DSP_CONTROL 0x16 /* DSP control register */ + #define MII_TG3_DSP_ADDRESS 0x17 /* DSP address register */ #define MII_TG3_DSP_TAP1 0x0001 @@ -2067,7 +2062,6 @@ #define MII_TG3_DSP_AADJ1CH0 0x001f #define MII_TG3_DSP_AADJ1CH3 0x601f #define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002 -#define MII_TG3_DSP_EXP1_INT_STAT 0x0f01 #define MII_TG3_DSP_EXP8 0x0f08 #define MII_TG3_DSP_EXP8_REJ2MHz 0x0001 #define MII_TG3_DSP_EXP8_AEDW 0x0200 @@ -2163,8 +2157,6 @@ /* APE shared memory. Accessible through BAR1 */ #define TG3_APE_FW_STATUS 0x400c #define APE_FW_STATUS_READY 0x00000100 -#define TG3_APE_FW_FEATURES 0x4010 -#define TG3_APE_FW_FEATURE_NCSI 0x00000002 #define TG3_APE_FW_VERSION 0x4018 #define APE_FW_VERSION_MAJMSK 0xff000000 #define APE_FW_VERSION_MAJSFT 24 @@ -2534,6 +2526,7 @@ struct tg3_link_config { /* When we go in and out of low power mode we need * to swap with this state. */ + int phy_is_low_power; u16 orig_speed; u8 orig_duplex; u8 orig_autoneg; @@ -2774,6 +2767,7 @@ struct tg3 { #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 #define TG3_FLAG_RX_CHECKSUMS 0x00000004 #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 +#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_ENABLE_ASF 0x00000020 #define TG3_FLAG_ASPM_WORKAROUND 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 @@ -2795,6 +2789,7 @@ struct tg3 { #define TG3_FLAG_TX_RECOVERY_PENDING 0x00200000 #define TG3_FLAG_WOL_CAP 0x00400000 #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 +#define TG3_FLAG_10_100_ONLY 0x01000000 #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 #define TG3_FLAG_CPMU_PRESENT 0x04000000 #define TG3_FLAG_40BIT_DMA_BUG 0x08000000 @@ -2805,15 +2800,22 @@ struct tg3 { u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 #define TG3_FLG2_TSO_BUG 0x00000002 +#define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 #define TG3_FLG2_TSO_CAPABLE 0x00000020 +#define TG3_FLG2_PHY_ADC_BUG 0x00000040 +#define TG3_FLG2_PHY_5704_A0_BUG 0x00000080 +#define TG3_FLG2_PHY_BER_BUG 0x00000100 #define TG3_FLG2_PCI_EXPRESS 0x00000200 #define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400 #define TG3_FLG2_HW_AUTONEG 0x00000800 #define TG3_FLG2_IS_NIC 0x00001000 +#define TG3_FLG2_PHY_SERDES 0x00002000 +#define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 #define TG3_FLG2_FLASH 0x00008000 #define TG3_FLG2_HW_TSO_1 0x00010000 +#define TG3_FLG2_SERDES_PREEMPHASIS 0x00020000 #define TG3_FLG2_5705_PLUS 0x00040000 #define TG3_FLG2_5750_PLUS 0x00080000 #define TG3_FLG2_HW_TSO_3 0x00100000 @@ -2821,6 +2823,10 @@ struct tg3 { #define TG3_FLG2_USING_MSIX 0x00400000 #define TG3_FLG2_USING_MSI_OR_MSIX (TG3_FLG2_USING_MSI | \ TG3_FLG2_USING_MSIX) +#define TG3_FLG2_MII_SERDES 0x00800000 +#define TG3_FLG2_ANY_SERDES (TG3_FLG2_PHY_SERDES | \ + TG3_FLG2_MII_SERDES) +#define TG3_FLG2_PARALLEL_DETECT 0x01000000 #define TG3_FLG2_ICH_WORKAROUND 0x02000000 #define TG3_FLG2_5780_CLASS 0x04000000 #define TG3_FLG2_HW_TSO_2 0x08000000 @@ -2828,7 +2834,9 @@ struct tg3 { TG3_FLG2_HW_TSO_2 | \ TG3_FLG2_HW_TSO_3) #define TG3_FLG2_1SHOT_MSI 0x10000000 +#define TG3_FLG2_PHY_JITTER_BUG 0x20000000 #define TG3_FLG2_NO_FWARE_REPORTED 0x40000000 +#define TG3_FLG2_PHY_ADJUST_TRIM 0x80000000 u32 tg3_flags3; #define TG3_FLG3_NO_NVRAM_ADDR_TRANS 0x00000001 #define TG3_FLG3_ENABLE_APE 0x00000002 @@ -2836,12 +2844,15 @@ struct tg3 { #define TG3_FLG3_5701_DMA_BUG 0x00000008 #define TG3_FLG3_USE_PHYLIB 0x00000010 #define TG3_FLG3_MDIOBUS_INITED 0x00000020 +#define TG3_FLG3_PHY_CONNECTED 0x00000080 #define TG3_FLG3_RGMII_INBAND_DISABLE 0x00000100 #define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200 #define TG3_FLG3_RGMII_EXT_IBND_TX_EN 0x00000400 #define TG3_FLG3_CLKREQ_BUG 0x00000800 +#define TG3_FLG3_PHY_ENABLE_APD 0x00001000 #define TG3_FLG3_5755_PLUS 0x00002000 #define TG3_FLG3_NO_NVRAM 0x00004000 +#define TG3_FLG3_PHY_IS_FET 0x00010000 #define TG3_FLG3_ENABLE_RSS 0x00020000 #define TG3_FLG3_ENABLE_TSS 0x00040000 #define TG3_FLG3_4G_DMA_BNDRY_BUG 0x00080000 @@ -2849,7 +2860,6 @@ struct tg3 { #define TG3_FLG3_SHORT_DMA_BUG 0x00200000 #define TG3_FLG3_USE_JUMBO_BDFLAG 0x00400000 #define TG3_FLG3_L1PLLPD_EN 0x00800000 -#define TG3_FLG3_5717_PLUS 0x01000000 struct timer_list timer; u16 timer_counter; @@ -2946,27 +2956,6 @@ struct tg3 { (X) == TG3_PHY_ID_BCM57765 || (X) == TG3_PHY_ID_BCM5719C || \ (X) == TG3_PHY_ID_BCM8002) - u32 phy_flags; -#define TG3_PHYFLG_IS_LOW_POWER 0x00000001 -#define TG3_PHYFLG_IS_CONNECTED 0x00000002 -#define TG3_PHYFLG_USE_MI_INTERRUPT 0x00000004 -#define TG3_PHYFLG_PHY_SERDES 0x00000010 -#define TG3_PHYFLG_MII_SERDES 0x00000020 -#define TG3_PHYFLG_ANY_SERDES (TG3_PHYFLG_PHY_SERDES | \ - TG3_PHYFLG_MII_SERDES) -#define TG3_PHYFLG_IS_FET 0x00000040 -#define TG3_PHYFLG_10_100_ONLY 0x00000080 -#define TG3_PHYFLG_ENABLE_APD 0x00000100 -#define TG3_PHYFLG_CAPACITIVE_COUPLING 0x00000200 -#define TG3_PHYFLG_NO_ETH_WIRE_SPEED 0x00000400 -#define TG3_PHYFLG_JITTER_BUG 0x00000800 -#define TG3_PHYFLG_ADJUST_TRIM 0x00001000 -#define TG3_PHYFLG_ADC_BUG 0x00002000 -#define TG3_PHYFLG_5704_A0_BUG 0x00004000 -#define TG3_PHYFLG_BER_BUG 0x00008000 -#define TG3_PHYFLG_SERDES_PREEMPHASIS 0x00010000 -#define TG3_PHYFLG_PARALLEL_DETECT 0x00020000 - u32 led_ctrl; u32 phy_otp; diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 55f3a3e667a9..6ad6fe706312 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -149,7 +149,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file) tfile->tun = tun; tun->tfile = tfile; tun->socket.file = file; - netif_carrier_on(tun->dev); dev_hold(tun->dev); sock_hold(tun->socket.sk); atomic_inc(&tfile->count); @@ -163,7 +162,6 @@ static void __tun_detach(struct tun_struct *tun) { /* Detach from net device */ netif_tx_lock_bh(tun->dev); - netif_carrier_off(tun->dev); tun->tfile = NULL; tun->socket.file = NULL; netif_tx_unlock_bh(tun->dev); @@ -738,18 +736,8 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; else if (sinfo->gso_type & SKB_GSO_UDP) gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; - else { - printk(KERN_ERR "tun: unexpected GSO type: " - "0x%x, gso_size %d, hdr_len %d\n", - sinfo->gso_type, gso.gso_size, - gso.hdr_len); - print_hex_dump(KERN_ERR, "tun: ", - DUMP_PREFIX_NONE, - 16, 1, skb->head, - min((int)gso.hdr_len, 64), true); - WARN_ON_ONCE(1); - return -EINVAL; - } + else + BUG(); if (sinfo->gso_type & SKB_GSO_TCP_ECN) gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN; } else @@ -1576,6 +1564,12 @@ static void tun_set_msglevel(struct net_device *dev, u32 value) #endif } +static u32 tun_get_link(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + return !!tun->tfile; +} + static u32 tun_get_rx_csum(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); @@ -1597,7 +1591,7 @@ static const struct ethtool_ops tun_ethtool_ops = { .get_drvinfo = tun_get_drvinfo, .get_msglevel = tun_get_msglevel, .set_msglevel = tun_set_msglevel, - .get_link = ethtool_op_get_link, + .get_link = tun_get_link, .get_rx_csum = tun_get_rx_csum, .set_rx_csum = tun_set_rx_csum }; diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index 8d532f9b50d0..e17dd7430915 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -594,7 +594,7 @@ static void dump_regs(struct ucc_geth_private *ugeth) { int i; - ugeth_info("UCC%d Geth registers:", ugeth->ug_info->uf_info.ucc_num + 1); + ugeth_info("UCC%d Geth registers:", ugeth->ug_info->uf_info.ucc_num); ugeth_info("Base address: 0x%08x", (u32) ugeth->ug_regs); ugeth_info("maccfg1 : addr - 0x%08x, val - 0x%08x", diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index 3b03794ac3f5..7eab4071ea26 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -44,7 +44,6 @@ #include #include #include -#include #define DRIVER_VERSION "22-Aug-2005" @@ -159,6 +158,16 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) } EXPORT_SYMBOL_GPL(usbnet_get_endpoints); +static u8 nibble(unsigned char c) +{ + if (likely(isdigit(c))) + return c - '0'; + c = toupper(c); + if (likely(isxdigit(c))) + return 10 + c - 'A'; + return 0; +} + int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress) { int tmp, i; @@ -174,7 +183,7 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress) } for (i = tmp = 0; i < 6; i++, tmp += 2) dev->net->dev_addr [i] = - (hex_to_bin(buf[tmp]) << 4) + hex_to_bin(buf[tmp + 1]); + (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]); return 0; } EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr); @@ -615,7 +624,7 @@ static void usbnet_terminate_urbs(struct usbnet *dev) while (!skb_queue_empty(&dev->rxq) && !skb_queue_empty(&dev->txq) && !skb_queue_empty(&dev->done)) { - schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS)); + schedule_timeout(UNLINK_TIMEOUT_MS); set_current_state(TASK_UNINTERRUPTIBLE); netif_dbg(dev, ifdown, dev->net, "waited for %d urb completions\n", temp); diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c index abe0ff53daf3..9d64186050f3 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c @@ -664,13 +664,8 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, while (len) { u32 buf_size; - if (len < VMXNET3_MAX_TX_BUF_SIZE) { - buf_size = len; - dw2 |= len; - } else { - buf_size = VMXNET3_MAX_TX_BUF_SIZE; - /* spec says that for TxDesc.len, 0 == 2^14 */ - } + buf_size = len > VMXNET3_MAX_TX_BUF_SIZE ? + VMXNET3_MAX_TX_BUF_SIZE : len; tbi = tq->buf_info + tq->tx_ring.next2fill; tbi->map_type = VMXNET3_MAP_SINGLE; @@ -678,13 +673,13 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, skb->data + buf_offset, buf_size, PCI_DMA_TODEVICE); - tbi->len = buf_size; + tbi->len = buf_size; /* this automatically convert 2^14 to 0 */ gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); - gdesc->dword[2] = cpu_to_le32(dw2); + gdesc->dword[2] = cpu_to_le32(dw2 | buf_size); gdesc->dword[3] = 0; dev_dbg(&adapter->netdev->dev, diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_int.h b/trunk/drivers/net/vmxnet3/vmxnet3_int.h index 2121c735cabd..762a6a7763fe 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_int.h +++ b/trunk/drivers/net/vmxnet3/vmxnet3_int.h @@ -68,10 +68,10 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.0.14.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.0.13.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01000E00 +#define VMXNET3_DRIVER_VERSION_NUM 0x01000B00 /* diff --git a/trunk/drivers/net/vxge/vxge-main.c b/trunk/drivers/net/vxge/vxge-main.c index c7c5605b3728..94d87e80abcd 100644 --- a/trunk/drivers/net/vxge/vxge-main.c +++ b/trunk/drivers/net/vxge/vxge-main.c @@ -41,8 +41,6 @@ * ******************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -146,7 +144,7 @@ vxge_callback_link_up(struct __vxge_hw_device *hldev) vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); - netdev_notice(vdev->ndev, "Link Up\n"); + printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name); vdev->stats.link_up++; netif_carrier_on(vdev->ndev); @@ -170,7 +168,7 @@ vxge_callback_link_down(struct __vxge_hw_device *hldev) vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); - netdev_notice(vdev->ndev, "Link Down\n"); + printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name); vdev->stats.link_down++; netif_carrier_off(vdev->ndev); @@ -2681,7 +2679,7 @@ vxge_open(struct net_device *dev) if (vxge_hw_device_link_state_get(vdev->devh) == VXGE_HW_LINK_UP) { netif_carrier_on(vdev->ndev); - netdev_notice(vdev->ndev, "Link Up\n"); + printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name); vdev->stats.link_up++; } @@ -2819,7 +2817,7 @@ int do_vxge_close(struct net_device *dev, int do_io) } netif_carrier_off(vdev->ndev); - netdev_notice(vdev->ndev, "Link Down\n"); + printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name); netif_tx_stop_all_queues(vdev->ndev); /* Note that at this point xmit() is stopped by upper layer */ @@ -3846,7 +3844,9 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) struct vxgedev *vdev = netdev_priv(netdev); if (pci_enable_device(pdev)) { - netdev_err(netdev, "Cannot re-enable device after reset\n"); + printk(KERN_ERR "%s: " + "Cannot re-enable device after reset\n", + VXGE_DRIVER_NAME); return PCI_ERS_RESULT_DISCONNECT; } @@ -3871,8 +3871,9 @@ static void vxge_io_resume(struct pci_dev *pdev) if (netif_running(netdev)) { if (vxge_open(netdev)) { - netdev_err(netdev, - "Can't bring device back up after reset\n"); + printk(KERN_ERR "%s: " + "Can't bring device back up after reset\n", + VXGE_DRIVER_NAME); return; } } @@ -4429,9 +4430,13 @@ static int __init vxge_starter(void) { int ret = 0; + char version[32]; + snprintf(version, 32, "%s", DRV_VERSION); - pr_info("Copyright(c) 2002-2010 Exar Corp.\n"); - pr_info("Driver version: %s\n", DRV_VERSION); + printk(KERN_INFO "%s: Copyright(c) 2002-2010 Exar Corp.\n", + VXGE_DRIVER_NAME); + printk(KERN_INFO "%s: Driver version: %s\n", + VXGE_DRIVER_NAME, version); verify_bandwidth(); diff --git a/trunk/drivers/net/wimax/i2400m/i2400m-usb.h b/trunk/drivers/net/wimax/i2400m/i2400m-usb.h index eb80243e22df..2d7c96d7e865 100644 --- a/trunk/drivers/net/wimax/i2400m/i2400m-usb.h +++ b/trunk/drivers/net/wimax/i2400m/i2400m-usb.h @@ -152,7 +152,6 @@ enum { /* Device IDs */ USB_DEVICE_ID_I6050 = 0x0186, USB_DEVICE_ID_I6050_2 = 0x0188, - USB_DEVICE_ID_I6250 = 0x0187, }; diff --git a/trunk/drivers/net/wimax/i2400m/usb.c b/trunk/drivers/net/wimax/i2400m/usb.c index d3365ac85dde..0d5081d77dc0 100644 --- a/trunk/drivers/net/wimax/i2400m/usb.c +++ b/trunk/drivers/net/wimax/i2400m/usb.c @@ -491,7 +491,6 @@ int i2400mu_probe(struct usb_interface *iface, switch (id->idProduct) { case USB_DEVICE_ID_I6050: case USB_DEVICE_ID_I6050_2: - case USB_DEVICE_ID_I6250: i2400mu->i6050 = 1; break; default: @@ -740,7 +739,6 @@ static struct usb_device_id i2400mu_id_table[] = { { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) }, { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) }, - { USB_DEVICE(0x8086, USB_DEVICE_ID_I6250) }, { USB_DEVICE(0x8086, 0x0181) }, { USB_DEVICE(0x8086, 0x1403) }, { USB_DEVICE(0x8086, 0x1405) }, diff --git a/trunk/drivers/net/wireless/adm8211.c b/trunk/drivers/net/wireless/adm8211.c index a105087af963..bde2fa8bb639 100644 --- a/trunk/drivers/net/wireless/adm8211.c +++ b/trunk/drivers/net/wireless/adm8211.c @@ -373,8 +373,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) pktlen = status & RDES0_STATUS_FL; if (pktlen > RX_PKT_SIZE) { if (net_ratelimit()) - wiphy_debug(dev->wiphy, "frame too long (%d)\n", - pktlen); + printk(KERN_DEBUG "%s: frame too long (%d)\n", + wiphy_name(dev->wiphy), pktlen); pktlen = RX_PKT_SIZE; } @@ -454,10 +454,10 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) static irqreturn_t adm8211_interrupt(int irq, void *dev_id) { -#define ADM8211_INT(x) \ -do { \ - if (unlikely(stsr & ADM8211_STSR_ ## x)) \ - wiphy_debug(dev->wiphy, "%s\n", #x); \ +#define ADM8211_INT(x) \ +do { \ + if (unlikely(stsr & ADM8211_STSR_ ## x)) \ + printk(KERN_DEBUG "%s: " #x "\n", wiphy_name(dev->wiphy)); \ } while (0) struct ieee80211_hw *dev = dev_id; @@ -570,9 +570,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data) } if (timeout == 0) { - wiphy_debug(dev->wiphy, - "adm8211_write_bbp(%d,%d) failed prewrite (reg=0x%08x)\n", - addr, data, reg); + printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed" + " prewrite (reg=0x%08x)\n", + wiphy_name(dev->wiphy), addr, data, reg); return -ETIMEDOUT; } @@ -605,9 +605,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data) if (timeout == 0) { ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) & ~ADM8211_BBPCTL_WR); - wiphy_debug(dev->wiphy, - "adm8211_write_bbp(%d,%d) failed postwrite (reg=0x%08x)\n", - addr, data, reg); + printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed" + " postwrite (reg=0x%08x)\n", + wiphy_name(dev->wiphy), addr, data, reg); return -ETIMEDOUT; } @@ -675,8 +675,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) break; default: - wiphy_debug(dev->wiphy, "unsupported transceiver type %d\n", - priv->transceiver_type); + printk(KERN_DEBUG "%s: unsupported transceiver type %d\n", + wiphy_name(dev->wiphy), priv->transceiver_type); break; } @@ -732,8 +732,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) /* Nothing to do for ADMtek BBP */ } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK) - wiphy_debug(dev->wiphy, "unsupported bbp type %d\n", - priv->bbp_type); + printk(KERN_DEBUG "%s: unsupported BBP type %d\n", + wiphy_name(dev->wiphy), priv->bbp_type); ADM8211_RESTORE(); @@ -1027,12 +1027,13 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev) break; default: - wiphy_debug(dev->wiphy, "unsupported transceiver %d\n", - priv->transceiver_type); + printk(KERN_DEBUG "%s: unsupported transceiver %d\n", + wiphy_name(dev->wiphy), priv->transceiver_type); break; } } else - wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type); + printk(KERN_DEBUG "%s: unsupported BBP %d\n", + wiphy_name(dev->wiphy), priv->bbp_type); ADM8211_CSR_WRITE(SYNRF, 0); @@ -1508,13 +1509,15 @@ static int adm8211_start(struct ieee80211_hw *dev) /* Power up MAC and RF chips */ retval = adm8211_hw_reset(dev); if (retval) { - wiphy_err(dev->wiphy, "hardware reset failed\n"); + printk(KERN_ERR "%s: hardware reset failed\n", + wiphy_name(dev->wiphy)); goto fail; } retval = adm8211_init_rings(dev); if (retval) { - wiphy_err(dev->wiphy, "failed to initialize rings\n"); + printk(KERN_ERR "%s: failed to initialize rings\n", + wiphy_name(dev->wiphy)); goto fail; } @@ -1525,7 +1528,8 @@ static int adm8211_start(struct ieee80211_hw *dev) retval = request_irq(priv->pdev->irq, adm8211_interrupt, IRQF_SHARED, "adm8211", dev); if (retval) { - wiphy_err(dev->wiphy, "failed to register irq handler\n"); + printk(KERN_ERR "%s: failed to register IRQ handler\n", + wiphy_name(dev->wiphy)); goto fail; } @@ -1902,8 +1906,9 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, goto err_free_eeprom; } - wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n", - dev->wiphy->perm_addr, pdev->revision); + printk(KERN_INFO "%s: hwaddr %pM, Rev 0x%02x\n", + wiphy_name(dev->wiphy), dev->wiphy->perm_addr, + pdev->revision); return 0; diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index 1d05445d4ba3..6b605df8a923 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -2931,8 +2931,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, release_region( dev->base_addr, 64 ); err_out_nets: airo_networks_free(ai); -err_out_free: del_airo_dev(ai); +err_out_free: free_netdev(dev); return NULL; } @@ -4657,7 +4657,7 @@ static ssize_t proc_write( struct file *file, loff_t *offset ) { loff_t pos = *offset; - struct proc_data *priv = file->private_data; + struct proc_data *priv = (struct proc_data*)file->private_data; if (!priv->wbuffer) return -EINVAL; @@ -4689,7 +4689,7 @@ static int proc_status_open(struct inode *inode, struct file *file) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = file->private_data; + data = (struct proc_data *)file->private_data; if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -4772,7 +4772,7 @@ static int proc_stats_rid_open( struct inode *inode, if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = file->private_data; + data = (struct proc_data *)file->private_data; if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5045,7 +5045,7 @@ static int proc_config_open(struct inode *inode, struct file *file) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = file->private_data; + data = (struct proc_data *)file->private_data; if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5127,7 +5127,7 @@ static int proc_config_open(struct inode *inode, struct file *file) static void proc_SSID_on_close(struct inode *inode, struct file *file) { - struct proc_data *data = file->private_data; + struct proc_data *data = (struct proc_data *)file->private_data; struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = dev->ml_priv; @@ -5163,7 +5163,7 @@ static void proc_SSID_on_close(struct inode *inode, struct file *file) } static void proc_APList_on_close( struct inode *inode, struct file *file ) { - struct proc_data *data = file->private_data; + struct proc_data *data = (struct proc_data *)file->private_data; struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = dev->ml_priv; @@ -5309,7 +5309,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { memset(key, 0, sizeof(key)); - data = file->private_data; + data = (struct proc_data *)file->private_data; if ( !data->writelen ) return; if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' && @@ -5363,7 +5363,7 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(&wkr, 0, sizeof(wkr)); - data = file->private_data; + data = (struct proc_data *)file->private_data; if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5409,7 +5409,7 @@ static int proc_SSID_open(struct inode *inode, struct file *file) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = file->private_data; + data = (struct proc_data *)file->private_data; if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5453,7 +5453,7 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = file->private_data; + data = (struct proc_data *)file->private_data; if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5495,7 +5495,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = file->private_data; + data = (struct proc_data *)file->private_data; if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index d5140a87f073..cd8caeab86ea 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -89,19 +89,22 @@ #define DBG_DEFAULTS 0 /* Use our own dbg macro */ -#define at76_dbg(bits, format, arg...) \ -do { \ - if (at76_debug & (bits)) \ - printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg); \ -} while (0) - -#define at76_dbg_dump(bits, buf, len, format, arg...) \ -do { \ - if (at76_debug & (bits)) { \ - printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg); \ - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \ - } \ -} while (0) +#define at76_dbg(bits, format, arg...) \ + do { \ + if (at76_debug & (bits)) \ + printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \ + ## arg); \ + } while (0) + +#define at76_dbg_dump(bits, buf, len, format, arg...) \ + do { \ + if (at76_debug & (bits)) { \ + printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \ + ## arg); \ + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, \ + buf, len); \ + } \ + } while (0) static uint at76_debug = DBG_DEFAULTS; @@ -655,8 +658,8 @@ static int at76_get_hw_config(struct at76_priv *priv) exit: kfree(hwcfg); if (ret < 0) - wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n", - ret); + printk(KERN_ERR "%s: cannot get HW Config (error %d)\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -791,9 +794,8 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) do { status = at76_get_cmd_status(priv->udev, cmd); if (status < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_cmd_status failed: %d\n", - status); + printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n", + wiphy_name(priv->hw->wiphy), status); break; } @@ -808,8 +810,9 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) schedule_timeout_interruptible(HZ / 10); /* 100 ms */ if (time_after(jiffies, timeout)) { - wiphy_err(priv->hw->wiphy, - "completion timeout for command %d\n", cmd); + printk(KERN_ERR + "%s: completion timeout for command %d\n", + wiphy_name(priv->hw->wiphy), cmd); status = -ETIMEDOUT; break; } @@ -830,9 +833,9 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf) ret = at76_wait_completion(priv, CMD_SET_MIB); if (ret != CMD_STATUS_COMPLETE) { - wiphy_info(priv->hw->wiphy, - "set_mib: at76_wait_completion failed with %d\n", - ret); + printk(KERN_INFO + "%s: set_mib: at76_wait_completion failed " + "with %d\n", wiphy_name(priv->hw->wiphy), ret); ret = -EIO; } @@ -852,8 +855,8 @@ static int at76_set_radio(struct at76_priv *priv, int enable) ret = at76_set_card_command(priv->udev, cmd, NULL, 0); if (ret < 0) - wiphy_err(priv->hw->wiphy, - "at76_set_card_command(%d) failed: %d\n", cmd, ret); + printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n", + wiphy_name(priv->hw->wiphy), cmd, ret); else ret = 1; @@ -873,8 +876,8 @@ static int at76_set_pm_mode(struct at76_priv *priv) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - wiphy_err(priv->hw->wiphy, "set_mib (pm_mode) failed: %d\n", - ret); + printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -890,8 +893,8 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - wiphy_err(priv->hw->wiphy, "set_mib (preamble) failed: %d\n", - ret); + printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -907,8 +910,8 @@ static int at76_set_frag(struct at76_priv *priv, u16 size) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - wiphy_err(priv->hw->wiphy, - "set_mib (frag threshold) failed: %d\n", ret); + printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -924,7 +927,8 @@ static int at76_set_rts(struct at76_priv *priv, u16 size) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - wiphy_err(priv->hw->wiphy, "set_mib (rts) failed: %d\n", ret); + printk(KERN_ERR "%s: set_mib (rts) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -940,8 +944,8 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - wiphy_err(priv->hw->wiphy, - "set_mib (autorate fallback) failed: %d\n", ret); + printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -959,8 +963,8 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m, sizeof(struct mib_mac_addr)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_mib (mac_addr) failed: %d\n", ret); + printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -988,8 +992,8 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m, sizeof(struct mib_mac_wep)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_mib (mac_wep) failed: %d\n", ret); + printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1025,8 +1029,8 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m, sizeof(struct mib_mac_mgmt)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_mib (mac_mgmt) failed: %d\n", ret); + printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1061,8 +1065,8 @@ static void at76_dump_mib_mac(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_mib (mac) failed: %d\n", ret); + printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1098,8 +1102,8 @@ static void at76_dump_mib_phy(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_mib (phy) failed: %d\n", ret); + printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1131,8 +1135,8 @@ static void at76_dump_mib_local(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_mib (local) failed: %d\n", ret); + printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1157,8 +1161,8 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m, sizeof(struct mib_mdomain)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, - "at76_get_mib (mdomain) failed: %d\n", ret); + printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto exit; } @@ -1229,16 +1233,16 @@ static int at76_submit_rx_urb(struct at76_priv *priv) struct sk_buff *skb = priv->rx_skb; if (!priv->rx_urb) { - wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n", - __func__); + printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", + wiphy_name(priv->hw->wiphy), __func__); return -EFAULT; } if (!skb) { skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); if (!skb) { - wiphy_err(priv->hw->wiphy, - "cannot allocate rx skbuff\n"); + printk(KERN_ERR "%s: cannot allocate rx skbuff\n", + wiphy_name(priv->hw->wiphy)); ret = -ENOMEM; goto exit; } @@ -1257,14 +1261,15 @@ static int at76_submit_rx_urb(struct at76_priv *priv) at76_dbg(DBG_DEVSTART, "usb_submit_urb returned -ENODEV"); else - wiphy_err(priv->hw->wiphy, - "rx, usb_submit_urb failed: %d\n", ret); + printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); } exit: if (ret < 0 && ret != -ENODEV) - wiphy_err(priv->hw->wiphy, - "cannot submit rx urb - please unload the driver and/or power cycle the device\n"); + printk(KERN_ERR "%s: cannot submit rx urb - please unload the " + "driver and/or power cycle the device\n", + wiphy_name(priv->hw->wiphy)); return ret; } @@ -1433,8 +1438,8 @@ static int at76_startup_device(struct at76_priv *priv) ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config, sizeof(struct at76_card_config)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n", - ret); + printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return ret; } @@ -1499,8 +1504,8 @@ static void at76_work_set_promisc(struct work_struct *work) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - wiphy_err(priv->hw->wiphy, - "set_mib (promiscuous_mode) failed: %d\n", ret); + printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); mutex_unlock(&priv->mtx); } @@ -1663,16 +1668,16 @@ static int at76_join(struct at76_priv *priv) sizeof(struct at76_req_join)); if (ret < 0) { - wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n", - ret); + printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return 0; } ret = at76_wait_completion(priv, CMD_JOIN); at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); if (ret != CMD_STATUS_COMPLETE) { - wiphy_err(priv->hw->wiphy, "at76_wait_completion failed: %d\n", - ret); + printk(KERN_ERR "%s: at76_wait_completion failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); return 0; } @@ -1740,8 +1745,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) at76_dbg(DBG_MAC80211, "%s()", __func__); if (priv->tx_urb->status == -EINPROGRESS) { - wiphy_err(priv->hw->wiphy, - "%s called while tx urb is pending\n", __func__); + printk(KERN_ERR "%s: %s called while tx urb is pending\n", + wiphy_name(priv->hw->wiphy), __func__); return NETDEV_TX_BUSY; } @@ -1789,12 +1794,13 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) submit_len, at76_mac80211_tx_callback, priv); ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); if (ret) { - wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret); + printk(KERN_ERR "%s: error in tx submit urb: %d\n", + wiphy_name(priv->hw->wiphy), ret); if (ret == -EINVAL) - wiphy_err(priv->hw->wiphy, - "-einval: tx urb %p hcpriv %p complete %p\n", - priv->tx_urb, - priv->tx_urb->hcpriv, priv->tx_urb->complete); + printk(KERN_ERR + "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", + wiphy_name(priv->hw->wiphy), priv->tx_urb, + priv->tx_urb->hcpriv, priv->tx_urb->complete); } return 0; @@ -1811,8 +1817,8 @@ static int at76_mac80211_start(struct ieee80211_hw *hw) ret = at76_submit_rx_urb(priv); if (ret < 0) { - wiphy_err(priv->hw->wiphy, "open: submit_rx_urb failed: %d\n", - ret); + printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", + wiphy_name(priv->hw->wiphy), ret); goto error; } @@ -2310,12 +2316,14 @@ static int at76_init_new_device(struct at76_priv *priv, priv->mac80211_registered = 1; - wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n", - dev_name(&interface->dev), priv->mac_addr, - priv->fw_version.major, priv->fw_version.minor, - priv->fw_version.patch, priv->fw_version.build); - wiphy_info(priv->hw->wiphy, "regulatory domain 0x%02x: %s\n", - priv->regulatory_domain, priv->domain->name); + printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n", + wiphy_name(priv->hw->wiphy), + dev_name(&interface->dev), priv->mac_addr, + priv->fw_version.major, priv->fw_version.minor, + priv->fw_version.patch, priv->fw_version.build); + printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", + wiphy_name(priv->hw->wiphy), + priv->regulatory_domain, priv->domain->name); exit: return ret; @@ -2477,7 +2485,7 @@ static void at76_disconnect(struct usb_interface *interface) if (!priv) return; - wiphy_info(priv->hw->wiphy, "disconnecting\n"); + printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy)); at76_delete_device(priv); dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); } diff --git a/trunk/drivers/net/wireless/ath/ar9170/cmd.c b/trunk/drivers/net/wireless/ath/ar9170/cmd.c index 4604de09a8b2..cf6f5c4174a6 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/cmd.c +++ b/trunk/drivers/net/wireless/ath/ar9170/cmd.c @@ -48,7 +48,8 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL); if (err) - wiphy_debug(ar->hw->wiphy, "writing memory failed\n"); + printk(KERN_DEBUG "%s: writing memory failed\n", + wiphy_name(ar->hw->wiphy)); return err; } @@ -66,8 +67,8 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf), (u8 *) buf, 0, NULL); if (err) - wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n", - reg, val); + printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n", + wiphy_name(ar->hw->wiphy), reg, val); return err; } diff --git a/trunk/drivers/net/wireless/ath/ar9170/led.c b/trunk/drivers/net/wireless/ath/ar9170/led.c index 832d90087f8a..86c4e79f6bc8 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/led.c +++ b/trunk/drivers/net/wireless/ath/ar9170/led.c @@ -133,8 +133,8 @@ static int ar9170_register_led(struct ar9170 *ar, int i, char *name, err = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds[i].l); if (err) - wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", - ar->leds[i].name, err); + printk(KERN_ERR "%s: failed to register %s LED (%d).\n", + wiphy_name(ar->hw->wiphy), ar->leds[i].name, err); else ar->leds[i].registered = true; diff --git a/trunk/drivers/net/wireless/ath/ar9170/main.c b/trunk/drivers/net/wireless/ath/ar9170/main.c index c67b05f3bcbd..2abc87578994 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/main.c +++ b/trunk/drivers/net/wireless/ath/ar9170/main.c @@ -198,13 +198,12 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; struct ieee80211_hdr *hdr = (void *) txc->frame_data; - wiphy_debug(ar->hw->wiphy, - "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d " - "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", - skb, skb_get_queue_mapping(skb), - ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), - le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), - jiffies_to_msecs(arinfo->timeout - jiffies)); + printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d " + "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", + wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), + ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), + le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), + jiffies_to_msecs(arinfo->timeout - jiffies)); } static void __ar9170_dump_txqueue(struct ar9170 *ar, @@ -214,8 +213,8 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar, int i = 0; printk(KERN_DEBUG "---[ cut here ]---\n"); - wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n", - skb_queue_len(queue)); + printk(KERN_DEBUG "%s: %d entries in queue.\n", + wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); skb_queue_walk(queue, skb) { printk(KERN_DEBUG "index:%d =>\n", i++); @@ -245,14 +244,15 @@ static void __ar9170_dump_txstats(struct ar9170 *ar) { int i; - wiphy_debug(ar->hw->wiphy, "qos queue stats\n"); + printk(KERN_DEBUG "%s: QoS queue stats\n", + wiphy_name(ar->hw->wiphy)); for (i = 0; i < __AR9170_NUM_TXQ; i++) - wiphy_debug(ar->hw->wiphy, - "queue:%d limit:%d len:%d waitack:%d stopped:%d\n", - i, ar->tx_stats[i].limit, ar->tx_stats[i].len, - skb_queue_len(&ar->tx_status[i]), - ieee80211_queue_stopped(ar->hw, i)); + printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d " + " stopped:%d\n", wiphy_name(ar->hw->wiphy), i, + ar->tx_stats[i].limit, ar->tx_stats[i].len, + skb_queue_len(&ar->tx_status[i]), + ieee80211_queue_stopped(ar->hw, i)); } #endif /* AR9170_QUEUE_STOP_DEBUG */ @@ -274,9 +274,9 @@ static void ar9170_recycle_expired(struct ar9170 *ar, if (time_is_before_jiffies(arinfo->timeout)) { #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "[%ld > %ld] frame expired => recycle\n", - jiffies, arinfo->timeout); + printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " + "recycle\n", wiphy_name(ar->hw->wiphy), + jiffies, arinfo->timeout); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ __skb_unlink(skb, queue); @@ -317,8 +317,8 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, break; default: - wiphy_err(ar->hw->wiphy, - "invalid tx_status response (%x)\n", tx_status); + printk(KERN_ERR "%s: invalid tx_status response (%x).\n", + wiphy_name(ar->hw->wiphy), tx_status); break; } @@ -339,7 +339,8 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) { #ifdef AR9170_QUEUE_STOP_DEBUG - wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue); + printk(KERN_DEBUG "%s: wake queue %d\n", + wiphy_name(ar->hw->wiphy), queue); __ar9170_dump_txstats(ar); #endif /* AR9170_QUEUE_STOP_DEBUG */ ieee80211_wake_queue(ar->hw, queue); @@ -386,9 +387,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "skip frame => da %pm != %pm\n", - mac, ieee80211_get_DA(hdr)); + printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", + wiphy_name(ar->hw->wiphy), mac, + ieee80211_get_DA(hdr)); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ continue; @@ -399,8 +400,8 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "skip frame => rate %d != %d\n", rate, r); + printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", + wiphy_name(ar->hw->wiphy), rate, r); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ continue; @@ -412,9 +413,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, } #ifdef AR9170_QUEUE_DEBUG - wiphy_err(ar->hw->wiphy, - "ESS:[%pM] does not have any outstanding frames in queue.\n", - mac); + printk(KERN_ERR "%s: ESS:[%pM] does not have any " + "outstanding frames in queue.\n", + wiphy_name(ar->hw->wiphy), mac); __ar9170_dump_txqueue(ar, queue); #endif /* AR9170_QUEUE_DEBUG */ spin_unlock_irqrestore(&queue->lock, flags); @@ -443,8 +444,8 @@ static void ar9170_tx_janitor(struct work_struct *work) for (i = 0; i < __AR9170_NUM_TXQ; i++) { #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n", - i); + printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", + wiphy_name(ar->hw->wiphy), i); ar9170_dump_txqueue(ar, &ar->tx_pending[i]); ar9170_dump_txqueue(ar, &ar->tx_status[i]); #endif /* AR9170_QUEUE_DEBUG */ @@ -494,9 +495,8 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT; #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "recv tx_status for %pm, p:%08x, q:%d\n", - cmd->tx_status.dst, phy, q); + printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n", + wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q); #endif /* AR9170_QUEUE_DEBUG */ skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, @@ -582,7 +582,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) break; default: - pr_info("received unhandled event %x\n", cmd->type); + printk(KERN_INFO "received unhandled event %x\n", cmd->type); print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); break; } @@ -675,9 +675,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, /* TODO: update netdevice's RX dropped/errors statistics */ if (ar9170_nag_limiter(ar)) - wiphy_debug(ar->hw->wiphy, - "received frame with suspicious error code (%#x).\n", - error); + printk(KERN_DEBUG "%s: received frame with " + "suspicious error code (%#x).\n", + wiphy_name(ar->hw->wiphy), error); return -EINVAL; } @@ -704,9 +704,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, break; default: if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "invalid plcp cck rate (%x).\n", - head->plcp[0]); + printk(KERN_ERR "%s: invalid plcp cck rate " + "(%x).\n", wiphy_name(ar->hw->wiphy), + head->plcp[0]); return -EINVAL; } break; @@ -740,9 +740,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, break; default: if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "invalid plcp ofdm rate (%x).\n", - head->plcp[0]); + printk(KERN_ERR "%s: invalid plcp ofdm rate " + "(%x).\n", wiphy_name(ar->hw->wiphy), + head->plcp[0]); return -EINVAL; } if (status->band == IEEE80211_BAND_2GHZ) @@ -761,7 +761,8 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, default: if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, "invalid modulation\n"); + printk(KERN_ERR "%s: invalid modulation\n", + wiphy_name(ar->hw->wiphy)); return -EINVAL; } @@ -862,8 +863,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) ar->rx_mpdu.has_plcp = true; } else { if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "plcp info is clipped.\n"); + printk(KERN_ERR "%s: plcp info is clipped.\n", + wiphy_name(ar->hw->wiphy)); return ; } break; @@ -876,8 +877,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) phy = (void *)(buf + mpdu_len); } else { if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "frame tail is clipped.\n"); + printk(KERN_ERR "%s: frame tail is clipped.\n", + wiphy_name(ar->hw->wiphy)); return ; } @@ -887,8 +888,9 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (!ar9170_nag_limiter(ar)) return ; - wiphy_err(ar->hw->wiphy, - "rx stream did not start with a first_mpdu frame tag.\n"); + printk(KERN_ERR "%s: rx stream did not start " + "with a first_mpdu frame tag.\n", + wiphy_name(ar->hw->wiphy)); return ; } @@ -952,8 +954,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (!ar->rx_failover_missing) { /* this is no "short read". */ if (ar9170_nag_limiter(ar)) { - wiphy_err(ar->hw->wiphy, - "missing tag!\n"); + printk(KERN_ERR "%s: missing tag!\n", + wiphy_name(ar->hw->wiphy)); goto err_telluser; } else goto err_silent; @@ -961,8 +963,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (ar->rx_failover_missing > tlen) { if (ar9170_nag_limiter(ar)) { - wiphy_err(ar->hw->wiphy, - "possible multi stream corruption!\n"); + printk(KERN_ERR "%s: possible multi " + "stream corruption!\n", + wiphy_name(ar->hw->wiphy)); goto err_telluser; } else goto err_silent; @@ -994,8 +997,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (ar->rx_failover_missing) { /* TODO: handle double stream corruption. */ if (ar9170_nag_limiter(ar)) { - wiphy_err(ar->hw->wiphy, - "double rx stream corruption!\n"); + printk(KERN_ERR "%s: double rx stream " + "corruption!\n", + wiphy_name(ar->hw->wiphy)); goto err_telluser; } else goto err_silent; @@ -1038,9 +1042,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (tlen) { if (net_ratelimit()) - wiphy_err(ar->hw->wiphy, - "%d bytes of unprocessed data left in rx stream!\n", - tlen); + printk(KERN_ERR "%s: %d bytes of unprocessed " + "data left in rx stream!\n", + wiphy_name(ar->hw->wiphy), tlen); goto err_telluser; } @@ -1048,9 +1052,10 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) return ; err_telluser: - wiphy_err(ar->hw->wiphy, - "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n", - clen, wlen, tlen, ar->rx_failover_missing); + printk(KERN_ERR "%s: damaged RX stream data [want:%d, " + "data:%d, rx:%d, pending:%d ]\n", + wiphy_name(ar->hw->wiphy), clen, wlen, tlen, + ar->rx_failover_missing); if (ar->rx_failover_missing) print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, @@ -1060,8 +1065,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, skb->data, skb->len); - wiphy_err(ar->hw->wiphy, - "If you see this message frequently, please check your hardware and cables.\n"); + printk(KERN_ERR "%s: please check your hardware and cables, if " + "you see this message frequently.\n", + wiphy_name(ar->hw->wiphy)); err_silent: if (ar->rx_failover_missing) { @@ -1378,10 +1384,10 @@ static void ar9170_tx(struct ar9170 *ar) if (remaining_space < frames) { #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "tx quota reached queue:%d, " - "remaining slots:%d, needed:%d\n", - i, remaining_space, frames); + printk(KERN_DEBUG "%s: tx quota reached queue:%d, " + "remaining slots:%d, needed:%d\n", + wiphy_name(ar->hw->wiphy), i, remaining_space, + frames); #endif /* AR9170_QUEUE_DEBUG */ frames = remaining_space; } @@ -1390,14 +1396,18 @@ static void ar9170_tx(struct ar9170 *ar) ar->tx_stats[i].count += frames; if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, "queue %d full\n", i); - wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n"); + printk(KERN_DEBUG "%s: queue %d full\n", + wiphy_name(ar->hw->wiphy), i); + + printk(KERN_DEBUG "%s: stuck frames: ===>\n", + wiphy_name(ar->hw->wiphy)); ar9170_dump_txqueue(ar, &ar->tx_pending[i]); ar9170_dump_txqueue(ar, &ar->tx_status[i]); #endif /* AR9170_QUEUE_DEBUG */ #ifdef AR9170_QUEUE_STOP_DEBUG - wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i); + printk(KERN_DEBUG "%s: stop queue %d\n", + wiphy_name(ar->hw->wiphy), i); __ar9170_dump_txstats(ar); #endif /* AR9170_QUEUE_STOP_DEBUG */ ieee80211_stop_queue(ar->hw, i); @@ -1425,7 +1435,8 @@ static void ar9170_tx(struct ar9170 *ar) msecs_to_jiffies(AR9170_TX_TIMEOUT); #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i); + printk(KERN_DEBUG "%s: send frame q:%d =>\n", + wiphy_name(ar->hw->wiphy), i); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ @@ -1442,25 +1453,26 @@ static void ar9170_tx(struct ar9170 *ar) } #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "ar9170_tx report for queue %d\n", i); + printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", + wiphy_name(ar->hw->wiphy), i); - wiphy_debug(ar->hw->wiphy, - "unprocessed pending frames left:\n"); + printk(KERN_DEBUG "%s: unprocessed pending frames left:\n", + wiphy_name(ar->hw->wiphy)); ar9170_dump_txqueue(ar, &ar->tx_pending[i]); #endif /* AR9170_QUEUE_DEBUG */ if (unlikely(frames_failed)) { #ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "frames failed %d =>\n", frames_failed); + printk(KERN_DEBUG "%s: frames failed %d =>\n", + wiphy_name(ar->hw->wiphy), frames_failed); #endif /* AR9170_QUEUE_DEBUG */ spin_lock_irqsave(&ar->tx_stats_lock, flags); ar->tx_stats[i].len -= frames_failed; ar->tx_stats[i].count -= frames_failed; #ifdef AR9170_QUEUE_STOP_DEBUG - wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i); + printk(KERN_DEBUG "%s: wake queue %d\n", + wiphy_name(ar->hw->wiphy), i); __ar9170_dump_txstats(ar); #endif /* AR9170_QUEUE_STOP_DEBUG */ ieee80211_wake_queue(ar->hw, i); @@ -1905,24 +1917,6 @@ static int ar9170_get_stats(struct ieee80211_hw *hw, return 0; } -static int ar9170_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct ar9170 *ar = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - /* TODO: update noise value, e.g. call ar9170_set_channel */ - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = ar->noise[0]; - - return 0; -} - static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *param) { @@ -1975,7 +1969,6 @@ static const struct ieee80211_ops ar9170_ops = { .get_tsf = ar9170_op_get_tsf, .set_key = ar9170_set_key, .get_stats = ar9170_get_stats, - .get_survey = ar9170_get_survey, .ampdu_action = ar9170_ampdu_action, }; diff --git a/trunk/drivers/net/wireless/ath/ar9170/phy.c b/trunk/drivers/net/wireless/ath/ar9170/phy.c index 0dbfcf79ac96..45a415ea809a 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/phy.c +++ b/trunk/drivers/net/wireless/ath/ar9170/phy.c @@ -670,7 +670,8 @@ static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) ar9170_regwrite_finish(); err = ar9170_regwrite_result(); if (err) - wiphy_err(ar->hw->wiphy, "rf init failed\n"); + printk(KERN_ERR "%s: rf init failed\n", + wiphy_name(ar->hw->wiphy)); return err; } @@ -1701,8 +1702,9 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, 0x200 | ar->phy_heavy_clip); if (err) { if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "failed to set heavy clip\n"); + printk(KERN_ERR "%s: failed to set " + "heavy clip\n", + wiphy_name(ar->hw->wiphy)); } } diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 0d5de2574dd1..20328bdd138b 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -388,7 +388,7 @@ static int ath5k_init(struct ath5k_softc *sc); static int ath5k_stop_locked(struct ath5k_softc *sc); static int ath5k_stop_hw(struct ath5k_softc *sc); static irqreturn_t ath5k_intr(int irq, void *dev_id); -static void ath5k_reset_work(struct work_struct *work); +static void ath5k_tasklet_reset(unsigned long data); static void ath5k_tasklet_calibrate(unsigned long data); @@ -831,12 +831,11 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); + tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); - INIT_WORK(&sc->reset_work, ath5k_reset_work); - ret = ath5k_eeprom_read_mac(ah, mac); if (ret) { ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", @@ -1728,6 +1727,8 @@ ath5k_rx_stop(struct ath5k_softc *sc) ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ ath5k_debug_printrxbuffs(sc, ah); + + sc->rxlink = NULL; /* just in case */ } static unsigned int @@ -2293,8 +2294,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) * frame contents are done as needed and the slot time is * also adjusted based on current state. * - * This is called from software irq context (beacontq tasklets) - * or user context from ath5k_beacon_config. + * This is called from software irq context (beacontq or restq + * tasklets) or user context from ath5k_beacon_config. */ static void ath5k_beacon_send(struct ath5k_softc *sc) @@ -2327,7 +2328,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) sc->bmisscount); ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "stuck beacon, resetting\n"); - ieee80211_queue_work(sc->hw, &sc->reset_work); + tasklet_schedule(&sc->restq); } return; } @@ -2631,20 +2632,12 @@ ath5k_stop_locked(struct ath5k_softc *sc) if (!test_bit(ATH_STAT_INVALID, sc->status)) { ath5k_rx_stop(sc); ath5k_hw_phy_disable(ah); - } + } else + sc->rxlink = NULL; return 0; } -static void stop_tasklets(struct ath5k_softc *sc) -{ - tasklet_kill(&sc->rxtq); - tasklet_kill(&sc->txtq); - tasklet_kill(&sc->calib); - tasklet_kill(&sc->beacontq); - tasklet_kill(&sc->ani_tasklet); -} - /* * Stop the device, grabbing the top-level lock to protect * against concurrent entry through ath5k_init (which can happen @@ -2689,7 +2682,12 @@ ath5k_stop_hw(struct ath5k_softc *sc) mmiowb(); mutex_unlock(&sc->lock); - stop_tasklets(sc); + tasklet_kill(&sc->rxtq); + tasklet_kill(&sc->txtq); + tasklet_kill(&sc->restq); + tasklet_kill(&sc->calib); + tasklet_kill(&sc->beacontq); + tasklet_kill(&sc->ani_tasklet); ath5k_rfkill_hw_stop(sc->ah); @@ -2739,7 +2737,7 @@ ath5k_intr(int irq, void *dev_id) */ ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "fatal int, resetting\n"); - ieee80211_queue_work(sc->hw, &sc->reset_work); + tasklet_schedule(&sc->restq); } else if (unlikely(status & AR5K_INT_RXORN)) { /* * Receive buffers are full. Either the bus is busy or @@ -2754,7 +2752,7 @@ ath5k_intr(int irq, void *dev_id) if (ah->ah_mac_srev < AR5K_SREV_AR5212) { ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "rx overrun, resetting\n"); - ieee80211_queue_work(sc->hw, &sc->reset_work); + tasklet_schedule(&sc->restq); } else tasklet_schedule(&sc->rxtq); @@ -2768,7 +2766,7 @@ ath5k_intr(int irq, void *dev_id) * RXE bit is written, but it doesn't work at * least on older hardware revs. */ - sc->stats.rxeol_intr++; + sc->rxlink = NULL; } if (status & AR5K_INT_TXURN) { /* bump tx trigger level */ @@ -2801,6 +2799,14 @@ ath5k_intr(int irq, void *dev_id) return IRQ_HANDLED; } +static void +ath5k_tasklet_reset(unsigned long data) +{ + struct ath5k_softc *sc = (void *)data; + + ath5k_reset(sc, sc->curchan); +} + /* * Periodically recalibrate the PHY to account * for temperature/environment changes. @@ -2824,7 +2830,7 @@ ath5k_tasklet_calibrate(unsigned long data) * to load new gain values. */ ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); - ieee80211_queue_work(sc->hw, &sc->reset_work); + ath5k_reset(sc, sc->curchan); } if (ath5k_hw_phy_calibrate(ah, sc->curchan)) ATH5K_ERR(sc, "calibration of channel %u failed\n", @@ -2928,8 +2934,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, /* * Reset the hardware. If chan is not NULL, then also pause rx/tx * and change to the given channel. - * - * This should be called with sc->lock. */ static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) @@ -2939,11 +2943,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); - ath5k_hw_set_imr(ah, 0); - synchronize_irq(sc->pdev->irq); - stop_tasklets(sc); - if (chan) { + ath5k_hw_set_imr(ah, 0); ath5k_txq_cleanup(sc); ath5k_rx_stop(sc); @@ -2989,16 +2990,6 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) return ret; } -static void ath5k_reset_work(struct work_struct *work) -{ - struct ath5k_softc *sc = container_of(work, struct ath5k_softc, - reset_work); - - mutex_lock(&sc->lock); - ath5k_reset(sc, sc->curchan); - mutex_unlock(&sc->lock); -} - static int ath5k_start(struct ieee80211_hw *hw) { return ath5k_init(hw->priv); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.h b/trunk/drivers/net/wireless/ath/ath5k/base.h index dc1241f9c4e8..56221bc7c8cd 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.h +++ b/trunk/drivers/net/wireless/ath/ath5k/base.h @@ -47,7 +47,6 @@ #include #include #include -#include #include "ath5k.h" #include "debug.h" @@ -137,7 +136,6 @@ struct ath5k_statistics { unsigned int mib_intr; unsigned int rxorn_intr; - unsigned int rxeol_intr; }; #if CHAN_DEBUG @@ -191,7 +189,7 @@ struct ath5k_softc { unsigned int led_pin, /* GPIO pin for driving LED */ led_on; /* pin setting for LED on */ - struct work_struct reset_work; /* deferred chip reset */ + struct tasklet_struct restq; /* reset tasklet */ unsigned int rxbufsize; /* rx size based on mtu */ struct list_head rxbuf; /* receive buffer */ diff --git a/trunk/drivers/net/wireless/ath/ath5k/debug.c b/trunk/drivers/net/wireless/ath/ath5k/debug.c index 4cccc29964f6..8c638865c712 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/debug.c +++ b/trunk/drivers/net/wireless/ath/ath5k/debug.c @@ -239,9 +239,6 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf, "TSF\t\t0x%016llx\tTU: %08x\n", (unsigned long long)tsf, TSF_TO_TU(tsf)); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -282,7 +279,7 @@ static ssize_t write_file_reset(struct file *file, { struct ath5k_softc *sc = file->private_data; ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "debug file triggered reset\n"); - ieee80211_queue_work(sc->hw, &sc->reset_work); + tasklet_schedule(&sc->restq); return count; } @@ -337,9 +334,6 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf, sc->debug.level == dbg_info[i].level ? '+' : ' ', dbg_info[i].level, dbg_info[i].desc); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -439,9 +433,6 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, "AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -551,9 +542,6 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", st->tx_all_count); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -693,9 +681,6 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2))); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -781,9 +766,6 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n); } - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ahb.c b/trunk/drivers/net/wireless/ath/ath9k/ahb.c index 1a984b02e9e5..85fdd26039c8 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ahb.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ahb.c @@ -131,8 +131,11 @@ static int ath_ahb_probe(struct platform_device *pdev) ah = sc->sc_ah; ath9k_hw_name(ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)mem, irq); + printk(KERN_INFO + "%s: %s mem=0x%lx, irq=%d\n", + wiphy_name(hw->wiphy), + hw_name, + (unsigned long)mem, irq); return 0; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 3d2c8679bc85..4a910b78de52 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1506,9 +1506,6 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah, nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); nfarray[2] = sign_extend(nf, 9); - if (!IS_CHAN_HT40(ah->curchan)) - return; - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); nfarray[3] = sign_extend(nf, 9); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 303c63da5ea3..75b80d13ff91 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -85,6 +85,21 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ar9287PciePhy_clkreq_always_on_L1_9287_1_1, ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1), 2); + } else if (AR_SREV_9287_10_OR_LATER(ah)) { + INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0, + ARRAY_SIZE(ar9287Modes_9287_1_0), 6); + INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0, + ARRAY_SIZE(ar9287Common_9287_1_0), 2); + + if (ah->config.pcie_clock_req) + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9287PciePhy_clkreq_off_L1_9287_1_0, + ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2); + else + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9287PciePhy_clkreq_always_on_L1_9287_1_0, + ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0), + 2); } else if (AR_SREV_9285_12_OR_LATER(ah)) { @@ -103,6 +118,21 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), 2); } + } else if (AR_SREV_9285_10_OR_LATER(ah)) { + INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285, + ARRAY_SIZE(ar9285Modes_9285), 6); + INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285, + ARRAY_SIZE(ar9285Common_9285), 2); + + if (ah->config.pcie_clock_req) { + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9285PciePhy_clkreq_off_L1_9285, + ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); + } else { + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9285PciePhy_clkreq_always_on_L1_9285, + ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); + } } else if (AR_SREV_9280_20_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, ARRAY_SIZE(ar9280Modes_9280_2), 6); @@ -121,6 +151,11 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesAdditional, ar9280Modes_fast_clock_9280_2, ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); + } else if (AR_SREV_9280_10_OR_LATER(ah)) { + INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280, + ARRAY_SIZE(ar9280Modes_9280), 6); + INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280, + ARRAY_SIZE(ar9280Common_9280), 2); } else if (AR_SREV_9160_10_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, ARRAY_SIZE(ar5416Modes_9160), 6); @@ -270,6 +305,10 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9287Modes_rx_gain_9287_1_1, ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); + else if (AR_SREV_9287_10(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9287Modes_rx_gain_9287_1_0, + ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6); else if (AR_SREV_9280_20(ah)) ar9280_20_hw_init_rxgain_ini(ah); @@ -277,6 +316,10 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9287Modes_tx_gain_9287_1_1, ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); + } else if (AR_SREV_9287_10(ah)) { + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9287Modes_tx_gain_9287_1_0, + ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6); } else if (AR_SREV_9280_20(ah)) { ar9280_20_hw_init_txgain_ini(ah); } else if (AR_SREV_9285_12_OR_LATER(ah)) { @@ -346,6 +389,29 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), INI_RA(&ah->iniPcieSerdes, i, 1)); } + } else if (AR_SREV_9280(ah) && + (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) { + REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); + REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); + + /* RX shut off when elecidle is asserted */ + REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); + REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); + REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); + + /* Shut off CLKREQ active in L1 */ + if (ah->config.pcie_clock_req) + REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); + else + REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); + + REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); + REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); + REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); + + /* Load the new settings */ + REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); + } else { ENABLE_REGWRITE_BUFFER(ah); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index 6203eed860dd..13b5e484c2ef 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -14,56 +14,209 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -static const u32 ar9280Modes_9280_2[][6] = { +static const u32 ar9280Modes_9280[][6] = { {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0}, {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, - {0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e}, - {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, - {0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, - {0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, - {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, - {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0}, + {0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563}, + {0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563}, + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e}, + {0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20, 0x00049d18}, + {0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190}, {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, - {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b, 0x00000016}, - {0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, - {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010}, + {0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010}, {0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, {0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, {0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210}, - {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce}, - {0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c}, - {0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00}, {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214, 0x00000214}, + {0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218, 0x00000218}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224, 0x00000224}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228, 0x00000228}, + {0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c, 0x0000022c}, + {0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230, 0x00000230}, + {0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4, 0x000002a4}, + {0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8, 0x000002a8}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac, 0x000002ac}, + {0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0, 0x000002b0}, + {0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4, 0x000002b4}, + {0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8, 0x000002b8}, + {0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390, 0x00000390}, + {0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394, 0x00000394}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398, 0x00000398}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334, 0x00000334}, + {0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338, 0x00000338}, + {0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac, 0x000003ac}, + {0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0, 0x000003b0}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4, 0x000003b4}, + {0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8, 0x000003b8}, + {0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5, 0x000003a5}, + {0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9, 0x000003a9}, + {0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad, 0x000003ad}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, {0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444}, - {0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, - {0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, + {0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788}, + {0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019}, + {0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019}, {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000, 0x13c88000}, - {0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000}, - {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, - {0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000, 0x0c000000}, - {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000}, + {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002}, + {0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009}, + {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b}, + {0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012}, + {0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048}, + {0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a}, + {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211}, + {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, + {0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b}, + {0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412}, + {0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414}, + {0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a}, + {0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649}, + {0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b}, + {0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49}, + {0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48}, + {0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a}, + {0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88}, + {0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a}, + {0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9}, + {0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42}, + {0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c, 0x0e4d048c}, + {0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828, 0x12035828}, + {0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000, 0x807ec000}, + {0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000, 0x00110000}, }; -static const u32 ar9280Common_9280_2[][2] = { +static const u32 ar9280Common_9280[][2] = { /* Addr allmodes */ {0x0000000c, 0x00000000}, {0x00000030, 0x00020015}, @@ -149,10 +302,7 @@ static const u32 ar9280Common_9280_2[][2] = { {0x00004030, 0x00000002}, {0x0000403c, 0x00000002}, {0x00004024, 0x0000001f}, - {0x00004060, 0x00000000}, - {0x00004064, 0x00000000}, {0x00007010, 0x00000033}, - {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, {0x00008004, 0x00000000}, {0x00008008, 0x00000000}, @@ -168,7 +318,7 @@ static const u32 ar9280Common_9280_2[][2] = { {0x00008060, 0x0000000f}, {0x00008064, 0x00000000}, {0x00008070, 0x00000000}, - {0x000080c0, 0x2a80001a}, + {0x000080c0, 0x2a82301a}, {0x000080c4, 0x05dc01e0}, {0x000080c8, 0x1f402710}, {0x000080cc, 0x01f40000}, @@ -190,6 +340,7 @@ static const u32 ar9280Common_9280_2[][2] = { {0x00008110, 0x00000168}, {0x00008118, 0x000100aa}, {0x0000811c, 0x00003210}, + {0x00008120, 0x08f04800}, {0x00008124, 0x00000000}, {0x00008128, 0x00000000}, {0x0000812c, 0x00000000}, @@ -197,14 +348,15 @@ static const u32 ar9280Common_9280_2[][2] = { {0x00008134, 0x00000000}, {0x00008138, 0x00000000}, {0x0000813c, 0x00000000}, - {0x00008144, 0xffffffff}, + {0x00008144, 0x00000000}, {0x00008168, 0x00000000}, {0x0000816c, 0x00000000}, {0x00008170, 0x32143320}, {0x00008174, 0xfaa4fa50}, {0x00008178, 0x00000100}, {0x0000817c, 0x00000000}, - {0x000081c0, 0x00000000}, + {0x000081c4, 0x00000000}, + {0x000081d0, 0x00003210}, {0x000081ec, 0x00000000}, {0x000081f0, 0x00000000}, {0x000081f4, 0x00000000}, @@ -235,7 +387,6 @@ static const u32 ar9280Common_9280_2[][2] = { {0x00008258, 0x00000000}, {0x0000825c, 0x400000ff}, {0x00008260, 0x00080922}, - {0x00008264, 0x88a00010}, {0x00008270, 0x00000000}, {0x00008274, 0x40000000}, {0x00008278, 0x003e4180}, @@ -245,25 +396,30 @@ static const u32 ar9280Common_9280_2[][2] = { {0x0000828c, 0x00000000}, {0x00008294, 0x00000000}, {0x00008298, 0x00000000}, - {0x0000829c, 0x00000000}, - {0x00008300, 0x00000040}, + {0x00008300, 0x00000000}, + {0x00008304, 0x00000000}, + {0x00008308, 0x00000000}, + {0x0000830c, 0x00000000}, + {0x00008310, 0x00000000}, {0x00008314, 0x00000000}, + {0x00008318, 0x00000000}, {0x00008328, 0x00000000}, {0x0000832c, 0x00000007}, {0x00008330, 0x00000302}, {0x00008334, 0x00000e00}, - {0x00008338, 0x00ff0000}, + {0x00008338, 0x00000000}, {0x0000833c, 0x00000000}, {0x00008340, 0x000107ff}, - {0x00008344, 0x00481043}, + {0x00008344, 0x00000000}, {0x00009808, 0x00000000}, - {0x0000980c, 0xafa68e30}, + {0x0000980c, 0xaf268e30}, {0x00009810, 0xfd14e000}, {0x00009814, 0x9c0a9f6b}, {0x0000981c, 0x00000000}, {0x0000982c, 0x0000a000}, {0x00009830, 0x00000000}, {0x0000983c, 0x00200400}, + {0x00009840, 0x206a01ae}, {0x0000984c, 0x0040233c}, {0x0000a84c, 0x0040233c}, {0x00009854, 0x00000044}, @@ -271,7 +427,6 @@ static const u32 ar9280Common_9280_2[][2] = { {0x00009904, 0x00000000}, {0x00009908, 0x00000000}, {0x0000990c, 0x00000000}, - {0x00009910, 0x01002310}, {0x0000991c, 0x10000fff}, {0x00009920, 0x04900000}, {0x0000a920, 0x04900000}, @@ -282,10 +437,11 @@ static const u32 ar9280Common_9280_2[][2] = { {0x0000993c, 0x00000000}, {0x00009948, 0x9280c00a}, {0x0000994c, 0x00020028}, - {0x00009954, 0x5f3ca3de}, - {0x00009958, 0x2108ecff}, - {0x00009940, 0x14750604}, + {0x00009954, 0xe250a51e}, + {0x00009958, 0x3388ffff}, + {0x00009940, 0x00781204}, {0x0000c95c, 0x004b6a8e}, + {0x0000c968, 0x000003ce}, {0x00009970, 0x190fb514}, {0x00009974, 0x00000000}, {0x00009978, 0x00000001}, @@ -301,45 +457,41 @@ static const u32 ar9280Common_9280_2[][2] = { {0x000099a0, 0x00000000}, {0x000099a4, 0x00000001}, {0x000099a8, 0x201fff00}, - {0x000099ac, 0x006f0000}, + {0x000099ac, 0x006f00c4}, {0x000099b0, 0x03051000}, {0x000099b4, 0x00000820}, - {0x000099c4, 0x06336f77}, - {0x000099c8, 0x6af6532f}, - {0x000099cc, 0x08f186c8}, - {0x000099d0, 0x00046384}, - {0x000099d4, 0x00000000}, - {0x000099d8, 0x00000000}, {0x000099dc, 0x00000000}, {0x000099e0, 0x00000000}, {0x000099e4, 0xaaaaaaaa}, {0x000099e8, 0x3c466478}, {0x000099ec, 0x0cc80caa}, - {0x000099f0, 0x00000000}, {0x000099fc, 0x00001042}, - {0x0000a208, 0x803e4788}, {0x0000a210, 0x4080a333}, {0x0000a214, 0x40206c10}, {0x0000a218, 0x009c4060}, {0x0000a220, 0x01834061}, {0x0000a224, 0x00000400}, {0x0000a228, 0x000003b5}, - {0x0000a22c, 0x233f7180}, + {0x0000a22c, 0x23277200}, {0x0000a234, 0x20202020}, {0x0000a238, 0x20202020}, + {0x0000a23c, 0x13c889af}, {0x0000a240, 0x38490a20}, {0x0000a244, 0x00007bb6}, {0x0000a248, 0x0fff3ffc}, - {0x0000a24c, 0x00000000}, + {0x0000a24c, 0x00000001}, + {0x0000a250, 0x001da000}, {0x0000a254, 0x00000000}, {0x0000a258, 0x0cdbd380}, {0x0000a25c, 0x0f0f0f01}, {0x0000a260, 0xdfa91f01}, {0x0000a268, 0x00000000}, - {0x0000a26c, 0x0e79e5c6}, - {0x0000b26c, 0x0e79e5c6}, + {0x0000a26c, 0x0ebae9c6}, + {0x0000b26c, 0x0ebae9c6}, {0x0000d270, 0x00820820}, {0x0000a278, 0x1ce739ce}, + {0x0000a27c, 0x050701ce}, + {0x0000a358, 0x7999aa0f}, {0x0000d35c, 0x07ffffef}, {0x0000d360, 0x0fffffe7}, {0x0000d364, 0x17ffffe5}, @@ -351,6 +503,7 @@ static const u32 ar9280Common_9280_2[][2] = { {0x0000d37c, 0x7fffffe2}, {0x0000d380, 0x7f3c7bba}, {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, {0x0000a38c, 0x20202020}, {0x0000a390, 0x20202020}, {0x0000a394, 0x1ce739ce}, @@ -374,556 +527,1609 @@ static const u32 ar9280Common_9280_2[][2] = { {0x0000a3e0, 0x000001ce}, {0x0000a3e4, 0x00000000}, {0x0000a3e8, 0x18c43433}, + {0x0000a3ec, 0x00f38081}, {0x00007800, 0x00040000}, {0x00007804, 0xdb005012}, {0x00007808, 0x04924914}, {0x0000780c, 0x21084210}, {0x00007810, 0x6d801300}, - {0x00007818, 0x07e41000}, + {0x00007814, 0x0019beff}, + {0x00007818, 0x07e40000}, + {0x0000781c, 0x00492000}, + {0x00007820, 0x92492480}, {0x00007824, 0x00040000}, {0x00007828, 0xdb005012}, {0x0000782c, 0x04924914}, {0x00007830, 0x21084210}, {0x00007834, 0x6d801300}, + {0x00007838, 0x0019beff}, {0x0000783c, 0x07e40000}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, + {0x00007840, 0x00492000}, + {0x00007844, 0x92492480}, + {0x00007848, 0x00120000}, {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x9259269a}, + {0x00007858, 0x92592692}, {0x00007860, 0x52802000}, {0x00007864, 0x0a8e370e}, {0x00007868, 0xc0102850}, {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, {0x00007874, 0x001b6db0}, {0x00007878, 0x00376b63}, {0x0000787c, 0x06db6db6}, {0x00007880, 0x006d8000}, {0x00007884, 0xffeffffe}, {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, + {0x00007890, 0x00060aeb}, + {0x00007894, 0x5a108000}, {0x00007898, 0x2a850160}, }; -static const u32 ar9280Modes_fast_clock_9280_2[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00001030, 0x00000268, 0x000004d0}, - {0x00001070, 0x0000018c, 0x00000318}, - {0x000010b0, 0x00000fd0, 0x00001fa0}, - {0x00008014, 0x044c044c, 0x08980898}, - {0x0000801c, 0x148ec02b, 0x148ec057}, - {0x00008318, 0x000044c0, 0x00008980}, - {0x00009820, 0x02020200, 0x02020200}, - {0x00009824, 0x01000f0f, 0x01000f0f}, - {0x00009828, 0x0b020001, 0x0b020001}, - {0x00009834, 0x00000f0f, 0x00000f0f}, - {0x00009844, 0x03721821, 0x03721821}, - {0x00009914, 0x00000898, 0x00001130}, - {0x00009918, 0x0000000b, 0x00000016}, -}; - -static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = { - {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, - {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, - {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, - {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, - {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, - {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, - {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, - {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, - {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, - {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, - {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, - {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, - {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, - {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, - {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, - {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, - {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, - {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, - {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, - {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, - {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, - {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, - {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, - {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, - {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, - {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, - {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, - {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, - {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, - {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, - {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, - {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, - {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, - {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, - {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, - {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, - {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, - {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, - {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, - {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, - {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, - {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, - {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, - {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, - {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, - {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, - {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, - {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10}, - {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b80, 0x00008b80, 0x00008b80}, - {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b84, 0x00008b84, 0x00008b84}, - {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b88, 0x00008b88, 0x00008b88}, - {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b8c, 0x00008b8c, 0x00008b8c}, - {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b90, 0x00008b90, 0x00008b90}, - {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b94, 0x00008b94, 0x00008b94}, - {0x00009adc, 0x0000b390, 0x0000b390, 0x00008b98, 0x00008b98, 0x00008b98}, - {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008ba4, 0x00008ba4, 0x00008ba4}, - {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008ba8, 0x00008ba8, 0x00008ba8}, - {0x00009ae8, 0x0000b780, 0x0000b780, 0x00008bac, 0x00008bac, 0x00008bac}, - {0x00009aec, 0x0000b784, 0x0000b784, 0x00008bb0, 0x00008bb0, 0x00008bb0}, - {0x00009af0, 0x0000b788, 0x0000b788, 0x00008bb4, 0x00008bb4, 0x00008bb4}, - {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008ba1, 0x00008ba1, 0x00008ba1}, - {0x00009af8, 0x0000b790, 0x0000b790, 0x00008ba5, 0x00008ba5, 0x00008ba5}, - {0x00009afc, 0x0000b794, 0x0000b794, 0x00008ba9, 0x00008ba9, 0x00008ba9}, - {0x00009b00, 0x0000b798, 0x0000b798, 0x00008bad, 0x00008bad, 0x00008bad}, - {0x00009b04, 0x0000d784, 0x0000d784, 0x00008bb1, 0x00008bb1, 0x00008bb1}, - {0x00009b08, 0x0000d788, 0x0000d788, 0x00008bb5, 0x00008bb5, 0x00008bb5}, - {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008ba2, 0x00008ba2, 0x00008ba2}, - {0x00009b10, 0x0000d790, 0x0000d790, 0x00008ba6, 0x00008ba6, 0x00008ba6}, - {0x00009b14, 0x0000f780, 0x0000f780, 0x00008baa, 0x00008baa, 0x00008baa}, - {0x00009b18, 0x0000f784, 0x0000f784, 0x00008bae, 0x00008bae, 0x00008bae}, - {0x00009b1c, 0x0000f788, 0x0000f788, 0x00008bb2, 0x00008bb2, 0x00008bb2}, - {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008bb6, 0x00008bb6, 0x00008bb6}, - {0x00009b24, 0x0000f790, 0x0000f790, 0x00008ba3, 0x00008ba3, 0x00008ba3}, - {0x00009b28, 0x0000f794, 0x0000f794, 0x00008ba7, 0x00008ba7, 0x00008ba7}, - {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008bab, 0x00008bab, 0x00008bab}, - {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008baf, 0x00008baf, 0x00008baf}, - {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008bb3, 0x00008bb3, 0x00008bb3}, - {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008bb7, 0x00008bb7, 0x00008bb7}, - {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008bc3, 0x00008bc3, 0x00008bc3}, - {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008bc7, 0x00008bc7, 0x00008bc7}, - {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008bcb, 0x00008bcb, 0x00008bcb}, - {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008bcf, 0x00008bcf, 0x00008bcf}, - {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008bd3, 0x00008bd3, 0x00008bd3}, - {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008bd7, 0x00008bd7, 0x00008bd7}, - {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, - {0x0000a848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, +static const u32 ar9280Modes_9280_2[][6] = { + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, + {0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, + {0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, + {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010}, + {0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, + {0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, + {0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210}, + {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce}, + {0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c}, + {0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444}, + {0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, + {0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000, 0x13c88000}, + {0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, + {0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000, 0x0c000000}, + {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000}, }; -static const u32 ar9280Modes_original_rxgain_9280_2[][6] = { - {0x00009a00, 0x00008184, 0x00008184, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a04, 0x00008188, 0x00008188, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a08, 0x0000818c, 0x0000818c, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a0c, 0x00008190, 0x00008190, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a10, 0x00008194, 0x00008194, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, - {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, - {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, - {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, - {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, - {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, - {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, - {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, - {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, - {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, - {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, - {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, - {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, - {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, - {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, - {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, - {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, - {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, - {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, - {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, - {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, - {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, - {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, - {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, - {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, - {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, - {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, - {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, - {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, - {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, - {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, - {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, - {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, - {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, - {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, - {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, - {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, - {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, - {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, - {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, - {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, - {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, - {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, - {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, - {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, - {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, - {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, - {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, - {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, - {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, - {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, - {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, - {0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c}, - {0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310}, - {0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384}, - {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388}, - {0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324}, - {0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704}, - {0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4}, - {0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8}, - {0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710}, - {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714}, - {0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720}, - {0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724}, - {0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728}, - {0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c}, - {0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0}, - {0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4}, - {0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8}, - {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0}, - {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4}, - {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8}, - {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5}, - {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9}, - {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad}, - {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1}, - {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5}, - {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9}, - {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5}, - {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9}, - {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1}, - {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5}, - {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9}, - {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6}, - {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca}, - {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce}, - {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2}, - {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6}, - {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3}, - {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7}, - {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb}, - {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf}, - {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7}, - {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, - {0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, -}; - -static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = { - {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, - {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, - {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, - {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, - {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, - {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, - {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, - {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, - {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, - {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, - {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, - {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, - {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, - {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, - {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, - {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, - {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, - {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, - {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, - {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, - {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, - {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, - {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, - {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, - {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, - {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, - {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, - {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, - {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, - {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, - {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, - {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, - {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, - {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, - {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, - {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, - {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, - {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, - {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, - {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, - {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, - {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, - {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, - {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, - {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, - {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, - {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, - {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, - {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, - {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, - {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, - {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, - {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, - {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, - {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, - {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, - {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, - {0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310}, - {0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314}, - {0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320}, - {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324}, - {0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328}, - {0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c}, - {0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330}, - {0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334}, - {0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321}, - {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325}, - {0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329}, - {0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d}, - {0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331}, - {0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335}, - {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322}, - {0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326}, - {0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a}, - {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e}, - {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332}, - {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336}, - {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323}, - {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327}, - {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b}, - {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f}, - {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333}, - {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337}, - {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343}, - {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347}, - {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b}, - {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f}, - {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353}, - {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357}, - {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, - {0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, -}; - -static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = { - {0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, - {0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce}, - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002}, - {0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008}, - {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010}, - {0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012}, - {0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014}, - {0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a}, - {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211}, - {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, - {0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411}, - {0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413}, - {0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811}, - {0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813}, - {0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14}, - {0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50}, - {0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c}, - {0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a}, - {0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92}, - {0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2}, - {0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5}, - {0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54}, - {0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5}, - {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, - {0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, - {0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, - {0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, - {0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, - {0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, - {0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, -}; - -static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = { - {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, - {0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce}, - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002}, - {0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009}, - {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b}, - {0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012}, - {0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048}, - {0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a}, - {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211}, - {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, - {0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b}, - {0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412}, - {0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414}, - {0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a}, - {0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649}, - {0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b}, - {0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49}, - {0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48}, - {0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a}, - {0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88}, - {0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a}, - {0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9}, - {0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42}, - {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, - {0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, - {0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, - {0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, - {0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, - {0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, - {0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, -}; - -static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffc}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffd}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { +static const u32 ar9280Common_9280_2[][2] = { /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020015}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00007010, 0x00000033}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x40000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0x00481043}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafa68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x0000a84c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x00009910, 0x01002310}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x0000a920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x2108ecff}, + {0x00009940, 0x14750604}, + {0x0000c95c, 0x004b6a8e}, + {0x00009970, 0x190fb514}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x006f0000}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099c4, 0x06336f77}, + {0x000099c8, 0x6af6532f}, + {0x000099cc, 0x08f186c8}, + {0x000099d0, 0x00046384}, + {0x000099d4, 0x00000000}, + {0x000099d8, 0x00000000}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x000099fc, 0x00001042}, + {0x0000a208, 0x803e4788}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x40206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x233f7180}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a240, 0x38490a20}, + {0x0000a244, 0x00007bb6}, + {0x0000a248, 0x0fff3ffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0cdbd380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0e79e5c6}, + {0x0000b26c, 0x0e79e5c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3c8, 0x00000246}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x00007800, 0x00040000}, + {0x00007804, 0xdb005012}, + {0x00007808, 0x04924914}, + {0x0000780c, 0x21084210}, + {0x00007810, 0x6d801300}, + {0x00007818, 0x07e41000}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb005012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x6d801300}, + {0x0000783c, 0x07e40000}, + {0x00007848, 0x00100000}, + {0x0000784c, 0x773f0567}, + {0x00007850, 0x54214514}, + {0x00007854, 0x12035828}, + {0x00007858, 0x9259269a}, + {0x00007860, 0x52802000}, + {0x00007864, 0x0a8e370e}, + {0x00007868, 0xc0102850}, + {0x0000786c, 0x812d4000}, + {0x00007870, 0x807ec400}, + {0x00007874, 0x001b6db0}, + {0x00007878, 0x00376b63}, + {0x0000787c, 0x06db6db6}, + {0x00007880, 0x006d8000}, + {0x00007884, 0xffeffffe}, + {0x00007888, 0xffeffffe}, + {0x0000788c, 0x00010000}, + {0x00007890, 0x02060aeb}, + {0x00007898, 0x2a850160}, +}; + +static const u32 ar9280Modes_fast_clock_9280_2[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, + {0x000010b0, 0x00000fd0, 0x00001fa0}, + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, + {0x00009820, 0x02020200, 0x02020200}, + {0x00009824, 0x01000f0f, 0x01000f0f}, + {0x00009828, 0x0b020001, 0x0b020001}, + {0x00009834, 0x00000f0f, 0x00000f0f}, + {0x00009844, 0x03721821, 0x03721821}, + {0x00009914, 0x00000898, 0x00001130}, + {0x00009918, 0x0000000b, 0x00000016}, +}; + +static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = { + {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, + {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, + {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b80, 0x00008b80, 0x00008b80}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b84, 0x00008b84, 0x00008b84}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b88, 0x00008b88, 0x00008b88}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b8c, 0x00008b8c, 0x00008b8c}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b90, 0x00008b90, 0x00008b90}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b94, 0x00008b94, 0x00008b94}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008b98, 0x00008b98, 0x00008b98}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008ba4, 0x00008ba4, 0x00008ba4}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008ba8, 0x00008ba8, 0x00008ba8}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x00008bac, 0x00008bac, 0x00008bac}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00008bb0, 0x00008bb0, 0x00008bb0}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00008bb4, 0x00008bb4, 0x00008bb4}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008ba1, 0x00008ba1, 0x00008ba1}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00008ba5, 0x00008ba5, 0x00008ba5}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x00008ba9, 0x00008ba9, 0x00008ba9}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x00008bad, 0x00008bad, 0x00008bad}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x00008bb1, 0x00008bb1, 0x00008bb1}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00008bb5, 0x00008bb5, 0x00008bb5}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008ba2, 0x00008ba2, 0x00008ba2}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00008ba6, 0x00008ba6, 0x00008ba6}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x00008baa, 0x00008baa, 0x00008baa}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00008bae, 0x00008bae, 0x00008bae}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x00008bb2, 0x00008bb2, 0x00008bb2}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008bb6, 0x00008bb6, 0x00008bb6}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x00008ba3, 0x00008ba3, 0x00008ba3}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x00008ba7, 0x00008ba7, 0x00008ba7}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008bab, 0x00008bab, 0x00008bab}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008baf, 0x00008baf, 0x00008baf}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008bb3, 0x00008bb3, 0x00008bb3}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008bb7, 0x00008bb7, 0x00008bb7}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008bc3, 0x00008bc3, 0x00008bc3}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008bc7, 0x00008bc7, 0x00008bc7}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008bcb, 0x00008bcb, 0x00008bcb}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008bcf, 0x00008bcf, 0x00008bcf}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008bd3, 0x00008bd3, 0x00008bd3}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008bd7, 0x00008bd7, 0x00008bd7}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, +}; + +static const u32 ar9280Modes_original_rxgain_9280_2[][6] = { + {0x00009a00, 0x00008184, 0x00008184, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a04, 0x00008188, 0x00008188, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a10, 0x00008194, 0x00008194, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, +}; + +static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = { + {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, + {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, + {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, + {0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, +}; + +static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = { + {0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, + {0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002}, + {0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008}, + {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010}, + {0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012}, + {0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014}, + {0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a}, + {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211}, + {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, + {0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411}, + {0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413}, + {0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811}, + {0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813}, + {0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14}, + {0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50}, + {0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c}, + {0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a}, + {0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92}, + {0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2}, + {0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5}, + {0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54}, + {0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5}, + {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, + {0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, + {0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, + {0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, + {0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, + {0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, + {0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, +}; + +static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = { + {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, + {0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002}, + {0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009}, + {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b}, + {0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012}, + {0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048}, + {0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a}, + {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211}, + {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, + {0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b}, + {0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412}, + {0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414}, + {0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a}, + {0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649}, + {0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b}, + {0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49}, + {0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48}, + {0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a}, + {0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88}, + {0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a}, + {0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9}, + {0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42}, + {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, + {0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, + {0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, + {0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, + {0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, + {0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, + {0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, +}; + +static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = { + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffc}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, +}; + +static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = { + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffd}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, +}; + +static const u32 ar9285Modes_9285[][6] = { + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0}, + {0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e, 0x00001059}, + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e}, + {0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18}, + {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d}, + {0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020, 0xdfbc1010}, + {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c}, + {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000}, + {0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000}, + {0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000}, + {0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000}, + {0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000}, + {0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000}, + {0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000}, + {0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000}, + {0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000}, + {0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000}, + {0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000}, + {0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000}, + {0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000}, + {0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000}, + {0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000}, + {0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000}, + {0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000}, + {0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000}, + {0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000}, + {0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000}, + {0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000}, + {0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000}, + {0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000}, + {0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000}, + {0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000}, + {0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000}, + {0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000}, + {0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000}, + {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, + {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, + {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, + {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, + {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, + {0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000}, + {0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000}, + {0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000}, + {0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000}, + {0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000}, + {0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000}, + {0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000}, + {0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000}, + {0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000}, + {0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000}, + {0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000}, + {0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000}, + {0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000}, + {0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000}, + {0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000}, + {0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000}, + {0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000}, + {0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000}, + {0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000}, + {0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000}, + {0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000}, + {0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000}, + {0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000}, + {0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000}, + {0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000}, + {0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000}, + {0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000}, + {0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000}, + {0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000}, + {0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000}, + {0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000}, + {0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000}, + {0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000}, + {0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000}, + {0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000}, + {0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000}, + {0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000}, + {0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000}, + {0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000}, + {0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000}, + {0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000}, + {0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000}, + {0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000}, + {0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000}, + {0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000}, + {0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000}, + {0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000}, + {0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000}, + {0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000}, + {0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000}, + {0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000}, + {0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000}, + {0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000}, + {0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000}, + {0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000}, + {0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000}, + {0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000}, + {0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000}, + {0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000}, + {0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000}, + {0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000}, + {0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000}, + {0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000}, + {0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000}, + {0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000}, + {0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000}, + {0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000}, + {0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000}, + {0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000}, + {0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000}, + {0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000}, + {0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000}, + {0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000}, + {0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000}, + {0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000}, + {0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000}, + {0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000}, + {0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000}, + {0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000}, + {0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000}, + {0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000}, + {0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000}, + {0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000}, + {0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000}, + {0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000}, + {0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000}, + {0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000}, + {0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000}, + {0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000}, + {0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000}, + {0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000}, + {0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000}, + {0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000}, + {0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000}, + {0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000}, + {0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000}, + {0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000}, + {0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000}, + {0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000}, + {0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000}, + {0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000}, + {0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000}, + {0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000}, + {0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000}, + {0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000}, + {0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000}, + {0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000}, + {0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000}, + {0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000}, + {0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000}, + {0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000}, + {0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000}, + {0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000}, + {0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000}, + {0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000}, + {0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000}, + {0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000}, + {0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000}, + {0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000}, + {0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000}, + {0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000}, + {0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000}, + {0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000}, + {0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000}, + {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004}, + {0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000, 0x001da000}, + {0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de, 0x00000000}, + {0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e, 0x00000000}, + {0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e, 0x00000000}, + {0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, +}; + +static const u32 ar9285Common_9285[][2] = { + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020045}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00007010, 0x00000031}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x00000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008120, 0x08f04800}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0x00000000}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081d0, 0x00003210}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000001}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00000000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x00010380}, + {0x00008344, 0x00481043}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafe68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x00009910, 0x01002310}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009940, 0x14750604}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x2108ecff}, + {0x00009968, 0x000003ce}, + {0x00009970, 0x1927b515}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x2def0a00}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x0000a208, 0x803e6788}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x00206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x00000000}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a244, 0x00000000}, + {0x0000a248, 0xfffffffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0ccb5380}, + {0x0000a25c, 0x15151501}, + {0x0000a260, 0xdfa90f01}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0ebae9e6}, + {0x0000d270, 0x0d820820}, + {0x0000a278, 0x39ce739c}, + {0x0000a27c, 0x050e039c}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x39ce739c}, + {0x0000a398, 0x0000039c}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x39ce739c}, + {0x0000a3e0, 0x0000039c}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x0000a3ec, 0x00f70081}, + {0x00007800, 0x00140000}, + {0x00007804, 0x0e4548d8}, + {0x00007808, 0x54214514}, + {0x0000780c, 0x02025820}, + {0x00007810, 0x71c0d388}, + {0x00007814, 0x924934a8}, + {0x0000781c, 0x00000000}, + {0x00007820, 0x00000c04}, + {0x00007824, 0x00d86fff}, + {0x00007828, 0x26d2491b}, + {0x0000782c, 0x6e36d97b}, + {0x00007830, 0xedb6d96c}, + {0x00007834, 0x71400086}, + {0x00007838, 0xfac68800}, + {0x0000783c, 0x0001fffe}, + {0x00007840, 0xffeb1a20}, + {0x00007844, 0x000c0db6}, + {0x00007848, 0x6db61b6f}, + {0x0000784c, 0x6d9b66db}, + {0x00007850, 0x6d8c6dba}, + {0x00007854, 0x00040000}, + {0x00007858, 0xdb003012}, + {0x0000785c, 0x04924914}, + {0x00007860, 0x21084210}, + {0x00007864, 0xf7d7ffde}, + {0x00007868, 0xc2034080}, + {0x0000786c, 0x48609eb4}, + {0x00007870, 0x10142c00}, +}; + +static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, {0x00004040, 0x13160820}, {0x00004040, 0xe5980560}, {0x00004040, 0xc01dcffd}, @@ -1248,14 +2454,568 @@ static const u32 ar9285Modes_9285_1_2[][6] = { {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, +}; + +static const u32 ar9285Common_9285_1_2[][2] = { + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020045}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00007010, 0x00000031}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x00000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008120, 0x08f04810}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081d0, 0x0000320a}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000001}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x00010380}, + {0x00008344, 0x00481043}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafe68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x00009910, 0x01002310}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009940, 0x14750604}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x2108ecff}, + {0x00009968, 0x000003ce}, + {0x00009970, 0x192bb514}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x2def0400}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x0000a208, 0x803e68c8}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x00206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x00000000}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a244, 0x00000000}, + {0x0000a248, 0xfffffffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0ccb5380}, + {0x0000a25c, 0x15151501}, + {0x0000a260, 0xdfa90f01}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0ebae9e6}, + {0x0000d270, 0x0d820820}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x0000a3ec, 0x00f70081}, + {0x00007800, 0x00140000}, + {0x00007804, 0x0e4548d8}, + {0x00007808, 0x54214514}, + {0x0000780c, 0x02025830}, + {0x00007810, 0x71c0d388}, + {0x0000781c, 0x00000000}, + {0x00007824, 0x00d86fff}, + {0x0000782c, 0x6e36d97b}, + {0x00007834, 0x71400087}, + {0x00007844, 0x000c0db6}, + {0x00007848, 0x6db6246f}, + {0x0000784c, 0x6d9b66db}, + {0x00007850, 0x6d8c6dba}, + {0x00007854, 0x00040000}, + {0x00007858, 0xdb003012}, + {0x0000785c, 0x04924914}, + {0x00007860, 0x21084210}, + {0x00007864, 0xf7d7ffde}, + {0x00007868, 0xc2034080}, + {0x00007870, 0x10142c00}, +}; + +static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, + {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, + {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, + {0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803}, + {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, + {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, + {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, + {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, + {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, +}; + +static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = { + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, + {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, + {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, + {0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801}, + {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, + {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, + {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, + {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, +}; + +static const u32 ar9285Modes_XE2_0_normal_power[][6] = { + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, + {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, + {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae}, + {0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441}, + {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, + {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, + {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, + {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, +}; + +static const u32 ar9285Modes_XE2_0_high_power[][6] = { + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, + {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, + {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e}, + {0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443}, + {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, + {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, + {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, + {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, + {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, +}; + +static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffd}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, +}; + +static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffc}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, +}; + +static const u32 ar9287Modes_9287_1_0[][6] = { + {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x00000000, 0x00000000, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0}, + {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, + {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18}, + {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881}, + {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010}, + {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, + {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, + {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210}, + {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce}, + {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c}, + {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444}, + {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000}, {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, + {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; -static const u32 ar9285Common_9285_1_2[][2] = { +static const u32 ar9287Common_9287_1_0[][2] = { /* Addr allmodes */ {0x0000000c, 0x00000000}, - {0x00000030, 0x00020045}, + {0x00000030, 0x00020015}, {0x00000034, 0x00000005}, {0x00000040, 0x00000000}, {0x00000044, 0x00000008}, @@ -1340,7 +3100,8 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x00004024, 0x0000001f}, {0x00004060, 0x00000000}, {0x00004064, 0x00000000}, - {0x00007010, 0x00000031}, + {0x00007010, 0x00000033}, + {0x00007020, 0x00000000}, {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, {0x00008004, 0x00000000}, @@ -1350,7 +3111,7 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x00008020, 0x00000000}, {0x00008038, 0x00000000}, {0x0000803c, 0x00000000}, - {0x00008048, 0x00000000}, + {0x00008048, 0x40000000}, {0x00008054, 0x00000000}, {0x00008058, 0x00000000}, {0x0000805c, 0x000fc78f}, @@ -1379,7 +3140,6 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x00008110, 0x00000168}, {0x00008118, 0x000100aa}, {0x0000811c, 0x00003210}, - {0x00008120, 0x08f04810}, {0x00008124, 0x00000000}, {0x00008128, 0x00000000}, {0x0000812c, 0x00000000}, @@ -1390,12 +3150,13 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x00008144, 0xffffffff}, {0x00008168, 0x00000000}, {0x0000816c, 0x00000000}, - {0x00008170, 0x32143320}, + {0x00008170, 0x18487320}, {0x00008174, 0xfaa4fa50}, {0x00008178, 0x00000100}, {0x0000817c, 0x00000000}, {0x000081c0, 0x00000000}, - {0x000081d0, 0x0000320a}, + {0x000081c4, 0x00000000}, + {0x000081d4, 0x00000000}, {0x000081ec, 0x00000000}, {0x000081f0, 0x00000000}, {0x000081f4, 0x00000000}, @@ -1433,20 +3194,34 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x0000827c, 0x00000000}, {0x00008284, 0x0000002c}, {0x00008288, 0x0000002c}, - {0x0000828c, 0x00000000}, + {0x0000828c, 0x000000ff}, {0x00008294, 0x00000000}, {0x00008298, 0x00000000}, {0x0000829c, 0x00000000}, {0x00008300, 0x00000040}, {0x00008314, 0x00000000}, {0x00008328, 0x00000000}, - {0x0000832c, 0x00000001}, + {0x0000832c, 0x00000007}, {0x00008330, 0x00000302}, {0x00008334, 0x00000e00}, {0x00008338, 0x00ff0000}, {0x0000833c, 0x00000000}, - {0x00008340, 0x00010380}, - {0x00008344, 0x00481043}, + {0x00008340, 0x000107ff}, + {0x00008344, 0x01c81043}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0x0fffffff}, + {0x00008394, 0x0fffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, {0x00009808, 0x00000000}, {0x0000980c, 0xafe68e30}, {0x00009810, 0xfd14e000}, @@ -1456,69 +3231,80 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x00009830, 0x00000000}, {0x0000983c, 0x00200400}, {0x0000984c, 0x0040233c}, + {0x0000a84c, 0x0040233c}, {0x00009854, 0x00000044}, {0x00009900, 0x00000000}, {0x00009904, 0x00000000}, {0x00009908, 0x00000000}, {0x0000990c, 0x00000000}, - {0x00009910, 0x01002310}, + {0x00009910, 0x10002310}, {0x0000991c, 0x10000fff}, {0x00009920, 0x04900000}, + {0x0000a920, 0x04900000}, {0x00009928, 0x00000001}, {0x0000992c, 0x00000004}, + {0x00009930, 0x00000000}, + {0x0000a930, 0x00000000}, {0x00009934, 0x1e1f2022}, {0x00009938, 0x0a0b0c0d}, {0x0000993c, 0x00000000}, - {0x00009940, 0x14750604}, {0x00009948, 0x9280c00a}, {0x0000994c, 0x00020028}, {0x00009954, 0x5f3ca3de}, - {0x00009958, 0x2108ecff}, - {0x00009968, 0x000003ce}, - {0x00009970, 0x192bb514}, + {0x00009958, 0x0108ecff}, + {0x00009940, 0x14750604}, + {0x0000c95c, 0x004b6a8e}, + {0x00009970, 0x990bb515}, {0x00009974, 0x00000000}, {0x00009978, 0x00000001}, {0x0000997c, 0x00000000}, - {0x00009980, 0x00000000}, - {0x00009984, 0x00000000}, - {0x00009988, 0x00000000}, - {0x0000998c, 0x00000000}, - {0x00009990, 0x00000000}, - {0x00009994, 0x00000000}, - {0x00009998, 0x00000000}, - {0x0000999c, 0x00000000}, {0x000099a0, 0x00000000}, {0x000099a4, 0x00000001}, {0x000099a8, 0x201fff00}, - {0x000099ac, 0x2def0400}, + {0x000099ac, 0x0c6f0000}, {0x000099b0, 0x03051000}, {0x000099b4, 0x00000820}, + {0x000099c4, 0x06336f77}, + {0x000099c8, 0x6af65329}, + {0x000099cc, 0x08f186c8}, + {0x000099d0, 0x00046384}, {0x000099dc, 0x00000000}, {0x000099e0, 0x00000000}, {0x000099e4, 0xaaaaaaaa}, {0x000099e8, 0x3c466478}, {0x000099ec, 0x0cc80caa}, {0x000099f0, 0x00000000}, - {0x0000a208, 0x803e68c8}, + {0x000099fc, 0x00001042}, + {0x0000a1f4, 0x00fffeff}, + {0x0000a1f8, 0x00f5f9ff}, + {0x0000a1fc, 0xb79f6427}, + {0x0000a208, 0x803e4788}, {0x0000a210, 0x4080a333}, - {0x0000a214, 0x00206c10}, + {0x0000a214, 0x40206c10}, {0x0000a218, 0x009c4060}, {0x0000a220, 0x01834061}, {0x0000a224, 0x00000400}, {0x0000a228, 0x000003b5}, - {0x0000a22c, 0x00000000}, + {0x0000a22c, 0x233f7180}, {0x0000a234, 0x20202020}, {0x0000a238, 0x20202020}, + {0x0000a23c, 0x13c889af}, + {0x0000a240, 0x38490a20}, {0x0000a244, 0x00000000}, {0x0000a248, 0xfffffffc}, {0x0000a24c, 0x00000000}, {0x0000a254, 0x00000000}, - {0x0000a258, 0x0ccb5380}, - {0x0000a25c, 0x15151501}, - {0x0000a260, 0xdfa90f01}, + {0x0000a258, 0x0cdbd380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a264, 0x00418a11}, + {0x0000b264, 0x00418a11}, {0x0000a268, 0x00000000}, - {0x0000a26c, 0x0ebae9e6}, - {0x0000d270, 0x0d820820}, + {0x0000a26c, 0x0e79e5c6}, + {0x0000b26c, 0x0e79e5c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000a27c, 0x050701ce}, {0x0000d35c, 0x07ffffef}, {0x0000d360, 0x0fffffe7}, {0x0000d364, 0x17ffffe5}, @@ -1529,210 +3315,385 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x0000d378, 0x5fffffe2}, {0x0000d37c, 0x7fffffe2}, {0x0000d380, 0x7f3c7bba}, - {0x0000d384, 0xf3307ff0}, - {0x0000a388, 0x0c000000}, - {0x0000a38c, 0x20202020}, - {0x0000a390, 0x20202020}, - {0x0000a39c, 0x00000001}, - {0x0000a3a0, 0x00000000}, - {0x0000a3a4, 0x00000000}, - {0x0000a3a8, 0x00000000}, - {0x0000a3ac, 0x00000000}, - {0x0000a3b0, 0x00000000}, - {0x0000a3b4, 0x00000000}, - {0x0000a3b8, 0x00000000}, - {0x0000a3bc, 0x00000000}, - {0x0000a3c0, 0x00000000}, - {0x0000a3c4, 0x00000000}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000b398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3c8, 0x00000246}, {0x0000a3cc, 0x20202020}, {0x0000a3d0, 0x20202020}, {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, {0x0000a3e4, 0x00000000}, {0x0000a3e8, 0x18c43433}, {0x0000a3ec, 0x00f70081}, - {0x00007800, 0x00140000}, - {0x00007804, 0x0e4548d8}, - {0x00007808, 0x54214514}, - {0x0000780c, 0x02025830}, - {0x00007810, 0x71c0d388}, - {0x0000781c, 0x00000000}, - {0x00007824, 0x00d86fff}, - {0x0000782c, 0x6e36d97b}, - {0x00007834, 0x71400087}, - {0x00007844, 0x000c0db6}, - {0x00007848, 0x6db6246f}, - {0x0000784c, 0x6d9b66db}, - {0x00007850, 0x6d8c6dba}, - {0x00007854, 0x00040000}, - {0x00007858, 0xdb003012}, - {0x0000785c, 0x04924914}, - {0x00007860, 0x21084210}, - {0x00007864, 0xf7d7ffde}, - {0x00007868, 0xc2034080}, - {0x00007870, 0x10142c00}, -}; - -static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, - {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, - {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, - {0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803}, - {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, - {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, - {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, - {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, - {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, - {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, - {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, -}; - -static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, - {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, - {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, - {0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801}, - {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, - {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, - {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, - {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, - {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, - {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, - {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, - {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a3f0, 0x01036a1e}, + {0x0000a3f4, 0x00000000}, + {0x0000b3f4, 0x00000000}, + {0x0000a7d8, 0x00000001}, + {0x00007800, 0x00000800}, + {0x00007804, 0x6c35ffb0}, + {0x00007808, 0x6db6c000}, + {0x0000780c, 0x6db6cb30}, + {0x00007810, 0x6db6cb6c}, + {0x00007814, 0x0501e200}, + {0x00007818, 0x0094128d}, + {0x0000781c, 0x976ee392}, + {0x00007820, 0xf75ff6fc}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb003012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x00140000}, + {0x00007838, 0x0e4548d8}, + {0x0000783c, 0x54214514}, + {0x00007840, 0x02025820}, + {0x00007844, 0x71c0d388}, + {0x00007848, 0x934934a8}, + {0x00007850, 0x00000000}, + {0x00007854, 0x00000800}, + {0x00007858, 0x6c35ffb0}, + {0x0000785c, 0x6db6c000}, + {0x00007860, 0x6db6cb2c}, + {0x00007864, 0x6db6cb6c}, + {0x00007868, 0x0501e200}, + {0x0000786c, 0x0094128d}, + {0x00007870, 0x976ee392}, + {0x00007874, 0xf75ff6fc}, + {0x00007878, 0x00040000}, + {0x0000787c, 0xdb003012}, + {0x00007880, 0x04924914}, + {0x00007884, 0x21084210}, + {0x00007888, 0x001b6db0}, + {0x0000788c, 0x00376b63}, + {0x00007890, 0x06db6db6}, + {0x00007894, 0x006d8000}, + {0x00007898, 0x48100000}, + {0x0000789c, 0x00000000}, + {0x000078a0, 0x08000000}, + {0x000078a4, 0x0007ffd8}, + {0x000078a8, 0x0007ffd8}, + {0x000078ac, 0x001c0020}, + {0x000078b0, 0x000611eb}, + {0x000078b4, 0x40008080}, + {0x000078b8, 0x2a850160}, }; -static const u32 ar9285Modes_XE2_0_normal_power[][6] = { +static const u32 ar9287Modes_tx_gain_9287_1_0[][6] = { {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, - {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, - {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae}, - {0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441}, - {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, - {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, - {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, - {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, - {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, - {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, - {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, - {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c}, + {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b}, + {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a}, + {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a}, + {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a}, + {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, + {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a}, + {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a}, + {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c}, + {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc}, + {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4}, + {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc}, + {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede}, + {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, + {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e}, + {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e}, + {0x0000a780, 0x00000000, 0x00000000, 0x00000060, 0x00000060, 0x00000060}, + {0x0000a784, 0x00000000, 0x00000000, 0x00004062, 0x00004062, 0x00004062}, + {0x0000a788, 0x00000000, 0x00000000, 0x00008064, 0x00008064, 0x00008064}, + {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0a4, 0x0000c0a4, 0x0000c0a4}, + {0x0000a790, 0x00000000, 0x00000000, 0x000100b0, 0x000100b0, 0x000100b0}, + {0x0000a794, 0x00000000, 0x00000000, 0x000140b2, 0x000140b2, 0x000140b2}, + {0x0000a798, 0x00000000, 0x00000000, 0x000180b4, 0x000180b4, 0x000180b4}, + {0x0000a79c, 0x00000000, 0x00000000, 0x0001c0f4, 0x0001c0f4, 0x0001c0f4}, + {0x0000a7a0, 0x00000000, 0x00000000, 0x00020134, 0x00020134, 0x00020134}, + {0x0000a7a4, 0x00000000, 0x00000000, 0x000240fe, 0x000240fe, 0x000240fe}, + {0x0000a7a8, 0x00000000, 0x00000000, 0x0002813e, 0x0002813e, 0x0002813e}, + {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c17e, 0x0002c17e, 0x0002c17e}, + {0x0000a7b0, 0x00000000, 0x00000000, 0x000301be, 0x000301be, 0x000301be}, + {0x0000a7b4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7b8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7bc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7c0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7c4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7c8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7cc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7d0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a7d4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe}, + {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000}, }; -static const u32 ar9285Modes_XE2_0_high_power[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, - {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, - {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e}, - {0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443}, - {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, - {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, - {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, - {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, - {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, - {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, - {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, +static const u32 ar9287Modes_rx_gain_9287_1_0[][6] = { + {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, + {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, + {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, + {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, + {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, + {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, + {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, + {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, + {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, + {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, + {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, + {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, + {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, + {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, + {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, + {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, + {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, + {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, + {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, + {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, + {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, + {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, + {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, + {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, + {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, + {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, + {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, + {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, + {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, + {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, + {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, + {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, + {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, + {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, + {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, + {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, + {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, + {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, + {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, + {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, + {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, + {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, + {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, + {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, + {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, + {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, + {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, + {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, + {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, + {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, + {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, + {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, + {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, + {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, + {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, + {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, + {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, + {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, + {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, + {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, + {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, + {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, + {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, + {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, + {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, + {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, + {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, + {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, + {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, + {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, + {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, + {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, + {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, + {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, + {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, + {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, + {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, + {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, + {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, + {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, + {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, + {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, + {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, + {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, + {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, + {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, + {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, + {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, + {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, + {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, + {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, + {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, + {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, + {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, + {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, + {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, + {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, + {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, + {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, + {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, + {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, + {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, + {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, + {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, + {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, + {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, + {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, + {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, + {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, + {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, + {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, + {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, + {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, + {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, + {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, + {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, + {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, + {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, + {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, + {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, + {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, + {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, + {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, + {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, + {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, + {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, + {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, + {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, + {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, + {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, + {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, + {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, + {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, + {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, + {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, + {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, + {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, + {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, + {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, + {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, + {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, + {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, + {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, + {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, + {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, + {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, + {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, + {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, + {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, + {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, + {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, + {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, + {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, + {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, + {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, + {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, + {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, + {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, + {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, + {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, + {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, + {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, + {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, + {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, + {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, + {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, + {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, + {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, + {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, + {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, + {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, + {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, + {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, + {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, + {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, + {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, }; -static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { +static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = { /* Addr allmodes */ {0x00004040, 0x9248fd00}, {0x00004040, 0x24924924}, @@ -1746,7 +3707,7 @@ static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { {0x00004044, 0x00000000}, }; -static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { +static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = { /* Addr allmodes */ {0x00004040, 0x9248fd00}, {0x00004040, 0x24924924}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c index adbf031fbc5a..4922b8d4a938 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -477,8 +477,7 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah, nfarray[0] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); - if (IS_CHAN_HT40(ah->curchan)) - nfarray[3] = sign_extend(nf, 9); + nfarray[3] = sign_extend(nf, 9); if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) return; @@ -487,8 +486,7 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah, nfarray[1] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); - if (IS_CHAN_HT40(ah->curchan)) - nfarray[4] = sign_extend(nf, 9); + nfarray[4] = sign_extend(nf, 9); } static void ar9002_hw_set_nf_limits(struct ath_hw *ah) diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 5b995bee70ae..06ef71019c12 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -579,39 +579,12 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; if ((rxsp->status11 & AR_RxFrameOK) == 0) { - /* - * AR_CRCErr will bet set to true if we're on the last - * subframe and the AR_PostDelimCRCErr is caught. - * In a way this also gives us a guarantee that when - * (!(AR_CRCErr) && (AR_PostDelimCRCErr)) we cannot - * possibly be reviewing the last subframe. AR_CRCErr - * is the CRC of the actual data. - */ if (rxsp->status11 & AR_CRCErr) { rxs->rs_status |= ATH9K_RXERR_CRC; } else if (rxsp->status11 & AR_PHYErr) { + rxs->rs_status |= ATH9K_RXERR_PHY; phyerr = MS(rxsp->status11, AR_PHYErrCode); - /* - * If we reach a point here where AR_PostDelimCRCErr is - * true it implies we're *not* on the last subframe. In - * in that case that we know already that the CRC of - * the frame was OK, and MAC would send an ACK for that - * subframe, even if we did get a phy error of type - * ATH9K_PHYERR_OFDM_RESTART. This is only applicable - * to frame that are prior to the last subframe. - * The AR_PostDelimCRCErr is the CRC for the MPDU - * delimiter, which contains the 4 reserved bits, - * the MPDU length (12 bits), and follows the MPDU - * delimiter for an A-MPDU subframe (0x4E = 'N' ASCII). - */ - if ((phyerr == ATH9K_PHYERR_OFDM_RESTART) && - (rxsp->status11 & AR_PostDelimCRCErr)) { - rxs->rs_phyerr = 0; - } else { - rxs->rs_status |= ATH9K_RXERR_PHY; - rxs->rs_phyerr = phyerr; - } - + rxs->rs_phyerr = phyerr; } else if (rxsp->status11 & AR_DecryptCRCErr) { rxs->rs_status |= ATH9K_RXERR_DECRYPT; } else if (rxsp->status11 & AR_MichaelErr) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c index a753a431bb13..7c93338540ae 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1029,9 +1029,6 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah, nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); nfarray[2] = sign_extend(nf, 9); - if (!IS_CHAN_HT40(ah->curchan)) - return; - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); nfarray[3] = sign_extend(nf, 9); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 998ae2c49ed2..6e486a508edb 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -687,7 +687,7 @@ bool ath9k_all_wiphys_idle(struct ath_softc *sc); void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); -bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); +void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); void ath_start_rfkill_poll(struct ath_softc *sc); extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); diff --git a/trunk/drivers/net/wireless/ath/ath9k/calib.c b/trunk/drivers/net/wireless/ath/ath9k/calib.c index 139289e4e933..7f4c55f90e74 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/calib.c @@ -172,9 +172,26 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) struct ath9k_nfcal_hist *h; unsigned i, j; int32_t val; - u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; + u8 chainmask; struct ath_common *common = ath9k_hw_common(ah); + if (AR_SREV_9300_20_OR_LATER(ah)) + chainmask = 0x3F; + else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) + chainmask = 0x9; + else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { + if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4)) + chainmask = 0x1B; + else + chainmask = 0x09; + } else { + if (ah->rxchainmask & 0x4) + chainmask = 0x3F; + else if (ah->rxchainmask & 0x2) + chainmask = 0x1B; + else + chainmask = 0x09; + } h = ah->nfCalHist; for (i = 0; i < NUM_NF_READINGS; i++) { @@ -261,7 +278,7 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) ath_print(common, ATH_DBG_CALIBRATE, "NF calibrated [%s] [chain %d] is %d\n", - (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); + (i > 3 ? "ext" : "ctl"), i % 3, nf[i]); if (nf[i] > limit->max) { ath_print(common, ATH_DBG_CALIBRATE, diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 9cccd12e8f21..afafc4d4b8fb 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -222,7 +222,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_data_per_freq_4k *pRawDataSet, u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, + u16 tPdGainOverlap, int16_t *pMinCalPower, u16 *pPdGainBoundaries, u8 *pPDADCValues, u16 numXpdGains) { @@ -308,6 +308,8 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, } } + *pMinCalPower = (int16_t)(minPwrT4[0] / 2); + k = 0; for (i = 0; i < numXpdGains; i++) { @@ -397,6 +399,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK]; u16 numPiers, i, j; + int16_t tMinCalPower; u16 numXpdGain, xpdMask; u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; u32 reg32, regOffset, regChainOffset; @@ -449,7 +452,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, - gainBoundaries, + &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); ENABLE_REGWRITE_BUFFER(ah); diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 4a52cf03808b..37207dfd1799 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -223,6 +223,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, struct cal_data_per_freq_ar9287 *pRawDataSet, u8 *bChans, u16 availPiers, u16 tPdGainOverlap, + int16_t *pMinCalPower, u16 *pPdGainBoundaries, u8 *pPDADCValues, u16 numXpdGains) @@ -302,6 +303,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, } } + *pMinCalPower = (int16_t)(minPwrT4[0] / 2); k = 0; for (i = 0; i < numXpdGains; i++) { @@ -456,6 +458,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; u16 numPiers = 0, i, j; + int16_t tMinCalPower; u16 numXpdGain, xpdMask; u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; u32 reg32, regOffset, regChainOffset, regval; @@ -527,6 +530,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, + &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c index afa2b73ddbdd..02e6c2a55fe4 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -593,7 +593,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_data_per_freq *pRawDataSet, u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, + u16 tPdGainOverlap, int16_t *pMinCalPower, u16 *pPdGainBoundaries, u8 *pPDADCValues, u16 numXpdGains) { @@ -675,6 +675,8 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, } } + *pMinCalPower = (int16_t)(minPwrT4[0] / 2); + k = 0; for (i = 0; i < numXpdGains; i++) { @@ -836,7 +838,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; u16 numPiers, i, j; - int16_t diff = 0; + int16_t tMinCalPower, diff = 0; u16 numXpdGain, xpdMask; u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; u32 reg32, regOffset, regChainOffset; @@ -921,6 +923,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, + &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c index cf9bcc67ade2..e38ca66db849 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -438,11 +438,10 @@ static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv, bss_conf->bssid, be32_to_cpu(trate.capflags)); } -static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - enum ieee80211_ampdu_mlme_action action, - u16 tid) +int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_ampdu_mlme_action action, u16 tid) { struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_htc_target_aggr aggr; @@ -493,7 +492,8 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_priv *priv = + (struct ath9k_htc_priv *) file->private_data; struct ath9k_htc_target_stats cmd_rsp; char buf[512]; unsigned int len = 0; @@ -524,9 +524,6 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%19s : %10u\n", "TX Rate", priv->debug.txrate); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -539,7 +536,8 @@ static const struct file_operations fops_tgt_stats = { static ssize_t read_file_xmit(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_priv *priv = + (struct ath9k_htc_priv *) file->private_data; char buf[512]; unsigned int len = 0; @@ -572,9 +570,6 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, "%20s : %10u\n", "VO queued", priv->debug.tx_stats.queue_stats[WME_AC_VO]); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -587,7 +582,8 @@ static const struct file_operations fops_xmit = { static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_priv *priv = + (struct ath9k_htc_priv *) file->private_data; char buf[512]; unsigned int len = 0; @@ -601,9 +597,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, "%20s : %10u\n", "SKBs Dropped", priv->debug.rx_stats.skb_dropped); - if (len > sizeof(buf)) - len = sizeof(buf); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 8d291ccf5c88..2f83f975b891 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -532,8 +532,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && - !ah->is_pciexpress)) { + (AR_SREV_9280(ah) && !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; } else { diff --git a/trunk/drivers/net/wireless/ath/ath9k/init.c b/trunk/drivers/net/wireless/ath/ath9k/init.c index 243c1775f343..fe730cb16ec2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/init.c @@ -787,12 +787,12 @@ void ath9k_deinit_device(struct ath_softc *sc) ieee80211_unregister_hw(aphy->hw); ieee80211_free_hw(aphy->hw); } + kfree(sc->sec_wiphy); ieee80211_unregister_hw(hw); ath_rx_cleanup(sc); ath_tx_cleanup(sc); ath9k_deinit_softc(sc); - kfree(sc->sec_wiphy); } void ath_descdma_cleanup(struct ath_softc *sc, diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 0429dda0961f..4c0831ff6e92 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -279,7 +279,7 @@ void ath_paprd_calibrate(struct work_struct *work) hdr = (struct ieee80211_hdr *)skb->data; ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; hdr->frame_control = cpu_to_le16(ftype); - hdr->duration_id = cpu_to_le16(10); + hdr->duration_id = 10; memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); @@ -857,14 +857,9 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_ps_wakeup(sc); ieee80211_stop_queues(hw); - /* - * Keep the LED on when the radio is disabled - * during idle unassociated state. - */ - if (!sc->ps_idle) { - ath9k_hw_set_gpio(ah, ah->led_pin, 1); - ath9k_hw_cfg_gpio_input(ah, ah->led_pin); - } + /* Disable LED */ + ath9k_hw_set_gpio(ah, ah->led_pin, 1); + ath9k_hw_cfg_gpio_input(ah, ah->led_pin); /* Disable interrupts */ ath9k_hw_set_interrupts(ah, 0); @@ -1269,7 +1264,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - int i; mutex_lock(&sc->mutex); @@ -1282,12 +1276,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i]) - break; - } - - if (i == sc->num_sec_wiphy) { + if (!sc->num_sec_wiphy) { cancel_delayed_work_sync(&sc->wiphy_work); cancel_work_sync(&sc->chan_work); } @@ -1994,12 +1983,11 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); if (ath9k_wiphy_scanning(sc)) { + printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the " + "same time\n"); /* - * There is a race here in mac80211 but fixing it requires - * we revisit how we handle the scan complete callback. - * After mac80211 fixes we will not have configured hardware - * to the home channel nor would we have configured the RX - * filter yet. + * Do not allow the concurrent scanning state for now. This + * could be improved with scanning control moved into ath9k. */ mutex_unlock(&sc->mutex); return; @@ -2015,10 +2003,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) mutex_unlock(&sc->mutex); } -/* - * XXX: this requires a revisit after the driver - * scan_complete gets moved to another place/removed in mac80211. - */ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) { struct ath_wiphy *aphy = hw->priv; diff --git a/trunk/drivers/net/wireless/ath/ath9k/pci.c b/trunk/drivers/net/wireless/ath/ath9k/pci.c index b5b651413e77..257b10ba6f57 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/pci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/pci.c @@ -209,8 +209,11 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) } ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)mem, pdev->irq); + printk(KERN_INFO + "%s: %s mem=0x%lx, irq=%d\n", + wiphy_name(hw->wiphy), + hw_name, + (unsigned long)mem, pdev->irq); return 0; diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index e49be733d546..600ee0ba2880 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -20,145 +20,95 @@ #include "ath9k.h" static const struct ath_rate_table ar5416_11na_ratetable = { - 68, + 43, 8, /* MCS start */ { - [0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, - 5400, 0, 12, 0, 0, 0, 0 }, /* 6 Mb */ - [1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, - 7800, 1, 18, 0, 1, 1, 1 }, /* 9 Mb */ - [2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, - 10000, 2, 24, 2, 2, 2, 2 }, /* 12 Mb */ - [3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, - 13900, 3, 36, 2, 3, 3, 3 }, /* 18 Mb */ - [4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, - 17300, 4, 48, 4, 4, 4, 4 }, /* 24 Mb */ - [5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, - 23000, 5, 72, 4, 5, 5, 5 }, /* 36 Mb */ - [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, - 27400, 6, 96, 4, 6, 6, 6 }, /* 48 Mb */ - [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, - 29300, 7, 108, 4, 7, 7, 7 }, /* 54 Mb */ - [8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500, - 6400, 0, 0, 0, 38, 8, 38 }, /* 6.5 Mb */ - [9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, - 12700, 1, 1, 2, 39, 9, 39 }, /* 13 Mb */ - [10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, - 18800, 2, 2, 2, 40, 10, 40 }, /* 19.5 Mb */ - [11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, - 25000, 3, 3, 4, 41, 11, 41 }, /* 26 Mb */ - [12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, - 36700, 4, 4, 4, 42, 12, 42 }, /* 39 Mb */ - [13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, - 48100, 5, 5, 4, 43, 13, 43 }, /* 52 Mb */ - [14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, - 53500, 6, 6, 4, 44, 14, 44 }, /* 58.5 Mb */ - [15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, - 59000, 7, 7, 4, 45, 16, 46 }, /* 65 Mb */ - [16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, - 65400, 7, 7, 4, 45, 16, 46 }, /* 75 Mb */ - [17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, - 12700, 8, 8, 0, 47, 17, 47 }, /* 13 Mb */ - [18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, - 24800, 9, 9, 2, 48, 18, 48 }, /* 26 Mb */ - [19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, - 36600, 10, 10, 2, 49, 19, 49 }, /* 39 Mb */ - [20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, - 48100, 11, 11, 4, 50, 20, 50 }, /* 52 Mb */ - [21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, - 69500, 12, 12, 4, 51, 21, 51 }, /* 78 Mb */ - [22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, - 89500, 13, 13, 4, 52, 22, 52 }, /* 104 Mb */ - [23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, - 98900, 14, 14, 4, 53, 23, 53 }, /* 117 Mb */ - [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, - 108300, 15, 15, 4, 54, 25, 55 }, /* 130 Mb */ - [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, - 120000, 15, 15, 4, 54, 25, 55 }, /* 144.4 Mb */ - [26] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, - 17400, 16, 16, 0, 56, 26, 56 }, /* 19.5 Mb */ - [27] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, - 35100, 17, 17, 2, 57, 27, 57 }, /* 39 Mb */ - [28] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, - 52600, 18, 18, 2, 58, 28, 58 }, /* 58.5 Mb */ - [29] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, - 70400, 19, 19, 4, 59, 29, 59 }, /* 78 Mb */ - [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, - 104900, 20, 20, 4, 60, 31, 61 }, /* 117 Mb */ - [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, - 115800, 20, 20, 4, 60, 31, 61 }, /* 130 Mb*/ - [32] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, - 137200, 21, 21, 4, 62, 33, 63 }, /* 156 Mb */ - [33] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, - 151100, 21, 21, 4, 62, 33, 63 }, /* 173.3 Mb */ - [34] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, - 152800, 22, 22, 4, 64, 35, 65 }, /* 175.5 Mb */ - [35] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, - 168400, 22, 22, 4, 64, 35, 65 }, /* 195 Mb*/ - [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, - 168400, 23, 23, 4, 66, 37, 67 }, /* 195 Mb */ - [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, - 185000, 23, 23, 4, 66, 37, 67 }, /* 216.7 Mb */ - [38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, - 13200, 0, 0, 0, 38, 38, 38 }, /* 13.5 Mb*/ - [39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, - 25900, 1, 1, 2, 39, 39, 39 }, /* 27.0 Mb*/ - [40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, - 38600, 2, 2, 2, 40, 40, 40 }, /* 40.5 Mb*/ - [41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, - 49800, 3, 3, 4, 41, 41, 41 }, /* 54 Mb */ - [42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, - 72200, 4, 4, 4, 42, 42, 42 }, /* 81 Mb */ - [43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000, - 92900, 5, 5, 4, 43, 43, 43 }, /* 108 Mb */ - [44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, - 102700, 6, 6, 4, 44, 44, 44 }, /* 121.5 Mb*/ - [45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, - 112000, 7, 7, 4, 45, 46, 46 }, /* 135 Mb */ - [46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, - 122000, 7, 7, 4, 45, 46, 46 }, /* 150 Mb */ - [47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, - 25800, 8, 8, 0, 47, 47, 47 }, /* 27 Mb */ - [48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, - 49800, 9, 9, 2, 48, 48, 48 }, /* 54 Mb */ - [49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, - 71900, 10, 10, 2, 49, 49, 49 }, /* 81 Mb */ - [50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, - 92500, 11, 11, 4, 50, 50, 50 }, /* 108 Mb */ - [51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, - 130300, 12, 12, 4, 51, 51, 51 }, /* 162 Mb */ - [52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, - 162800, 13, 13, 4, 52, 52, 52 }, /* 216 Mb */ - [53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, - 178200, 14, 14, 4, 53, 53, 53 }, /* 243 Mb */ - [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, - 192100, 15, 15, 4, 54, 55, 55 }, /* 270 Mb */ - [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, - 207000, 15, 15, 4, 54, 55, 55 }, /* 300 Mb */ - [56] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, - 36100, 16, 16, 0, 56, 56, 56 }, /* 40.5 Mb */ - [57] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, - 72900, 17, 17, 2, 57, 57, 57 }, /* 81 Mb */ - [58] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, - 108300, 18, 18, 2, 58, 58, 58 }, /* 121.5 Mb */ - [59] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, - 142000, 19, 19, 4, 59, 59, 59 }, /* 162 Mb */ - [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, - 205100, 20, 20, 4, 60, 61, 61 }, /* 243 Mb */ - [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, - 224700, 20, 20, 4, 60, 61, 61 }, /* 270 Mb */ - [62] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, - 263100, 21, 21, 4, 62, 63, 63 }, /* 324 Mb */ - [63] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, - 288000, 21, 21, 4, 62, 63, 63 }, /* 360 Mb */ - [64] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, - 290700, 22, 22, 4, 64, 65, 65 }, /* 364.5 Mb */ - [65] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, - 317200, 22, 22, 4, 64, 65, 65 }, /* 405 Mb */ - [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, - 317200, 23, 23, 4, 66, 67, 67 }, /* 405 Mb */ - [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, - 346400, 23, 23, 4, 66, 67, 67 }, /* 450 Mb */ + { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ + 5400, 0, 12, 0, 0, 0, 0, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ + 7800, 1, 18, 0, 1, 1, 1, 1 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ + 10000, 2, 24, 2, 2, 2, 2, 2 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ + 13900, 3, 36, 2, 3, 3, 3, 3 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ + 17300, 4, 48, 4, 4, 4, 4, 4 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ + 23000, 5, 72, 4, 5, 5, 5, 5 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ + 27400, 6, 96, 4, 6, 6, 6, 6 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ + 29300, 7, 108, 4, 7, 7, 7, 7 }, + { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ + 6400, 0, 0, 0, 8, 25, 8, 25 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ + 12700, 1, 1, 2, 9, 26, 9, 26 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ + 18800, 2, 2, 2, 10, 27, 10, 27 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ + 25000, 3, 3, 4, 11, 28, 11, 28 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ + 36700, 4, 4, 4, 12, 29, 12, 29 }, + { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ + 48100, 5, 5, 4, 13, 30, 13, 30 }, + { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ + 53500, 6, 6, 4, 14, 31, 14, 31 }, + { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ + 59000, 7, 7, 4, 15, 32, 15, 33 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ + 12700, 8, 8, 3, 16, 34, 16, 34 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ + 24800, 9, 9, 2, 17, 35, 17, 35 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ + 36600, 10, 10, 2, 18, 36, 18, 36 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ + 48100, 11, 11, 4, 19, 37, 19, 37 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ + 69500, 12, 12, 4, 20, 38, 20, 38 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ + 89500, 13, 13, 4, 21, 39, 21, 39 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ + 98900, 14, 14, 4, 22, 40, 22, 40 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ + 108300, 15, 15, 4, 23, 41, 24, 42 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */ + 12000, 15, 15, 4, 23, 41, 24, 42 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ + 13200, 0, 0, 0, 8, 25, 25, 25 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ + 25900, 1, 1, 2, 9, 26, 26, 26 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ + 38600, 2, 2, 2, 10, 27, 27, 27 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ + 49800, 3, 3, 4, 11, 28, 28, 28 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ + 72200, 4, 4, 4, 12, 29, 29, 29 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ + 92900, 5, 5, 4, 13, 30, 30, 30 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ + 102700, 6, 6, 4, 14, 31, 31, 31 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ + 112000, 7, 7, 4, 15, 32, 33, 33 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ + 122000, 7, 7, 4, 15, 32, 33, 33 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ + 25800, 8, 8, 0, 16, 34, 34, 34 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ + 49800, 9, 9, 2, 17, 35, 35, 35 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ + 71900, 10, 10, 2, 18, 36, 36, 36 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ + 92500, 11, 11, 4, 19, 37, 37, 37 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ + 130300, 12, 12, 4, 20, 38, 38, 38 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ + 162800, 13, 13, 4, 21, 39, 39, 39 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ + 178200, 14, 14, 4, 22, 40, 40, 40 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ + 192100, 15, 15, 4, 23, 41, 42, 42 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ + 207000, 15, 15, 4, 23, 41, 42, 42 }, }, 50, /* probe interval */ WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ @@ -168,153 +118,103 @@ static const struct ath_rate_table ar5416_11na_ratetable = { * for HT are the 64K max aggregate limit */ static const struct ath_rate_table ar5416_11ng_ratetable = { - 72, + 47, 12, /* MCS start */ { - [0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000, - 900, 0, 2, 0, 0, 0, 0 }, /* 1 Mb */ - [1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000, - 1900, 1, 4, 1, 1, 1, 1 }, /* 2 Mb */ - [2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500, - 4900, 2, 11, 2, 2, 2, 2 }, /* 5.5 Mb */ - [3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000, - 8100, 3, 22, 3, 3, 3, 3 }, /* 11 Mb */ - [4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, - 5400, 4, 12, 4, 4, 4, 4 }, /* 6 Mb */ - [5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, - 7800, 5, 18, 4, 5, 5, 5 }, /* 9 Mb */ - [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, - 10100, 6, 24, 6, 6, 6, 6 }, /* 12 Mb */ - [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, - 14100, 7, 36, 6, 7, 7, 7 }, /* 18 Mb */ - [8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, - 17700, 8, 48, 8, 8, 8, 8 }, /* 24 Mb */ - [9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, - 23700, 9, 72, 8, 9, 9, 9 }, /* 36 Mb */ - [10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, - 27400, 10, 96, 8, 10, 10, 10 }, /* 48 Mb */ - [11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, - 30900, 11, 108, 8, 11, 11, 11 }, /* 54 Mb */ - [12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500, - 6400, 0, 0, 4, 42, 12, 42 }, /* 6.5 Mb */ - [13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, - 12700, 1, 1, 6, 43, 13, 43 }, /* 13 Mb */ - [14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, - 18800, 2, 2, 6, 44, 14, 44 }, /* 19.5 Mb*/ - [15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, - 25000, 3, 3, 8, 45, 15, 45 }, /* 26 Mb */ - [16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, - 36700, 4, 4, 8, 46, 16, 46 }, /* 39 Mb */ - [17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, - 48100, 5, 5, 8, 47, 17, 47 }, /* 52 Mb */ - [18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, - 53500, 6, 6, 8, 48, 18, 48 }, /* 58.5 Mb */ - [19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, - 59000, 7, 7, 8, 49, 20, 50 }, /* 65 Mb */ - [20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, - 65400, 7, 7, 8, 49, 20, 50 }, /* 65 Mb*/ - [21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, - 12700, 8, 8, 4, 51, 21, 51 }, /* 13 Mb */ - [22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, - 24800, 9, 9, 6, 52, 22, 52 }, /* 26 Mb */ - [23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, - 36600, 10, 10, 6, 53, 23, 53 }, /* 39 Mb */ - [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, - 48100, 11, 11, 8, 54, 24, 54 }, /* 52 Mb */ - [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, - 69500, 12, 12, 8, 55, 25, 55 }, /* 78 Mb */ - [26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, - 89500, 13, 13, 8, 56, 26, 56 }, /* 104 Mb */ - [27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, - 98900, 14, 14, 8, 57, 27, 57 }, /* 117 Mb */ - [28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, - 108300, 15, 15, 8, 58, 29, 59 }, /* 130 Mb */ - [29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, - 120000, 15, 15, 8, 58, 29, 59 }, /* 144.4 Mb */ - [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, - 17400, 16, 16, 4, 60, 30, 60 }, /* 19.5 Mb */ - [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, - 35100, 17, 17, 6, 61, 31, 61 }, /* 39 Mb */ - [32] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, - 52600, 18, 18, 6, 62, 32, 62 }, /* 58.5 Mb */ - [33] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, - 70400, 19, 19, 8, 63, 33, 63 }, /* 78 Mb */ - [34] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, - 104900, 20, 20, 8, 64, 35, 65 }, /* 117 Mb */ - [35] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, - 115800, 20, 20, 8, 64, 35, 65 }, /* 130 Mb */ - [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, - 137200, 21, 21, 8, 66, 37, 67 }, /* 156 Mb */ - [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, - 151100, 21, 21, 8, 66, 37, 67 }, /* 173.3 Mb */ - [38] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, - 152800, 22, 22, 8, 68, 39, 69 }, /* 175.5 Mb */ - [39] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, - 168400, 22, 22, 8, 68, 39, 69 }, /* 195 Mb */ - [40] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, - 168400, 23, 23, 8, 70, 41, 71 }, /* 195 Mb */ - [41] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, - 185000, 23, 23, 8, 70, 41, 71 }, /* 216.7 Mb */ - [42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, - 13200, 0, 0, 8, 42, 42, 42 }, /* 13.5 Mb */ - [43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, - 25900, 1, 1, 8, 43, 43, 43 }, /* 27.0 Mb */ - [44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, - 38600, 2, 2, 8, 44, 44, 44 }, /* 40.5 Mb */ - [45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, - 49800, 3, 3, 8, 45, 45, 45 }, /* 54 Mb */ - [46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, - 72200, 4, 4, 8, 46, 46, 46 }, /* 81 Mb */ - [47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000, - 92900, 5, 5, 8, 47, 47, 47 }, /* 108 Mb */ - [48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, - 102700, 6, 6, 8, 48, 48, 48 }, /* 121.5 Mb */ - [49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, - 112000, 7, 7, 8, 49, 50, 50 }, /* 135 Mb */ - [50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, - 122000, 7, 7, 8, 49, 50, 50 }, /* 150 Mb */ - [51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, - 25800, 8, 8, 8, 51, 51, 51 }, /* 27 Mb */ - [52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, - 49800, 9, 9, 8, 52, 52, 52 }, /* 54 Mb */ - [53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, - 71900, 10, 10, 8, 53, 53, 53 }, /* 81 Mb */ - [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, - 92500, 11, 11, 8, 54, 54, 54 }, /* 108 Mb */ - [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, - 130300, 12, 12, 8, 55, 55, 55 }, /* 162 Mb */ - [56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, - 162800, 13, 13, 8, 56, 56, 56 }, /* 216 Mb */ - [57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, - 178200, 14, 14, 8, 57, 57, 57 }, /* 243 Mb */ - [58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, - 192100, 15, 15, 8, 58, 59, 59 }, /* 270 Mb */ - [59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, - 207000, 15, 15, 8, 58, 59, 59 }, /* 300 Mb */ - [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, - 36100, 16, 16, 8, 60, 60, 60 }, /* 40.5 Mb */ - [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, - 72900, 17, 17, 8, 61, 61, 61 }, /* 81 Mb */ - [62] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, - 108300, 18, 18, 8, 62, 62, 62 }, /* 121.5 Mb */ - [63] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, - 142000, 19, 19, 8, 63, 63, 63 }, /* 162 Mb */ - [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, - 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ - [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, - 224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */ - [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, - 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ - [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, - 288000, 21, 21, 8, 66, 67, 67 }, /* 360 Mb */ - [68] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, - 290700, 22, 22, 8, 68, 69, 69 }, /* 364.5 Mb */ - [69] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, - 317200, 22, 22, 8, 68, 69, 69 }, /* 405 Mb */ - [70] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, - 317200, 23, 23, 8, 70, 71, 71 }, /* 405 Mb */ - [71] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, - 346400, 23, 23, 8, 70, 71, 71 }, /* 450 Mb */ + { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ + 900, 0, 2, 0, 0, 0, 0, 0 }, + { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ + 1900, 1, 4, 1, 1, 1, 1, 1 }, + { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ + 4900, 2, 11, 2, 2, 2, 2, 2 }, + { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ + 8100, 3, 22, 3, 3, 3, 3, 3 }, + { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ + 5400, 4, 12, 4, 4, 4, 4, 4 }, + { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ + 7800, 5, 18, 4, 5, 5, 5, 5 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ + 10100, 6, 24, 6, 6, 6, 6, 6 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ + 14100, 7, 36, 6, 7, 7, 7, 7 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ + 17700, 8, 48, 8, 8, 8, 8, 8 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ + 23700, 9, 72, 8, 9, 9, 9, 9 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ + 27400, 10, 96, 8, 10, 10, 10, 10 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ + 30900, 11, 108, 8, 11, 11, 11, 11 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ + 6400, 0, 0, 4, 12, 29, 12, 29 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ + 12700, 1, 1, 6, 13, 30, 13, 30 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ + 18800, 2, 2, 6, 14, 31, 14, 31 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ + 25000, 3, 3, 8, 15, 32, 15, 32 }, + { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ + 36700, 4, 4, 8, 16, 33, 16, 33 }, + { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ + 48100, 5, 5, 8, 17, 34, 17, 34 }, + { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ + 53500, 6, 6, 8, 18, 35, 18, 35 }, + { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ + 59000, 7, 7, 8, 19, 36, 19, 37 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ + 12700, 8, 8, 4, 20, 38, 20, 38 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ + 24800, 9, 9, 6, 21, 39, 21, 39 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ + 36600, 10, 10, 6, 22, 40, 22, 40 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ + 48100, 11, 11, 8, 23, 41, 23, 41 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ + 69500, 12, 12, 8, 24, 42, 24, 42 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ + 89500, 13, 13, 8, 25, 43, 25, 43 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ + 98900, 14, 14, 8, 26, 44, 26, 44 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ + 108300, 15, 15, 8, 27, 45, 28, 46 }, + { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */ + 120000, 15, 15, 8, 27, 45, 28, 46 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ + 13200, 0, 0, 8, 12, 29, 29, 29 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ + 25900, 1, 1, 8, 13, 30, 30, 30 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ + 38600, 2, 2, 8, 14, 31, 31, 31 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ + 49800, 3, 3, 8, 15, 32, 32, 32 }, + { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ + 72200, 4, 4, 8, 16, 33, 33, 33 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ + 92900, 5, 5, 8, 17, 34, 34, 34 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ + 102700, 6, 6, 8, 18, 35, 35, 35 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ + 112000, 7, 7, 8, 19, 36, 37, 37 }, + { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ + 122000, 7, 7, 8, 19, 36, 37, 37 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ + 25800, 8, 8, 8, 20, 38, 38, 38 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ + 49800, 9, 9, 8, 21, 39, 39, 39 }, + { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ + 71900, 10, 10, 8, 22, 40, 40, 40 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ + 92500, 11, 11, 8, 23, 41, 41, 41 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ + 130300, 12, 12, 8, 24, 42, 42, 42 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ + 162800, 13, 13, 8, 25, 43, 43, 43 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ + 178200, 14, 14, 8, 26, 44, 44, 44 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ + 192100, 15, 15, 8, 27, 45, 46, 46 }, + { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ + 207000, 15, 15, 8, 27, 45, 46, 46 }, }, 50, /* probe interval */ WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ @@ -324,22 +224,22 @@ static const struct ath_rate_table ar5416_11a_ratetable = { 8, 0, { - { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ - 5400, 0, 12, 0}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ - 7800, 1, 18, 0}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ - 10000, 2, 24, 2}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ - 13900, 3, 36, 2}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ - 17300, 4, 48, 4}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ - 23000, 5, 72, 4}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ - 27400, 6, 96, 4}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ - 29300, 7, 108, 4}, + { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ + 5400, 0, 12, 0, 0, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ + 7800, 1, 18, 0, 1, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ + 10000, 2, 24, 2, 2, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ + 13900, 3, 36, 2, 3, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ + 17300, 4, 48, 4, 4, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ + 23000, 5, 72, 4, 5, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ + 27400, 6, 96, 4, 6, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ + 29300, 7, 108, 4, 7, 0 }, }, 50, /* probe interval */ 0, /* Phy rates allowed initially */ @@ -349,30 +249,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = { 12, 0, { - { RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ - 900, 0, 2, 0}, - { RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ - 1900, 1, 4, 1}, - { RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ - 4900, 2, 11, 2}, - { RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ - 8100, 3, 22, 3}, - { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ - 5400, 4, 12, 4}, - { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ - 7800, 5, 18, 4}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ - 10000, 6, 24, 6}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ - 13900, 7, 36, 6}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ - 17300, 8, 48, 8}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ - 23000, 9, 72, 8}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ - 27400, 10, 96, 8}, - { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ - 29300, 11, 108, 8}, + { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ + 900, 0, 2, 0, 0, 0 }, + { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ + 1900, 1, 4, 1, 1, 0 }, + { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ + 4900, 2, 11, 2, 2, 0 }, + { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ + 8100, 3, 22, 3, 3, 0 }, + { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ + 5400, 4, 12, 4, 4, 0 }, + { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ + 7800, 5, 18, 4, 5, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ + 10000, 6, 24, 6, 6, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ + 13900, 7, 36, 6, 7, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ + 17300, 8, 48, 8, 8, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ + 23000, 9, 72, 8, 9, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ + 27400, 10, 96, 8, 10, 0 }, + { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ + 29300, 11, 108, 8, 11, 0 }, }, 50, /* probe interval */ 0, /* Phy rates allowed initially */ @@ -442,7 +342,7 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, u8 index, int valid_tx_rate) { BUG_ON(index > ath_rc_priv->rate_table_size); - ath_rc_priv->valid_rate_index[index] = !!valid_tx_rate; + ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; } static inline @@ -474,8 +374,6 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw) return 0; if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) return 0; - if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG)) - return 0; if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG)) return 0; if (!ignore_cw && WLAN_RC_PHY_HT(phy)) @@ -506,9 +404,13 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, u32 capflag) { u8 i, hi = 0; + u32 valid; for (i = 0; i < rate_table->rate_cnt; i++) { - if (rate_table->info[i].rate_flags & RC_LEGACY) { + valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? + rate_table->info[i].valid_single_stream : + rate_table->info[i].valid); + if (valid == 1) { u32 phy = rate_table->info[i].phy; u8 valid_rate_count = 0; @@ -520,7 +422,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; ath_rc_priv->valid_phy_ratecnt[phy] += 1; ath_rc_set_valid_txmask(ath_rc_priv, i, 1); - hi = i; + hi = A_MAX(hi, i); } } @@ -538,7 +440,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, for (i = 0; i < rateset->rs_nrates; i++) { for (j = 0; j < rate_table->rate_cnt; j++) { u32 phy = rate_table->info[j].phy; - u16 rate_flags = rate_table->info[i].rate_flags; + u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? + rate_table->info[j].valid_single_stream : + rate_table->info[j].valid); u8 rate = rateset->rs_rates[i]; u8 dot11rate = rate_table->info[j].dot11rate; @@ -547,9 +451,8 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, * (VALID/VALID_20/VALID_40) flags */ if ((rate == dot11rate) && - (rate_flags & WLAN_RC_CAP_MODE(capflag)) == - WLAN_RC_CAP_MODE(capflag) && - (rate_flags & WLAN_RC_CAP_STREAM(capflag)) && + ((valid & WLAN_RC_CAP_MODE(capflag)) == + WLAN_RC_CAP_MODE(capflag)) && !WLAN_RC_PHY_HT(phy)) { u8 valid_rate_count = 0; @@ -583,13 +486,14 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, for (i = 0; i < rateset->rs_nrates; i++) { for (j = 0; j < rate_table->rate_cnt; j++) { u32 phy = rate_table->info[j].phy; - u16 rate_flags = rate_table->info[j].rate_flags; + u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? + rate_table->info[j].valid_single_stream : + rate_table->info[j].valid); u8 rate = rateset->rs_rates[i]; u8 dot11rate = rate_table->info[j].dot11rate; if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) || - !(rate_flags & WLAN_RC_CAP_STREAM(capflag)) || - !WLAN_RC_PHY_HT_VALID(rate_flags, capflag)) + !WLAN_RC_PHY_HT_VALID(valid, capflag)) continue; if (!ath_rc_valid_phyrate(phy, capflag, 0)) @@ -685,15 +589,12 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, if (rate > (ath_rc_priv->rate_table_size - 1)) rate = ath_rc_priv->rate_table_size - 1; - if (RC_TS_ONLY(rate_table->info[rate].rate_flags) && - (ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG)) - return rate; - - if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) && - (ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG))) + if (rate_table->info[rate].valid && + (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) return rate; - if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags)) + if (rate_table->info[rate].valid_single_stream && + !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) return rate; /* This should not happen */ @@ -1106,19 +1007,12 @@ static void ath_rc_update_ht(struct ath_softc *sc, static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, struct ieee80211_tx_rate *rate) { - int rix = 0, i = 0; - int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; + int rix; if (!(rate->flags & IEEE80211_TX_RC_MCS)) return rate->idx; - while (rate->idx > mcs_rix_off[i] && - i < sizeof(mcs_rix_off)/sizeof(int)) { - rix++; i++; - } - - rix += rate->idx + rate_table->mcs_start; - + rix = rate->idx + rate_table->mcs_start; if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (rate->flags & IEEE80211_TX_RC_SHORT_GI)) rix = rate_table->info[rix].ht_index; @@ -1126,6 +1020,8 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, rix = rate_table->info[rix].sgi_index; else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) rix = rate_table->info[rix].cw40index; + else + rix = rate_table->info[rix].base_index; return rix; } @@ -1307,14 +1203,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, if (sta->ht_cap.ht_supported) { caps = WLAN_RC_HT_FLAG; - if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2]) - caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG; - else if (sta->ht_cap.mcs.rx_mask[1]) + if (sta->ht_cap.mcs.rx_mask[1]) caps |= WLAN_RC_DS_FLAG; if (is_cw40) caps |= WLAN_RC_40_FLAG; if (is_sgi) caps |= WLAN_RC_SGI_FLAG; + } return caps; diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.h b/trunk/drivers/net/wireless/ath/ath9k/rc.h index dc1082654501..3d8d40cdc99e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.h @@ -24,63 +24,32 @@ struct ath_softc; #define ATH_RATE_MAX 30 -#define RATE_TABLE_SIZE 72 +#define RATE_TABLE_SIZE 64 #define MAX_TX_RATE_PHY 48 +/* VALID_ALL - valid for 20/40/Legacy, + * VALID - Legacy only, + * VALID_20 - HT 20 only, + * VALID_40 - HT 40 only */ -#define RC_INVALID 0x0000 -#define RC_LEGACY 0x0001 -#define RC_SS 0x0002 -#define RC_DS 0x0004 -#define RC_TS 0x0008 -#define RC_HT_20 0x0010 -#define RC_HT_40 0x0020 - -#define RC_STREAM_MASK 0xe -#define RC_DS_OR_LATER(f) ((((f) & RC_STREAM_MASK) == RC_DS) || \ - (((f) & RC_STREAM_MASK) == (RC_DS | RC_TS))) -#define RC_TS_ONLY(f) (((f) & RC_STREAM_MASK) == RC_TS) -#define RC_SS_OR_LEGACY(f) ((f) & (RC_SS | RC_LEGACY)) - -#define RC_HT_2040 (RC_HT_20 | RC_HT_40) -#define RC_ALL_STREAM (RC_SS | RC_DS | RC_TS) -#define RC_L_SD (RC_LEGACY | RC_SS | RC_DS) -#define RC_L_SDT (RC_LEGACY | RC_SS | RC_DS | RC_TS) -#define RC_HT_S_20 (RC_HT_20 | RC_SS) -#define RC_HT_D_20 (RC_HT_20 | RC_DS) -#define RC_HT_T_20 (RC_HT_20 | RC_TS) -#define RC_HT_S_40 (RC_HT_40 | RC_SS) -#define RC_HT_D_40 (RC_HT_40 | RC_DS) -#define RC_HT_T_40 (RC_HT_40 | RC_TS) - -#define RC_HT_SD_20 (RC_HT_20 | RC_SS | RC_DS) -#define RC_HT_DT_20 (RC_HT_20 | RC_DS | RC_TS) -#define RC_HT_SD_40 (RC_HT_40 | RC_SS | RC_DS) -#define RC_HT_DT_40 (RC_HT_40 | RC_DS | RC_TS) - -#define RC_HT_SD_2040 (RC_HT_2040 | RC_SS | RC_DS) -#define RC_HT_SDT_2040 (RC_HT_2040 | RC_SS | RC_DS | RC_TS) - -#define RC_HT_SDT_20 (RC_HT_20 | RC_SS | RC_DS | RC_TS) -#define RC_HT_SDT_40 (RC_HT_40 | RC_SS | RC_DS | RC_TS) - -#define RC_ALL (RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM) +#define INVALID 0x0 +#define VALID 0x1 +#define VALID_20 0x2 +#define VALID_40 0x4 +#define VALID_2040 (VALID_20|VALID_40) +#define VALID_ALL (VALID_2040|VALID) enum { WLAN_RC_PHY_OFDM, WLAN_RC_PHY_CCK, WLAN_RC_PHY_HT_20_SS, WLAN_RC_PHY_HT_20_DS, - WLAN_RC_PHY_HT_20_TS, WLAN_RC_PHY_HT_40_SS, WLAN_RC_PHY_HT_40_DS, - WLAN_RC_PHY_HT_40_TS, WLAN_RC_PHY_HT_20_SS_HGI, WLAN_RC_PHY_HT_20_DS_HGI, - WLAN_RC_PHY_HT_20_TS_HGI, WLAN_RC_PHY_HT_40_SS_HGI, WLAN_RC_PHY_HT_40_DS_HGI, - WLAN_RC_PHY_HT_40_TS_HGI, WLAN_RC_PHY_MAX }; @@ -88,50 +57,36 @@ enum { || (_phy == WLAN_RC_PHY_HT_40_DS) \ || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) -#define WLAN_RC_PHY_TS(_phy) ((_phy == WLAN_RC_PHY_HT_20_TS) \ - || (_phy == WLAN_RC_PHY_HT_40_TS) \ - || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) #define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \ || (_phy == WLAN_RC_PHY_HT_20_DS) \ - || (_phy == WLAN_RC_PHY_HT_20_TS) \ || (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_20_TS_HGI)) + || (_phy == WLAN_RC_PHY_HT_20_DS_HGI)) #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ || (_phy == WLAN_RC_PHY_HT_40_DS) \ - || (_phy == WLAN_RC_PHY_HT_40_TS) \ || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) + || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) #define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \ || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) + || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) #define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \ - ((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY)) - -#define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ? \ - (RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS))) + (capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID)) /* Return TRUE if flag supports HT20 && client supports HT20 or * return TRUE if flag supports HT40 && client supports HT40. * This is used becos some rates overlap between HT20/HT40. */ #define WLAN_RC_PHY_HT_VALID(flag, capflag) \ - (((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \ - ((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG))) + (((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \ + ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG))) #define WLAN_RC_DS_FLAG (0x01) -#define WLAN_RC_TS_FLAG (0x02) -#define WLAN_RC_40_FLAG (0x04) -#define WLAN_RC_SGI_FLAG (0x08) -#define WLAN_RC_HT_FLAG (0x10) +#define WLAN_RC_40_FLAG (0x02) +#define WLAN_RC_SGI_FLAG (0x04) +#define WLAN_RC_HT_FLAG (0x08) /** * struct ath_rate_table - Rate Control table @@ -155,13 +110,15 @@ struct ath_rate_table { int rate_cnt; int mcs_start; struct { - u16 rate_flags; + u8 valid; + u8 valid_single_stream; u8 phy; u32 ratekbps; u32 user_ratekbps; u8 ratecode; u8 dot11rate; u8 ctrl_rate; + u8 base_index; u8 cw40index; u8 sgi_index; u8 ht_index; diff --git a/trunk/drivers/net/wireless/ath/ath9k/virtual.c b/trunk/drivers/net/wireless/ath/ath9k/virtual.c index fd20241f57d8..89423ca23d2c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/virtual.c +++ b/trunk/drivers/net/wireless/ath/ath9k/virtual.c @@ -695,18 +695,16 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) idle ? "idle" : "not-idle"); } /* Only bother starting a queue on an active virtual wiphy */ -bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) +void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) { struct ieee80211_hw *hw = sc->pri_wiphy->hw; unsigned int i; - bool txq_started = false; spin_lock_bh(&sc->wiphy_lock); /* Start the primary wiphy */ if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) { ieee80211_wake_queue(hw, skb_queue); - txq_started = true; goto unlock; } @@ -720,13 +718,11 @@ bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) hw = aphy->hw; ieee80211_wake_queue(hw, skb_queue); - txq_started = true; break; } unlock: spin_unlock_bh(&sc->wiphy_lock); - return txq_started; } /* Go ahead and propagate information to all virtual wiphys, it won't hurt */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 501b72821b4d..bd52ac111795 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -329,6 +329,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; struct ieee80211_tx_rate rates[4]; + unsigned long flags; skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; @@ -345,21 +346,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (!sta) { rcu_read_unlock(); - INIT_LIST_HEAD(&bf_head); - while (bf) { - bf_next = bf->bf_next; - - bf->bf_state.bf_type |= BUF_XRETRY; - if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || - !bf->bf_stale || bf_next != NULL) - list_move_tail(&bf->list, &bf_head); - - ath_tx_rc_status(bf, ts, 0, 0, false); - ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, - 0, 0); - - bf = bf_next; - } + spin_lock_irqsave(&sc->tx.txbuflock, flags); + list_splice_tail_init(bf_q, &sc->tx.txbuf); + spin_unlock_irqrestore(&sc->tx.txbuflock, flags); return; } @@ -518,14 +507,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, bf = bf_next; } - /* prepend un-acked frames to the beginning of the pending frame queue */ - if (!list_empty(&bf_pending)) { - spin_lock_bh(&txq->axq_lock); - list_splice(&bf_pending, &tid->buf_q); - ath_tx_queue_tid(txq, tid); - spin_unlock_bh(&txq->axq_lock); - } - if (tid->state & AGGR_CLEANUP) { if (tid->baw_head == tid->baw_tail) { tid->state &= ~AGGR_ADDBA_COMPLETE; @@ -538,6 +519,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, return; } + /* prepend un-acked frames to the beginning of the pending frame queue */ + if (!list_empty(&bf_pending)) { + spin_lock_bh(&txq->axq_lock); + list_splice(&bf_pending, &tid->buf_q); + ath_tx_queue_tid(txq, tid); + spin_unlock_bh(&txq->axq_lock); + } + rcu_read_unlock(); if (needreset) @@ -2077,8 +2066,8 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { - if (ath_mac80211_start_queue(sc, qnum)) - txq->stopped = 0; + ath_mac80211_start_queue(sc, qnum); + txq->stopped = 0; } spin_unlock_bh(&txq->axq_lock); } diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 20631ae2ddd7..8e243798ae93 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -108,7 +108,7 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; module_param_named(verbose, b43_modparam_verbose, int, 0644); MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); -static int b43_modparam_pio = B43_PIO_DEFAULT; +int b43_modparam_pio = B43_PIO_DEFAULT; module_param_named(pio, b43_modparam_pio, int, 0644); MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); diff --git a/trunk/drivers/net/wireless/b43/phy_g.c b/trunk/drivers/net/wireless/b43/phy_g.c index 0dc33b65e86b..29bf34ced865 100644 --- a/trunk/drivers/net/wireless/b43/phy_g.c +++ b/trunk/drivers/net/wireless/b43/phy_g.c @@ -972,7 +972,7 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode) b43_phy_maskset(dev, 0x04A2, 0xFFF0, 0x000B); if (phy->rev >= 3) { - b43_phy_mask(dev, 0x048A, 0x7FFF); + b43_phy_mask(dev, 0x048A, (u16)~0x8000); b43_phy_maskset(dev, 0x0415, 0x8000, 0x36D8); b43_phy_maskset(dev, 0x0416, 0x8000, 0x36D8); b43_phy_maskset(dev, 0x0417, 0xFE00, 0x016D); diff --git a/trunk/drivers/net/wireless/b43/phy_lp.c b/trunk/drivers/net/wireless/b43/phy_lp.c index fd50eb116243..c6afe9d94590 100644 --- a/trunk/drivers/net/wireless/b43/phy_lp.c +++ b/trunk/drivers/net/wireless/b43/phy_lp.c @@ -1145,7 +1145,7 @@ static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev *dev) B43_WARN_ON(1); } b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD, - ~B43_LPPHY_TX_PWR_CTL_CMD_MODE & 0xFFFF, ctl); + (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, ctl); } static void lpphy_set_tx_power_control(struct b43_wldev *dev, @@ -1522,11 +1522,11 @@ static void lpphy_tx_pctl_init_hw(struct b43_wldev *dev) b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xFF); b43_phy_write(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xA); b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD, - ~B43_LPPHY_TX_PWR_CTL_CMD_MODE & 0xFFFF, + (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF); b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0xF8FF); b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD, - ~B43_LPPHY_TX_PWR_CTL_CMD_MODE & 0xFFFF, + (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW); if (dev->phy.rev < 2) { @@ -2698,7 +2698,7 @@ static enum b43_txpwr_result b43_lpphy_op_recalc_txpower(struct b43_wldev *dev, return B43_TXPWR_RES_DONE; } -static void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on) +void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on) { if (on) { b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xfff8); diff --git a/trunk/drivers/net/wireless/b43/phy_n.c b/trunk/drivers/net/wireless/b43/phy_n.c index 5a725703770c..3d6b33775964 100644 --- a/trunk/drivers/net/wireless/b43/phy_n.c +++ b/trunk/drivers/net/wireless/b43/phy_n.c @@ -509,8 +509,7 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); - b43_phy_maskset(dev, B43_NPHY_RFSEQCA, - ~B43_NPHY_RFSEQCA_RXDIS & 0xFFFF, + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS, ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT)); @@ -763,7 +762,7 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev) if (tmp & 0x1) b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP); else if (tmp & 0x2) - b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); + b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000); b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004); @@ -1010,7 +1009,7 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) b43_nphy_set_rf_sequence(dev, 5, rfseq_events, rfseq_delays, 3); b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, - ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF, + (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV, 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -1117,7 +1116,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); b43_phy_mask(dev, B43_NPHY_PIL_DW1, - ~B43_NPHY_PIL_DW_64QAM & 0xFFFF); + (u16)~B43_NPHY_PIL_DW_64QAM); b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); @@ -2456,8 +2455,7 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600); regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG); - b43_phy_mask(dev, B43_NPHY_BBCFG, - ~B43_NPHY_BBCFG_RSTRX & 0xFFFF); + b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX); tmp = b43_ntab_read(dev, B43_NTAB16(8, 3)); regs[5] = tmp; @@ -2932,7 +2930,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, tmp[5] = b43_phy_read(dev, rfctl[1]); b43_phy_maskset(dev, B43_NPHY_RFSEQCA, - ~B43_NPHY_RFSEQCA_RXDIS & 0xFFFF, + (u16)~B43_NPHY_RFSEQCA_RXDIS, ((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, (1 - i)); @@ -3293,7 +3291,7 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); - b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF); + b43_phy_mask(dev, B43_PHY_B_BBCFG, (u16)~0xC000); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); } diff --git a/trunk/drivers/net/wireless/b43/wa.c b/trunk/drivers/net/wireless/b43/wa.c index 9a335da65b42..97c79161c208 100644 --- a/trunk/drivers/net/wireless/b43/wa.c +++ b/trunk/drivers/net/wireless/b43/wa.c @@ -382,7 +382,7 @@ static void b43_wa_altagc(struct b43_wldev *dev) b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25); } - b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, 0x00FF, 0x5700); + b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, (u16)~0xFF00, 0x5700); b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F); b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80); b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300); @@ -400,9 +400,9 @@ static void b43_wa_altagc(struct b43_wldev *dev) b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020); b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200); b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E); - b43_phy_maskset(dev, B43_PHY_OFDM(0x96), 0x00FF, 0x1A00); + b43_phy_maskset(dev, B43_PHY_OFDM(0x96), (u16)~0xFF00, 0x1A00); b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028); - b43_phy_maskset(dev, B43_PHY_OFDM(0x81), 0x00FF, 0x2C00); + b43_phy_maskset(dev, B43_PHY_OFDM(0x81), (u16)~0xFF00, 0x2C00); if (phy->rev == 1) { b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B); b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002); @@ -412,7 +412,7 @@ static void b43_wa_altagc(struct b43_wldev *dev) b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004); if (phy->rev >= 6) { b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A); - b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, 0x0FFF, 0x3000); + b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, (u16)~0xF000, 0x3000); } } b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874); diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index 5bbff4c5a489..56350d571960 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -174,7 +174,7 @@ that only one external action is invoked at a time. #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" -static struct pm_qos_request_list *ipw2100_pm_qos_req; +struct pm_qos_request_list *ipw2100_pm_qos_req; /* Debugging stuff */ #ifdef CONFIG_IPW2100_DEBUG diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw.h b/trunk/drivers/net/wireless/ipw2x00/libipw.h index 70f5586d96bd..4736861bc4f8 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw.h +++ b/trunk/drivers/net/wireless/ipw2x00/libipw.h @@ -828,6 +828,7 @@ struct libipw_device { int host_strip_iv_icv; int host_open_frag; + int host_build_iv; int ieee802_1x; /* is IEEE 802.1X used */ /* WPA data */ diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c index 32dee2ce5d31..55965408ff3f 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c @@ -62,8 +62,8 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -static struct cfg80211_ops libipw_config_ops = { }; -static void *libipw_wiphy_privid = &libipw_wiphy_privid; +struct cfg80211_ops libipw_config_ops = { }; +void *libipw_wiphy_privid = &libipw_wiphy_privid; static int libipw_networks_allocate(struct libipw_device *ieee) { diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_tx.c b/trunk/drivers/net/wireless/ipw2x00/libipw_tx.c index 01c88a71abe1..da8beac7fcf3 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_tx.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_tx.c @@ -260,7 +260,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size, rts_required; unsigned long flags; - int encrypt, host_encrypt, host_encrypt_msdu; + int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv; __be16 ether_type; int bytes, fc, hdr_len; struct sk_buff *skb_frag; @@ -301,6 +301,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) host_encrypt = ieee->host_encrypt && encrypt && crypt; host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt; + host_build_iv = ieee->host_build_iv && encrypt && crypt; if (!encrypt && ieee->ieee802_1x && ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) { @@ -312,7 +313,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) skb_copy_from_linear_data(skb, dest, ETH_ALEN); skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN); - if (host_encrypt) + if (host_encrypt || host_build_iv) fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | IEEE80211_FCTL_PROTECTED; else @@ -466,7 +467,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) for (; i < nr_frags; i++) { skb_frag = txb->fragments[i]; - if (host_encrypt) + if (host_encrypt || host_build_iv) skb_reserve(skb_frag, crypt->ops->extra_mpdu_prefix_len); @@ -501,6 +502,15 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) * to insert the IV between the header and the payload */ if (host_encrypt) libipw_encrypt_fragment(ieee, skb_frag, hdr_len); + else if (host_build_iv) { + atomic_inc(&crypt->refcnt); + if (crypt->ops->build_iv) + crypt->ops->build_iv(skb_frag, hdr_len, + ieee->sec.keys[ieee->sec.active_key], + ieee->sec.key_sizes[ieee->sec.active_key], + crypt->priv); + atomic_dec(&crypt->refcnt); + } if (ieee->config & (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS)) diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_wx.c b/trunk/drivers/net/wireless/ipw2x00/libipw_wx.c index d7bd6cf00a81..3633c6682e49 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_wx.c @@ -320,7 +320,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee, }; int i, key, key_provided, len; struct lib80211_crypt_data **crypt; - int host_crypto = ieee->host_encrypt || ieee->host_decrypt; + int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv; DECLARE_SSID_BUF(ssid); LIBIPW_DEBUG_WX("SET_ENCODE\n"); @@ -411,6 +411,10 @@ int libipw_wx_set_encode(struct libipw_device *ieee, /* If a new key was provided, set it up */ if (erq->length > 0) { +#ifdef CONFIG_LIBIPW_DEBUG + DECLARE_SSID_BUF(ssid); +#endif + len = erq->length <= 5 ? 5 : 13; memcpy(sec.keys[key], keybuf, erq->length); if (len > erq->length) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c index 8848333bc3a9..c281d07ec5e5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -222,7 +222,6 @@ static struct iwl_lib_ops iwl1000_lib = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, - .bt_stats_read = iwl_ucode_bt_stats_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c index d6531ad3906a..1dd3bc4c107e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1605,8 +1605,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv) if (!test_bit(STATUS_TEMPERATURE, &priv->status)) vt = sign_extend(R4, 23); else - vt = sign_extend(le32_to_cpu(priv->_agn.statistics. - general.common.temperature), 23); + vt = sign_extend(le32_to_cpu( + priv->_agn.statistics.general.temperature), 23); IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); @@ -2285,9 +2285,7 @@ static struct iwl_lib_ops iwl4965_lib = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, - .bt_stats_read = iwl_ucode_bt_stats_read, }, - .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, }; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index 8093ce2804fb..7d89d99ce19c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -265,7 +265,7 @@ static void iwl5150_temperature(struct iwl_priv *priv) u32 vt = 0; s32 offset = iwl_temp_calib_to_offset(priv); - vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature); + vt = le32_to_cpu(priv->_agn.statistics.general.temperature); vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; /* now vt hold the temperature in Kelvin */ priv->temperature = KELVIN_TO_CELSIUS(vt); @@ -398,7 +398,6 @@ static struct iwl_lib_ops iwl5000_lib = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, - .bt_stats_read = iwl_ucode_bt_stats_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index 58270529a0e4..095521952bbe 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -323,7 +323,6 @@ static struct iwl_lib_ops iwl6000_lib = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, - .bt_stats_read = iwl_ucode_bt_stats_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, @@ -501,7 +500,6 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, .need_dc_calib = true, - .bt_statistics = true, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -537,7 +535,6 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, .need_dc_calib = true, - .bt_statistics = true, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -575,7 +572,6 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, .need_dc_calib = true, - .bt_statistics = true, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -611,7 +607,6 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, .need_dc_calib = true, - .bt_statistics = true, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -649,7 +644,6 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, .need_dc_calib = true, - .bt_statistics = true, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -685,7 +679,6 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, .need_dc_calib = true, - .bt_statistics = true, }; /* diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index c4c5691032a6..90033e8752bb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -605,7 +605,8 @@ void iwl_init_sensitivity(struct iwl_priv *priv) IWL_DEBUG_CALIB(priv, "<rx.general); + struct statistics_rx *statistics = &(resp->rx); unsigned long flags; struct statistics_general_data statis; @@ -631,16 +632,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_statistics) { - rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> - rx.general.common); - ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); - cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck); - } else { - rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general); - ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm); - cck = &(((struct iwl_notif_statistics *)resp)->rx.cck); - } if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -649,23 +640,23 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) /* Extract Statistics: */ rx_enable_time = le32_to_cpu(rx_info->channel_load); - fa_cck = le32_to_cpu(cck->false_alarm_cnt); - fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt); - bad_plcp_cck = le32_to_cpu(cck->plcp_err); - bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err); + fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt); + fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt); + bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err); + bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err); statis.beacon_silence_rssi_a = - le32_to_cpu(rx_info->beacon_silence_rssi_a); + le32_to_cpu(statistics->general.beacon_silence_rssi_a); statis.beacon_silence_rssi_b = - le32_to_cpu(rx_info->beacon_silence_rssi_b); + le32_to_cpu(statistics->general.beacon_silence_rssi_b); statis.beacon_silence_rssi_c = - le32_to_cpu(rx_info->beacon_silence_rssi_c); + le32_to_cpu(statistics->general.beacon_silence_rssi_c); statis.beacon_energy_a = - le32_to_cpu(rx_info->beacon_energy_a); + le32_to_cpu(statistics->general.beacon_energy_a); statis.beacon_energy_b = - le32_to_cpu(rx_info->beacon_energy_b); + le32_to_cpu(statistics->general.beacon_energy_b); statis.beacon_energy_c = - le32_to_cpu(rx_info->beacon_energy_c); + le32_to_cpu(statistics->general.beacon_energy_c); spin_unlock_irqrestore(&priv->lock, flags); @@ -737,7 +728,8 @@ static inline u8 find_first_chain(u8 mask) * 1) Which antennas are connected. * 2) Differential rx gain settings to balance the 3 receivers. */ -void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) +void iwl_chain_noise_calibration(struct iwl_priv *priv, + struct iwl_notif_statistics *stat_resp) { struct iwl_chain_noise_data *data = NULL; @@ -761,7 +753,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) u32 active_chains = 0; u8 num_tx_chains; unsigned long flags; - struct statistics_rx_non_phy *rx_info; + struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general); u8 first_chain; if (priv->disable_chain_noise_cal) @@ -780,13 +772,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_statistics) { - rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> - rx.general.common); - } else { - rx_info = &(((struct iwl_notif_statistics *)stat_resp)-> - rx.general); - } if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -795,19 +780,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK); rxon_chnum = le16_to_cpu(priv->staging_rxon.channel); - if (priv->cfg->bt_statistics) { - stat_band24 = !!(((struct iwl_bt_notif_statistics *) - stat_resp)->flag & - STATISTICS_REPLY_FLG_BAND_24G_MSK); - stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *) - stat_resp)->flag) >> 16; - } else { - stat_band24 = !!(((struct iwl_notif_statistics *) - stat_resp)->flag & - STATISTICS_REPLY_FLG_BAND_24G_MSK); - stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *) - stat_resp)->flag) >> 16; - } + stat_band24 = !!(stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); + stat_chnum = le32_to_cpu(stat_resp->flag) >> 16; /* Make sure we accumulate data for just the associated channel * (even if scanning). */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index f052c6d09b37..75d6bfcbc607 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -31,24 +31,21 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) { int p = 0; - u32 flag; - if (priv->cfg->bt_statistics) - flag = le32_to_cpu(priv->_agn.statistics_bt.flag); - else - flag = le32_to_cpu(priv->_agn.statistics.flag); - - p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); - if (flag & UCODE_STATISTICS_CLEAR_MSK) + p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", + le32_to_cpu(priv->_agn.statistics.flag)); + if (le32_to_cpu(priv->_agn.statistics.flag) & + UCODE_STATISTICS_CLEAR_MSK) p += scnprintf(buf + p, bufsz - p, - "\tStatistics have been cleared\n"); + "\tStatistics have been cleared\n"); p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", - (flag & UCODE_STATISTICS_FREQUENCY_MSK) - ? "2.4 GHz" : "5.2 GHz"); + (le32_to_cpu(priv->_agn.statistics.flag) & + UCODE_STATISTICS_FREQUENCY_MSK) + ? "2.4 GHz" : "5.2 GHz"); p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", - (flag & UCODE_STATISTICS_NARROW_BAND_MSK) - ? "enabled" : "disabled"); - + (le32_to_cpu(priv->_agn.statistics.flag) & + UCODE_STATISTICS_NARROW_BAND_MSK) + ? "enabled" : "disabled"); return p; } @@ -82,43 +79,22 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { - ofdm = &priv->_agn.statistics_bt.rx.ofdm; - cck = &priv->_agn.statistics_bt.rx.cck; - general = &priv->_agn.statistics_bt.rx.general.common; - ht = &priv->_agn.statistics_bt.rx.ofdm_ht; - accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm; - accum_cck = &priv->_agn.accum_statistics_bt.rx.cck; - accum_general = - &priv->_agn.accum_statistics_bt.rx.general.common; - accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht; - delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm; - delta_cck = &priv->_agn.delta_statistics_bt.rx.cck; - delta_general = - &priv->_agn.delta_statistics_bt.rx.general.common; - delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht; - max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm; - max_cck = &priv->_agn.max_delta_bt.rx.cck; - max_general = &priv->_agn.max_delta_bt.rx.general.common; - max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht; - } else { - ofdm = &priv->_agn.statistics.rx.ofdm; - cck = &priv->_agn.statistics.rx.cck; - general = &priv->_agn.statistics.rx.general; - ht = &priv->_agn.statistics.rx.ofdm_ht; - accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; - accum_cck = &priv->_agn.accum_statistics.rx.cck; - accum_general = &priv->_agn.accum_statistics.rx.general; - accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; - delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; - delta_cck = &priv->_agn.delta_statistics.rx.cck; - delta_general = &priv->_agn.delta_statistics.rx.general; - delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; - max_ofdm = &priv->_agn.max_delta.rx.ofdm; - max_cck = &priv->_agn.max_delta.rx.cck; - max_general = &priv->_agn.max_delta.rx.general; - max_ht = &priv->_agn.max_delta.rx.ofdm_ht; - } + ofdm = &priv->_agn.statistics.rx.ofdm; + cck = &priv->_agn.statistics.rx.cck; + general = &priv->_agn.statistics.rx.general; + ht = &priv->_agn.statistics.rx.ofdm_ht; + accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; + accum_cck = &priv->_agn.accum_statistics.rx.cck; + accum_general = &priv->_agn.accum_statistics.rx.general; + accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; + delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; + delta_cck = &priv->_agn.delta_statistics.rx.cck; + delta_general = &priv->_agn.delta_statistics.rx.general; + delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; + max_ofdm = &priv->_agn.max_delta.rx.ofdm; + max_cck = &priv->_agn.max_delta.rx.cck; + max_general = &priv->_agn.max_delta.rx.general; + max_ht = &priv->_agn.max_delta.rx.ofdm_ht; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" @@ -584,18 +560,10 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { - tx = &priv->_agn.statistics_bt.tx; - accum_tx = &priv->_agn.accum_statistics_bt.tx; - delta_tx = &priv->_agn.delta_statistics_bt.tx; - max_tx = &priv->_agn.max_delta_bt.tx; - } else { - tx = &priv->_agn.statistics.tx; - accum_tx = &priv->_agn.accum_statistics.tx; - delta_tx = &priv->_agn.delta_statistics.tx; - max_tx = &priv->_agn.max_delta.tx; - } - + tx = &priv->_agn.statistics.tx; + accum_tx = &priv->_agn.accum_statistics.tx; + delta_tx = &priv->_agn.delta_statistics.tx; + max_tx = &priv->_agn.max_delta.tx; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", @@ -791,8 +759,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, char *buf; int bufsz = sizeof(struct statistics_general) * 10 + 300; ssize_t ret; - struct statistics_general_common *general, *accum_general; - struct statistics_general_common *delta_general, *max_general; + struct statistics_general *general, *accum_general; + struct statistics_general *delta_general, *max_general; struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; struct statistics_div *div, *accum_div, *delta_div, *max_div; @@ -809,34 +777,18 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { - general = &priv->_agn.statistics_bt.general.common; - dbg = &priv->_agn.statistics_bt.general.common.dbg; - div = &priv->_agn.statistics_bt.general.common.div; - accum_general = &priv->_agn.accum_statistics_bt.general.common; - accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg; - accum_div = &priv->_agn.accum_statistics_bt.general.common.div; - delta_general = &priv->_agn.delta_statistics_bt.general.common; - max_general = &priv->_agn.max_delta_bt.general.common; - delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg; - max_dbg = &priv->_agn.max_delta_bt.general.common.dbg; - delta_div = &priv->_agn.delta_statistics_bt.general.common.div; - max_div = &priv->_agn.max_delta_bt.general.common.div; - } else { - general = &priv->_agn.statistics.general.common; - dbg = &priv->_agn.statistics.general.common.dbg; - div = &priv->_agn.statistics.general.common.div; - accum_general = &priv->_agn.accum_statistics.general.common; - accum_dbg = &priv->_agn.accum_statistics.general.common.dbg; - accum_div = &priv->_agn.accum_statistics.general.common.div; - delta_general = &priv->_agn.delta_statistics.general.common; - max_general = &priv->_agn.max_delta.general.common; - delta_dbg = &priv->_agn.delta_statistics.general.common.dbg; - max_dbg = &priv->_agn.max_delta.general.common.dbg; - delta_div = &priv->_agn.delta_statistics.general.common.div; - max_div = &priv->_agn.max_delta.general.common.div; - } - + general = &priv->_agn.statistics.general; + dbg = &priv->_agn.statistics.general.dbg; + div = &priv->_agn.statistics.general.div; + accum_general = &priv->_agn.accum_statistics.general; + delta_general = &priv->_agn.delta_statistics.general; + max_general = &priv->_agn.max_delta.general; + accum_dbg = &priv->_agn.accum_statistics.general.dbg; + delta_dbg = &priv->_agn.delta_statistics.general.dbg; + max_dbg = &priv->_agn.max_delta.general.dbg; + accum_div = &priv->_agn.accum_statistics.general.div; + delta_div = &priv->_agn.delta_statistics.general.div; + max_div = &priv->_agn.max_delta.general.div; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", @@ -859,13 +811,6 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, le32_to_cpu(dbg->burst_count), accum_dbg->burst_count, delta_dbg->burst_count, max_dbg->burst_count); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "wait_for_silence_timeout_count:", - le32_to_cpu(dbg->wait_for_silence_timeout_cnt), - accum_dbg->wait_for_silence_timeout_cnt, - delta_dbg->wait_for_silence_timeout_cnt, - max_dbg->wait_for_silence_timeout_cnt); pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u %10u %10u %10u\n", "sleep_time:", @@ -924,90 +869,3 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, kfree(buf); return ret; } - -ssize_t iwl_ucode_bt_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = (struct iwl_priv *)file->private_data; - int pos = 0; - char *buf; - int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200; - ssize_t ret; - struct statistics_bt_activity *bt, *accum_bt; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->mutex); - ret = iwl_send_statistics_request(priv, CMD_SYNC, false); - mutex_unlock(&priv->mutex); - - if (ret) { - IWL_ERR(priv, - "Error sending statistics request: %zd\n", ret); - return -EAGAIN; - } - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * the statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - bt = &priv->_agn.statistics_bt.general.activity; - accum_bt = &priv->_agn.accum_statistics_bt.general.activity; - - pos += iwl_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "\t\t\tcurrent\t\t\taccumulative\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(bt->hi_priority_tx_req_cnt), - accum_bt->hi_priority_tx_req_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n", - le32_to_cpu(bt->hi_priority_tx_denied_cnt), - accum_bt->hi_priority_tx_denied_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(bt->lo_priority_tx_req_cnt), - accum_bt->lo_priority_tx_req_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", - le32_to_cpu(bt->lo_priority_tx_denied_cnt), - accum_bt->lo_priority_tx_denied_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(bt->hi_priority_rx_req_cnt), - accum_bt->hi_priority_rx_req_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n", - le32_to_cpu(bt->hi_priority_rx_denied_cnt), - accum_bt->hi_priority_rx_denied_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(bt->lo_priority_rx_req_cnt), - accum_bt->lo_priority_rx_req_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", - le32_to_cpu(bt->lo_priority_rx_denied_cnt), - accum_bt->lo_priority_rx_denied_cnt); - - pos += scnprintf(buf + pos, bufsz - pos, - "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", - le32_to_cpu(priv->_agn.statistics_bt.rx. - general.num_bt_kills), - priv->_agn.accum_statistics_bt.rx. - general.num_bt_kills); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h index bbdce5913ac7..59b1f25f0d85 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h @@ -37,8 +37,6 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); -ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); #else static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -55,9 +53,4 @@ static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user { return 0; } -static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - return 0; -} #endif diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index a7216dda9786..f06d1feedf81 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -164,7 +164,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd; + cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; cmd.hdr.first_group = 0; cmd.hdr.groups_num = 1; cmd.hdr.data_valid = 1; @@ -197,7 +197,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) data->beacon_count = 0; memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd; + cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; cmd.hdr.first_group = 0; cmd.hdr.groups_num = 1; cmd.hdr.data_valid = 1; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a1b6d202d57c..74623e0d535f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -364,7 +364,7 @@ void iwlagn_temperature(struct iwl_priv *priv) { /* store temperature from statistics (in Celsius) */ priv->temperature = - le32_to_cpu(priv->_agn.statistics.general.common.temperature); + le32_to_cpu(priv->_agn.statistics.general.temperature); iwl_tt_handler(priv); } @@ -1234,10 +1234,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); spin_lock_irqsave(&priv->lock, flags); - if (priv->is_internal_short_scan) - interval = 0; - else - interval = vif->bss_conf.beacon_int; + interval = vif ? vif->bss_conf.beacon_int : 0; spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 9490eced1198..d54edc326f81 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -67,22 +67,17 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, * exactly when to expect beacons, therefore only when we're associated. */ static void iwl_rx_calc_noise(struct iwl_priv *priv) { - struct statistics_rx_non_phy *rx_info; + struct statistics_rx_non_phy *rx_info + = &(priv->_agn.statistics.rx.general); int num_active_rx = 0; int total_silence = 0; - int bcn_silence_a, bcn_silence_b, bcn_silence_c; - int last_rx_noise; - - if (priv->cfg->bt_statistics) - rx_info = &(priv->_agn.statistics_bt.rx.general.common); - else - rx_info = &(priv->_agn.statistics.rx.general); - bcn_silence_a = + int bcn_silence_a = le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; - bcn_silence_b = + int bcn_silence_b = le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; - bcn_silence_c = + int bcn_silence_c = le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; + int last_rx_noise; if (bcn_silence_a) { total_silence += bcn_silence_a; @@ -117,35 +112,17 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) static void iwl_accumulative_statistics(struct iwl_priv *priv, __le32 *stats) { - int i, size; + int i; __le32 *prev_stats; u32 *accum_stats; u32 *delta, *max_delta; - struct statistics_general_common *general, *accum_general; - struct statistics_tx *tx, *accum_tx; - if (priv->cfg->bt_statistics) { - prev_stats = (__le32 *)&priv->_agn.statistics_bt; - accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; - size = sizeof(struct iwl_bt_notif_statistics); - general = &priv->_agn.statistics_bt.general.common; - accum_general = &priv->_agn.accum_statistics_bt.general.common; - tx = &priv->_agn.statistics_bt.tx; - accum_tx = &priv->_agn.accum_statistics_bt.tx; - delta = (u32 *)&priv->_agn.delta_statistics_bt; - max_delta = (u32 *)&priv->_agn.max_delta_bt; - } else { - prev_stats = (__le32 *)&priv->_agn.statistics; - accum_stats = (u32 *)&priv->_agn.accum_statistics; - size = sizeof(struct iwl_notif_statistics); - general = &priv->_agn.statistics.general.common; - accum_general = &priv->_agn.accum_statistics.general.common; - tx = &priv->_agn.statistics.tx; - accum_tx = &priv->_agn.accum_statistics.tx; - delta = (u32 *)&priv->_agn.delta_statistics; - max_delta = (u32 *)&priv->_agn.max_delta; - } - for (i = sizeof(__le32); i < size; + prev_stats = (__le32 *)&priv->_agn.statistics; + accum_stats = (u32 *)&priv->_agn.accum_statistics; + delta = (u32 *)&priv->_agn.delta_statistics; + max_delta = (u32 *)&priv->_agn.max_delta; + + for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); i += sizeof(__le32), stats++, prev_stats++, delta++, max_delta++, accum_stats++) { if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { @@ -158,12 +135,18 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, } /* reset accumulative statistics for "no-counter" type statistics */ - accum_general->temperature = general->temperature; - accum_general->temperature_m = general->temperature_m; - accum_general->ttl_timestamp = general->ttl_timestamp; - accum_tx->tx_power.ant_a = tx->tx_power.ant_a; - accum_tx->tx_power.ant_b = tx->tx_power.ant_b; - accum_tx->tx_power.ant_c = tx->tx_power.ant_c; + priv->_agn.accum_statistics.general.temperature = + priv->_agn.statistics.general.temperature; + priv->_agn.accum_statistics.general.temperature_m = + priv->_agn.statistics.general.temperature_m; + priv->_agn.accum_statistics.general.ttl_timestamp = + priv->_agn.statistics.general.ttl_timestamp; + priv->_agn.accum_statistics.tx.tx_power.ant_a = + priv->_agn.statistics.tx.tx_power.ant_a; + priv->_agn.accum_statistics.tx.tx_power.ant_b = + priv->_agn.statistics.tx.tx_power.ant_b; + priv->_agn.accum_statistics.tx.tx_power.ant_c = + priv->_agn.statistics.tx.tx_power.ant_c; } #endif @@ -202,30 +185,11 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, * by zero. */ if (plcp_msec) { - struct statistics_rx_phy *ofdm; - struct statistics_rx_ht_phy *ofdm_ht; - - if (priv->cfg->bt_statistics) { - ofdm = &pkt->u.stats_bt.rx.ofdm; - ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; - combined_plcp_delta = - (le32_to_cpu(ofdm->plcp_err) - - le32_to_cpu(priv->_agn.statistics_bt. - rx.ofdm.plcp_err)) + - (le32_to_cpu(ofdm_ht->plcp_err) - - le32_to_cpu(priv->_agn.statistics_bt. - rx.ofdm_ht.plcp_err)); - } else { - ofdm = &pkt->u.stats.rx.ofdm; - ofdm_ht = &pkt->u.stats.rx.ofdm_ht; - combined_plcp_delta = - (le32_to_cpu(ofdm->plcp_err) - - le32_to_cpu(priv->_agn.statistics. - rx.ofdm.plcp_err)) + - (le32_to_cpu(ofdm_ht->plcp_err) - - le32_to_cpu(priv->_agn.statistics. - rx.ofdm_ht.plcp_err)); - } + combined_plcp_delta = + (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - + le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) + + (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - + le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err)); if ((combined_plcp_delta > 0) && ((combined_plcp_delta * 100) / plcp_msec) > @@ -242,14 +206,15 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, * plcp_msec */ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %u, %u, %u, %d, %u mSecs\n", - priv->cfg->plcp_delta_threshold, - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - combined_plcp_delta, plcp_msec); - + "%u, %u, %u, %u, %d, %u mSecs\n", + priv->cfg->plcp_delta_threshold, + le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), + le32_to_cpu( + priv->_agn.statistics.rx.ofdm.plcp_err), + le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), + le32_to_cpu( + priv->_agn.statistics.rx.ofdm_ht.plcp_err), + combined_plcp_delta, plcp_msec); rc = false; } } @@ -262,50 +227,24 @@ void iwl_rx_statistics(struct iwl_priv *priv, int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); - if (priv->cfg->bt_statistics) { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_bt_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); - change = ((priv->_agn.statistics_bt.general.common.temperature != - pkt->u.stats_bt.general.common.temperature) || - ((priv->_agn.statistics_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); -#endif + IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", + (int)sizeof(priv->_agn.statistics), + le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); - } else { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); + change = ((priv->_agn.statistics.general.temperature != + pkt->u.stats.general.temperature) || + ((priv->_agn.statistics.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); - change = ((priv->_agn.statistics.general.common.temperature != - pkt->u.stats.general.common.temperature) || - ((priv->_agn.statistics.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); #ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); #endif - - } - iwl_recover_from_statistics(priv, pkt); - if (priv->cfg->bt_statistics) - memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, - sizeof(priv->_agn.statistics_bt)); - else - memcpy(&priv->_agn.statistics, &pkt->u.stats, - sizeof(priv->_agn.statistics)); + memcpy(&priv->_agn.statistics, &pkt->u.stats, + sizeof(priv->_agn.statistics)); set_bit(STATUS_STATISTICS, &priv->status); @@ -338,12 +277,6 @@ void iwl_reply_statistics(struct iwl_priv *priv, sizeof(struct iwl_notif_statistics)); memset(&priv->_agn.max_delta, 0, sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.accum_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.delta_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.max_delta_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); #endif IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index 35337b1e7cac..7391c63fb024 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -294,7 +292,9 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, struct ieee80211_hdr *hdr, int left) { - if (!priv->ibss_beacon) + if (!iwl_is_associated(priv) || !priv->ibss_beacon || + ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && + (priv->iw_mode != NL80211_IFTYPE_AP))) return 0; if (priv->ibss_beacon->len > left) @@ -1692,7 +1692,6 @@ static void iwl_nic_start(struct iwl_priv *priv) struct iwlagn_ucode_capabilities { u32 max_probe_length; - u32 standard_phy_calibration_size; }; static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); @@ -1828,6 +1827,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, u32 tlv_len; enum iwl_ucode_tlv_type tlv_type; const u8 *tlv_data; + int ret = 0; if (len < sizeof(*ucode)) { IWL_ERR(priv, "uCode has invalid length: %zd\n", len); @@ -1863,8 +1863,9 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, len -= sizeof(*ucode); - while (len >= sizeof(*tlv)) { + while (len >= sizeof(*tlv) && !ret) { u16 tlv_alt; + u32 fixed_tlv_size = 4; len -= sizeof(*tlv); tlv = (void *)data; @@ -1912,57 +1913,59 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, pieces->boot_size = tlv_len; break; case IWL_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->max_probe_length = + if (tlv_len != fixed_tlv_size) + ret = -EINVAL; + else + capa->max_probe_length = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_INIT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_ptr = + if (tlv_len != fixed_tlv_size) + ret = -EINVAL; + else + pieces->init_evtlog_ptr = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_size = + if (tlv_len != fixed_tlv_size) + ret = -EINVAL; + else + pieces->init_evtlog_size = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_INIT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_errlog_ptr = + if (tlv_len != fixed_tlv_size) + ret = -EINVAL; + else + pieces->init_errlog_ptr = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_ptr = + if (tlv_len != fixed_tlv_size) + ret = -EINVAL; + else + pieces->inst_evtlog_ptr = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_size = + if (tlv_len != fixed_tlv_size) + ret = -EINVAL; + else + pieces->inst_evtlog_size = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_errlog_ptr = + if (tlv_len != fixed_tlv_size) + ret = -EINVAL; + else + pieces->inst_errlog_ptr = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_ENHANCE_SENS_TBL: if (tlv_len) - goto invalid_tlv_len; - priv->enhance_sensitivity_table = true; - break; - case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->standard_phy_calibration_size = - le32_to_cpup((__le32 *)tlv_data); + ret = -EINVAL; + else + priv->enhance_sensitivity_table = true; break; default: IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); @@ -1973,16 +1976,14 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, if (len) { IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); - return -EINVAL; + ret = -EINVAL; + } else if (ret) { + IWL_ERR(priv, "TLV %d has invalid size: %u\n", + tlv_type, tlv_len); + iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len); } - return 0; - - invalid_tlv_len: - IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); - iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); - - return -EINVAL; + return ret; } /** @@ -2004,8 +2005,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) u32 build; struct iwlagn_ucode_capabilities ucode_capa = { .max_probe_length = 200, - .standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE, }; memset(&pieces, 0, sizeof(pieces)); @@ -2227,20 +2226,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) pieces.boot_size); memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size); - /* - * figure out the offset of chain noise reset and gain commands - * base on the size of standard phy calibration commands table size - */ - if (ucode_capa.standard_phy_calibration_size > - IWL_MAX_PHY_CALIBRATE_TBL_SIZE) - ucode_capa.standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; - - priv->_agn.phy_calib_chain_noise_reset_cmd = - ucode_capa.standard_phy_calibration_size; - priv->_agn.phy_calib_chain_noise_gain_cmd = - ucode_capa.standard_phy_calibration_size + 1; - /************************************************** * This is still part of probe() in a sense... * @@ -3023,17 +3008,9 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) } if (priv->start_calib) { - if (priv->cfg->bt_statistics) { - iwl_chain_noise_calibration(priv, - (void *)&priv->_agn.statistics_bt); - iwl_sensitivity_calibration(priv, - (void *)&priv->_agn.statistics_bt); - } else { - iwl_chain_noise_calibration(priv, - (void *)&priv->_agn.statistics); - iwl_sensitivity_calibration(priv, - (void *)&priv->_agn.statistics); - } + iwl_chain_noise_calibration(priv, &priv->_agn.statistics); + + iwl_sensitivity_calibration(priv, &priv->_agn.statistics); } mutex_unlock(&priv->mutex); @@ -3932,7 +3909,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); unsigned long flags; - u16 pci_cmd, num_mac; + u16 pci_cmd; + u8 perm_addr[ETH_ALEN]; /************************ * 1. Allocating HW data @@ -4050,17 +4028,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_free_eeprom; /* extract MAC Address */ - iwl_eeprom_get_mac(priv, priv->addresses[0].addr); - IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); - priv->hw->wiphy->addresses = priv->addresses; - priv->hw->wiphy->n_addresses = 1; - num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); - if (num_mac > 1) { - memcpy(priv->addresses[1].addr, priv->addresses[0].addr, - ETH_ALEN); - priv->addresses[1].addr[5]++; - priv->hw->wiphy->n_addresses++; - } + iwl_eeprom_get_mac(priv, perm_addr); + IWL_DEBUG_INFO(priv, "MAC address: %pM\n", perm_addr); + SET_IEEE80211_PERM_ADDR(priv->hw, perm_addr); /************************ * 5. Setup HW constants @@ -4419,18 +4389,19 @@ static int __init iwl_init(void) { int ret; - pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); - pr_info(DRV_COPYRIGHT "\n"); + printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); + printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); ret = iwlagn_rate_control_register(); if (ret) { - pr_err("Unable to register rate control algorithm: %d\n", ret); + printk(KERN_ERR DRV_NAME + "Unable to register rate control algorithm: %d\n", ret); return ret; } ret = pci_register_driver(&iwl_driver); if (ret) { - pr_err("Unable to initialize PCI module\n"); + printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); goto error_register; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h b/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h index ba9523fbb300..2b7b1df83ba0 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h @@ -66,8 +66,10 @@ #include "iwl-core.h" #include "iwl-commands.h" -void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); -void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); +void iwl_chain_noise_calibration(struct iwl_priv *priv, + struct iwl_notif_statistics *stat_resp); +void iwl_sensitivity_calibration(struct iwl_priv *priv, + struct iwl_notif_statistics *resp); void iwl_init_sensitivity(struct iwl_priv *priv); void iwl_reset_run_time_calib(struct iwl_priv *priv); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h index 60725a5c1b69..8d2db9d22045 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -964,8 +964,8 @@ struct iwl_qosparam_cmd { #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ #define IWL_INVALID_STATION 255 -#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) -#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) +#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2); +#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) #define STA_FLG_MAX_AGG_SIZE_POS (19) @@ -1245,7 +1245,7 @@ struct iwl_txfifo_flush_cmd { __le32 fifo_control; __le16 flush_control; __le16 reserved; -} __packed; +} __attribute__ ((packed)); /* * REPLY_WEP_KEY = 0x20 @@ -3035,8 +3035,7 @@ struct iwl39_statistics_tx { struct statistics_dbg { __le32 burst_check; __le32 burst_count; - __le32 wait_for_silence_timeout_cnt; - __le32 reserved[3]; + __le32 reserved[4]; } __packed; struct iwl39_statistics_div { @@ -3127,13 +3126,6 @@ struct statistics_rx_non_phy { __le32 beacon_energy_c; } __packed; -struct statistics_rx_non_phy_bt { - struct statistics_rx_non_phy common; - /* additional stats for bt */ - __le32 num_bt_kills; - __le32 reserved[2]; -} __packed; - struct statistics_rx { struct statistics_rx_phy ofdm; struct statistics_rx_phy cck; @@ -3141,13 +3133,6 @@ struct statistics_rx { struct statistics_rx_ht_phy ofdm_ht; } __packed; -struct statistics_rx_bt { - struct statistics_rx_phy ofdm; - struct statistics_rx_phy cck; - struct statistics_rx_non_phy_bt general; - struct statistics_rx_ht_phy ofdm_ht; -} __packed; - /** * struct statistics_tx_power - current tx power * @@ -3210,7 +3195,7 @@ struct statistics_div { __le32 reserved2; } __packed; -struct statistics_general_common { +struct statistics_general { __le32 temperature; /* radio temperature */ __le32 temperature_m; /* for 5000 and up, this is radio voltage */ struct statistics_dbg dbg; @@ -3226,30 +3211,6 @@ struct statistics_general_common { * in order to get out of bad PHY status */ __le32 num_of_sos_states; -} __packed; - -struct statistics_bt_activity { - /* Tx statistics */ - __le32 hi_priority_tx_req_cnt; - __le32 hi_priority_tx_denied_cnt; - __le32 lo_priority_tx_req_cnt; - __le32 lo_priority_tx_denied_cnt; - /* Rx statistics */ - __le32 hi_priority_rx_req_cnt; - __le32 hi_priority_rx_denied_cnt; - __le32 lo_priority_rx_req_cnt; - __le32 lo_priority_rx_denied_cnt; -} __packed; - -struct statistics_general { - struct statistics_general_common common; - __le32 reserved2; - __le32 reserved3; -} __packed; - -struct statistics_general_bt { - struct statistics_general_common common; - struct statistics_bt_activity activity; __le32 reserved2; __le32 reserved3; } __packed; @@ -3311,12 +3272,6 @@ struct iwl_notif_statistics { struct statistics_general general; } __packed; -struct iwl_bt_notif_statistics { - __le32 flag; - struct statistics_rx_bt rx; - struct statistics_tx tx; - struct statistics_general_bt general; -} __packed; /* * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) @@ -3592,7 +3547,7 @@ struct iwl_sensitivity_cmd { struct iwl_enhance_sensitivity_cmd { __le16 control; /* always use "1" */ __le16 enhance_table[ENHANCE_HD_TABLE_SIZE]; /* use HD_* as index */ -} __packed; +} __attribute__ ((packed)); /** @@ -3660,10 +3615,10 @@ enum { IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18, + IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD = 18, + IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD = 19, }; -#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) #define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff) @@ -3988,7 +3943,6 @@ struct iwl_rx_packet { struct iwl_sleep_notification sleep_notif; struct iwl_spectrum_resp spectrum; struct iwl_notif_statistics stats; - struct iwl_bt_notif_statistics stats_bt; struct iwl_compressed_ba_resp compressed_ba; struct iwl_missed_beacon_notif missed_beacon; struct iwl_coex_medium_notification coex_medium_notif; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index 8024d44ce4bb..f73eb08a9494 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -170,7 +170,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, struct ieee80211_hw *hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops); if (hw == NULL) { - pr_err("%s: Can not allocate network device\n", + printk(KERN_ERR "%s: Can not allocate network device\n", cfg->name); goto out; } @@ -1748,37 +1748,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv) iwlcore_commit_rxon(priv); } -static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - __le64 timestamp; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = skb; - - timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - priv->timestamp = le64_to_cpu(timestamp); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - spin_unlock_irqrestore(&priv->lock, flags); - - priv->cfg->ops->lib->post_associate(priv, priv->vif); - - return 0; -} - void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, @@ -1794,15 +1763,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (changes & BSS_CHANGED_QOS) { - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - priv->qos_data.qos_active = bss_conf->qos; - iwl_update_qos(priv); - spin_unlock_irqrestore(&priv->lock, flags); - } - if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { dev_kfree_skb(priv->ibss_beacon); priv->ibss_beacon = ieee80211_beacon_get(hw, vif); @@ -1945,6 +1905,38 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_bss_info_changed); +int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + __le64 timestamp; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return -EIO; + } + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->ibss_beacon) + dev_kfree_skb(priv->ibss_beacon); + + priv->ibss_beacon = skb; + + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + priv->timestamp = le64_to_cpu(timestamp); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); + + priv->cfg->ops->lib->post_associate(priv, priv->vif); + + return 0; +} +EXPORT_SYMBOL(iwl_mac_beacon_update); + static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) { iwl_connection_init_rx_config(priv, vif); @@ -2142,6 +2134,15 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) iwl_set_tx_power(priv, conf->power_level, false); } + if (changed & IEEE80211_CONF_CHANGE_QOS) { + bool qos_active = !!(conf->flags & IEEE80211_CONF_QOS); + + spin_lock_irqsave(&priv->lock, flags); + priv->qos_data.qos_active = qos_active; + iwl_update_qos(priv); + spin_unlock_irqrestore(&priv->lock, flags); + } + if (!iwl_is_ready(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); goto out; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index e9d23f2f869d..fcbba3d604de 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -125,8 +125,6 @@ struct iwl_debugfs_ops { size_t count, loff_t *ppos); ssize_t (*general_stats_read)(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); - ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); }; struct iwl_temp_ops { @@ -337,7 +335,6 @@ struct iwl_cfg { u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; const bool need_dc_calib; - const bool bt_statistics; }; /*************************** @@ -380,6 +377,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); +int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); int iwl_commit_rxon(struct iwl_priv *priv); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e96a1bb12783..088a2c13f59b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1267,7 +1267,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = file->private_data; + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; int pos = 0; char buf[128]; const size_t bufsz = sizeof(buf); @@ -1317,7 +1317,7 @@ static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = file->private_data; + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; int len = 0; char buf[20]; @@ -1329,7 +1329,7 @@ static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = file->private_data; + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; int len = 0; char buf[20]; @@ -1342,7 +1342,7 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = file->private_data; + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; char *buf; int pos = 0; ssize_t ret = -EFAULT; @@ -1404,7 +1404,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = file->private_data; + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; int pos = 0; char buf[12]; const size_t bufsz = sizeof(buf); @@ -1519,16 +1519,6 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, return count; } -static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = (struct iwl_priv *)file->private_data; - - return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file, - user_buf, count, ppos); -} - DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -1551,7 +1541,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(force_reset); DEBUGFS_READ_FILE_OPS(rxon_flags); DEBUGFS_READ_FILE_OPS(rxon_filter_flags); DEBUGFS_WRITE_FILE_OPS(txfifo_flush); -DEBUGFS_READ_FILE_OPS(ucode_bt_stats); /* * Create the debugfs files and directories @@ -1619,8 +1608,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); if (priv->cfg->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->bt_statistics) - DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); if (priv->cfg->sensitivity_calib_by_driver) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h index f35bcad56e36..c4dba62b74af 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -571,7 +571,6 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, - IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, }; struct iwl_ucode_tlv { @@ -1154,9 +1153,6 @@ struct iwl_priv { u32 hw_wa_rev; u8 rev_id; - /* EEPROM MAC addresses */ - struct mac_address addresses[2]; - /* uCode images, save to reload in case of failure */ int fw_index; /* firmware we're trying to load */ u32 ucode_ver; /* version of ucode, copy of @@ -1325,23 +1321,11 @@ struct iwl_priv { u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; - /* - * chain noise reset and gain commands are the - * two extra calibration commands follows the standard - * phy calibration commands - */ - u8 phy_calib_chain_noise_reset_cmd; - u8 phy_calib_chain_noise_gain_cmd; - struct iwl_notif_statistics statistics; - struct iwl_bt_notif_statistics statistics_bt; #ifdef CONFIG_IWLWIFI_DEBUGFS struct iwl_notif_statistics accum_statistics; struct iwl_notif_statistics delta_statistics; struct iwl_notif_statistics max_delta; - struct iwl_bt_notif_statistics accum_statistics_bt; - struct iwl_bt_notif_statistics delta_statistics_bt; - struct iwl_bt_notif_statistics max_delta_bt; #endif } _agn; #endif diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h index a4772aff51fe..3452dfa7b571 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -402,7 +402,6 @@ struct iwl_eeprom_calib_info { #define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ #define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */ -#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ /* The following masks are to be applied on EEPROM_RADIO_CONFIG */ #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c index b0c6b0473901..2a7c399fee1e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -429,10 +429,11 @@ void iwl_bg_scan_check(struct work_struct *data) return; mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status) && - !test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n", - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); + if (test_bit(STATUS_SCANNING, &priv->status) || + test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting " + "adapter (%dms)\n", + jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) iwl_send_scan_abort(priv); @@ -497,11 +498,12 @@ void iwl_bg_abort_scan(struct work_struct *work) !test_bit(STATUS_GEO_CONFIGURED, &priv->status)) return; - cancel_delayed_work(&priv->scan_check); - mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) - iwl_send_scan_abort(priv); + + cancel_delayed_work_sync(&priv->scan_check); + set_bit(STATUS_SCAN_ABORTING, &priv->status); + iwl_send_scan_abort(priv); + mutex_unlock(&priv->mutex); } EXPORT_SYMBOL(iwl_bg_abort_scan); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index d24eb47d3705..8eb347106902 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -313,7 +311,9 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, int left) { - if (!iwl_is_associated(priv) || !priv->ibss_beacon) + if (!iwl_is_associated(priv) || !priv->ibss_beacon || + ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && + (priv->iw_mode != NL80211_IFTYPE_AP))) return 0; if (priv->ibss_beacon->len > left) @@ -2883,10 +2883,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); spin_lock_irqsave(&priv->lock, flags); - if (priv->is_internal_short_scan) - interval = 0; - else - interval = vif->bss_conf.beacon_int; + interval = vif ? vif->bss_conf.beacon_int : 0; spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; @@ -3935,7 +3932,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e * space for this driver's private structure */ hw = iwl_alloc_all(cfg, &iwl3945_hw_ops); if (hw == NULL) { - pr_err("Can not allocate network device\n"); + printk(KERN_ERR DRV_NAME "Can not allocate network device\n"); err = -ENOMEM; goto out; } @@ -4227,18 +4224,19 @@ static int __init iwl3945_init(void) { int ret; - pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); - pr_info(DRV_COPYRIGHT "\n"); + printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); + printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); ret = iwl3945_rate_control_register(); if (ret) { - pr_err("Unable to register rate control algorithm: %d\n", ret); + printk(KERN_ERR DRV_NAME + "Unable to register rate control algorithm: %d\n", ret); return ret; } ret = pci_register_driver(&iwl3945_driver); if (ret) { - pr_err("Unable to initialize PCI module\n"); + printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); goto error_register; } diff --git a/trunk/drivers/net/wireless/libertas/cfg.c b/trunk/drivers/net/wireless/libertas/cfg.c index 25f902760980..f36cc970ad1b 100644 --- a/trunk/drivers/net/wireless/libertas/cfg.c +++ b/trunk/drivers/net/wireless/libertas/cfg.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -890,7 +891,7 @@ struct cmd_key_material { __le16 action; struct MrvlIEtype_keyParamSet param; -} __packed; +} __attribute__ ((packed)); static int lbs_set_key_material(struct lbs_private *priv, int key_type, @@ -1382,10 +1383,93 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, } + +/*************************************************************************** + * Monitor mode + */ + +/* like "struct cmd_ds_802_11_monitor_mode", but with cmd_header. Once we + * get rid of WEXT, this should go into host.h */ +struct cmd_monitor_mode { + struct cmd_header hdr; + + __le16 action; + __le16 mode; +} __attribute__ ((packed)); + +static int lbs_enable_monitor_mode(struct lbs_private *priv, int mode) +{ + struct cmd_monitor_mode cmd; + int ret; + + lbs_deb_enter(LBS_DEB_CFG80211); + + /* + * cmd 98 00 + * size 0c 00 + * sequence xx xx + * result 00 00 + * action 01 00 ACT_SET + * enable 01 00 + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_SET); + cmd.mode = cpu_to_le16(mode); + + ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd); + + if (ret == 0) + priv->dev->type = ARPHRD_IEEE80211_RADIOTAP; + else + priv->dev->type = ARPHRD_ETHER; + + lbs_deb_leave(LBS_DEB_CFG80211); + return ret; +} + + + + + + /*************************************************************************** * Get station */ +/* + * Returns the signal or 0 in case of an error. + */ + +/* like "struct cmd_ds_802_11_rssi", but with cmd_header. Once we get rid + * of WEXT, this should go into host.h */ +struct cmd_rssi { + struct cmd_header hdr; + + __le16 n_or_snr; + __le16 nf; + __le16 avg_snr; + __le16 avg_nf; +} __attribute__ ((packed)); + +static int lbs_get_signal(struct lbs_private *priv, s8 *signal, s8 *noise) +{ + struct cmd_rssi cmd; + int ret; + + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.n_or_snr = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); + ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd); + + if (ret == 0) { + *signal = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), + le16_to_cpu(cmd.nf)); + *noise = CAL_NF(le16_to_cpu(cmd.nf)); + } + return ret; +} + + static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_info *sinfo) { @@ -1406,7 +1490,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, sinfo->rx_packets = priv->dev->stats.rx_packets; /* Get current RSSI */ - ret = lbs_get_rssi(priv, &signal, &noise); + ret = lbs_get_signal(priv, &signal, &noise); if (ret == 0) { sinfo->signal = signal; sinfo->filled |= STATION_INFO_SIGNAL; @@ -1446,7 +1530,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, survey->channel = ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(priv->channel)); - ret = lbs_get_rssi(priv, &signal, &noise); + ret = lbs_get_signal(priv, &signal, &noise); if (ret == 0) { survey->filled = SURVEY_INFO_NOISE_DBM; survey->noise = noise; @@ -1474,17 +1558,17 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev, switch (type) { case NL80211_IFTYPE_MONITOR: - ret = lbs_set_monitor_mode(priv, 1); + ret = lbs_enable_monitor_mode(priv, 1); break; case NL80211_IFTYPE_STATION: if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) - ret = lbs_set_monitor_mode(priv, 0); + ret = lbs_enable_monitor_mode(priv, 0); if (!ret) ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1); break; case NL80211_IFTYPE_ADHOC: if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) - ret = lbs_set_monitor_mode(priv, 0); + ret = lbs_enable_monitor_mode(priv, 0); if (!ret) ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2); break; @@ -1979,20 +2063,113 @@ int lbs_cfg_register(struct lbs_private *priv) return ret; } -int lbs_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) +/** + * @brief This function sets DOMAIN INFO to FW + * @param priv pointer to struct lbs_private + * @return 0; -1 +*/ +static int lbs_11d_set_domain_info(struct lbs_private *priv) { - struct lbs_private *priv = wiphy_priv(wiphy); int ret; + ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO, + CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, NULL); + if (ret) + lbs_deb_11d("fail to dnld domain info\n"); + + return ret; +} + +static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy, + struct regulatory_request *request) +{ + u8 no_of_triplet = 0; + u8 no_of_parsed_chan = 0; + u8 first_channel = 0, next_chan = 0, max_pwr = 0; + u8 i, flag = 0; + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + struct lbs_private *priv = wiphy_priv(wiphy); + struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CFG80211); + + /* Set country code */ + domain_info->country_code[0] = request->alpha2[0]; + domain_info->country_code[1] = request->alpha2[1]; + domain_info->country_code[2] = ' '; + + for (band = 0; band < IEEE80211_NUM_BANDS ; band++) { + + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels ; i++) { + ch = &sband->channels[i]; + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (!flag) { + flag = 1; + next_chan = first_channel = (u32) ch->hw_value; + max_pwr = ch->max_power; + no_of_parsed_chan = 1; + continue; + } + + if (ch->hw_value == next_chan + 1 && + ch->max_power == max_pwr) { + next_chan++; + no_of_parsed_chan++; + } else { + domain_info->triplet[no_of_triplet] + .chans.first_channel = first_channel; + domain_info->triplet[no_of_triplet] + .chans.num_channels = no_of_parsed_chan; + domain_info->triplet[no_of_triplet] + .chans.max_power = max_pwr; + no_of_triplet++; + flag = 0; + } + } + if (flag) { + domain_info->triplet[no_of_triplet] + .chans.first_channel = first_channel; + domain_info->triplet[no_of_triplet] + .chans.num_channels = no_of_parsed_chan; + domain_info->triplet[no_of_triplet] + .chans.max_power = max_pwr; + no_of_triplet++; + } + } + + domain_info->no_triplet = no_of_triplet; + + /* Set domain info */ + ret = lbs_11d_set_domain_info(priv); + if (ret) + lbs_pr_err("11D: error setting domain info in FW\n"); + + lbs_deb_leave(LBS_DEB_CFG80211); +} + +int lbs_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " "callback for domain %c%c\n", request->alpha2[0], request->alpha2[1]); - ret = lbs_set_11d_domain_info(priv, request, wiphy->bands); + lbs_send_domain_info_cmd_fw(wiphy, request); lbs_deb_leave(LBS_DEB_CFG80211); - return ret; + + return 0; } void lbs_scan_deinit(struct lbs_private *priv) diff --git a/trunk/drivers/net/wireless/libertas/cfg.h b/trunk/drivers/net/wireless/libertas/cfg.h index 4f46bb744bee..756fb98f9f05 100644 --- a/trunk/drivers/net/wireless/libertas/cfg.h +++ b/trunk/drivers/net/wireless/libertas/cfg.h @@ -13,6 +13,12 @@ void lbs_cfg_free(struct lbs_private *priv); int lbs_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +/* All of those are TODOs: */ +#define lbs_cmd_802_11_rssi(priv, cmdptr) (0) +#define lbs_ret_802_11_rssi(priv, resp) (0) +#define lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action) (0) +#define lbs_ret_802_11_bcn_ctrl(priv, resp) (0) + void lbs_send_disconnect_notification(struct lbs_private *priv); void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); diff --git a/trunk/drivers/net/wireless/libertas/cmd.c b/trunk/drivers/net/wireless/libertas/cmd.c index 70745928f3f8..749fbde4fd54 100644 --- a/trunk/drivers/net/wireless/libertas/cmd.c +++ b/trunk/drivers/net/wireless/libertas/cmd.c @@ -6,14 +6,13 @@ #include #include #include -#include #include "decl.h" #include "cfg.h" #include "cmd.h" -#define CAL_NF(nf) ((s32)(-(s32)(nf))) -#define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf))) + +static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); /** * @brief Simple callback that copies response back into command @@ -74,6 +73,30 @@ static u8 is_command_allowed_in_ps(u16 cmd) return 0; } +/** + * @brief This function checks if the command is allowed. + * + * @param priv A pointer to lbs_private structure + * @return allowed or not allowed. + */ + +static int lbs_is_cmd_allowed(struct lbs_private *priv) +{ + int ret = 1; + + lbs_deb_enter(LBS_DEB_CMD); + + if (!priv->is_auto_deep_sleep_enabled) { + if (priv->is_deep_sleep) { + lbs_deb_cmd("command not allowed in deep sleep\n"); + ret = 0; + } + } + + lbs_deb_leave(LBS_DEB_CMD); + return ret; +} + /** * @brief Updates the hardware details like MAC address and regulatory region * @@ -204,49 +227,42 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, } EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); -/** - * @brief Sets the Power Save mode - * - * @param priv A pointer to struct lbs_private structure - * @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or - * PS_MODE_ACTION_EXIT_PS) - * @param block Whether to block on a response or not - * - * @return 0 on success, error on failure - */ -int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block) +static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd, + u16 cmd_action) { - struct cmd_ds_802_11_ps_mode cmd; - int ret = 0; + struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode; lbs_deb_enter(LBS_DEB_CMD); - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(cmd_action); + cmd->command = cpu_to_le16(CMD_802_11_PS_MODE); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) + + sizeof(struct cmd_header)); + psm->action = cpu_to_le16(cmd_action); + psm->multipledtim = 0; + switch (cmd_action) { + case CMD_SUBCMD_ENTER_PS: + lbs_deb_cmd("PS command:" "SubCode- Enter PS\n"); + + psm->locallisteninterval = 0; + psm->nullpktinterval = 0; + psm->multipledtim = + cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM); + break; - if (cmd_action == PS_MODE_ACTION_ENTER_PS) { - lbs_deb_cmd("PS_MODE: action ENTER_PS\n"); - cmd.multipledtim = cpu_to_le16(1); /* Default DTIM multiple */ - } else if (cmd_action == PS_MODE_ACTION_EXIT_PS) { - lbs_deb_cmd("PS_MODE: action EXIT_PS\n"); - } else { - /* We don't handle CONFIRM_SLEEP here because it needs to - * be fastpathed to the firmware. - */ - lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action); - ret = -EOPNOTSUPP; - goto out; - } + case CMD_SUBCMD_EXIT_PS: + lbs_deb_cmd("PS command:" "SubCode- Exit PS\n"); + break; - if (block) - ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd); - else - lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd)); + case CMD_SUBCMD_SLEEP_CONFIRMED: + lbs_deb_cmd("PS command: SubCode- sleep confirm\n"); + break; -out: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; + default: + break; + } + + lbs_deb_leave(LBS_DEB_CMD); + return 0; } int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, @@ -560,35 +576,23 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) return ret; } -/** - * @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW) - * - * @param priv A pointer to struct lbs_private structure - * @param enable 1 to enable monitor mode, 0 to disable - * - * @return 0 on success, error on failure - */ -int lbs_set_monitor_mode(struct lbs_private *priv, int enable) +static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd, + u16 cmd_action, void *pdata_buf) { - struct cmd_ds_802_11_monitor_mode cmd; - int ret; + struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor; - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_SET); - if (enable) - cmd.mode = cpu_to_le16(0x1); - - lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable); + cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE); + cmd->size = + cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) + + sizeof(struct cmd_header)); - ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd); - if (ret == 0) { - priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP : - ARPHRD_ETHER; + monitor->action = cpu_to_le16(cmd_action); + if (cmd_action == CMD_ACT_SET) { + monitor->mode = + cpu_to_le16((u16) (*(u32 *) pdata_buf)); } - lbs_deb_leave(LBS_DEB_CMD); - return ret; + return 0; } /** @@ -673,242 +677,78 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel) return ret; } -/** - * @brief Get current RSSI and noise floor - * - * @param priv A pointer to struct lbs_private structure - * @param rssi On successful return, signal level in mBm - * - * @return The channel on success, error on failure - */ -int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) +static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr, + u8 cmd_action, void *pdata_buf) { - struct cmd_ds_802_11_rssi cmd; - int ret = 0; + struct lbs_offset_value *offval; lbs_deb_enter(LBS_DEB_CMD); - BUG_ON(rssi == NULL); - BUG_ON(nf == NULL); + offval = (struct lbs_offset_value *)pdata_buf; - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - /* Average SNR over last 8 beacons */ - cmd.n_or_snr = cpu_to_le16(8); + switch (le16_to_cpu(cmdptr->command)) { + case CMD_MAC_REG_ACCESS: + { + struct cmd_ds_mac_reg_access *macreg; - ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd); - if (ret == 0) { - *nf = CAL_NF(le16_to_cpu(cmd.nf)); - *rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf)); - } + cmdptr->size = + cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access) + + sizeof(struct cmd_header)); + macreg = + (struct cmd_ds_mac_reg_access *)&cmdptr->params. + macreg; - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} + macreg->action = cpu_to_le16(cmd_action); + macreg->offset = cpu_to_le16((u16) offval->offset); + macreg->value = cpu_to_le32(offval->value); -/** - * @brief Send regulatory and 802.11d domain information to the firmware - * - * @param priv pointer to struct lbs_private - * @param request cfg80211 regulatory request structure - * @param bands the device's supported bands and channels - * - * @return 0 on success, error code on failure -*/ -int lbs_set_11d_domain_info(struct lbs_private *priv, - struct regulatory_request *request, - struct ieee80211_supported_band **bands) -{ - struct cmd_ds_802_11d_domain_info cmd; - struct mrvl_ie_domain_param_set *domain = &cmd.domain; - struct ieee80211_country_ie_triplet *t; - enum ieee80211_band band; - struct ieee80211_channel *ch; - u8 num_triplet = 0; - u8 num_parsed_chan = 0; - u8 first_channel = 0, next_chan = 0, max_pwr = 0; - u8 i, flag = 0; - size_t triplet_size; - int ret; - - lbs_deb_enter(LBS_DEB_11D); - - memset(&cmd, 0, sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_SET); - - lbs_deb_11d("Setting country code '%c%c'\n", - request->alpha2[0], request->alpha2[1]); - - domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); - - /* Set country code */ - domain->country_code[0] = request->alpha2[0]; - domain->country_code[1] = request->alpha2[1]; - domain->country_code[2] = ' '; - - /* Now set up the channel triplets; firmware is somewhat picky here - * and doesn't validate channel numbers and spans; hence it would - * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since - * the last 3 aren't valid channels, the driver is responsible for - * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20) - * etc. - */ - for (band = 0; - (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS); - band++) { - - if (!bands[band]) - continue; - - for (i = 0; - (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS); - i++) { - ch = &bands[band]->channels[i]; - if (ch->flags & IEEE80211_CHAN_DISABLED) - continue; - - if (!flag) { - flag = 1; - next_chan = first_channel = (u32) ch->hw_value; - max_pwr = ch->max_power; - num_parsed_chan = 1; - continue; - } - - if ((ch->hw_value == next_chan + 1) && - (ch->max_power == max_pwr)) { - /* Consolidate adjacent channels */ - next_chan++; - num_parsed_chan++; - } else { - /* Add this triplet */ - lbs_deb_11d("11D triplet (%d, %d, %d)\n", - first_channel, num_parsed_chan, - max_pwr); - t = &domain->triplet[num_triplet]; - t->chans.first_channel = first_channel; - t->chans.num_channels = num_parsed_chan; - t->chans.max_power = max_pwr; - num_triplet++; - flag = 0; - } - } - - if (flag) { - /* Add last triplet */ - lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel, - num_parsed_chan, max_pwr); - t = &domain->triplet[num_triplet]; - t->chans.first_channel = first_channel; - t->chans.num_channels = num_parsed_chan; - t->chans.max_power = max_pwr; - num_triplet++; + break; } - } - - lbs_deb_11d("# triplets %d\n", num_triplet); - - /* Set command header sizes */ - triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet); - domain->header.len = cpu_to_le16(sizeof(domain->country_code) + - triplet_size); - - lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set", - (u8 *) &cmd.domain.country_code, - le16_to_cpu(domain->header.len)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) + - sizeof(cmd.action) + - sizeof(cmd.domain.header) + - sizeof(cmd.domain.country_code) + - triplet_size); + case CMD_BBP_REG_ACCESS: + { + struct cmd_ds_bbp_reg_access *bbpreg; - ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd); + cmdptr->size = + cpu_to_le16(sizeof + (struct cmd_ds_bbp_reg_access) + + sizeof(struct cmd_header)); + bbpreg = + (struct cmd_ds_bbp_reg_access *)&cmdptr->params. + bbpreg; - lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); - return ret; -} + bbpreg->action = cpu_to_le16(cmd_action); + bbpreg->offset = cpu_to_le16((u16) offval->offset); + bbpreg->value = (u8) offval->value; -/** - * @brief Read a MAC, Baseband, or RF register - * - * @param priv pointer to struct lbs_private - * @param cmd register command, one of CMD_MAC_REG_ACCESS, - * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS - * @param offset byte offset of the register to get - * @param value on success, the value of the register at 'offset' - * - * @return 0 on success, error code on failure -*/ -int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) -{ - struct cmd_ds_reg_access cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - BUG_ON(value == NULL); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_GET); + break; + } - if (reg != CMD_MAC_REG_ACCESS && - reg != CMD_BBP_REG_ACCESS && - reg != CMD_RF_REG_ACCESS) { - ret = -EINVAL; - goto out; - } + case CMD_RF_REG_ACCESS: + { + struct cmd_ds_rf_reg_access *rfreg; - ret = lbs_cmd_with_response(priv, reg, &cmd); - if (ret) { - if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) - *value = cmd.value.bbp_rf; - else if (reg == CMD_MAC_REG_ACCESS) - *value = le32_to_cpu(cmd.value.mac); - } + cmdptr->size = + cpu_to_le16(sizeof + (struct cmd_ds_rf_reg_access) + + sizeof(struct cmd_header)); + rfreg = + (struct cmd_ds_rf_reg_access *)&cmdptr->params. + rfreg; -out: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -/** - * @brief Write a MAC, Baseband, or RF register - * - * @param priv pointer to struct lbs_private - * @param cmd register command, one of CMD_MAC_REG_ACCESS, - * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS - * @param offset byte offset of the register to set - * @param value the value to write to the register at 'offset' - * - * @return 0 on success, error code on failure -*/ -int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) -{ - struct cmd_ds_reg_access cmd; - int ret = 0; + rfreg->action = cpu_to_le16(cmd_action); + rfreg->offset = cpu_to_le16((u16) offval->offset); + rfreg->value = (u8) offval->value; - lbs_deb_enter(LBS_DEB_CMD); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_SET); + break; + } - if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) - cmd.value.bbp_rf = (u8) (value & 0xFF); - else if (reg == CMD_MAC_REG_ACCESS) - cmd.value.mac = cpu_to_le32(value); - else { - ret = -EINVAL; - goto out; + default: + break; } - ret = lbs_cmd_with_response(priv, reg, &cmd); - -out: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; + lbs_deb_leave(LBS_DEB_CMD); + return 0; } static void lbs_queue_cmd(struct lbs_private *priv, @@ -931,15 +771,16 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf; + struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1]; - if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { + if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) addtail = 0; } } - if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM) + if (le16_to_cpu(cmdnode->cmdbuf->command) == + CMD_802_11_WAKEUP_CONFIRM) addtail = 0; spin_lock_irqsave(&priv->driver_lock, flags); @@ -974,6 +815,7 @@ static void lbs_submit_command(struct lbs_private *priv, spin_lock_irqsave(&priv->driver_lock, flags); priv->cur_cmd = cmdnode; + priv->cur_cmd_retcode = 0; spin_unlock_irqrestore(&priv->driver_lock, flags); cmdsize = le16_to_cpu(cmd->size); @@ -1046,6 +888,9 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv, void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, int result) { + if (cmd == priv->cur_cmd) + priv->cur_cmd_retcode = result; + cmd->result = result; cmd->cmdwaitqwoken = 1; wake_up_interruptible(&cmd->cmdwait_q); @@ -1112,6 +957,240 @@ void lbs_set_mac_control(struct lbs_private *priv) lbs_deb_leave(LBS_DEB_CMD); } +/** + * @brief This function implements command CMD_802_11D_DOMAIN_INFO + * @param priv pointer to struct lbs_private + * @param cmd pointer to cmd buffer + * @param cmdno cmd ID + * @param cmdOption cmd action + * @return 0 +*/ +int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, + struct cmd_ds_command *cmd, + u16 cmdoption) +{ + struct cmd_ds_802_11d_domain_info *pdomaininfo = + &cmd->params.domaininfo; + struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain; + u8 nr_triplet = priv->domain_reg.no_triplet; + + lbs_deb_enter(LBS_DEB_11D); + + lbs_deb_11d("nr_triplet=%x\n", nr_triplet); + + pdomaininfo->action = cpu_to_le16(cmdoption); + if (cmdoption == CMD_ACT_GET) { + cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + + sizeof(struct cmd_header)); + lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, + le16_to_cpu(cmd->size)); + goto done; + } + + domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); + memcpy(domain->countrycode, priv->domain_reg.country_code, + sizeof(domain->countrycode)); + + domain->header.len = cpu_to_le16(nr_triplet + * sizeof(struct ieee80211_country_ie_triplet) + + sizeof(domain->countrycode)); + + if (nr_triplet) { + memcpy(domain->triplet, priv->domain_reg.triplet, + nr_triplet * + sizeof(struct ieee80211_country_ie_triplet)); + + cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + + le16_to_cpu(domain->header.len) + + sizeof(struct mrvl_ie_header) + + sizeof(struct cmd_header)); + } else { + cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + + sizeof(struct cmd_header)); + } + + lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd, + le16_to_cpu(cmd->size)); + +done: + lbs_deb_enter(LBS_DEB_11D); + return 0; +} + +/** + * @brief This function prepare the command before send to firmware. + * + * @param priv A pointer to struct lbs_private structure + * @param cmd_no command number + * @param cmd_action command action: GET or SET + * @param wait_option wait option: wait response or not + * @param cmd_oid cmd oid: treated as sub command + * @param pdata_buf A pointer to informaion buffer + * @return 0 or -1 + */ +int lbs_prepare_and_send_command(struct lbs_private *priv, + u16 cmd_no, + u16 cmd_action, + u16 wait_option, u32 cmd_oid, void *pdata_buf) +{ + int ret = 0; + struct cmd_ctrl_node *cmdnode; + struct cmd_ds_command *cmdptr; + unsigned long flags; + + lbs_deb_enter(LBS_DEB_HOST); + + if (!priv) { + lbs_deb_host("PREP_CMD: priv is NULL\n"); + ret = -1; + goto done; + } + + if (priv->surpriseremoved) { + lbs_deb_host("PREP_CMD: card removed\n"); + ret = -1; + goto done; + } + + if (!lbs_is_cmd_allowed(priv)) { + ret = -EBUSY; + goto done; + } + + cmdnode = lbs_get_cmd_ctrl_node(priv); + + if (cmdnode == NULL) { + lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); + + /* Wake up main thread to execute next command */ + wake_up_interruptible(&priv->waitq); + ret = -1; + goto done; + } + + cmdnode->callback = NULL; + cmdnode->callback_arg = (unsigned long)pdata_buf; + + cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf; + + lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no); + + /* Set sequence number, command and INT option */ + priv->seqnum++; + cmdptr->seqnum = cpu_to_le16(priv->seqnum); + + cmdptr->command = cpu_to_le16(cmd_no); + cmdptr->result = 0; + + switch (cmd_no) { + case CMD_802_11_PS_MODE: + ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); + break; + + case CMD_MAC_REG_ACCESS: + case CMD_BBP_REG_ACCESS: + case CMD_RF_REG_ACCESS: + ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf); + break; + + case CMD_802_11_MONITOR_MODE: + ret = lbs_cmd_802_11_monitor_mode(cmdptr, + cmd_action, pdata_buf); + break; + + case CMD_802_11_RSSI: + ret = lbs_cmd_802_11_rssi(priv, cmdptr); + break; + + case CMD_802_11_SET_AFC: + case CMD_802_11_GET_AFC: + + cmdptr->command = cpu_to_le16(cmd_no); + cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) + + sizeof(struct cmd_header)); + + memmove(&cmdptr->params.afc, + pdata_buf, sizeof(struct cmd_ds_802_11_afc)); + + ret = 0; + goto done; + + case CMD_802_11D_DOMAIN_INFO: + cmdptr->command = cpu_to_le16(cmd_no); + ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_action); + break; + + case CMD_802_11_TPC_CFG: + cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG); + cmdptr->size = + cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) + + sizeof(struct cmd_header)); + + memmove(&cmdptr->params.tpccfg, + pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg)); + + ret = 0; + break; + +#ifdef CONFIG_LIBERTAS_MESH + + case CMD_BT_ACCESS: + ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf); + break; + + case CMD_FWT_ACCESS: + ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); + break; + +#endif + + case CMD_802_11_BEACON_CTRL: + ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action); + break; + case CMD_802_11_DEEP_SLEEP: + cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP); + cmdptr->size = cpu_to_le16(sizeof(struct cmd_header)); + break; + default: + lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no); + ret = -1; + break; + } + + /* return error, since the command preparation failed */ + if (ret != 0) { + lbs_deb_host("PREP_CMD: command preparation failed\n"); + lbs_cleanup_and_insert_cmd(priv, cmdnode); + ret = -1; + goto done; + } + + cmdnode->cmdwaitqwoken = 0; + + lbs_queue_cmd(priv, cmdnode); + wake_up_interruptible(&priv->waitq); + + if (wait_option & CMD_OPTION_WAITFORRSP) { + lbs_deb_host("PREP_CMD: wait for response\n"); + might_sleep(); + wait_event_interruptible(cmdnode->cmdwait_q, + cmdnode->cmdwaitqwoken); + } + + spin_lock_irqsave(&priv->driver_lock, flags); + if (priv->cur_cmd_retcode) { + lbs_deb_host("PREP_CMD: command failed with return code %d\n", + priv->cur_cmd_retcode); + priv->cur_cmd_retcode = 0; + ret = -1; + } + spin_unlock_irqrestore(&priv->driver_lock, flags); + +done: + lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); + return ret; +} + /** * @brief This function allocates the command buffer and link * it to command free queue. @@ -1205,7 +1284,7 @@ int lbs_free_cmd_buffer(struct lbs_private *priv) * @param priv A pointer to struct lbs_private structure * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL */ -static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) +static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv) { struct cmd_ctrl_node *tempnode; unsigned long flags; @@ -1288,10 +1367,10 @@ int lbs_execute_next_command(struct lbs_private *priv) /* * 1. Non-PS command: * Queue it. set needtowakeup to TRUE if current state - * is SLEEP, otherwise call send EXIT_PS. - * 2. PS command but not EXIT_PS: + * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS. + * 2. PS command but not Exit_PS: * Ignore it. - * 3. PS command EXIT_PS: + * 3. PS command Exit_PS: * Set needtowakeup to TRUE if current state is SLEEP, * otherwise send this command down to firmware * immediately. @@ -1305,11 +1384,8 @@ int lbs_execute_next_command(struct lbs_private *priv) /* w/ new scheme, it will not reach here. since it is blocked in main_thread. */ priv->needtowakeup = 1; - } else { - lbs_set_ps_mode(priv, - PS_MODE_ACTION_EXIT_PS, - false); - } + } else + lbs_ps_wakeup(priv, 0); ret = 0; goto done; @@ -1324,7 +1400,7 @@ int lbs_execute_next_command(struct lbs_private *priv) "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", psm->action); if (psm->action != - cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { + cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { lbs_deb_host( "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); list_del(&cmdnode->list); @@ -1384,16 +1460,13 @@ int lbs_execute_next_command(struct lbs_private *priv) lbs_deb_host( "EXEC_NEXT_CMD: WPA enabled and GTK_SET" " go back to PS_SLEEP"); - lbs_set_ps_mode(priv, - PS_MODE_ACTION_ENTER_PS, - false); + lbs_ps_sleep(priv, 0); } } else { lbs_deb_host( "EXEC_NEXT_CMD: cmdpendingq empty, " "go back to PS_SLEEP"); - lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, - false); + lbs_ps_sleep(priv, 0); } } #endif @@ -1441,6 +1514,43 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) lbs_deb_leave(LBS_DEB_HOST); } +void lbs_ps_sleep(struct lbs_private *priv, int wait_option) +{ + lbs_deb_enter(LBS_DEB_HOST); + + /* + * PS is currently supported only in Infrastructure mode + * Remove this check if it is to be supported in IBSS mode also + */ + + lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, + CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL); + + lbs_deb_leave(LBS_DEB_HOST); +} + +/** + * @brief This function sends Exit_PS command to firmware. + * + * @param priv A pointer to struct lbs_private structure + * @param wait_option wait response or not + * @return n/a + */ +void lbs_ps_wakeup(struct lbs_private *priv, int wait_option) +{ + __le32 Localpsmode; + + lbs_deb_enter(LBS_DEB_HOST); + + Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM); + + lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, + CMD_SUBCMD_EXIT_PS, + wait_option, 0, &Localpsmode); + + lbs_deb_leave(LBS_DEB_HOST); +} + /** * @brief This function checks condition and prepares to * send sleep confirm command to firmware if ok. @@ -1565,18 +1675,12 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, goto done; } - /* No commands are allowed in Deep Sleep until we toggle the GPIO - * to wake up the card and it has signaled that it's ready. - */ - if (!priv->is_auto_deep_sleep_enabled) { - if (priv->is_deep_sleep) { - lbs_deb_cmd("command not allowed in deep sleep\n"); - cmdnode = ERR_PTR(-EBUSY); - goto done; - } + if (!lbs_is_cmd_allowed(priv)) { + cmdnode = ERR_PTR(-EBUSY); + goto done; } - cmdnode = lbs_get_free_cmd_node(priv); + cmdnode = lbs_get_cmd_ctrl_node(priv); if (cmdnode == NULL) { lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); diff --git a/trunk/drivers/net/wireless/libertas/cmd.h b/trunk/drivers/net/wireless/libertas/cmd.h index 7109d6b717ea..386e565d99ad 100644 --- a/trunk/drivers/net/wireless/libertas/cmd.h +++ b/trunk/drivers/net/wireless/libertas/cmd.h @@ -3,8 +3,6 @@ #ifndef _LBS_CMD_H_ #define _LBS_CMD_H_ -#include - #include "host.h" #include "dev.h" @@ -39,6 +37,11 @@ struct cmd_ctrl_node { #define lbs_cmd_with_response(priv, cmdnr, cmd) \ lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd)) +int lbs_prepare_and_send_command(struct lbs_private *priv, + u16 cmd_no, + u16 cmd_action, + u16 wait_option, u32 cmd_oid, void *pdata_buf); + void lbs_cmd_async(struct lbs_private *priv, uint16_t command, struct cmd_header *in_cmd, int in_cmd_size); @@ -89,6 +92,10 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, struct sleep_params *sp); +void lbs_ps_sleep(struct lbs_private *priv, int wait_option); + +void lbs_ps_wakeup(struct lbs_private *priv, int wait_option); + void lbs_ps_confirm_sleep(struct lbs_private *priv); int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on); @@ -122,18 +129,4 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep); int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep); -int lbs_set_monitor_mode(struct lbs_private *priv, int enable); - -int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf); - -int lbs_set_11d_domain_info(struct lbs_private *priv, - struct regulatory_request *request, - struct ieee80211_supported_band **bands); - -int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value); - -int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value); - -int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block); - #endif /* _LBS_CMD_H */ diff --git a/trunk/drivers/net/wireless/libertas/cmdresp.c b/trunk/drivers/net/wireless/libertas/cmdresp.c index 5e95da9dcc2e..a0d9482ef5e2 100644 --- a/trunk/drivers/net/wireless/libertas/cmdresp.c +++ b/trunk/drivers/net/wireless/libertas/cmdresp.c @@ -49,11 +49,171 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) if (priv->psstate != PS_STATE_FULL_POWER) { /* make firmware to exit PS mode */ lbs_deb_cmd("disconnected, so exit PS mode\n"); - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false); + lbs_ps_wakeup(priv, 0); } lbs_deb_leave(LBS_DEB_ASSOC); } +static int lbs_ret_reg_access(struct lbs_private *priv, + u16 type, struct cmd_ds_command *resp) +{ + int ret = 0; + + lbs_deb_enter(LBS_DEB_CMD); + + switch (type) { + case CMD_RET(CMD_MAC_REG_ACCESS): + { + struct cmd_ds_mac_reg_access *reg = &resp->params.macreg; + + priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); + priv->offsetvalue.value = le32_to_cpu(reg->value); + break; + } + + case CMD_RET(CMD_BBP_REG_ACCESS): + { + struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg; + + priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); + priv->offsetvalue.value = reg->value; + break; + } + + case CMD_RET(CMD_RF_REG_ACCESS): + { + struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg; + + priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); + priv->offsetvalue.value = reg->value; + break; + } + + default: + ret = -1; + } + + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; +} + +/** + * @brief This function parses countryinfo from AP and download country info to FW + * @param priv pointer to struct lbs_private + * @param resp pointer to command response buffer + * @return 0; -1 + */ +static int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) +{ + struct cmd_ds_802_11d_domain_info *domaininfo = + &resp->params.domaininforesp; + struct mrvl_ie_domain_param_set *domain = &domaininfo->domain; + u16 action = le16_to_cpu(domaininfo->action); + s16 ret = 0; + u8 nr_triplet = 0; + + lbs_deb_enter(LBS_DEB_11D); + + lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp, + (int)le16_to_cpu(resp->size)); + + nr_triplet = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / + sizeof(struct ieee80211_country_ie_triplet); + + lbs_deb_11d("domain info resp: nr_triplet %d\n", nr_triplet); + + if (nr_triplet > MRVDRV_MAX_TRIPLET_802_11D) { + lbs_deb_11d("invalid number of triplets returned!!\n"); + return -1; + } + + switch (action) { + case CMD_ACT_SET: /*Proc set action */ + break; + + case CMD_ACT_GET: + break; + default: + lbs_deb_11d("invalid action:%d\n", domaininfo->action); + ret = -1; + break; + } + + lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); + return ret; +} + +static inline int handle_cmd_response(struct lbs_private *priv, + struct cmd_header *cmd_response) +{ + struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response; + int ret = 0; + unsigned long flags; + uint16_t respcmd = le16_to_cpu(resp->command); + + lbs_deb_enter(LBS_DEB_HOST); + + switch (respcmd) { + case CMD_RET(CMD_MAC_REG_ACCESS): + case CMD_RET(CMD_BBP_REG_ACCESS): + case CMD_RET(CMD_RF_REG_ACCESS): + ret = lbs_ret_reg_access(priv, respcmd, resp); + break; + + case CMD_RET(CMD_802_11_SET_AFC): + case CMD_RET(CMD_802_11_GET_AFC): + spin_lock_irqsave(&priv->driver_lock, flags); + memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc, + sizeof(struct cmd_ds_802_11_afc)); + spin_unlock_irqrestore(&priv->driver_lock, flags); + + break; + + case CMD_RET(CMD_802_11_BEACON_STOP): + break; + + case CMD_RET(CMD_802_11_RSSI): + ret = lbs_ret_802_11_rssi(priv, resp); + break; + + case CMD_RET(CMD_802_11D_DOMAIN_INFO): + ret = lbs_ret_802_11d_domain_info(resp); + break; + + case CMD_RET(CMD_802_11_TPC_CFG): + spin_lock_irqsave(&priv->driver_lock, flags); + memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg, + sizeof(struct cmd_ds_802_11_tpc_cfg)); + spin_unlock_irqrestore(&priv->driver_lock, flags); + break; + + case CMD_RET(CMD_BT_ACCESS): + spin_lock_irqsave(&priv->driver_lock, flags); + if (priv->cur_cmd->callback_arg) + memcpy((void *)priv->cur_cmd->callback_arg, + &resp->params.bt.addr1, 2 * ETH_ALEN); + spin_unlock_irqrestore(&priv->driver_lock, flags); + break; + case CMD_RET(CMD_FWT_ACCESS): + spin_lock_irqsave(&priv->driver_lock, flags); + if (priv->cur_cmd->callback_arg) + memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt, + sizeof(resp->params.fwt)); + spin_unlock_irqrestore(&priv->driver_lock, flags); + break; + case CMD_RET(CMD_802_11_BEACON_CTRL): + ret = lbs_ret_802_11_bcn_ctrl(priv, resp); + break; + + default: + lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n", + le16_to_cpu(resp->command)); + break; + } + lbs_deb_leave(LBS_DEB_HOST); + return ret; +} + int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) { uint16_t respcmd, curcmd; @@ -112,6 +272,9 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) del_timer(&priv->command_timer); priv->cmd_timed_out = 0; + /* Store the response code to cur_cmd_retcode. */ + priv->cur_cmd_retcode = result; + if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1]; u16 action = le16_to_cpu(psmode->action); @@ -129,9 +292,9 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) * lbs_execute_next_command(). */ if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR && - action == PS_MODE_ACTION_ENTER_PS) + action == CMD_SUBCMD_ENTER_PS) priv->psmode = LBS802_11POWERMODECAM; - } else if (action == PS_MODE_ACTION_ENTER_PS) { + } else if (action == CMD_SUBCMD_ENTER_PS) { priv->needtowakeup = 0; priv->psstate = PS_STATE_AWAKE; @@ -146,12 +309,11 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) spin_unlock_irqrestore(&priv->driver_lock, flags); mutex_unlock(&priv->lock); - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, - false); + lbs_ps_wakeup(priv, 0); mutex_lock(&priv->lock); spin_lock_irqsave(&priv->driver_lock, flags); } - } else if (action == PS_MODE_ACTION_EXIT_PS) { + } else if (action == CMD_SUBCMD_EXIT_PS) { priv->needtowakeup = 0; priv->psstate = PS_STATE_FULL_POWER; lbs_deb_host("CMD_RESP: EXIT_PS command response\n"); @@ -192,7 +354,8 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) if (priv->cur_cmd && priv->cur_cmd->callback) { ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg, resp); - } + } else + ret = handle_cmd_response(priv, resp); spin_lock_irqsave(&priv->driver_lock, flags); @@ -289,7 +452,7 @@ int lbs_process_event(struct lbs_private *priv, u32 event) * in lbs_ps_wakeup() */ lbs_deb_cmd("waking up ...\n"); - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false); + lbs_ps_wakeup(priv, 0); } break; diff --git a/trunk/drivers/net/wireless/libertas/debugfs.c b/trunk/drivers/net/wireless/libertas/debugfs.c index 651a79c8de8a..acaf81164624 100644 --- a/trunk/drivers/net/wireless/libertas/debugfs.c +++ b/trunk/drivers/net/wireless/libertas/debugfs.c @@ -446,24 +446,30 @@ static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf, } + static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; + struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; - u32 val = 0; - if (!buf) return -ENOMEM; - ret = lbs_get_reg(priv, CMD_MAC_REG_ACCESS, priv->mac_offset, &val); + offval.offset = priv->mac_offset; + offval.value = 0; + + ret = lbs_prepare_and_send_command(priv, + CMD_MAC_REG_ACCESS, 0, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); if (!ret) { - pos = snprintf(buf, len, "MAC[0x%x] = 0x%08x\n", - priv->mac_offset, val); + pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n", + priv->mac_offset, priv->offsetvalue.value); + ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); } free_page(addr); @@ -501,6 +507,7 @@ static ssize_t lbs_wrmac_write(struct file *file, struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; + struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; if (!buf) @@ -517,7 +524,11 @@ static ssize_t lbs_wrmac_write(struct file *file, goto out_unlock; } - res = lbs_set_reg(priv, CMD_MAC_REG_ACCESS, offset, value); + offval.offset = offset; + offval.value = value; + res = lbs_prepare_and_send_command(priv, + CMD_MAC_REG_ACCESS, 1, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); if (!res) @@ -531,20 +542,25 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; + struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; - u32 val; - if (!buf) return -ENOMEM; - ret = lbs_get_reg(priv, CMD_BBP_REG_ACCESS, priv->bbp_offset, &val); + offval.offset = priv->bbp_offset; + offval.value = 0; + + ret = lbs_prepare_and_send_command(priv, + CMD_BBP_REG_ACCESS, 0, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); if (!ret) { - pos = snprintf(buf, len, "BBP[0x%x] = 0x%08x\n", - priv->bbp_offset, val); + pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n", + priv->bbp_offset, priv->offsetvalue.value); + ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); } free_page(addr); @@ -583,6 +599,7 @@ static ssize_t lbs_wrbbp_write(struct file *file, struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; + struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; if (!buf) @@ -599,7 +616,11 @@ static ssize_t lbs_wrbbp_write(struct file *file, goto out_unlock; } - res = lbs_set_reg(priv, CMD_BBP_REG_ACCESS, offset, value); + offval.offset = offset; + offval.value = value; + res = lbs_prepare_and_send_command(priv, + CMD_BBP_REG_ACCESS, 1, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); if (!res) @@ -613,20 +634,25 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; + struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; - u32 val; - if (!buf) return -ENOMEM; - ret = lbs_get_reg(priv, CMD_RF_REG_ACCESS, priv->rf_offset, &val); + offval.offset = priv->rf_offset; + offval.value = 0; + + ret = lbs_prepare_and_send_command(priv, + CMD_RF_REG_ACCESS, 0, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); if (!ret) { - pos = snprintf(buf, len, "RF[0x%x] = 0x%08x\n", - priv->rf_offset, val); + pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n", + priv->rf_offset, priv->offsetvalue.value); + ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); } free_page(addr); @@ -665,6 +691,7 @@ static ssize_t lbs_wrrf_write(struct file *file, struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; + struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; if (!buf) @@ -681,7 +708,11 @@ static ssize_t lbs_wrrf_write(struct file *file, goto out_unlock; } - res = lbs_set_reg(priv, CMD_RF_REG_ACCESS, offset, value); + offval.offset = offset; + offval.value = value; + res = lbs_prepare_and_send_command(priv, + CMD_RF_REG_ACCESS, 1, + CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); if (!res) @@ -874,7 +905,7 @@ static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, p = buf; - d = file->private_data; + d = (struct debug_data *)file->private_data; for (i = 0; i < num_of_items; i++) { if (d[i].size == 1) @@ -913,7 +944,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, char *p0; char *p1; char *p2; - struct debug_data *d = f->private_data; + struct debug_data *d = (struct debug_data *)f->private_data; pdata = kmalloc(cnt, GFP_KERNEL); if (pdata == NULL) diff --git a/trunk/drivers/net/wireless/libertas/decl.h b/trunk/drivers/net/wireless/libertas/decl.h index 1d141fefd767..ba5438a7ba17 100644 --- a/trunk/drivers/net/wireless/libertas/decl.h +++ b/trunk/drivers/net/wireless/libertas/decl.h @@ -53,4 +53,9 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv); u32 lbs_fw_index_to_data_rate(u8 index); u8 lbs_data_rate_to_fw_index(u32 rate); +int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, + struct cmd_ds_command *cmd, u16 cmdoption); + +int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp); + #endif diff --git a/trunk/drivers/net/wireless/libertas/defs.h b/trunk/drivers/net/wireless/libertas/defs.h index d00c728cec47..ea3f10ef4e00 100644 --- a/trunk/drivers/net/wireless/libertas/defs.h +++ b/trunk/drivers/net/wireless/libertas/defs.h @@ -172,6 +172,11 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define MRVDRV_MAX_BSS_DESCRIPTS 16 #define MRVDRV_MAX_REGION_CODE 6 +#define MRVDRV_IGNORE_MULTIPLE_DTIM 0xfffe +#define MRVDRV_MIN_MULTIPLE_DTIM 1 +#define MRVDRV_MAX_MULTIPLE_DTIM 5 +#define MRVDRV_DEFAULT_MULTIPLE_DTIM 1 + #define MRVDRV_DEFAULT_LISTEN_INTERVAL 10 #define MRVDRV_CHANNELS_PER_SCAN 4 @@ -296,6 +301,19 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define BAND_G (0x02) #define ALL_802_11_BANDS (BAND_B | BAND_G) +/** MACRO DEFINITIONS */ +#define CAL_NF(NF) ((s32)(-(s32)(NF))) +#define CAL_RSSI(SNR, NF) ((s32)((s32)(SNR) + CAL_NF(NF))) +#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) + +#define DEFAULT_BCN_AVG_FACTOR 8 +#define DEFAULT_DATA_AVG_FACTOR 8 +#define AVG_SCALE 100 +#define CAL_AVG_SNR_NF(AVG, SNRNF, N) \ + (((AVG) == 0) ? ((u16)(SNRNF) * AVG_SCALE) : \ + ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \ + AVG_SCALE)) / N)) + #define MAX_RATES 14 #define MAX_LEDS 8 diff --git a/trunk/drivers/net/wireless/libertas/dev.h b/trunk/drivers/net/wireless/libertas/dev.h index 3c7e255e18c7..4536d9c0ad87 100644 --- a/trunk/drivers/net/wireless/libertas/dev.h +++ b/trunk/drivers/net/wireless/libertas/dev.h @@ -60,10 +60,14 @@ struct lbs_private { struct dentry *regs_dir; struct dentry *debugfs_regs_files[6]; + /** 11D and domain regulatory data */ + struct lbs_802_11d_domain_reg domain_reg; + /* Hardware debugging */ u32 mac_offset; u32 bbp_offset; u32 rf_offset; + struct lbs_offset_value offsetvalue; /* Power management */ u16 psmode; @@ -111,10 +115,12 @@ struct lbs_private { struct cmd_ctrl_node *cur_cmd; struct list_head cmdfreeq; /* free command buffers */ struct list_head cmdpendingq; /* pending command buffers */ + wait_queue_head_t cmd_pending; struct timer_list command_timer; int cmd_timed_out; /* Command responses sent from the hardware to the driver */ + int cur_cmd_retcode; u8 resp_idx; u8 resp_buf[2][LBS_UPLD_SIZE]; u32 resp_len[2]; diff --git a/trunk/drivers/net/wireless/libertas/host.h b/trunk/drivers/net/wireless/libertas/host.h index 5eac1351a021..db8e209878c1 100644 --- a/trunk/drivers/net/wireless/libertas/host.h +++ b/trunk/drivers/net/wireless/libertas/host.h @@ -94,9 +94,11 @@ #define CMD_802_11_BEACON_CTRL 0x00b0 /* For the IEEE Power Save */ -#define PS_MODE_ACTION_ENTER_PS 0x0030 -#define PS_MODE_ACTION_EXIT_PS 0x0031 -#define PS_MODE_ACTION_SLEEP_CONFIRMED 0x0034 +#define CMD_SUBCMD_ENTER_PS 0x0030 +#define CMD_SUBCMD_EXIT_PS 0x0031 +#define CMD_SUBCMD_SLEEP_CONFIRMED 0x0034 +#define CMD_SUBCMD_FULL_POWERDOWN 0x0035 +#define CMD_SUBCMD_FULL_POWERUP 0x0036 #define CMD_ENABLE_RSN 0x0001 #define CMD_DISABLE_RSN 0x0000 @@ -161,6 +163,11 @@ #define CMD_ACT_SET_TX_FIX_RATE 0x0001 #define CMD_ACT_GET_TX_RATE 0x0002 +/* Define action or option for CMD_802_11_PS_MODE */ +#define CMD_TYPE_CAM 0x0000 +#define CMD_TYPE_MAX_PSP 0x0001 +#define CMD_TYPE_FAST_PSP 0x0002 + /* Options for CMD_802_11_FW_WAKE_METHOD */ #define CMD_WAKE_METHOD_UNCHANGED 0x0000 #define CMD_WAKE_METHOD_COMMAND_INT 0x0001 @@ -382,21 +389,29 @@ struct lbs_offset_value { u32 value; } __packed; -#define MAX_11D_TRIPLETS 83 +#define MRVDRV_MAX_TRIPLET_802_11D 83 + +#define COUNTRY_CODE_LEN 3 struct mrvl_ie_domain_param_set { struct mrvl_ie_header header; - u8 country_code[3]; - struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS]; -} __packed; + u8 countrycode[COUNTRY_CODE_LEN]; + struct ieee80211_country_ie_triplet triplet[1]; +} __attribute__ ((packed)); struct cmd_ds_802_11d_domain_info { - struct cmd_header hdr; - __le16 action; struct mrvl_ie_domain_param_set domain; -} __packed; +} __attribute__ ((packed)); + +struct lbs_802_11d_domain_reg { + /** Country code*/ + u8 country_code[COUNTRY_CODE_LEN]; + /** No. of triplet*/ + u8 no_triplet; + struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D]; +} __attribute__ ((packed)); /* * Define data structure for CMD_GET_HW_SPEC @@ -560,15 +575,24 @@ struct cmd_ds_802_11_snmp_mib { u8 value[128]; } __packed; -struct cmd_ds_reg_access { - struct cmd_header hdr; +struct cmd_ds_mac_reg_access { + __le16 action; + __le16 offset; + __le32 value; +} __packed; +struct cmd_ds_bbp_reg_access { __le16 action; __le16 offset; - union { - u8 bbp_rf; /* for BBP and RF registers */ - __le32 mac; /* for MAC registers */ - } value; + u8 value; + u8 reserved[3]; +} __packed; + +struct cmd_ds_rf_reg_access { + __le16 action; + __le16 offset; + u8 value; + u8 reserved[3]; } __packed; struct cmd_ds_802_11_radio_control { @@ -579,8 +603,6 @@ struct cmd_ds_802_11_radio_control { } __packed; struct cmd_ds_802_11_beacon_control { - struct cmd_header hdr; - __le16 action; __le16 beacon_enable; __le16 beacon_period; @@ -622,19 +644,19 @@ struct cmd_ds_802_11_rf_channel { } __packed; struct cmd_ds_802_11_rssi { - struct cmd_header hdr; + /* weighting factor */ + __le16 N; - /* request: number of beacons (N) to average the SNR and NF over - * response: SNR of most recent beacon - */ - __le16 n_or_snr; + __le16 reserved_0; + __le16 reserved_1; + __le16 reserved_2; +} __packed; - /* The following fields are only set in the response. - * In the request these are reserved and should be set to 0. - */ - __le16 nf; /* most recent beacon noise floor */ - __le16 avg_snr; /* average SNR weighted by N from request */ - __le16 avg_nf; /* average noise floor weighted by N from request */ +struct cmd_ds_802_11_rssi_rsp { + __le16 SNR; + __le16 noisefloor; + __le16 avgSNR; + __le16 avgnoisefloor; } __packed; struct cmd_ds_802_11_mac_address { @@ -653,10 +675,7 @@ struct cmd_ds_802_11_rf_tx_power { s8 minlevel; } __packed; -/* MONITOR_MODE only exists in OLPC v5 firmware */ struct cmd_ds_802_11_monitor_mode { - struct cmd_header hdr; - __le16 action; __le16 mode; } __packed; @@ -676,35 +695,11 @@ struct cmd_ds_802_11_fw_wake_method { } __packed; struct cmd_ds_802_11_ps_mode { - struct cmd_header hdr; - __le16 action; - - /* Interval for keepalive in PS mode: - * 0x0000 = don't change - * 0x001E = firmware default - * 0xFFFF = disable - */ __le16 nullpktinterval; - - /* Number of DTIM intervals to wake up for: - * 0 = don't change - * 1 = firmware default - * 5 = max - */ __le16 multipledtim; - __le16 reserved; __le16 locallisteninterval; - - /* AdHoc awake period (FW v9+ only): - * 0 = don't change - * 1 = always awake (IEEE standard behavior) - * 2 - 31 = sleep for (n - 1) periods and awake for 1 period - * 32 - 254 = invalid - * 255 = sleep at each ATIM - */ - __le16 adhoc_awake_period; } __packed; struct cmd_confirm_sleep { @@ -887,17 +882,12 @@ struct cmd_ds_802_11_pa_cfg { struct cmd_ds_802_11_led_ctrl { - struct cmd_header hdr; - __le16 action; __le16 numled; u8 data[256]; } __packed; -/* Automatic Frequency Control */ struct cmd_ds_802_11_afc { - struct cmd_header hdr; - __le16 afc_auto; union { struct { @@ -920,8 +910,6 @@ struct cmd_ds_get_tsf { } __packed; struct cmd_ds_bt_access { - struct cmd_header hdr; - __le16 action; __le32 id; u8 addr1[ETH_ALEN]; @@ -929,8 +917,6 @@ struct cmd_ds_bt_access { } __packed; struct cmd_ds_fwt_access { - struct cmd_header hdr; - __le16 action; __le32 id; u8 valid; @@ -969,4 +955,34 @@ struct cmd_ds_mesh_access { /* Number of stats counters returned by the firmware */ #define MESH_STATS_NUM 8 + +struct cmd_ds_command { + /* command header */ + __le16 command; + __le16 size; + __le16 seqnum; + __le16 result; + + /* command Body */ + union { + struct cmd_ds_802_11_ps_mode psmode; + struct cmd_ds_802_11_monitor_mode monitor; + struct cmd_ds_802_11_rssi rssi; + struct cmd_ds_802_11_rssi_rsp rssirsp; + struct cmd_ds_mac_reg_access macreg; + struct cmd_ds_bbp_reg_access bbpreg; + struct cmd_ds_rf_reg_access rfreg; + + struct cmd_ds_802_11d_domain_info domaininfo; + struct cmd_ds_802_11d_domain_info domaininforesp; + + struct cmd_ds_802_11_tpc_cfg tpccfg; + struct cmd_ds_802_11_afc afc; + struct cmd_ds_802_11_led_ctrl ledgpio; + + struct cmd_ds_bt_access bt; + struct cmd_ds_fwt_access fwt; + struct cmd_ds_802_11_beacon_control bcn_ctrl; + } params; +} __packed; #endif diff --git a/trunk/drivers/net/wireless/libertas/if_usb.c b/trunk/drivers/net/wireless/libertas/if_usb.c index 07ece9d26c63..3678e532874f 100644 --- a/trunk/drivers/net/wireless/libertas/if_usb.c +++ b/trunk/drivers/net/wireless/libertas/if_usb.c @@ -433,7 +433,7 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) static int if_usb_reset_device(struct if_usb_card *cardp) { - struct cmd_header *cmd = cardp->ep_out_buf + 4; + struct cmd_ds_command *cmd = cardp->ep_out_buf + 4; int ret; lbs_deb_enter(LBS_DEB_USB); @@ -441,7 +441,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp) *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); cmd->command = cpu_to_le16(CMD_802_11_RESET); - cmd->size = cpu_to_le16(sizeof(cmd)); + cmd->size = cpu_to_le16(sizeof(struct cmd_header)); cmd->result = cpu_to_le16(0); cmd->seqnum = cpu_to_le16(0x5a5a); usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header)); diff --git a/trunk/drivers/net/wireless/libertas/main.c b/trunk/drivers/net/wireless/libertas/main.c index 258967144b96..2a0b590a93f1 100644 --- a/trunk/drivers/net/wireless/libertas/main.c +++ b/trunk/drivers/net/wireless/libertas/main.c @@ -157,7 +157,12 @@ static void lbs_tx_timeout(struct net_device *dev) to kick it somehow? */ lbs_host_to_card_done(priv); - /* FIXME: reset the card */ + /* More often than not, this actually happens because the + firmware has crapped itself -- rather than just a very + busy medium. So send a harmless command, and if/when + _that_ times out, we'll kick it in the head. */ + lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, + 0, 0, NULL); lbs_deb_leave(LBS_DEB_TX); } @@ -502,6 +507,12 @@ static int lbs_thread(void *data) if (!priv->dnld_sent && !priv->cur_cmd) lbs_execute_next_command(priv); + /* Wake-up command waiters which can't sleep in + * lbs_prepare_and_send_command + */ + if (!list_empty(&priv->cmdpendingq)) + wake_up_all(&priv->cmd_pending); + spin_lock_irq(&priv->driver_lock); if (!priv->dnld_sent && priv->tx_pending_len > 0) { int ret = priv->hw_host_to_card(priv, MVMS_DAT, @@ -527,6 +538,7 @@ static int lbs_thread(void *data) del_timer(&priv->command_timer); del_timer(&priv->auto_deepsleep_timer); + wake_up_all(&priv->cmd_pending); lbs_deb_leave(LBS_DEB_THREAD); return 0; @@ -651,6 +663,7 @@ static void lbs_cmd_timeout_handler(unsigned long data) static void auto_deepsleep_timer_fn(unsigned long data) { struct lbs_private *priv = (struct lbs_private *)data; + int ret; lbs_deb_enter(LBS_DEB_CMD); @@ -658,15 +671,14 @@ static void auto_deepsleep_timer_fn(unsigned long data) priv->is_activity_detected = 0; } else { if (priv->is_auto_deep_sleep_enabled && - (!priv->wakeup_dev_required) && - (priv->connect_status != LBS_CONNECTED)) { - struct cmd_header cmd; - + (!priv->wakeup_dev_required) && + (priv->connect_status != LBS_CONNECTED)) { lbs_deb_main("Entering auto deep sleep mode...\n"); - memset(&cmd, 0, sizeof(cmd)); - cmd.size = cpu_to_le16(sizeof(cmd)); - lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd, - sizeof(cmd)); + ret = lbs_prepare_and_send_command(priv, + CMD_802_11_DEEP_SLEEP, 0, + 0, 0, NULL); + if (ret) + lbs_pr_err("Enter Deep Sleep command failed\n"); } } mod_timer(&priv->auto_deepsleep_timer , jiffies + @@ -734,6 +746,7 @@ static int lbs_init_adapter(struct lbs_private *priv) INIT_LIST_HEAD(&priv->cmdpendingq); spin_lock_init(&priv->driver_lock); + init_waitqueue_head(&priv->cmd_pending); /* Allocate the command buffers */ if (lbs_allocate_cmd_buffer(priv)) { @@ -889,7 +902,7 @@ void lbs_remove_card(struct lbs_private *priv) if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; - lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); + lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); } if (priv->is_deep_sleep) { @@ -1052,7 +1065,7 @@ static int __init lbs_init_module(void) memset(&confirm_sleep, 0, sizeof(confirm_sleep)); confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE); confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep)); - confirm_sleep.action = cpu_to_le16(PS_MODE_ACTION_SLEEP_CONFIRMED); + confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED); lbs_debugfs_init(); lbs_deb_leave(LBS_DEB_MAIN); return 0; diff --git a/trunk/drivers/net/wireless/libertas/mesh.c b/trunk/drivers/net/wireless/libertas/mesh.c index 194762ab0142..bc5bc1384c35 100644 --- a/trunk/drivers/net/wireless/libertas/mesh.c +++ b/trunk/drivers/net/wireless/libertas/mesh.c @@ -455,189 +455,65 @@ void lbs_mesh_set_txpd(struct lbs_private *priv, * Mesh command handling */ -/** - * @brief Add or delete Mesh Blinding Table entries - * - * @param priv A pointer to struct lbs_private structure - * @param add TRUE to add the entry, FALSE to delete it - * @param addr1 Destination address to blind or unblind - * - * @return 0 on success, error on failure - */ -int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) +int lbs_cmd_bt_access(struct cmd_ds_command *cmd, + u16 cmd_action, void *pdata_buf) { - struct cmd_ds_bt_access cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); + struct cmd_ds_bt_access *bt_access = &cmd->params.bt; + lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); - BUG_ON(addr1 == NULL); + cmd->command = cpu_to_le16(CMD_BT_ACCESS); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + + sizeof(struct cmd_header)); + cmd->result = 0; + bt_access->action = cpu_to_le16(cmd_action); - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - memcpy(cmd.addr1, addr1, ETH_ALEN); - if (add) { - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD); + switch (cmd_action) { + case CMD_ACT_BT_ACCESS_ADD: + memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN); lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", - addr1, ETH_ALEN); - } else { - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL); + bt_access->addr1, 6); + break; + case CMD_ACT_BT_ACCESS_DEL: + memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN); lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", - addr1, ETH_ALEN); + bt_access->addr1, 6); + break; + case CMD_ACT_BT_ACCESS_LIST: + bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); + break; + case CMD_ACT_BT_ACCESS_RESET: + break; + case CMD_ACT_BT_ACCESS_SET_INVERT: + bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); + break; + case CMD_ACT_BT_ACCESS_GET_INVERT: + break; + default: + break; } - - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -/** - * @brief Reset/clear the mesh blinding table - * - * @param priv A pointer to struct lbs_private structure - * - * @return 0 on success, error on failure - */ -int lbs_mesh_bt_reset(struct lbs_private *priv) -{ - struct cmd_ds_bt_access cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET); - - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -/** - * @brief Gets the inverted status of the mesh blinding table - * - * Normally the firmware "blinds" or ignores traffic from mesh nodes in the - * table, but an inverted table allows *only* traffic from nodes listed in - * the table. - * - * @param priv A pointer to struct lbs_private structure - * @param invert On success, TRUE if the blinding table is inverted, - * FALSE if it is not inverted - * - * @return 0 on success, error on failure - */ -int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) -{ - struct cmd_ds_bt_access cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - BUG_ON(inverted == NULL); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT); - - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); - if (ret == 0) - *inverted = !!cmd.id; - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -/** - * @brief Sets the inverted status of the mesh blinding table - * - * Normally the firmware "blinds" or ignores traffic from mesh nodes in the - * table, but an inverted table allows *only* traffic from nodes listed in - * the table. - * - * @param priv A pointer to struct lbs_private structure - * @param invert TRUE to invert the blinding table (only traffic from - * listed nodes allowed), FALSE to return it - * to normal state (listed nodes ignored) - * - * @return 0 on success, error on failure - */ -int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) -{ - struct cmd_ds_bt_access cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); - cmd.id = !!inverted; - - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -/** - * @brief List an entry in the mesh blinding table - * - * @param priv A pointer to struct lbs_private structure - * @param id The ID of the entry to list - * @param addr1 MAC address associated with the table entry - * - * @return 0 on success, error on failure - */ -int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) -{ - struct cmd_ds_bt_access cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - BUG_ON(addr1 == NULL); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); - cmd.id = cpu_to_le32(id); - - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); - if (ret == 0) - memcpy(addr1, cmd.addr1, sizeof(cmd.addr1)); - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; + lbs_deb_leave(LBS_DEB_CMD); + return 0; } -/** - * @brief Access the mesh forwarding table - * - * @param priv A pointer to struct lbs_private structure - * @param cmd_action The forwarding table action to perform - * @param cmd The pre-filled FWT_ACCESS command - * - * @return 0 on success and 'cmd' will be filled with the - * firmware's response - */ -int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, - struct cmd_ds_fwt_access *cmd) +int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, + u16 cmd_action, void *pdata_buf) { - int ret; - + struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); - cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS); - cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)); - cmd->hdr.result = 0; - cmd->action = cpu_to_le16(cmd_action); + cmd->command = cpu_to_le16(CMD_FWT_ACCESS); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + + sizeof(struct cmd_header)); + cmd->result = 0; - ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd); + if (pdata_buf) + memcpy(fwt_access, pdata_buf, sizeof(*fwt_access)); + else + memset(fwt_access, 0, sizeof(*fwt_access)); + + fwt_access->action = cpu_to_le16(cmd_action); - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + lbs_deb_leave(LBS_DEB_CMD); return 0; } diff --git a/trunk/drivers/net/wireless/libertas/mesh.h b/trunk/drivers/net/wireless/libertas/mesh.h index afb2e8dead3f..84ea2481ff20 100644 --- a/trunk/drivers/net/wireless/libertas/mesh.h +++ b/trunk/drivers/net/wireless/libertas/mesh.h @@ -8,7 +8,6 @@ #include #include -#include "host.h" #ifdef CONFIG_LIBERTAS_MESH @@ -52,15 +51,10 @@ struct cmd_ds_command; struct cmd_ds_mesh_access; struct cmd_ds_mesh_config; -int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1); -int lbs_mesh_bt_reset(struct lbs_private *priv); -int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted); -int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted); -int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1); - -int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, - struct cmd_ds_fwt_access *cmd); - +int lbs_cmd_bt_access(struct cmd_ds_command *cmd, + u16 cmd_action, void *pdata_buf); +int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, + u16 cmd_action, void *pdata_buf); int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, struct cmd_ds_mesh_access *cmd); int lbs_mesh_config_send(struct lbs_private *priv, diff --git a/trunk/drivers/net/wireless/libertas/tx.c b/trunk/drivers/net/wireless/libertas/tx.c index 8000ca6165d0..411a3bbf035e 100644 --- a/trunk/drivers/net/wireless/libertas/tx.c +++ b/trunk/drivers/net/wireless/libertas/tx.c @@ -180,7 +180,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) { struct tx_radiotap_hdr *radiotap_hdr; - if (priv->wdev->iftype != NL80211_IFTYPE_MONITOR || + if (!priv->wdev->iftype == NL80211_IFTYPE_MONITOR || priv->currenttxskb == NULL) return; diff --git a/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h b/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h index ad77b92d0b41..737eac92ef72 100644 --- a/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h +++ b/trunk/drivers/net/wireless/libertas_tf/libertas_tf.h @@ -253,9 +253,6 @@ struct lbtf_private { u8 fw_ready; u8 surpriseremoved; struct sk_buff_head bc_ps_buf; - - /* Most recently reported noise in dBm */ - s8 noise; }; /* 802.11-related definitions */ diff --git a/trunk/drivers/net/wireless/libertas_tf/main.c b/trunk/drivers/net/wireless/libertas_tf/main.c index 9278b3c8ee30..817fffc0de4b 100644 --- a/trunk/drivers/net/wireless/libertas_tf/main.c +++ b/trunk/drivers/net/wireless/libertas_tf/main.c @@ -525,22 +525,6 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, lbtf_deb_leave(LBTF_DEB_MACOPS); } -static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct lbtf_private *priv = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = priv->noise; - - return 0; -} - static const struct ieee80211_ops lbtf_ops = { .tx = lbtf_op_tx, .start = lbtf_op_start, @@ -551,7 +535,6 @@ static const struct ieee80211_ops lbtf_ops = { .prepare_multicast = lbtf_op_prepare_multicast, .configure_filter = lbtf_op_configure_filter, .bss_info_changed = lbtf_op_bss_info_changed, - .get_survey = lbtf_op_get_survey, }; int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) @@ -572,7 +555,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) stats.freq = priv->cur_freq; stats.band = IEEE80211_BAND_2GHZ; stats.signal = prxpd->snr; - priv->noise = prxpd->nf; /* Marvell rate index has a hole at value 4 */ if (prxpd->rx_rate > 4) --prxpd->rx_rate; diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index 01ad7f77383a..e7f299dc9ef5 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -486,7 +486,8 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, struct ieee80211_rx_status rx_status; if (data->idle) { - wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n"); + printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n", + wiphy_name(hw->wiphy)); return false; } @@ -575,7 +576,7 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int mac80211_hwsim_start(struct ieee80211_hw *hw) { struct mac80211_hwsim_data *data = hw->priv; - wiphy_debug(hw->wiphy, "%s\n", __func__); + printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); data->started = 1; return 0; } @@ -586,15 +587,16 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) struct mac80211_hwsim_data *data = hw->priv; data->started = 0; del_timer(&data->beacon_timer); - wiphy_debug(hw->wiphy, "%s\n", __func__); + printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); } static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", + wiphy_name(hw->wiphy), __func__, vif->type, + vif->addr); hwsim_set_magic(vif); return 0; } @@ -603,8 +605,9 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, static void mac80211_hwsim_remove_interface( struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", + wiphy_name(hw->wiphy), __func__, vif->type, + vif->addr); hwsim_check_magic(vif); hwsim_clear_magic(vif); } @@ -667,14 +670,13 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) [IEEE80211_SMPS_DYNAMIC] = "dynamic", }; - wiphy_debug(hw->wiphy, - "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", - __func__, - conf->channel->center_freq, - hwsim_chantypes[conf->channel_type], - !!(conf->flags & IEEE80211_CONF_IDLE), - !!(conf->flags & IEEE80211_CONF_PS), - smps_modes[conf->smps_mode]); + printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", + wiphy_name(hw->wiphy), __func__, + conf->channel->center_freq, + hwsim_chantypes[conf->channel_type], + !!(conf->flags & IEEE80211_CONF_IDLE), + !!(conf->flags & IEEE80211_CONF_PS), + smps_modes[conf->smps_mode]); data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); @@ -694,7 +696,7 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, { struct mac80211_hwsim_data *data = hw->priv; - wiphy_debug(hw->wiphy, "%s\n", __func__); + printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); data->rx_filter = 0; if (*total_flags & FIF_PROMISC_IN_BSS) @@ -715,23 +717,26 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, hwsim_check_magic(vif); - wiphy_debug(hw->wiphy, "%s(changed=0x%x)\n", __func__, changed); + printk(KERN_DEBUG "%s:%s(changed=0x%x)\n", + wiphy_name(hw->wiphy), __func__, changed); if (changed & BSS_CHANGED_BSSID) { - wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n", - __func__, info->bssid); + printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n", + wiphy_name(hw->wiphy), __func__, + info->bssid); memcpy(vp->bssid, info->bssid, ETH_ALEN); } if (changed & BSS_CHANGED_ASSOC) { - wiphy_debug(hw->wiphy, " ASSOC: assoc=%d aid=%d\n", - info->assoc, info->aid); + printk(KERN_DEBUG " %s: ASSOC: assoc=%d aid=%d\n", + wiphy_name(hw->wiphy), info->assoc, info->aid); vp->assoc = info->assoc; vp->aid = info->aid; } if (changed & BSS_CHANGED_BEACON_INT) { - wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int); + printk(KERN_DEBUG " %s: BCNINT: %d\n", + wiphy_name(hw->wiphy), info->beacon_int); data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000; if (WARN_ON(!data->beacon_int)) data->beacon_int = 1; @@ -741,28 +746,31 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - wiphy_debug(hw->wiphy, " ERP_CTS_PROT: %d\n", - info->use_cts_prot); + printk(KERN_DEBUG " %s: ERP_CTS_PROT: %d\n", + wiphy_name(hw->wiphy), info->use_cts_prot); } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - wiphy_debug(hw->wiphy, " ERP_PREAMBLE: %d\n", - info->use_short_preamble); + printk(KERN_DEBUG " %s: ERP_PREAMBLE: %d\n", + wiphy_name(hw->wiphy), info->use_short_preamble); } if (changed & BSS_CHANGED_ERP_SLOT) { - wiphy_debug(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot); + printk(KERN_DEBUG " %s: ERP_SLOT: %d\n", + wiphy_name(hw->wiphy), info->use_short_slot); } if (changed & BSS_CHANGED_HT) { - wiphy_debug(hw->wiphy, " HT: op_mode=0x%x, chantype=%s\n", - info->ht_operation_mode, - hwsim_chantypes[info->channel_type]); + printk(KERN_DEBUG " %s: HT: op_mode=0x%x, chantype=%s\n", + wiphy_name(hw->wiphy), + info->ht_operation_mode, + hwsim_chantypes[info->channel_type]); } if (changed & BSS_CHANGED_BASIC_RATES) { - wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n", - (unsigned long long) info->basic_rates); + printk(KERN_DEBUG " %s: BASIC_RATES: 0x%llx\n", + wiphy_name(hw->wiphy), + (unsigned long long) info->basic_rates); } } @@ -816,11 +824,10 @@ static int mac80211_hwsim_conf_tx( struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { - wiphy_debug(hw->wiphy, - "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n", - __func__, queue, - params->txop, params->cw_min, - params->cw_max, params->aifs); + printk(KERN_DEBUG "%s:%s (queue=%d txop=%d cw_min=%d cw_max=%d " + "aifs=%d)\n", + wiphy_name(hw->wiphy), __func__, queue, + params->txop, params->cw_min, params->cw_max, params->aifs); return 0; } @@ -830,7 +837,8 @@ static int mac80211_hwsim_get_survey( { struct ieee80211_conf *conf = &hw->conf; - wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx); + printk(KERN_DEBUG "%s:%s (idx=%d)\n", + wiphy_name(hw->wiphy), __func__, idx); if (idx != 0) return -ENOENT; @@ -1100,9 +1108,8 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) if (!vp->assoc) return; - wiphy_debug(data->hw->wiphy, - "%s: send PS-Poll to %pM for aid %d\n", - __func__, vp->bssid, vp->aid); + printk(KERN_DEBUG "%s:%s: send PS-Poll to %pM for aid %d\n", + wiphy_name(data->hw->wiphy), __func__, vp->bssid, vp->aid); skb = dev_alloc_skb(sizeof(*pspoll)); if (!skb) @@ -1130,9 +1137,8 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, if (!vp->assoc) return; - wiphy_debug(data->hw->wiphy, - "%s: send data::nullfunc to %pM ps=%d\n", - __func__, vp->bssid, ps); + printk(KERN_DEBUG "%s:%s: send data::nullfunc to %pM ps=%d\n", + wiphy_name(data->hw->wiphy), __func__, vp->bssid, ps); skb = dev_alloc_skb(sizeof(*hdr)); if (!skb) @@ -1467,8 +1473,9 @@ static int __init init_mac80211_hwsim(void) break; } - wiphy_debug(hw->wiphy, "hwaddr %pm registered\n", - hw->wiphy->perm_addr); + printk(KERN_DEBUG "%s: hwaddr %pM registered\n", + wiphy_name(hw->wiphy), + hw->wiphy->perm_addr); data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir); diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index d761ed2d8af4..c019fdc131c0 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -86,7 +86,7 @@ struct rxd_ops { void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); void (*rxd_refill)(void *rxd, dma_addr_t addr, int len); int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status, - __le16 *qos, s8 *noise); + __le16 *qos); }; struct mwl8k_device_info { @@ -207,9 +207,6 @@ struct mwl8k_priv { /* Tasklet to perform RX. */ struct tasklet_struct poll_rx_task; - - /* Most recently reported noise in dBm */ - s8 noise; }; /* Per interface specific private data */ @@ -317,15 +314,13 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ #define MWL8K_CMD_UPDATE_STADB 0x1123 -static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) +static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize) { - u16 command = le16_to_cpu(cmd); - #define MWL8K_CMDNAME(x) case MWL8K_CMD_##x: do {\ snprintf(buf, bufsize, "%s", #x);\ return buf;\ } while (0) - switch (command & ~0x8000) { + switch (cmd & ~0x8000) { MWL8K_CMDNAME(CODE_DNLD); MWL8K_CMDNAME(GET_HW_SPEC); MWL8K_CMDNAME(SET_HW_SPEC); @@ -744,7 +739,7 @@ static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) static int mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, - __le16 *qos, s8 *noise) + __le16 *qos) { struct mwl8k_rxd_8366_ap *rxd = _rxd; @@ -755,7 +750,6 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, memset(status, 0, sizeof(*status)); status->signal = -rxd->rssi; - *noise = -rxd->noise_floor; if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { status->flag |= RX_FLAG_HT; @@ -843,7 +837,7 @@ static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len) static int mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, - __le16 *qos, s8 *noise) + __le16 *qos) { struct mwl8k_rxd_sta *rxd = _rxd; u16 rate_info; @@ -857,7 +851,6 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, memset(status, 0, sizeof(*status)); status->signal = -rxd->rssi; - *noise = -rxd->noise_level; status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); @@ -910,14 +903,16 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); if (rxq->rxd == NULL) { - wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n"); + printk(KERN_ERR "%s: failed to alloc RX descriptors\n", + wiphy_name(hw->wiphy)); return -ENOMEM; } memset(rxq->rxd, 0, size); rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); if (rxq->buf == NULL) { - wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n"); + printk(KERN_ERR "%s: failed to alloc RX skbuff list\n", + wiphy_name(hw->wiphy)); pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); return -ENOMEM; } @@ -1058,8 +1053,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit) rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size); - pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos, - &priv->noise); + pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos); if (pkt_len < 0) break; @@ -1145,14 +1139,16 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); if (txq->txd == NULL) { - wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n"); + printk(KERN_ERR "%s: failed to alloc TX descriptors\n", + wiphy_name(hw->wiphy)); return -ENOMEM; } memset(txq->txd, 0, size); txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); if (txq->skb == NULL) { - wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n"); + printk(KERN_ERR "%s: failed to alloc TX skbuff list\n", + wiphy_name(hw->wiphy)); pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); return -ENOMEM; } @@ -1208,12 +1204,11 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw) unused++; } - wiphy_err(hw->wiphy, - "txq[%d] len=%d head=%d tail=%d " - "fw_owned=%d drv_owned=%d unused=%d\n", - i, - txq->len, txq->head, txq->tail, - fw_owned, drv_owned, unused); + printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d " + "fw_owned=%d drv_owned=%d unused=%d\n", + wiphy_name(hw->wiphy), i, + txq->len, txq->head, txq->tail, + fw_owned, drv_owned, unused); } } @@ -1257,23 +1252,25 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) if (timeout) { WARN_ON(priv->pending_tx_pkts); if (retry) { - wiphy_notice(hw->wiphy, "tx rings drained\n"); + printk(KERN_NOTICE "%s: tx rings drained\n", + wiphy_name(hw->wiphy)); } break; } if (priv->pending_tx_pkts < oldcount) { - wiphy_notice(hw->wiphy, - "waiting for tx rings to drain (%d -> %d pkts)\n", - oldcount, priv->pending_tx_pkts); + printk(KERN_NOTICE "%s: waiting for tx rings " + "to drain (%d -> %d pkts)\n", + wiphy_name(hw->wiphy), oldcount, + priv->pending_tx_pkts); retry = 1; continue; } priv->tx_wait = NULL; - wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", - MWL8K_TX_WAIT_TIMEOUT_MS); + printk(KERN_ERR "%s: tx rings stuck for %d ms\n", + wiphy_name(hw->wiphy), MWL8K_TX_WAIT_TIMEOUT_MS); mwl8k_dump_tx_rings(hw); rc = -ETIMEDOUT; @@ -1424,8 +1421,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(priv->pdev, dma)) { - wiphy_debug(hw->wiphy, - "failed to dma map skb, dropping TX frame.\n"); + printk(KERN_DEBUG "%s: failed to dma map skb, " + "dropping TX frame.\n", wiphy_name(hw->wiphy)); dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -1541,7 +1538,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) unsigned long timeout = 0; u8 buf[32]; - cmd->result = (__force __le16) 0xffff; + cmd->result = 0xffff; dma_size = le16_to_cpu(cmd->length); dma_addr = pci_map_single(priv->pdev, cmd, dma_size, PCI_DMA_BIDIRECTIONAL); @@ -1573,9 +1570,10 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) PCI_DMA_BIDIRECTIONAL); if (!timeout) { - wiphy_err(hw->wiphy, "command %s timeout after %u ms\n", - mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), - MWL8K_CMD_TIMEOUT_MS); + printk(KERN_ERR "%s: Command %s timeout after %u ms\n", + wiphy_name(hw->wiphy), + mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), + MWL8K_CMD_TIMEOUT_MS); rc = -ETIMEDOUT; } else { int ms; @@ -1584,14 +1582,15 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) rc = cmd->result ? -EINVAL : 0; if (rc) - wiphy_err(hw->wiphy, "command %s error 0x%x\n", - mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), - le16_to_cpu(cmd->result)); + printk(KERN_ERR "%s: Command %s error 0x%x\n", + wiphy_name(hw->wiphy), + mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), + le16_to_cpu(cmd->result)); else if (ms > 2000) - wiphy_notice(hw->wiphy, "command %s took %d ms\n", - mwl8k_cmd_name(cmd->code, - buf, sizeof(buf)), - ms); + printk(KERN_NOTICE "%s: Command %s took %d ms\n", + wiphy_name(hw->wiphy), + mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), + ms); } return rc; @@ -1843,22 +1842,22 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) priv->sta_macids_supported = 0x00000000; off = le32_to_cpu(cmd->wcbbase0) & 0xffff; - iowrite32(priv->txq[0].txd_dma, priv->sram + off); + iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off); off = le32_to_cpu(cmd->rxwrptr) & 0xffff; - iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); + iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off); off = le32_to_cpu(cmd->rxrdptr) & 0xffff; - iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); + iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off); off = le32_to_cpu(cmd->wcbbase1) & 0xffff; - iowrite32(priv->txq[1].txd_dma, priv->sram + off); + iowrite32(cpu_to_le32(priv->txq[1].txd_dma), priv->sram + off); off = le32_to_cpu(cmd->wcbbase2) & 0xffff; - iowrite32(priv->txq[2].txd_dma, priv->sram + off); + iowrite32(cpu_to_le32(priv->txq[2].txd_dma), priv->sram + off); off = le32_to_cpu(cmd->wcbbase3) & 0xffff; - iowrite32(priv->txq[3].txd_dma, priv->sram + off); + iowrite32(cpu_to_le32(priv->txq[3].txd_dma), priv->sram + off); } kfree(cmd); @@ -3053,7 +3052,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); p->ht_support = sta->ht_cap.ht_supported; - p->ht_caps = cpu_to_le16(sta->ht_cap.cap); + p->ht_caps = sta->ht_cap.cap; p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | ((sta->ht_cap.ampdu_density & 7) << 2); if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) @@ -3191,8 +3190,8 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) int rc; if (!priv->radio_on) { - wiphy_debug(hw->wiphy, - "dropped TX frame since radio disabled\n"); + printk(KERN_DEBUG "%s: dropped TX frame since radio " + "disabled\n", wiphy_name(hw->wiphy)); dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -3210,7 +3209,8 @@ static int mwl8k_start(struct ieee80211_hw *hw) rc = request_irq(priv->pdev->irq, mwl8k_interrupt, IRQF_SHARED, MWL8K_NAME, hw); if (rc) { - wiphy_err(hw->wiphy, "failed to register irq handler\n"); + printk(KERN_ERR "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); return -EIO; } @@ -3297,8 +3297,9 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw, * mode. (Sniffer mode is only used on STA firmware.) */ if (priv->sniffer_enabled) { - wiphy_info(hw->wiphy, - "unable to create STA interface because sniffer mode is enabled\n"); + printk(KERN_INFO "%s: unable to create STA " + "interface due to sniffer mode being enabled\n", + wiphy_name(hw->wiphy)); return -EINVAL; } @@ -3580,8 +3581,9 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw, */ if (!list_empty(&priv->vif_list)) { if (net_ratelimit()) - wiphy_info(hw->wiphy, - "not enabling sniffer mode because STA interface is active\n"); + printk(KERN_INFO "%s: not enabling sniffer " + "mode because STA interface is active\n", + wiphy_name(hw->wiphy)); return 0; } @@ -3761,22 +3763,6 @@ static int mwl8k_get_stats(struct ieee80211_hw *hw, return mwl8k_cmd_get_stat(hw, stats); } -static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct mwl8k_priv *priv = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = priv->noise; - - return 0; -} - static int mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, @@ -3808,7 +3794,6 @@ static const struct ieee80211_ops mwl8k_ops = { .sta_remove = mwl8k_sta_remove, .conf_tx = mwl8k_conf_tx, .get_stats = mwl8k_get_stats, - .get_survey = mwl8k_get_survey, .ampdu_action = mwl8k_ampdu_action, }; @@ -3926,7 +3911,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, priv->sram = pci_iomap(pdev, 0, 0x10000); if (priv->sram == NULL) { - wiphy_err(hw->wiphy, "cannot map device sram\n"); + printk(KERN_ERR "%s: Cannot map device SRAM\n", + wiphy_name(hw->wiphy)); goto err_iounmap; } @@ -3938,7 +3924,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, if (priv->regs == NULL) { priv->regs = pci_iomap(pdev, 2, 0x10000); if (priv->regs == NULL) { - wiphy_err(hw->wiphy, "cannot map device registers\n"); + printk(KERN_ERR "%s: Cannot map device registers\n", + wiphy_name(hw->wiphy)); goto err_iounmap; } } @@ -3950,14 +3937,16 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, /* Ask userland hotplug daemon for the device firmware */ rc = mwl8k_request_firmware(priv); if (rc) { - wiphy_err(hw->wiphy, "firmware files not found\n"); + printk(KERN_ERR "%s: Firmware files not found\n", + wiphy_name(hw->wiphy)); goto err_stop_firmware; } /* Load firmware into hardware */ rc = mwl8k_load_firmware(hw); if (rc) { - wiphy_err(hw->wiphy, "cannot start firmware\n"); + printk(KERN_ERR "%s: Cannot start firmware\n", + wiphy_name(hw->wiphy)); goto err_stop_firmware; } @@ -3968,8 +3957,9 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, if (priv->ap_fw) { priv->rxd_ops = priv->device_info->ap_rxd_ops; if (priv->rxd_ops == NULL) { - wiphy_err(hw->wiphy, - "Driver does not have AP firmware image support for this hardware\n"); + printk(KERN_ERR "%s: Driver does not have AP " + "firmware image support for this hardware\n", + wiphy_name(hw->wiphy)); goto err_stop_firmware; } } else { @@ -4047,7 +4037,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = request_irq(priv->pdev->irq, mwl8k_interrupt, IRQF_SHARED, MWL8K_NAME, hw); if (rc) { - wiphy_err(hw->wiphy, "failed to register irq handler\n"); + printk(KERN_ERR "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); goto err_free_queues; } @@ -4067,7 +4058,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = mwl8k_cmd_get_hw_spec_sta(hw); } if (rc) { - wiphy_err(hw->wiphy, "cannot initialise firmware\n"); + printk(KERN_ERR "%s: Cannot initialise firmware\n", + wiphy_name(hw->wiphy)); goto err_free_irq; } @@ -4081,14 +4073,15 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, /* Turn radio off */ rc = mwl8k_cmd_radio_disable(hw); if (rc) { - wiphy_err(hw->wiphy, "cannot disable\n"); + printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy)); goto err_free_irq; } /* Clear MAC address */ rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); if (rc) { - wiphy_err(hw->wiphy, "cannot clear mac address\n"); + printk(KERN_ERR "%s: Cannot clear MAC address\n", + wiphy_name(hw->wiphy)); goto err_free_irq; } @@ -4098,16 +4091,17 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = ieee80211_register_hw(hw); if (rc) { - wiphy_err(hw->wiphy, "cannot register device\n"); + printk(KERN_ERR "%s: Cannot register device\n", + wiphy_name(hw->wiphy)); goto err_free_queues; } - wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", - priv->device_info->part_name, - priv->hw_rev, hw->wiphy->perm_addr, - priv->ap_fw ? "AP" : "STA", - (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, - (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); + printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n", + wiphy_name(hw->wiphy), priv->device_info->part_name, + priv->hw_rev, hw->wiphy->perm_addr, + priv->ap_fw ? "AP" : "STA", + (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, + (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); return 0; diff --git a/trunk/drivers/net/wireless/orinoco/cfg.c b/trunk/drivers/net/wireless/orinoco/cfg.c index 09fae2f0ea08..8c4169c227ae 100644 --- a/trunk/drivers/net/wireless/orinoco/cfg.c +++ b/trunk/drivers/net/wireless/orinoco/cfg.c @@ -117,8 +117,9 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_MONITOR: if (priv->broken_monitor && !force_monitor) { - wiphy_warn(wiphy, - "Monitor mode support is buggy in this firmware, not enabling\n"); + printk(KERN_WARNING "%s: Monitor mode support is " + "buggy in this firmware, not enabling\n", + wiphy_name(wiphy)); err = -EINVAL; } break; diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_usb.c b/trunk/drivers/net/wireless/orinoco/orinoco_usb.c index a38a7bd25f19..1558381998ee 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_usb.c @@ -1502,16 +1502,16 @@ static inline void ezusb_delete(struct ezusb_priv *upriv) ezusb_ctx_complete(list_entry(item, struct request_context, list)); - if (upriv->read_urb && upriv->read_urb->status == -EINPROGRESS) + if (upriv->read_urb->status == -EINPROGRESS) printk(KERN_ERR PFX "Some URB in progress\n"); mutex_unlock(&upriv->mtx); - if (upriv->read_urb) { - kfree(upriv->read_urb->transfer_buffer); + kfree(upriv->read_urb->transfer_buffer); + if (upriv->bap_buf != NULL) + kfree(upriv->bap_buf); + if (upriv->read_urb != NULL) usb_free_urb(upriv->read_urb); - } - kfree(upriv->bap_buf); if (upriv->dev) { struct orinoco_private *priv = ndev_priv(upriv->dev); orinoco_if_del(priv); diff --git a/trunk/drivers/net/wireless/p54/eeprom.c b/trunk/drivers/net/wireless/p54/eeprom.c index d687cb7f2a59..e51650ed49f2 100644 --- a/trunk/drivers/net/wireless/p54/eeprom.c +++ b/trunk/drivers/net/wireless/p54/eeprom.c @@ -149,15 +149,16 @@ static int p54_generate_band(struct ieee80211_hw *dev, continue; if (list->channels[i].data != CHAN_HAS_ALL) { - wiphy_err(dev->wiphy, - "%s%s%s is/are missing for channel:%d [%d MHz].\n", - (list->channels[i].data & CHAN_HAS_CAL ? "" : - " [iqauto calibration data]"), - (list->channels[i].data & CHAN_HAS_LIMIT ? "" : - " [output power limits]"), - (list->channels[i].data & CHAN_HAS_CURVE ? "" : - " [curve data]"), - list->channels[i].index, list->channels[i].freq); + printk(KERN_ERR "%s:%s%s%s is/are missing for " + "channel:%d [%d MHz].\n", + wiphy_name(dev->wiphy), + (list->channels[i].data & CHAN_HAS_CAL ? "" : + " [iqauto calibration data]"), + (list->channels[i].data & CHAN_HAS_LIMIT ? "" : + " [output power limits]"), + (list->channels[i].data & CHAN_HAS_CURVE ? "" : + " [curve data]"), + list->channels[i].index, list->channels[i].freq); continue; } @@ -167,8 +168,9 @@ static int p54_generate_band(struct ieee80211_hw *dev, } if (j == 0) { - wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n", - (band == IEEE80211_BAND_2GHZ) ? 2 : 5); + printk(KERN_ERR "%s: Disabling totally damaged %s band.\n", + wiphy_name(dev->wiphy), (band == IEEE80211_BAND_2GHZ) ? + "2 GHz" : "5 GHz"); ret = -ENODATA; goto err_out; @@ -242,9 +244,9 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) if ((priv->iq_autocal_len != priv->curve_data->entries) || (priv->iq_autocal_len != priv->output_limit->entries)) - wiphy_err(dev->wiphy, - "Unsupported or damaged EEPROM detected. " - "You may not be able to use all channels.\n"); + printk(KERN_ERR "%s: Unsupported or damaged EEPROM detected. " + "You may not be able to use all channels.\n", + wiphy_name(dev->wiphy)); max_channel_num = max_t(unsigned int, priv->output_limit->entries, priv->iq_autocal_len); @@ -417,14 +419,15 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, int i; if (len != (entry_size * num_entries)) { - wiphy_err(dev->wiphy, - "unknown rssi calibration data packing type:(%x) len:%d.\n", - type, len); + printk(KERN_ERR "%s: unknown rssi calibration data packing " + " type:(%x) len:%d.\n", + wiphy_name(dev->wiphy), type, len); print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len); - wiphy_err(dev->wiphy, "please report this issue.\n"); + printk(KERN_ERR "%s: please report this issue.\n", + wiphy_name(dev->wiphy)); return; } @@ -442,14 +445,15 @@ static void p54_parse_default_country(struct ieee80211_hw *dev, struct pda_country *country; if (len != sizeof(*country)) { - wiphy_err(dev->wiphy, - "found possible invalid default country eeprom entry. (entry size: %d)\n", - len); + printk(KERN_ERR "%s: found possible invalid default country " + "eeprom entry. (entry size: %d)\n", + wiphy_name(dev->wiphy), len); print_hex_dump_bytes("country:", DUMP_PREFIX_NONE, data, len); - wiphy_err(dev->wiphy, "please report this issue.\n"); + printk(KERN_ERR "%s: please report this issue.\n", + wiphy_name(dev->wiphy)); return; } @@ -474,8 +478,8 @@ static int p54_convert_output_limits(struct ieee80211_hw *dev, return -EINVAL; if (data[0] != 0) { - wiphy_err(dev->wiphy, "unknown output power db revision:%x\n", - data[0]); + printk(KERN_ERR "%s: unknown output power db revision:%x\n", + wiphy_name(dev->wiphy), data[0]); return -EINVAL; } @@ -583,9 +587,10 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) err = p54_convert_rev1(dev, curve_data); break; default: - wiphy_err(dev->wiphy, - "unknown curve data revision %d\n", - curve_data->cal_method_rev); + printk(KERN_ERR "%s: unknown curve data " + "revision %d\n", + wiphy_name(dev->wiphy), + curve_data->cal_method_rev); err = -ENODEV; break; } @@ -667,8 +672,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) if (!synth || !priv->iq_autocal || !priv->output_limit || !priv->curve_data) { - wiphy_err(dev->wiphy, - "not all required entries found in eeprom!\n"); + printk(KERN_ERR "%s: not all required entries found in eeprom!\n", + wiphy_name(dev->wiphy)); err = -EINVAL; goto err; } @@ -694,15 +699,15 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { u8 perm_addr[ETH_ALEN]; - wiphy_warn(dev->wiphy, - "invalid hwaddr! using randomly generated mac addr\n"); + printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n", + wiphy_name(dev->wiphy)); random_ether_addr(perm_addr); SET_IEEE80211_PERM_ADDR(dev, perm_addr); } - wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n", - dev->wiphy->perm_addr, priv->version, - p54_rf_chips[priv->rxhw]); + printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n", + wiphy_name(dev->wiphy), dev->wiphy->perm_addr, priv->version, + p54_rf_chips[priv->rxhw]); return 0; @@ -714,7 +719,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) priv->output_limit = NULL; priv->curve_data = NULL; - wiphy_err(dev->wiphy, "eeprom parse failed!\n"); + printk(KERN_ERR "%s: eeprom parse failed!\n", + wiphy_name(dev->wiphy)); return err; } EXPORT_SYMBOL_GPL(p54_parse_eeprom); diff --git a/trunk/drivers/net/wireless/p54/fwio.c b/trunk/drivers/net/wireless/p54/fwio.c index 47006bca4852..c43a5d461ab2 100644 --- a/trunk/drivers/net/wireless/p54/fwio.c +++ b/trunk/drivers/net/wireless/p54/fwio.c @@ -62,15 +62,16 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) case FW_LM20: case FW_LM87: { char *iftype = (char *)bootrec->data; - wiphy_info(priv->hw->wiphy, - "p54 detected a LM%c%c firmware\n", - iftype[2], iftype[3]); + printk(KERN_INFO "%s: p54 detected a LM%c%c " + "firmware\n", + wiphy_name(priv->hw->wiphy), + iftype[2], iftype[3]); break; } case FW_FMAC: default: - wiphy_err(priv->hw->wiphy, - "unsupported firmware\n"); + printk(KERN_ERR "%s: unsupported firmware\n", + wiphy_name(priv->hw->wiphy)); return -ENODEV; } break; @@ -124,15 +125,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) } if (fw_version) - wiphy_info(priv->hw->wiphy, - "fw rev %s - softmac protocol %x.%x\n", - fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); + printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n", + wiphy_name(priv->hw->wiphy), fw_version, + priv->fw_var >> 8, priv->fw_var & 0xff); if (priv->fw_var < 0x500) - wiphy_info(priv->hw->wiphy, - "you are using an obsolete firmware. " - "visit http://wireless.kernel.org/en/users/Drivers/p54 " - "and grab one for \"kernel >= 2.6.28\"!\n"); + printk(KERN_INFO "%s: you are using an obsolete firmware. " + "visit http://wireless.kernel.org/en/users/Drivers/p54 " + "and grab one for \"kernel >= 2.6.28\"!\n", + wiphy_name(priv->hw->wiphy)); if (priv->fw_var >= 0x300) { /* Firmware supports QoS, use it! */ @@ -151,14 +152,13 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) priv->hw->queues = P54_QUEUE_AC_NUM; } - wiphy_info(priv->hw->wiphy, - "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n", - (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no", - (priv->privacy_caps & - (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL)) - ? "YES" : "no", - (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) - ? "YES" : "no"); + printk(KERN_INFO "%s: cryptographic accelerator " + "WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(priv->hw->wiphy), + (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : + "no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP | + BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no", + (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ? + "YES" : "no"); if (priv->rx_keycache_size) { /* @@ -247,7 +247,8 @@ int p54_download_eeprom(struct p54_common *priv, void *buf, if (!wait_for_completion_interruptible_timeout( &priv->eeprom_comp, HZ)) { - wiphy_err(priv->hw->wiphy, "device does not respond!\n"); + printk(KERN_ERR "%s: device does not respond!\n", + wiphy_name(priv->hw->wiphy)); ret = -EBUSY; } priv->eeprom = NULL; @@ -522,9 +523,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) return 0; err: - wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n", - ieee80211_frequency_to_channel( - priv->hw->conf.channel->center_freq)); + printk(KERN_ERR "%s: frequency change to channel %d failed.\n", + wiphy_name(priv->hw->wiphy), ieee80211_frequency_to_channel( + priv->hw->conf.channel->center_freq)); dev_kfree_skb_any(skb); return -EINVAL; @@ -675,8 +676,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len, break; default: - wiphy_err(priv->hw->wiphy, - "invalid cryptographic algorithm: %d\n", algo); + printk(KERN_ERR "%s: invalid cryptographic algorithm: %d\n", + wiphy_name(priv->hw->wiphy), algo); dev_kfree_skb(skb); return -EINVAL; } diff --git a/trunk/drivers/net/wireless/p54/led.c b/trunk/drivers/net/wireless/p54/led.c index ea91f5cce6b3..9575ac033630 100644 --- a/trunk/drivers/net/wireless/p54/led.c +++ b/trunk/drivers/net/wireless/p54/led.c @@ -57,8 +57,8 @@ static void p54_update_leds(struct work_struct *work) err = p54_set_leds(priv); if (err && net_ratelimit()) - wiphy_err(priv->hw->wiphy, - "failed to update leds (%d).\n", err); + printk(KERN_ERR "%s: failed to update LEDs (%d).\n", + wiphy_name(priv->hw->wiphy), err); if (rerun) ieee80211_queue_delayed_work(priv->hw, &priv->led_work, @@ -102,8 +102,8 @@ static int p54_register_led(struct p54_common *priv, err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev); if (err) - wiphy_err(priv->hw->wiphy, - "failed to register %s led.\n", name); + printk(KERN_ERR "%s: Failed to register %s LED.\n", + wiphy_name(priv->hw->wiphy), name); else led->registered = 1; diff --git a/trunk/drivers/net/wireless/p54/main.c b/trunk/drivers/net/wireless/p54/main.c index 47db439b63bf..c072f41747ca 100644 --- a/trunk/drivers/net/wireless/p54/main.c +++ b/trunk/drivers/net/wireless/p54/main.c @@ -507,22 +507,6 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, return ret; } -static int p54_get_survey(struct ieee80211_hw *dev, int idx, - struct survey_info *survey) -{ - struct p54_common *priv = dev->priv; - struct ieee80211_conf *conf = &dev->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = clamp_t(s8, priv->noise, -128, 127); - - return 0; -} - static const struct ieee80211_ops p54_ops = { .tx = p54_tx_80211, .start = p54_start, @@ -539,7 +523,6 @@ static const struct ieee80211_ops p54_ops = { .configure_filter = p54_configure_filter, .conf_tx = p54_conf_tx, .get_stats = p54_get_stats, - .get_survey = p54_get_survey, }; struct ieee80211_hw *p54_init_common(size_t priv_data_len) diff --git a/trunk/drivers/net/wireless/p54/p54pci.c b/trunk/drivers/net/wireless/p54/p54pci.c index 822f8dc26e9c..a5ea89cde8c4 100644 --- a/trunk/drivers/net/wireless/p54/p54pci.c +++ b/trunk/drivers/net/wireless/p54/p54pci.c @@ -466,7 +466,8 @@ static int p54p_open(struct ieee80211_hw *dev) P54P_READ(dev_int); if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { - wiphy_err(dev->wiphy, "cannot boot firmware!\n"); + printk(KERN_ERR "%s: Cannot boot firmware!\n", + wiphy_name(dev->wiphy)); p54p_stop(dev); return -ETIMEDOUT; } diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c index 427b46f558ed..4e6891099d43 100644 --- a/trunk/drivers/net/wireless/p54/txrx.c +++ b/trunk/drivers/net/wireless/p54/txrx.c @@ -38,8 +38,8 @@ static void p54_dump_tx_queue(struct p54_common *priv) u32 largest_hole = 0, free; spin_lock_irqsave(&priv->tx_queue.lock, flags); - wiphy_debug(priv->hw->wiphy, "/ --- tx queue dump (%d entries) ---\n", - skb_queue_len(&priv->tx_queue)); + printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) ---\n", + wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue)); prev_addr = priv->rx_start; skb_queue_walk(&priv->tx_queue, skb) { @@ -48,23 +48,21 @@ static void p54_dump_tx_queue(struct p54_common *priv) hdr = (void *) skb->data; free = range->start_addr - prev_addr; - wiphy_debug(priv->hw->wiphy, - "| [%02d] => [skb:%p skb_len:0x%04x " - "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} " - "mem:{start:%04x end:%04x, free:%d}]\n", - i++, skb, skb->len, - le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len), - le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type), - range->start_addr, range->end_addr, free); + printk(KERN_DEBUG "%s: | [%02d] => [skb:%p skb_len:0x%04x " + "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} " + "mem:{start:%04x end:%04x, free:%d}]\n", + wiphy_name(priv->hw->wiphy), i++, skb, skb->len, + le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len), + le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type), + range->start_addr, range->end_addr, free); prev_addr = range->end_addr; largest_hole = max(largest_hole, free); } free = priv->rx_end - prev_addr; largest_hole = max(largest_hole, free); - wiphy_debug(priv->hw->wiphy, - "\\ --- [free: %d], largest free block: %d ---\n", - free, largest_hole); + printk(KERN_DEBUG "%s: \\ --- [free: %d], largest free block: %d ---\n", + wiphy_name(priv->hw->wiphy), free, largest_hole); spin_unlock_irqrestore(&priv->tx_queue.lock, flags); } #endif /* P54_MM_DEBUG */ @@ -540,7 +538,8 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) case P54_TRAP_BEACON_TX: break; case P54_TRAP_RADAR: - wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq); + printk(KERN_INFO "%s: radar (freq:%d MHz)\n", + wiphy_name(priv->hw->wiphy), freq); break; case P54_TRAP_NO_BEACON: if (priv->vif) @@ -559,8 +558,8 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) wiphy_rfkill_set_hw_state(priv->hw->wiphy, false); break; default: - wiphy_info(priv->hw->wiphy, "received event:%x freq:%d\n", - event, freq); + printk(KERN_INFO "%s: received event:%x freq:%d\n", + wiphy_name(priv->hw->wiphy), event, freq); break; } } @@ -585,9 +584,8 @@ static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb) p54_rx_eeprom_readback(priv, skb); break; default: - wiphy_debug(priv->hw->wiphy, - "not handling 0x%02x type control frame\n", - le16_to_cpu(hdr->type)); + printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n", + wiphy_name(priv->hw->wiphy), le16_to_cpu(hdr->type)); break; } return 0; diff --git a/trunk/drivers/net/wireless/ray_cs.c b/trunk/drivers/net/wireless/ray_cs.c index 9c38fc331dca..abff8934db13 100644 --- a/trunk/drivers/net/wireless/ray_cs.c +++ b/trunk/drivers/net/wireless/ray_cs.c @@ -97,6 +97,7 @@ static iw_stats *ray_get_wireless_stats(struct net_device *dev); static const struct iw_handler_def ray_handler_def; /***** Prototypes for raylink functions **************************************/ +static int asc_to_int(char a); static void authenticate(ray_dev_t *local); static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type); static void authenticate_timeout(u_long); @@ -1715,6 +1716,24 @@ static void authenticate_timeout(u_long data) join_net((u_long) local); } +/*===========================================================================*/ +static int asc_to_int(char a) +{ + if (a < '0') + return -1; + if (a <= '9') + return (a - '0'); + if (a < 'A') + return -1; + if (a <= 'F') + return (10 + a - 'A'); + if (a < 'a') + return -1; + if (a <= 'f') + return (10 + a - 'a'); + return -1; +} + /*===========================================================================*/ static int parse_addr(char *in_str, UCHAR *out) { @@ -1735,14 +1754,14 @@ static int parse_addr(char *in_str, UCHAR *out) i = 5; while (j > 0) { - if ((k = hex_to_bin(in_str[j--])) != -1) + if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k; else return 0; if (j == 0) break; - if ((k = hex_to_bin(in_str[j--])) != -1) + if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4; else return 0; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index cdaf93f48263..242d59558b79 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -350,14 +350,6 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, enum cipher curr_cipher; if (crypto->cmd == SET_KEY) { - /* - * Disallow to set WEP key other than with index 0, - * it is known that not work at least on some hardware. - * SW crypto will be used in that case. - */ - if (key->alg == ALG_WEP && key->keyidx != 0) - return -EOPNOTSUPP; - /* * Pairwise key will always be entry 0, but this * could collide with a shared key on the same @@ -384,7 +376,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher) return -EOPNOTSUPP; - rt2500usb_register_multiwrite(rt2x00dev, KEY_ENTRY(key->hw_key_idx), + rt2500usb_register_multiwrite(rt2x00dev, reg, crypto->key, sizeof(crypto->key)); /* @@ -825,7 +817,6 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2500usb_register_write(rt2x00dev, MAC_CSR8, reg); rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); - rt2x00_set_field16(®, TXRX_CSR0_ALGORITHM, CIPHER_NONE); rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0); rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dump.h b/trunk/drivers/net/wireless/rt2x00/rt2x00dump.h index 5d6e0b83151f..6df2e0b746b8 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dump.h @@ -116,7 +116,7 @@ struct rt2x00dump_hdr { __le16 chip_rt; __le16 chip_rf; - __le16 chip_rev; + __le32 chip_rev; __le16 type; __u8 queue_index; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c index 235e037e6509..4d8d2320c9fd 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -273,24 +273,17 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, mutex_init(&intf->beacon_skb_mutex); intf->beacon = entry; + if (vif->type == NL80211_IFTYPE_AP) + memcpy(&intf->bssid, vif->addr, ETH_ALEN); + memcpy(&intf->mac, vif->addr, ETH_ALEN); + /* * The MAC adddress must be configured after the device * has been initialized. Otherwise the device can reset * the MAC registers. - * The BSSID address must only be configured in AP mode, - * however we should not send an empty BSSID address for - * STA interfaces at this time, since this can cause - * invalid behavior in the device. */ - memcpy(&intf->mac, vif->addr, ETH_ALEN); - if (vif->type == NL80211_IFTYPE_AP) { - memcpy(&intf->bssid, vif->addr, ETH_ALEN); - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, - intf->mac, intf->bssid); - } else { - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, - intf->mac, NULL); - } + rt2x00lib_config_intf(rt2x00dev, intf, vif->type, + intf->mac, intf->bssid); /* * Some filters depend on the current working mode. We can force diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c index 1d8178563d76..42705028751d 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -103,7 +103,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) { struct rtl8180_priv *priv = dev->priv; unsigned int count = 32; - u8 signal, agc, sq; while (count--) { struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; @@ -131,18 +130,10 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) skb_put(skb, flags & 0xFFF); rx_status.antenna = (flags2 >> 15) & 1; + /* TODO: improve signal/rssi reporting */ + rx_status.signal = (flags2 >> 8) & 0x7F; + /* XXX: is this correct? */ rx_status.rate_idx = (flags >> 20) & 0xF; - agc = (flags2 >> 17) & 0x7F; - if (priv->r8185) { - if (rx_status.rate_idx > 3) - signal = 90 - clamp_t(u8, agc, 25, 90); - else - signal = 95 - clamp_t(u8, agc, 30, 95); - } else { - sq = flags2 & 0xff; - signal = priv->rf->calc_rssi(agc, sq); - } - rx_status.signal = signal; rx_status.freq = dev->conf.channel->center_freq; rx_status.band = dev->conf.channel->band; rx_status.mactime = le64_to_cpu(entry->tsft); @@ -361,7 +352,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) /* check success of reset */ if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) { - wiphy_err(dev->wiphy, "reset timeout!\n"); + printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy)); return -ETIMEDOUT; } @@ -445,7 +436,8 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) &priv->rx_ring_dma); if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { - wiphy_err(dev->wiphy, "cannot allocate rx ring\n"); + printk(KERN_ERR "%s: Cannot allocate RX ring\n", + wiphy_name(dev->wiphy)); return -ENOMEM; } @@ -502,8 +494,8 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); if (!ring || (unsigned long)ring & 0xFF) { - wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n", - prio); + printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n", + wiphy_name(dev->wiphy), prio); return -ENOMEM; } @@ -568,7 +560,8 @@ static int rtl8180_start(struct ieee80211_hw *dev) ret = request_irq(priv->pdev->irq, rtl8180_interrupt, IRQF_SHARED, KBUILD_MODNAME, dev); if (ret) { - wiphy_err(dev->wiphy, "failed to register irq handler\n"); + printk(KERN_ERR "%s: failed to register IRQ handler\n", + wiphy_name(dev->wiphy)); goto err_free_rings; } @@ -1105,8 +1098,9 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, goto err_iounmap; } - wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", - mac_addr, chip_name, priv->rf->name); + printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n", + wiphy_name(dev->wiphy), mac_addr, + chip_name, priv->rf->name); return 0; diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180_grf5101.c b/trunk/drivers/net/wireless/rtl818x/rtl8180_grf5101.c index 5cab9dfa8c07..947ee55f18b2 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180_grf5101.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180_grf5101.c @@ -69,15 +69,6 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) rtl8180_write_phy(dev, 0x10, ant); } -static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq) -{ - if (agc > 60) - return 65; - - /* TODO(?): just return agc (or agc + 5) to avoid mult / div */ - return 65 * agc / 60; -} - static void grf5101_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { @@ -185,6 +176,5 @@ const struct rtl818x_rf_ops grf5101_rf_ops = { .name = "GCT", .init = grf5101_rf_init, .stop = grf5101_rf_stop, - .set_chan = grf5101_rf_set_channel, - .calc_rssi = grf5101_rf_calc_rssi, + .set_chan = grf5101_rf_set_channel }; diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180_max2820.c b/trunk/drivers/net/wireless/rtl818x/rtl8180_max2820.c index 16c4655181c0..6c825fd7f3b6 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180_max2820.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180_max2820.c @@ -74,22 +74,6 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) rtl8180_write_phy(dev, 0x10, ant); } -static u8 max2820_rf_calc_rssi(u8 agc, u8 sq) -{ - bool odd; - - odd = !!(agc & 1); - - agc >>= 1; - if (odd) - agc += 76; - else - agc += 66; - - /* TODO: change addends above to avoid mult / div below */ - return 65 * agc / 100; -} - static void max2820_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { @@ -164,6 +148,5 @@ const struct rtl818x_rf_ops max2820_rf_ops = { .name = "Maxim", .init = max2820_rf_init, .stop = max2820_rf_stop, - .set_chan = max2820_rf_set_channel, - .calc_rssi = max2820_rf_calc_rssi, + .set_chan = max2820_rf_set_channel }; diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c b/trunk/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c index 69e4d4745dae..4d2be0d9672b 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c @@ -50,10 +50,7 @@ static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) udelay(10); for (i = 15; i >= 0; i--) { - u16 reg = reg80; - - if (bangdata & (1 << i)) - reg |= 1; + u16 reg = reg80 | !!(bangdata & (1 << i)); if (i & 1) rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180_sa2400.c b/trunk/drivers/net/wireless/rtl818x/rtl8180_sa2400.c index d064fcc5ec08..cea4e0ccb92d 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180_sa2400.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180_sa2400.c @@ -76,31 +76,6 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) } -static u8 sa2400_rf_rssi_map[] = { - 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, - 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, - 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, - 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, - 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, - 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, - 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, - 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, - 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, - 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, -}; - -static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq) -{ - if (sq == 0x80) - return 1; - - if (sq > 78) - return 32; - - /* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */ - return 65 * sa2400_rf_rssi_map[sq] / 100; -} - static void sa2400_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { @@ -223,6 +198,5 @@ const struct rtl818x_rf_ops sa2400_rf_ops = { .name = "Philips", .init = sa2400_rf_init, .stop = sa2400_rf_stop, - .set_chan = sa2400_rf_set_channel, - .calc_rssi = sa2400_rf_calc_rssi, + .set_chan = sa2400_rf_set_channel }; diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c index 5738a55c1b06..891b8490e349 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) } while (--i); if (!i) { - wiphy_err(dev->wiphy, "reset timeout!\n"); + printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy)); return -ETIMEDOUT; } @@ -589,7 +589,8 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) } while (--i); if (!i) { - wiphy_err(dev->wiphy, "eeprom reset timeout!\n"); + printk(KERN_ERR "%s: eeprom reset timeout!\n", + wiphy_name(dev->wiphy)); return -ETIMEDOUT; } @@ -1526,9 +1527,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, mutex_init(&priv->conf_mutex); skb_queue_head_init(&priv->b_tx_status.queue); - wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n", - mac_addr, chip_name, priv->asic_rev, priv->rf->name, - priv->rfkill_mask); + printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", + wiphy_name(dev->wiphy), mac_addr, + chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); #ifdef CONFIG_RTL8187_LEDS eeprom_93cx6_read(&eeprom, 0x3F, ®); diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index fd96f9112322..a09819386a1e 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c @@ -366,8 +366,8 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev) rtl8225_write(dev, 0x02, 0x044d); msleep(100); if (!(rtl8225_read(dev, 6) & (1 << 7))) - wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", - rtl8225_read(dev, 6)); + printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", + wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); } rtl8225_write(dev, 0x0, 0x127); @@ -735,8 +735,8 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev) rtl8225_write(dev, 0x02, 0x044D); msleep(100); if (!(rtl8225_read(dev, 6) & (1 << 7))) - wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", - rtl8225_read(dev, 6)); + printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", + wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); } msleep(200); diff --git a/trunk/drivers/net/wireless/rtl818x/rtl818x.h b/trunk/drivers/net/wireless/rtl818x/rtl818x.h index 1615f63b02f6..978519d1ff4c 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl818x.h +++ b/trunk/drivers/net/wireless/rtl818x/rtl818x.h @@ -193,7 +193,6 @@ struct rtl818x_rf_ops { void (*stop)(struct ieee80211_hw *); void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *); - u8 (*calc_rssi)(u8 agc, u8 sq); }; /** diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251.h b/trunk/drivers/net/wireless/wl12xx/wl1251.h index 6b942a28e6a5..4f5f02a26e62 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251.h +++ b/trunk/drivers/net/wireless/wl12xx/wl1251.h @@ -381,9 +381,6 @@ struct wl1251 { u32 chip_id; char fw_ver[21]; - - /* Most recently reported noise in dBm */ - s8 noise; }; int wl1251_plt_start(struct wl1251 *wl); diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_boot.c b/trunk/drivers/net/wireless/wl12xx/wl1251_boot.c index 65e0416be5b6..2545123931e8 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_boot.c @@ -225,7 +225,7 @@ static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag) int wl1251_boot_run_firmware(struct wl1251 *wl) { int loop, ret; - u32 chip_id, acx_intr; + u32 chip_id, interrupt; wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); @@ -242,15 +242,15 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) loop = 0; while (loop++ < INIT_LOOP) { udelay(INIT_LOOP_DELAY); - acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + interrupt = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - if (acx_intr == 0xffffffff) { + if (interrupt == 0xffffffff) { wl1251_error("error reading hardware complete " "init indication"); return -EIO; } /* check that ACX_INTR_INIT_COMPLETE is enabled */ - else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) { + else if (interrupt & WL1251_ACX_INTR_INIT_COMPLETE) { wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, WL1251_ACX_INTR_INIT_COMPLETE); break; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.h b/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.h index a9e4991369be..7e70dd5a21b8 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.h +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_cmd.h @@ -175,8 +175,8 @@ struct cmd_read_write_memory { #define WL1251_SCAN_NUM_PROBES 3 struct wl1251_scan_parameters { - __le32 rx_config_options; - __le32 rx_filter_options; + u32 rx_config_options; + u32 rx_filter_options; /* * Scan options: @@ -186,7 +186,7 @@ struct wl1251_scan_parameters { * bit 2: voice mode, 0 for normal scan. * bit 3: scan priority, 1 for high priority. */ - __le16 scan_options; + u16 scan_options; /* Number of channels to scan */ u8 num_channels; @@ -195,7 +195,7 @@ struct wl1251_scan_parameters { u8 num_probe_requests; /* Rate and modulation for probe requests */ - __le16 tx_rate; + u16 tx_rate; u8 tid_trigger; u8 ssid_len; @@ -204,8 +204,8 @@ struct wl1251_scan_parameters { } __packed; struct wl1251_scan_ch_parameters { - __le32 min_duration; /* in TU */ - __le32 max_duration; /* in TU */ + u32 min_duration; /* in TU */ + u32 max_duration; /* in TU */ u32 bssid_lsb; u16 bssid_msb; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_main.c b/trunk/drivers/net/wireless/wl12xx/wl1251_main.c index 861a5f33761e..38f72f417183 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_main.c @@ -411,7 +411,6 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int wl1251_op_start(struct ieee80211_hw *hw) { struct wl1251 *wl = hw->priv; - struct wiphy *wiphy = hw->wiphy; int ret = 0; wl1251_debug(DEBUG_MAC80211, "mac80211 start"); @@ -445,10 +444,6 @@ static int wl1251_op_start(struct ieee80211_hw *hw) wl1251_info("firmware booted (%s)", wl->fw_ver); - /* update hw/fw version info in wiphy struct */ - wiphy->hw_version = wl->chip_id; - strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version)); - out: if (ret < 0) wl1251_power_off(wl); @@ -1177,22 +1172,6 @@ static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue, return ret; } -static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct wl1251 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = wl->noise; - - return 0; -} - /* can't be const, mac80211 writes to this */ static struct ieee80211_supported_band wl1251_band_2ghz = { .channels = wl1251_channels, @@ -1214,7 +1193,6 @@ static const struct ieee80211_ops wl1251_ops = { .bss_info_changed = wl1251_op_bss_info_changed, .set_rts_threshold = wl1251_op_set_rts_threshold, .conf_tx = wl1251_op_conf_tx, - .get_survey = wl1251_op_get_survey, }; static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data) diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c b/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c index 1b6294b3b996..851515836a7f 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_rx.c @@ -74,12 +74,6 @@ static void wl1251_rx_status(struct wl1251 *wl, status->signal = desc->rssi; - /* - * FIXME: guessing that snr needs to be divided by two, otherwise - * the values don't make any sense - */ - wl->noise = desc->rssi - desc->snr / 2; - status->freq = ieee80211_channel_to_frequency(desc->channel); status->flag |= RX_FLAG_TSFT; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_tx.c b/trunk/drivers/net/wireless/wl12xx/wl1251_tx.c index a38ec199187a..c8223185efd2 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_tx.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_tx.c @@ -117,7 +117,7 @@ static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr) frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; tx_hdr->frag_threshold = cpu_to_le16(frag_threshold); - payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH; + payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH; if (payload_len > frag_threshold) { mem_blocks_per_frag = @@ -191,13 +191,11 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, if (control->control.hw_key && control->control.hw_key->alg == ALG_TKIP) { int hdrlen; - __le16 fc; - u16 length; + u16 fc; u8 *pos; - fc = *(__le16 *)(skb->data + sizeof(*tx_hdr)); - length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE; - tx_hdr->length = cpu_to_le16(length); + fc = *(u16 *)(skb->data + sizeof(*tx_hdr)); + tx_hdr->length += WL1251_TKIP_IV_SPACE; hdrlen = ieee80211_hdrlen(fc); diff --git a/trunk/drivers/net/wireless/wl12xx/wl1251_tx.h b/trunk/drivers/net/wireless/wl12xx/wl1251_tx.h index f40eeb37f5aa..65c4be8c2e80 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1251_tx.h +++ b/trunk/drivers/net/wireless/wl12xx/wl1251_tx.h @@ -114,7 +114,7 @@ struct tx_control { struct tx_double_buffer_desc { /* Length of payload, including headers. */ - __le16 length; + u16 length; /* * A bit mask that specifies the initial rate to be used @@ -133,10 +133,10 @@ struct tx_double_buffer_desc { * 0x0800 - 48Mbits * 0x1000 - 54Mbits */ - __le16 rate; + u16 rate; /* Time in us that a packet can spend in the target */ - __le32 expiry_time; + u32 expiry_time; /* index of the TX queue used for this packet */ u8 xmit_queue; @@ -150,7 +150,7 @@ struct tx_double_buffer_desc { * The FW should cut the packet into fragments * of this size. */ - __le16 frag_threshold; + u16 frag_threshold; /* Numbers of HW queue blocks to be allocated */ u8 num_mem_blocks; diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271.h b/trunk/drivers/net/wireless/wl12xx/wl1271.h index dd3cee6ea5bb..53d47d7a2a1d 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271.h +++ b/trunk/drivers/net/wireless/wl12xx/wl1271.h @@ -475,9 +475,6 @@ struct wl1271 { bool sg_enabled; struct list_head list; - - /* Most recently reported noise in dBm */ - s8 noise; }; int wl1271_plt_start(struct wl1271 *wl); diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271_main.c b/trunk/drivers/net/wireless/wl12xx/wl1271_main.c index 9d68f0012f05..d30de58cef90 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1271_main.c @@ -576,7 +576,7 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) goto out; } - wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); + wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); if (!wl->nvs) { wl1271_error("could not allocate memory for the nvs file"); @@ -584,6 +584,8 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) goto out; } + memcpy(wl->nvs, fw->data, fw->size); + out: release_firmware(fw); @@ -839,7 +841,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct wl1271 *wl = hw->priv; - struct wiphy *wiphy = hw->wiphy; int retries = WL1271_BOOT_RETRIES; int ret = 0; @@ -893,12 +894,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, wl->state = WL1271_STATE_ON; wl1271_info("firmware booted (%s)", wl->chip.fw_ver); - - /* update hw/fw version info in wiphy struct */ - wiphy->hw_version = wl->chip.id; - strncpy(wiphy->fw_version, wl->chip.fw_ver, - sizeof(wiphy->fw_version)); - goto out; irq_disable: @@ -1934,22 +1929,6 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) return mactime; } -static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct wl1271 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = wl->noise; - - return 0; -} - /* can't be const, mac80211 writes to this */ static struct ieee80211_rate wl1271_rates[] = { { .bitrate = 10, @@ -2179,7 +2158,6 @@ static const struct ieee80211_ops wl1271_ops = { .set_rts_threshold = wl1271_op_set_rts_threshold, .conf_tx = wl1271_op_conf_tx, .get_tsf = wl1271_op_get_tsf, - .get_survey = wl1271_op_get_survey, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) }; @@ -2372,13 +2350,15 @@ struct ieee80211_hw *wl1271_alloc_hw(void) goto err_hw_alloc; } - plat_dev = kmemdup(&wl1271_device, sizeof(wl1271_device), GFP_KERNEL); + plat_dev = kmalloc(sizeof(wl1271_device), GFP_KERNEL); if (!plat_dev) { wl1271_error("could not allocate platform_device"); ret = -ENOMEM; goto err_plat_alloc; } + memcpy(plat_dev, &wl1271_device, sizeof(wl1271_device)); + wl = hw->priv; memset(wl, 0, sizeof(*wl)); diff --git a/trunk/drivers/net/wireless/wl12xx/wl1271_rx.c b/trunk/drivers/net/wireless/wl12xx/wl1271_rx.c index 019aa79cd9df..e98f22b3c3ba 100644 --- a/trunk/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/trunk/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -55,13 +55,6 @@ static void wl1271_rx_status(struct wl1271 *wl, status->signal = desc->rssi; - /* - * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we - * need to divide by two for now, but TI has been discussing about - * changing it. This needs to be rechecked. - */ - wl->noise = desc->rssi - (desc->snr >> 1); - status->freq = ieee80211_channel_to_frequency(desc->channel); if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { diff --git a/trunk/drivers/s390/net/claw.c b/trunk/drivers/s390/net/claw.c index a75ed3083a6a..147bb1a69aba 100644 --- a/trunk/drivers/s390/net/claw.c +++ b/trunk/drivers/s390/net/claw.c @@ -295,7 +295,7 @@ claw_driver_group_store(struct device_driver *ddrv, const char *buf, int err; err = ccwgroup_create_from_string(claw_root_dev, claw_group_driver.driver_id, - &claw_ccw_driver, 2, buf); + &claw_ccw_driver, 3, buf); return err ? err : count; } diff --git a/trunk/drivers/s390/net/qeth_core.h b/trunk/drivers/s390/net/qeth_core.h index d1257768be90..d79892782a2b 100644 --- a/trunk/drivers/s390/net/qeth_core.h +++ b/trunk/drivers/s390/net/qeth_core.h @@ -188,7 +188,8 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, qeth_is_enabled6(c, f) : qeth_is_enabled(c, f)) #define QETH_IDX_FUNC_LEVEL_OSD 0x0101 -#define QETH_IDX_FUNC_LEVEL_IQD 0x4108 +#define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108 +#define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 #define QETH_MODELLIST_ARRAY \ {{0x1731, 0x01, 0x1732, QETH_CARD_TYPE_OSD, QETH_MAX_QUEUES, 0}, \ @@ -740,7 +741,6 @@ struct qeth_card { struct qeth_qdio_info qdio; struct qeth_perf_stats perf_stats; int use_hard_stop; - int read_or_write_problem; struct qeth_osn_info osn_info; struct qeth_discipline discipline; atomic_t force_alloc_skb; @@ -748,7 +748,6 @@ struct qeth_card { struct qdio_ssqd_desc ssqd; debug_info_t *debug; struct mutex conf_mutex; - struct mutex discipline_mutex; }; struct qeth_card_list_struct { diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 3a5a18a0fc28..b7019066c303 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -262,7 +262,6 @@ static int qeth_issue_next_read(struct qeth_card *card) QETH_DBF_MESSAGE(2, "%s error in starting next read ccw! " "rc=%i\n", dev_name(&card->gdev->dev), rc); atomic_set(&card->read.irq_pending, 0); - card->read_or_write_problem = 1; qeth_schedule_recovery(card); wake_up(&card->wait_q); } @@ -383,7 +382,6 @@ void qeth_clear_ipacmd_list(struct qeth_card *card) qeth_put_reply(reply); } spin_unlock_irqrestore(&card->lock, flags); - atomic_set(&card->write.irq_pending, 0); } EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list); @@ -1078,7 +1076,6 @@ static int qeth_setup_card(struct qeth_card *card) card->state = CARD_STATE_DOWN; card->lan_online = 0; card->use_hard_stop = 0; - card->read_or_write_problem = 0; card->dev = NULL; spin_lock_init(&card->vlanlock); spin_lock_init(&card->mclock); @@ -1087,7 +1084,6 @@ static int qeth_setup_card(struct qeth_card *card) spin_lock_init(&card->ip_lock); spin_lock_init(&card->thread_mask_lock); mutex_init(&card->conf_mutex); - mutex_init(&card->discipline_mutex); card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; @@ -1387,7 +1383,12 @@ static void qeth_init_func_level(struct qeth_card *card) { switch (card->info.type) { case QETH_CARD_TYPE_IQD: - card->info.func_level = QETH_IDX_FUNC_LEVEL_IQD; + if (card->ipato.enabled) + card->info.func_level = + QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT; + else + card->info.func_level = + QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT; break; case QETH_CARD_TYPE_OSD: case QETH_CARD_TYPE_OSN: @@ -1661,10 +1662,6 @@ int qeth_send_control_data(struct qeth_card *card, int len, QETH_CARD_TEXT(card, 2, "sendctl"); - if (card->read_or_write_problem) { - qeth_release_buffer(iob->channel, iob); - return -EIO; - } reply = qeth_alloc_reply(card); if (!reply) { return -ENOMEM; @@ -1736,9 +1733,6 @@ int qeth_send_control_data(struct qeth_card *card, int len, spin_unlock_irqrestore(&reply->card->lock, flags); reply->rc = -ETIME; atomic_inc(&reply->received); - atomic_set(&card->write.irq_pending, 0); - qeth_release_buffer(iob->channel, iob); - card->write.buf_no = (card->write.buf_no + 1) % QETH_CMD_BUFFER_NO; wake_up(&reply->wait_q); rc = reply->rc; qeth_put_reply(reply); @@ -1996,7 +1990,7 @@ static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, QETH_DBF_TEXT(SETUP, 2, "olmlimit"); dev_err(&card->gdev->dev, "A connection could not be " "established because of an OLM limit\n"); - iob->rc = -EMLINK; + rc = -EMLINK; } QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); return rc; @@ -2495,10 +2489,6 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, qeth_prepare_ipa_cmd(card, iob, prot_type); rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob, reply_cb, reply_param); - if (rc == -ETIME) { - qeth_clear_ipacmd_list(card); - qeth_schedule_recovery(card); - } return rc; } EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd); @@ -3423,6 +3413,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, { struct qeth_ipa_cmd *cmd; struct qeth_set_access_ctrl *access_ctrl_req; + int rc; QETH_CARD_TEXT(card, 4, "setaccb"); @@ -3449,6 +3440,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, card->gdev->dev.kobj.name, access_ctrl_req->subcmd_code, cmd->data.setadapterparms.hdr.return_code); + rc = 0; break; } case SET_ACCESS_CTRL_RC_NOT_SUPPORTED: @@ -3462,6 +3454,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, /* ensure isolation mode is "none" */ card->options.isolation = ISOLATION_MODE_NONE; + rc = -EOPNOTSUPP; break; } case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER: @@ -3476,6 +3469,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, /* ensure isolation mode is "none" */ card->options.isolation = ISOLATION_MODE_NONE; + rc = -EOPNOTSUPP; break; } case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF: @@ -3489,6 +3483,7 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, /* ensure isolation mode is "none" */ card->options.isolation = ISOLATION_MODE_NONE; + rc = -EPERM; break; } default: @@ -3502,11 +3497,12 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, /* ensure isolation mode is "none" */ card->options.isolation = ISOLATION_MODE_NONE; + rc = 0; break; } } qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); - return 0; + return rc; } static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, @@ -3748,10 +3744,15 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) /* skip 4 bytes (data_len struct member) to get req_len */ if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int))) return -EFAULT; - ureq = memdup_user(udata, req_len + sizeof(struct qeth_snmp_ureq_hdr)); - if (IS_ERR(ureq)) { + ureq = kmalloc(req_len+sizeof(struct qeth_snmp_ureq_hdr), GFP_KERNEL); + if (!ureq) { QETH_CARD_TEXT(card, 2, "snmpnome"); - return PTR_ERR(ureq); + return -ENOMEM; + } + if (copy_from_user(ureq, udata, + req_len + sizeof(struct qeth_snmp_ureq_hdr))) { + kfree(ureq); + return -EFAULT; } qinfo.udata_len = ureq->hdr.data_len; qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL); @@ -3970,7 +3971,6 @@ int qeth_core_hardsetup_card(struct qeth_card *card) else goto retry; } - card->read_or_write_problem = 0; rc = qeth_mpc_initialize(card); if (rc) { QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); @@ -4353,18 +4353,16 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) struct qeth_card *card = dev_get_drvdata(&gdev->dev); QETH_DBF_TEXT(SETUP, 2, "removedv"); + if (card->discipline.ccwgdriver) { + card->discipline.ccwgdriver->remove(gdev); + qeth_core_free_discipline(card); + } if (card->info.type == QETH_CARD_TYPE_OSN) { qeth_core_remove_osn_attributes(&gdev->dev); } else { qeth_core_remove_device_attributes(&gdev->dev); } - - if (card->discipline.ccwgdriver) { - card->discipline.ccwgdriver->remove(gdev); - qeth_core_free_discipline(card); - } - debug_unregister(card->debug); write_lock_irqsave(&qeth_core_card_list.rwlock, flags); list_del(&card->list); diff --git a/trunk/drivers/s390/net/qeth_core_sys.c b/trunk/drivers/s390/net/qeth_core_sys.c index 42fa783a70c8..2eb022ff2610 100644 --- a/trunk/drivers/s390/net/qeth_core_sys.c +++ b/trunk/drivers/s390/net/qeth_core_sys.c @@ -411,7 +411,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, if (!card) return -EINVAL; - mutex_lock(&card->discipline_mutex); + mutex_lock(&card->conf_mutex); if (card->state != CARD_STATE_DOWN) { rc = -EPERM; goto out; @@ -433,7 +433,6 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, if (card->options.layer2 == newdis) goto out; else { - card->info.mac_bits = 0; if (card->discipline.ccwgdriver) { card->discipline.ccwgdriver->remove(card->gdev); qeth_core_free_discipline(card); @@ -446,7 +445,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, rc = card->discipline.ccwgdriver->probe(card->gdev); out: - mutex_unlock(&card->discipline_mutex); + mutex_unlock(&card->conf_mutex); return rc ? rc : count; } diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index 830d63524d61..32d07c2dcc67 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -860,6 +860,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) unregister_netdev(card->dev); card->dev = NULL; } + + qeth_l2_del_all_mc(card); return; } @@ -933,7 +935,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) enum qeth_card_states recover_flag; BUG_ON(!card); - mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); QETH_DBF_TEXT(SETUP, 2, "setonlin"); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); @@ -1011,7 +1012,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); out: mutex_unlock(&card->conf_mutex); - mutex_unlock(&card->discipline_mutex); return 0; out_remove: @@ -1025,7 +1025,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) else card->state = CARD_STATE_DOWN; mutex_unlock(&card->conf_mutex); - mutex_unlock(&card->discipline_mutex); return rc; } @@ -1041,7 +1040,6 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, int rc = 0, rc2 = 0, rc3 = 0; enum qeth_card_states recover_flag; - mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); QETH_DBF_TEXT(SETUP, 3, "setoffl"); QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); @@ -1062,7 +1060,6 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, /* let user_space know that device is offline */ kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); mutex_unlock(&card->conf_mutex); - mutex_unlock(&card->discipline_mutex); return 0; } diff --git a/trunk/drivers/s390/net/qeth_l3.h b/trunk/drivers/s390/net/qeth_l3.h index e705b27ec7dc..8447d233d0b3 100644 --- a/trunk/drivers/s390/net/qeth_l3.h +++ b/trunk/drivers/s390/net/qeth_l3.h @@ -64,6 +64,5 @@ void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions, const u8 *); int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types); int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types); -int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *); #endif /* __QETH_L3_H__ */ diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index e22ae248f613..61d348e51920 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -195,7 +195,7 @@ static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len) } } -int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, +static int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card, struct qeth_ipaddr *addr) { struct qeth_ipato_entry *ipatoe; @@ -3354,8 +3354,6 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) { struct qeth_card *card = dev_get_drvdata(&cgdev->dev); - qeth_l3_remove_device_attributes(&cgdev->dev); - qeth_set_allowed_threads(card, 0, 1); wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); @@ -3369,6 +3367,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) card->dev = NULL; } + qeth_l3_remove_device_attributes(&cgdev->dev); qeth_l3_clear_ip_list(card, 0, 0); qeth_l3_clear_ipato_list(card); return; @@ -3381,7 +3380,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) enum qeth_card_states recover_flag; BUG_ON(!card); - mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); QETH_DBF_TEXT(SETUP, 2, "setonlin"); QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); @@ -3463,7 +3461,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); out: mutex_unlock(&card->conf_mutex); - mutex_unlock(&card->discipline_mutex); return 0; out_remove: card->use_hard_stop = 1; @@ -3476,7 +3473,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) else card->state = CARD_STATE_DOWN; mutex_unlock(&card->conf_mutex); - mutex_unlock(&card->discipline_mutex); return rc; } @@ -3492,7 +3488,6 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, int rc = 0, rc2 = 0, rc3 = 0; enum qeth_card_states recover_flag; - mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); QETH_DBF_TEXT(SETUP, 3, "setoffl"); QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); @@ -3513,7 +3508,6 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, /* let user_space know that device is offline */ kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); mutex_unlock(&card->conf_mutex); - mutex_unlock(&card->discipline_mutex); return 0; } diff --git a/trunk/drivers/s390/net/qeth_l3_sys.c b/trunk/drivers/s390/net/qeth_l3_sys.c index 67cfa68dcf1b..fb5318b30e99 100644 --- a/trunk/drivers/s390/net/qeth_l3_sys.c +++ b/trunk/drivers/s390/net/qeth_l3_sys.c @@ -479,7 +479,6 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct qeth_card *card = dev_get_drvdata(dev); - struct qeth_ipaddr *tmpipa, *t; char *tmp; int rc = 0; @@ -498,21 +497,8 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, card->ipato.enabled = (card->ipato.enabled)? 0 : 1; } else if (!strcmp(tmp, "1")) { card->ipato.enabled = 1; - list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) { - if ((tmpipa->type == QETH_IP_TYPE_NORMAL) && - qeth_l3_is_addr_covered_by_ipato(card, tmpipa)) - tmpipa->set_flags |= - QETH_IPA_SETIP_TAKEOVER_FLAG; - } - } else if (!strcmp(tmp, "0")) { card->ipato.enabled = 0; - list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) { - if (tmpipa->set_flags & - QETH_IPA_SETIP_TAKEOVER_FLAG) - tmpipa->set_flags &= - ~QETH_IPA_SETIP_TAKEOVER_FLAG; - } } else rc = -EINVAL; out: diff --git a/trunk/drivers/vhost/net.c b/trunk/drivers/vhost/net.c index f11e6bb5b036..d395b59289ae 100644 --- a/trunk/drivers/vhost/net.c +++ b/trunk/drivers/vhost/net.c @@ -302,54 +302,58 @@ static void handle_rx(struct vhost_net *net) unuse_mm(net->dev.mm); } -static void handle_tx_kick(struct work_struct *work) +static void handle_tx_kick(struct vhost_work *work) { - struct vhost_virtqueue *vq; - struct vhost_net *net; - vq = container_of(work, struct vhost_virtqueue, poll.work); - net = container_of(vq->dev, struct vhost_net, dev); + struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue, + poll.work); + struct vhost_net *net = container_of(vq->dev, struct vhost_net, dev); + handle_tx(net); } -static void handle_rx_kick(struct work_struct *work) +static void handle_rx_kick(struct vhost_work *work) { - struct vhost_virtqueue *vq; - struct vhost_net *net; - vq = container_of(work, struct vhost_virtqueue, poll.work); - net = container_of(vq->dev, struct vhost_net, dev); + struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue, + poll.work); + struct vhost_net *net = container_of(vq->dev, struct vhost_net, dev); + handle_rx(net); } -static void handle_tx_net(struct work_struct *work) +static void handle_tx_net(struct vhost_work *work) { - struct vhost_net *net; - net = container_of(work, struct vhost_net, poll[VHOST_NET_VQ_TX].work); + struct vhost_net *net = container_of(work, struct vhost_net, + poll[VHOST_NET_VQ_TX].work); handle_tx(net); } -static void handle_rx_net(struct work_struct *work) +static void handle_rx_net(struct vhost_work *work) { - struct vhost_net *net; - net = container_of(work, struct vhost_net, poll[VHOST_NET_VQ_RX].work); + struct vhost_net *net = container_of(work, struct vhost_net, + poll[VHOST_NET_VQ_RX].work); handle_rx(net); } static int vhost_net_open(struct inode *inode, struct file *f) { struct vhost_net *n = kmalloc(sizeof *n, GFP_KERNEL); + struct vhost_dev *dev; int r; + if (!n) return -ENOMEM; + + dev = &n->dev; n->vqs[VHOST_NET_VQ_TX].handle_kick = handle_tx_kick; n->vqs[VHOST_NET_VQ_RX].handle_kick = handle_rx_kick; - r = vhost_dev_init(&n->dev, n->vqs, VHOST_NET_VQ_MAX); + r = vhost_dev_init(dev, n->vqs, VHOST_NET_VQ_MAX); if (r < 0) { kfree(n); return r; } - vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT); - vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN); + vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, POLLOUT, dev); + vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, POLLIN, dev); n->tx_poll_state = VHOST_NET_POLL_DISABLED; f->private_data = n; @@ -656,25 +660,13 @@ static struct miscdevice vhost_net_misc = { static int vhost_net_init(void) { - int r = vhost_init(); - if (r) - goto err_init; - r = misc_register(&vhost_net_misc); - if (r) - goto err_reg; - return 0; -err_reg: - vhost_cleanup(); -err_init: - return r; - + return misc_register(&vhost_net_misc); } module_init(vhost_net_init); static void vhost_net_exit(void) { misc_deregister(&vhost_net_misc); - vhost_cleanup(); } module_exit(vhost_net_exit); diff --git a/trunk/drivers/vhost/vhost.c b/trunk/drivers/vhost/vhost.c index 248ed2db0711..30d93c2b45b8 100644 --- a/trunk/drivers/vhost/vhost.c +++ b/trunk/drivers/vhost/vhost.c @@ -17,12 +17,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -37,8 +37,6 @@ enum { VHOST_MEMORY_F_LOG = 0x1, }; -static struct workqueue_struct *vhost_workqueue; - static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt) { @@ -52,23 +50,31 @@ static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, static int vhost_poll_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key) { - struct vhost_poll *poll; - poll = container_of(wait, struct vhost_poll, wait); + struct vhost_poll *poll = container_of(wait, struct vhost_poll, wait); + if (!((unsigned long)key & poll->mask)) return 0; - queue_work(vhost_workqueue, &poll->work); + vhost_poll_queue(poll); return 0; } /* Init poll structure */ -void vhost_poll_init(struct vhost_poll *poll, work_func_t func, - unsigned long mask) +void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, + unsigned long mask, struct vhost_dev *dev) { - INIT_WORK(&poll->work, func); + struct vhost_work *work = &poll->work; + init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup); init_poll_funcptr(&poll->table, vhost_poll_func); poll->mask = mask; + poll->dev = dev; + + INIT_LIST_HEAD(&work->node); + work->fn = fn; + init_waitqueue_head(&work->done); + work->flushing = 0; + work->queue_seq = work->done_seq = 0; } /* Start polling a file. We add ourselves to file's wait queue. The caller must @@ -92,12 +98,40 @@ void vhost_poll_stop(struct vhost_poll *poll) * locks that are also used by the callback. */ void vhost_poll_flush(struct vhost_poll *poll) { - flush_work(&poll->work); + struct vhost_work *work = &poll->work; + unsigned seq; + int left; + int flushing; + + spin_lock_irq(&poll->dev->work_lock); + seq = work->queue_seq; + work->flushing++; + spin_unlock_irq(&poll->dev->work_lock); + wait_event(work->done, ({ + spin_lock_irq(&poll->dev->work_lock); + left = seq - work->done_seq <= 0; + spin_unlock_irq(&poll->dev->work_lock); + left; + })); + spin_lock_irq(&poll->dev->work_lock); + flushing = --work->flushing; + spin_unlock_irq(&poll->dev->work_lock); + BUG_ON(flushing < 0); } void vhost_poll_queue(struct vhost_poll *poll) { - queue_work(vhost_workqueue, &poll->work); + struct vhost_dev *dev = poll->dev; + struct vhost_work *work = &poll->work; + unsigned long flags; + + spin_lock_irqsave(&dev->work_lock, flags); + if (list_empty(&work->node)) { + list_add_tail(&work->node, &dev->work_list); + work->queue_seq++; + wake_up_process(dev->worker); + } + spin_unlock_irqrestore(&dev->work_lock, flags); } static void vhost_vq_reset(struct vhost_dev *dev, @@ -125,10 +159,51 @@ static void vhost_vq_reset(struct vhost_dev *dev, vq->log_ctx = NULL; } +static int vhost_worker(void *data) +{ + struct vhost_dev *dev = data; + struct vhost_work *work = NULL; + unsigned uninitialized_var(seq); + + for (;;) { + /* mb paired w/ kthread_stop */ + set_current_state(TASK_INTERRUPTIBLE); + + spin_lock_irq(&dev->work_lock); + if (work) { + work->done_seq = seq; + if (work->flushing) + wake_up_all(&work->done); + } + + if (kthread_should_stop()) { + spin_unlock_irq(&dev->work_lock); + __set_current_state(TASK_RUNNING); + return 0; + } + if (!list_empty(&dev->work_list)) { + work = list_first_entry(&dev->work_list, + struct vhost_work, node); + list_del_init(&work->node); + seq = work->queue_seq; + } else + work = NULL; + spin_unlock_irq(&dev->work_lock); + + if (work) { + __set_current_state(TASK_RUNNING); + work->fn(work); + } else + schedule(); + + } +} + long vhost_dev_init(struct vhost_dev *dev, struct vhost_virtqueue *vqs, int nvqs) { int i; + dev->vqs = vqs; dev->nvqs = nvqs; mutex_init(&dev->mutex); @@ -136,6 +211,9 @@ long vhost_dev_init(struct vhost_dev *dev, dev->log_file = NULL; dev->memory = NULL; dev->mm = NULL; + spin_lock_init(&dev->work_lock); + INIT_LIST_HEAD(&dev->work_list); + dev->worker = NULL; for (i = 0; i < dev->nvqs; ++i) { dev->vqs[i].dev = dev; @@ -143,9 +221,9 @@ long vhost_dev_init(struct vhost_dev *dev, vhost_vq_reset(dev, dev->vqs + i); if (dev->vqs[i].handle_kick) vhost_poll_init(&dev->vqs[i].poll, - dev->vqs[i].handle_kick, - POLLIN); + dev->vqs[i].handle_kick, POLLIN, dev); } + return 0; } @@ -159,12 +237,31 @@ long vhost_dev_check_owner(struct vhost_dev *dev) /* Caller should have device mutex */ static long vhost_dev_set_owner(struct vhost_dev *dev) { + struct task_struct *worker; + int err; /* Is there an owner already? */ - if (dev->mm) - return -EBUSY; + if (dev->mm) { + err = -EBUSY; + goto err_mm; + } /* No owner, become one */ dev->mm = get_task_mm(current); + worker = kthread_create(vhost_worker, dev, "vhost-%d", current->pid); + if (IS_ERR(worker)) { + err = PTR_ERR(worker); + goto err_worker; + } + + dev->worker = worker; + wake_up_process(worker); /* avoid contributing to loadavg */ + return 0; +err_worker: + if (dev->mm) + mmput(dev->mm); + dev->mm = NULL; +err_mm: + return err; } /* Caller should have device mutex */ @@ -217,6 +314,9 @@ void vhost_dev_cleanup(struct vhost_dev *dev) if (dev->mm) mmput(dev->mm); dev->mm = NULL; + + WARN_ON(!list_empty(&dev->work_list)); + kthread_stop(dev->worker); } static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) @@ -1115,16 +1215,3 @@ void vhost_disable_notify(struct vhost_virtqueue *vq) vq_err(vq, "Failed to enable notification at %p: %d\n", &vq->used->flags, r); } - -int vhost_init(void) -{ - vhost_workqueue = create_singlethread_workqueue("vhost"); - if (!vhost_workqueue) - return -ENOMEM; - return 0; -} - -void vhost_cleanup(void) -{ - destroy_workqueue(vhost_workqueue); -} diff --git a/trunk/drivers/vhost/vhost.h b/trunk/drivers/vhost/vhost.h index 11ee13dba0f7..3693327549b3 100644 --- a/trunk/drivers/vhost/vhost.h +++ b/trunk/drivers/vhost/vhost.h @@ -5,13 +5,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include struct vhost_device; @@ -20,19 +20,31 @@ enum { VHOST_NET_MAX_SG = MAX_SKB_FRAGS + 2, }; +struct vhost_work; +typedef void (*vhost_work_fn_t)(struct vhost_work *work); + +struct vhost_work { + struct list_head node; + vhost_work_fn_t fn; + wait_queue_head_t done; + int flushing; + unsigned queue_seq; + unsigned done_seq; +}; + /* Poll a file (eventfd or socket) */ /* Note: there's nothing vhost specific about this structure. */ struct vhost_poll { poll_table table; wait_queue_head_t *wqh; wait_queue_t wait; - /* struct which will handle all actual work. */ - struct work_struct work; + struct vhost_work work; unsigned long mask; + struct vhost_dev *dev; }; -void vhost_poll_init(struct vhost_poll *poll, work_func_t func, - unsigned long mask); +void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, + unsigned long mask, struct vhost_dev *dev); void vhost_poll_start(struct vhost_poll *poll, struct file *file); void vhost_poll_stop(struct vhost_poll *poll); void vhost_poll_flush(struct vhost_poll *poll); @@ -63,7 +75,7 @@ struct vhost_virtqueue { struct vhost_poll poll; /* The routine to call when the Guest pings us, or timeout. */ - work_func_t handle_kick; + vhost_work_fn_t handle_kick; /* Last available index we saw. */ u16 last_avail_idx; @@ -86,11 +98,11 @@ struct vhost_virtqueue { struct iovec hdr[VHOST_NET_MAX_SG]; size_t hdr_size; /* We use a kind of RCU to access private pointer. - * All readers access it from workqueue, which makes it possible to - * flush the workqueue instead of synchronize_rcu. Therefore readers do + * All readers access it from worker, which makes it possible to + * flush the vhost_work instead of synchronize_rcu. Therefore readers do * not need to call rcu_read_lock/rcu_read_unlock: the beginning of - * work item execution acts instead of rcu_read_lock() and the end of - * work item execution acts instead of rcu_read_lock(). + * vhost_work execution acts instead of rcu_read_lock() and the end of + * vhost_work execution acts instead of rcu_read_lock(). * Writers use virtqueue mutex. */ void *private_data; /* Log write descriptors */ @@ -110,6 +122,9 @@ struct vhost_dev { int nvqs; struct file *log_file; struct eventfd_ctx *log_ctx; + spinlock_t work_lock; + struct list_head work_list; + struct task_struct *worker; }; long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs); @@ -136,9 +151,6 @@ bool vhost_enable_notify(struct vhost_virtqueue *); int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, unsigned int log_num, u64 len); -int vhost_init(void); -void vhost_cleanup(void); - #define vq_err(vq, fmt, ...) do { \ pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \ if ((vq)->error_ctx) \ diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index 8ea5e3374507..641640dc7ae5 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -601,11 +601,8 @@ static int ioc_settimeout(unsigned int fd, unsigned int cmd, } /* Bluetooth ioctls */ -#define HCIUARTSETPROTO _IOW('U', 200, int) -#define HCIUARTGETPROTO _IOR('U', 201, int) -#define HCIUARTGETDEVICE _IOR('U', 202, int) -#define HCIUARTSETFLAGS _IOW('U', 203, int) -#define HCIUARTGETFLAGS _IOR('U', 204, int) +#define HCIUARTSETPROTO _IOW('U', 200, int) +#define HCIUARTGETPROTO _IOR('U', 201, int) #define BNEPCONNADD _IOW('B', 200, int) #define BNEPCONNDEL _IOW('B', 201, int) @@ -1331,8 +1328,6 @@ COMPATIBLE_IOCTL(HCISETLINKPOL) COMPATIBLE_IOCTL(HCISETLINKMODE) COMPATIBLE_IOCTL(HCISETACLMTU) COMPATIBLE_IOCTL(HCISETSCOMTU) -COMPATIBLE_IOCTL(HCIBLOCKADDR) -COMPATIBLE_IOCTL(HCIUNBLOCKADDR) COMPATIBLE_IOCTL(HCIINQUIRY) COMPATIBLE_IOCTL(HCIUARTSETPROTO) COMPATIBLE_IOCTL(HCIUARTGETPROTO) diff --git a/trunk/include/linux/can/platform/flexcan.h b/trunk/include/linux/can/platform/flexcan.h deleted file mode 100644 index 72b713ab57e9..000000000000 --- a/trunk/include/linux/can/platform/flexcan.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2010 Marc Kleine-Budde - * - * This file is released under the GPLv2 - * - */ - -#ifndef __CAN_PLATFORM_FLEXCAN_H -#define __CAN_PLATFORM_FLEXCAN_H - -/** - * struct flexcan_platform_data - flex CAN controller platform data - * @transceiver_enable: - called to power on/off the transceiver - * - */ -struct flexcan_platform_data { - void (*transceiver_switch)(int enable); -}; - -#endif /* __CAN_PLATFORM_FLEXCAN_H */ diff --git a/trunk/include/linux/etherdevice.h b/trunk/include/linux/etherdevice.h index 848480bc2bf9..3d7a6687d247 100644 --- a/trunk/include/linux/etherdevice.h +++ b/trunk/include/linux/etherdevice.h @@ -126,20 +126,6 @@ static inline void random_ether_addr(u8 *addr) addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ } -/** - * dev_hw_addr_random - Create random MAC and set device flag - * @dev: pointer to net_device structure - * @addr: Pointer to a six-byte array containing the Ethernet address - * - * Generate random MAC to be used by a device and set addr_assign_type - * so the state can be read by sysfs and be used by udev. - */ -static inline void dev_hw_addr_random(struct net_device *dev, u8 *hwaddr) -{ - dev->addr_assign_type |= NET_ADDR_RANDOM; - random_ether_addr(hwaddr); -} - /** * compare_ether_addr - Compare two Ethernet addresses * @addr1: Pointer to a six-byte array containing the Ethernet address diff --git a/trunk/include/linux/if_macvlan.h b/trunk/include/linux/if_macvlan.h index 35280b302290..e24ce6ea1fa3 100644 --- a/trunk/include/linux/if_macvlan.h +++ b/trunk/include/linux/if_macvlan.h @@ -72,8 +72,6 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, } } -extern void macvlan_common_setup(struct net_device *dev); - extern int macvlan_common_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], int (*receive)(struct sk_buff *skb), diff --git a/trunk/include/linux/ks8842.h b/trunk/include/linux/ks8842.h index 14ba4452296e..da0341b8ca0a 100644 --- a/trunk/include/linux/ks8842.h +++ b/trunk/include/linux/ks8842.h @@ -25,14 +25,10 @@ * struct ks8842_platform_data - Platform data of the KS8842 network driver * @macaddr: The MAC address of the device, set to all 0:s to use the on in * the chip. - * @rx_dma_channel: The DMA channel to use for RX, -1 for none. - * @tx_dma_channel: The DMA channel to use for TX, -1 for none. * */ struct ks8842_platform_data { u8 macaddr[ETH_ALEN]; - int rx_dma_channel; - int tx_dma_channel; }; #endif diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 1bca6171b1aa..b6262898ece0 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -66,11 +66,6 @@ struct wireless_dev; #define HAVE_FREE_NETDEV /* free_netdev() */ #define HAVE_NETDEV_PRIV /* netdev_priv() */ -/* hardware address assignment types */ -#define NET_ADDR_PERM 0 /* address is permanent (default) */ -#define NET_ADDR_RANDOM 1 /* address is generated randomly */ -#define NET_ADDR_STOLEN 2 /* address is stolen from other device */ - /* Backlog congestion levels */ #define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ #define NET_RX_DROP 1 /* packet dropped */ @@ -924,7 +919,6 @@ struct net_device { /* Interface address info. */ unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ - unsigned char addr_assign_type; /* hw address assignment type */ unsigned char addr_len; /* hardware address length */ unsigned short dev_id; /* for shared network cards */ diff --git a/trunk/include/linux/netfilter/Kbuild b/trunk/include/linux/netfilter/Kbuild index edeeabdc1500..bb103f43afa0 100644 --- a/trunk/include/linux/netfilter/Kbuild +++ b/trunk/include/linux/netfilter/Kbuild @@ -3,7 +3,6 @@ header-y += nf_conntrack_tuple_common.h header-y += nfnetlink_conntrack.h header-y += nfnetlink_log.h header-y += nfnetlink_queue.h -header-y += xt_CHECKSUM.h header-y += xt_CLASSIFY.h header-y += xt_CONNMARK.h header-y += xt_CONNSECMARK.h @@ -20,19 +19,17 @@ header-y += xt_TCPMSS.h header-y += xt_TCPOPTSTRIP.h header-y += xt_TEE.h header-y += xt_TPROXY.h -header-y += xt_cluster.h header-y += xt_comment.h header-y += xt_connbytes.h header-y += xt_connlimit.h header-y += xt_connmark.h header-y += xt_conntrack.h -header-y += xt_cpu.h +header-y += xt_cluster.h header-y += xt_dccp.h header-y += xt_dscp.h header-y += xt_esp.h header-y += xt_hashlimit.h header-y += xt_iprange.h -header-y += xt_ipvs.h header-y += xt_helper.h header-y += xt_length.h header-y += xt_limit.h diff --git a/trunk/include/linux/netfilter/nfnetlink_log.h b/trunk/include/linux/netfilter/nfnetlink_log.h index ea9b8d380527..1d0b84aa1d42 100644 --- a/trunk/include/linux/netfilter/nfnetlink_log.h +++ b/trunk/include/linux/netfilter/nfnetlink_log.h @@ -89,7 +89,7 @@ enum nfulnl_attr_config { #define NFULNL_COPY_NONE 0x00 #define NFULNL_COPY_META 0x01 #define NFULNL_COPY_PACKET 0x02 -/* 0xff is reserved, don't use it for new copy modes. */ +#define NFULNL_COPY_DISABLED 0x03 #define NFULNL_CFG_F_SEQ 0x0001 #define NFULNL_CFG_F_SEQ_GLOBAL 0x0002 diff --git a/trunk/include/linux/netfilter/xt_CHECKSUM.h b/trunk/include/linux/netfilter/xt_CHECKSUM.h deleted file mode 100644 index 9a2e4661654e..000000000000 --- a/trunk/include/linux/netfilter/xt_CHECKSUM.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Header file for iptables ipt_CHECKSUM target - * - * (C) 2002 by Harald Welte - * (C) 2010 Red Hat Inc - * Author: Michael S. Tsirkin - * - * This software is distributed under GNU GPL v2, 1991 -*/ -#ifndef _XT_CHECKSUM_TARGET_H -#define _XT_CHECKSUM_TARGET_H - -#include - -#define XT_CHECKSUM_OP_FILL 0x01 /* fill in checksum in IP header */ - -struct xt_CHECKSUM_info { - __u8 operation; /* bitset of operations */ -}; - -#endif /* _XT_CHECKSUM_TARGET_H */ diff --git a/trunk/include/linux/netfilter/xt_cpu.h b/trunk/include/linux/netfilter/xt_cpu.h deleted file mode 100644 index 93c7f11d8f42..000000000000 --- a/trunk/include/linux/netfilter/xt_cpu.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _XT_CPU_H -#define _XT_CPU_H - -#include - -struct xt_cpu_info { - __u32 cpu; - __u32 invert; -}; - -#endif /*_XT_CPU_H*/ diff --git a/trunk/include/linux/netfilter/xt_ipvs.h b/trunk/include/linux/netfilter/xt_ipvs.h deleted file mode 100644 index 1167aeb7a347..000000000000 --- a/trunk/include/linux/netfilter/xt_ipvs.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _XT_IPVS_H -#define _XT_IPVS_H - -enum { - XT_IPVS_IPVS_PROPERTY = 1 << 0, /* all other options imply this one */ - XT_IPVS_PROTO = 1 << 1, - XT_IPVS_VADDR = 1 << 2, - XT_IPVS_VPORT = 1 << 3, - XT_IPVS_DIR = 1 << 4, - XT_IPVS_METHOD = 1 << 5, - XT_IPVS_VPORTCTL = 1 << 6, - XT_IPVS_MASK = (1 << 7) - 1, - XT_IPVS_ONCE_MASK = XT_IPVS_MASK & ~XT_IPVS_IPVS_PROPERTY -}; - -struct xt_ipvs_mtinfo { - union nf_inet_addr vaddr, vmask; - __be16 vport; - __u8 l4proto; - __u8 fwd_method; - __be16 vportctl; - - __u8 invert; - __u8 bitmask; -}; - -#endif /* _XT_IPVS_H */ diff --git a/trunk/include/linux/netfilter/xt_quota.h b/trunk/include/linux/netfilter/xt_quota.h index b0d28c659ab7..8dc89dfc1361 100644 --- a/trunk/include/linux/netfilter/xt_quota.h +++ b/trunk/include/linux/netfilter/xt_quota.h @@ -11,9 +11,9 @@ struct xt_quota_priv; struct xt_quota_info { u_int32_t flags; u_int32_t pad; - aligned_u64 quota; /* Used internally by the kernel */ + aligned_u64 quota; struct xt_quota_priv *master; }; diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 9ac60dabb6ff..ae66851870be 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2053,6 +2053,7 @@ #define PCI_DEVICE_ID_NX2_57711E 0x1650 #define PCI_DEVICE_ID_TIGON3_5705 0x1653 #define PCI_DEVICE_ID_TIGON3_5705_2 0x1654 +#define PCI_DEVICE_ID_TIGON3_5720 0x1658 #define PCI_DEVICE_ID_TIGON3_5721 0x1659 #define PCI_DEVICE_ID_TIGON3_5722 0x165a #define PCI_DEVICE_ID_TIGON3_5723 0x165b @@ -2066,11 +2067,13 @@ #define PCI_DEVICE_ID_TIGON3_5754M 0x1672 #define PCI_DEVICE_ID_TIGON3_5755M 0x1673 #define PCI_DEVICE_ID_TIGON3_5756 0x1674 +#define PCI_DEVICE_ID_TIGON3_5750 0x1676 #define PCI_DEVICE_ID_TIGON3_5751 0x1677 #define PCI_DEVICE_ID_TIGON3_5715 0x1678 #define PCI_DEVICE_ID_TIGON3_5715S 0x1679 #define PCI_DEVICE_ID_TIGON3_5754 0x167a #define PCI_DEVICE_ID_TIGON3_5755 0x167b +#define PCI_DEVICE_ID_TIGON3_5750M 0x167c #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e #define PCI_DEVICE_ID_TIGON3_5787F 0x167f diff --git a/trunk/include/linux/rtnetlink.h b/trunk/include/linux/rtnetlink.h index 58d44491880f..fbc8cb0d48c3 100644 --- a/trunk/include/linux/rtnetlink.h +++ b/trunk/include/linux/rtnetlink.h @@ -282,7 +282,6 @@ enum rtattr_type_t { RTA_SESSION, /* no longer used */ RTA_MP_ALGO, /* no longer used */ RTA_TABLE, - RTA_MARK, __RTA_MAX }; diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index d89876b806a0..f5aa87e1e0c8 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -202,11 +202,10 @@ struct skb_shared_info { */ atomic_t dataref; + skb_frag_t frags[MAX_SKB_FRAGS]; /* Intermediate layers must ensure that destructor_arg * remains valid until skb destructor */ void * destructor_arg; - /* must be last field, see pskb_expand_head() */ - skb_frag_t frags[MAX_SKB_FRAGS]; }; /* We divide dataref into two halves. The higher 16 bits hold references diff --git a/trunk/include/net/bluetooth/bluetooth.h b/trunk/include/net/bluetooth/bluetooth.h index 27a902d9b3a9..ff77e8f882f1 100644 --- a/trunk/include/net/bluetooth/bluetooth.h +++ b/trunk/include/net/bluetooth/bluetooth.h @@ -84,7 +84,7 @@ enum { /* BD Address */ typedef struct { __u8 b[6]; -} __packed bdaddr_t; +} __attribute__((packed)) bdaddr_t; #define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) @@ -138,7 +138,6 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock); struct bt_skb_cb { __u8 pkt_type; __u8 incoming; - __u16 expect; __u8 tx_seq; __u8 retries; __u8 sar; diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index bcbdd6d4e6dd..fc0c502d9fd1 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -100,9 +100,6 @@ enum { #define HCISETACLMTU _IOW('H', 227, int) #define HCISETSCOMTU _IOW('H', 228, int) -#define HCIBLOCKADDR _IOW('H', 230, int) -#define HCIUNBLOCKADDR _IOW('H', 231, int) - #define HCIINQUIRY _IOR('H', 240, int) /* HCI timeouts */ @@ -230,7 +227,7 @@ struct hci_cp_inquiry { __u8 lap[3]; __u8 length; __u8 num_rsp; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_INQUIRY_CANCEL 0x0402 @@ -244,81 +241,81 @@ struct hci_cp_create_conn { __u8 pscan_mode; __le16 clock_offset; __u8 role_switch; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_DISCONNECT 0x0406 struct hci_cp_disconnect { __le16 handle; __u8 reason; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_ADD_SCO 0x0407 struct hci_cp_add_sco { __le16 handle; __le16 pkt_type; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_CREATE_CONN_CANCEL 0x0408 struct hci_cp_create_conn_cancel { bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_ACCEPT_CONN_REQ 0x0409 struct hci_cp_accept_conn_req { bdaddr_t bdaddr; __u8 role; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_REJECT_CONN_REQ 0x040a struct hci_cp_reject_conn_req { bdaddr_t bdaddr; __u8 reason; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_LINK_KEY_REPLY 0x040b struct hci_cp_link_key_reply { bdaddr_t bdaddr; __u8 link_key[16]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_LINK_KEY_NEG_REPLY 0x040c struct hci_cp_link_key_neg_reply { bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_PIN_CODE_REPLY 0x040d struct hci_cp_pin_code_reply { bdaddr_t bdaddr; __u8 pin_len; __u8 pin_code[16]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_PIN_CODE_NEG_REPLY 0x040e struct hci_cp_pin_code_neg_reply { bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_CHANGE_CONN_PTYPE 0x040f struct hci_cp_change_conn_ptype { __le16 handle; __le16 pkt_type; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_AUTH_REQUESTED 0x0411 struct hci_cp_auth_requested { __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_SET_CONN_ENCRYPT 0x0413 struct hci_cp_set_conn_encrypt { __le16 handle; __u8 encrypt; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415 struct hci_cp_change_conn_link_key { __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_REMOTE_NAME_REQ 0x0419 struct hci_cp_remote_name_req { @@ -326,28 +323,28 @@ struct hci_cp_remote_name_req { __u8 pscan_rep_mode; __u8 pscan_mode; __le16 clock_offset; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a struct hci_cp_remote_name_req_cancel { bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_REMOTE_FEATURES 0x041b struct hci_cp_read_remote_features { __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c struct hci_cp_read_remote_ext_features { __le16 handle; __u8 page; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_REMOTE_VERSION 0x041d struct hci_cp_read_remote_version { __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_SETUP_SYNC_CONN 0x0428 struct hci_cp_setup_sync_conn { @@ -358,7 +355,7 @@ struct hci_cp_setup_sync_conn { __le16 voice_setting; __u8 retrans_effort; __le16 pkt_type; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429 struct hci_cp_accept_sync_conn_req { @@ -369,13 +366,13 @@ struct hci_cp_accept_sync_conn_req { __le16 content_format; __u8 retrans_effort; __le16 pkt_type; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a struct hci_cp_reject_sync_conn_req { bdaddr_t bdaddr; __u8 reason; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_SNIFF_MODE 0x0803 struct hci_cp_sniff_mode { @@ -384,59 +381,59 @@ struct hci_cp_sniff_mode { __le16 min_interval; __le16 attempt; __le16 timeout; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_EXIT_SNIFF_MODE 0x0804 struct hci_cp_exit_sniff_mode { __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_ROLE_DISCOVERY 0x0809 struct hci_cp_role_discovery { __le16 handle; -} __packed; +} __attribute__ ((packed)); struct hci_rp_role_discovery { __u8 status; __le16 handle; __u8 role; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_SWITCH_ROLE 0x080b struct hci_cp_switch_role { bdaddr_t bdaddr; __u8 role; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_LINK_POLICY 0x080c struct hci_cp_read_link_policy { __le16 handle; -} __packed; +} __attribute__ ((packed)); struct hci_rp_read_link_policy { __u8 status; __le16 handle; __le16 policy; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_WRITE_LINK_POLICY 0x080d struct hci_cp_write_link_policy { __le16 handle; __le16 policy; -} __packed; +} __attribute__ ((packed)); struct hci_rp_write_link_policy { __u8 status; __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_DEF_LINK_POLICY 0x080e struct hci_rp_read_def_link_policy { __u8 status; __le16 policy; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f struct hci_cp_write_def_link_policy { __le16 policy; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_SNIFF_SUBRATE 0x0811 struct hci_cp_sniff_subrate { @@ -444,12 +441,12 @@ struct hci_cp_sniff_subrate { __le16 max_latency; __le16 min_remote_timeout; __le16 min_local_timeout; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_SET_EVENT_MASK 0x0c01 struct hci_cp_set_event_mask { __u8 mask[8]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_RESET 0x0c03 @@ -458,7 +455,7 @@ struct hci_cp_set_event_flt { __u8 flt_type; __u8 cond_type; __u8 condition[0]; -} __packed; +} __attribute__ ((packed)); /* Filter types */ #define HCI_FLT_CLEAR_ALL 0x00 @@ -477,13 +474,13 @@ struct hci_cp_set_event_flt { #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 struct hci_cp_write_local_name { __u8 name[248]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_LOCAL_NAME 0x0c14 struct hci_rp_read_local_name { __u8 status; __u8 name[248]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_WRITE_CA_TIMEOUT 0x0c16 @@ -511,23 +508,23 @@ struct hci_rp_read_local_name { struct hci_rp_read_class_of_dev { __u8 status; __u8 dev_class[3]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_WRITE_CLASS_OF_DEV 0x0c24 struct hci_cp_write_class_of_dev { __u8 dev_class[3]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_VOICE_SETTING 0x0c25 struct hci_rp_read_voice_setting { __u8 status; __le16 voice_setting; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_WRITE_VOICE_SETTING 0x0c26 struct hci_cp_write_voice_setting { __le16 voice_setting; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_HOST_BUFFER_SIZE 0x0c33 struct hci_cp_host_buffer_size { @@ -535,18 +532,18 @@ struct hci_cp_host_buffer_size { __u8 sco_mtu; __le16 acl_max_pkt; __le16 sco_max_pkt; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_SSP_MODE 0x0c55 struct hci_rp_read_ssp_mode { __u8 status; __u8 mode; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_WRITE_SSP_MODE 0x0c56 struct hci_cp_write_ssp_mode { __u8 mode; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_LOCAL_VERSION 0x1001 struct hci_rp_read_local_version { @@ -556,19 +553,19 @@ struct hci_rp_read_local_version { __u8 lmp_ver; __le16 manufacturer; __le16 lmp_subver; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_LOCAL_COMMANDS 0x1002 struct hci_rp_read_local_commands { __u8 status; __u8 commands[64]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_LOCAL_FEATURES 0x1003 struct hci_rp_read_local_features { __u8 status; __u8 features[8]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_LOCAL_EXT_FEATURES 0x1004 struct hci_rp_read_local_ext_features { @@ -576,7 +573,7 @@ struct hci_rp_read_local_ext_features { __u8 page; __u8 max_page; __u8 features[8]; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_BUFFER_SIZE 0x1005 struct hci_rp_read_buffer_size { @@ -585,13 +582,13 @@ struct hci_rp_read_buffer_size { __u8 sco_mtu; __le16 acl_max_pkt; __le16 sco_max_pkt; -} __packed; +} __attribute__ ((packed)); #define HCI_OP_READ_BD_ADDR 0x1009 struct hci_rp_read_bd_addr { __u8 status; bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); /* ---- HCI Events ---- */ #define HCI_EV_INQUIRY_COMPLETE 0x01 @@ -604,7 +601,7 @@ struct inquiry_info { __u8 pscan_mode; __u8 dev_class[3]; __le16 clock_offset; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_CONN_COMPLETE 0x03 struct hci_ev_conn_complete { @@ -613,54 +610,54 @@ struct hci_ev_conn_complete { bdaddr_t bdaddr; __u8 link_type; __u8 encr_mode; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_CONN_REQUEST 0x04 struct hci_ev_conn_request { bdaddr_t bdaddr; __u8 dev_class[3]; __u8 link_type; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_DISCONN_COMPLETE 0x05 struct hci_ev_disconn_complete { __u8 status; __le16 handle; __u8 reason; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_AUTH_COMPLETE 0x06 struct hci_ev_auth_complete { __u8 status; __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_REMOTE_NAME 0x07 struct hci_ev_remote_name { __u8 status; bdaddr_t bdaddr; __u8 name[248]; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_ENCRYPT_CHANGE 0x08 struct hci_ev_encrypt_change { __u8 status; __le16 handle; __u8 encrypt; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09 struct hci_ev_change_link_key_complete { __u8 status; __le16 handle; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_REMOTE_FEATURES 0x0b struct hci_ev_remote_features { __u8 status; __le16 handle; __u8 features[8]; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_REMOTE_VERSION 0x0c struct hci_ev_remote_version { @@ -669,7 +666,7 @@ struct hci_ev_remote_version { __u8 lmp_ver; __le16 manufacturer; __le16 lmp_subver; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_QOS_SETUP_COMPLETE 0x0d struct hci_qos { @@ -678,38 +675,38 @@ struct hci_qos { __u32 peak_bandwidth; __u32 latency; __u32 delay_variation; -} __packed; +} __attribute__ ((packed)); struct hci_ev_qos_setup_complete { __u8 status; __le16 handle; struct hci_qos qos; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_CMD_COMPLETE 0x0e struct hci_ev_cmd_complete { __u8 ncmd; __le16 opcode; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_CMD_STATUS 0x0f struct hci_ev_cmd_status { __u8 status; __u8 ncmd; __le16 opcode; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_ROLE_CHANGE 0x12 struct hci_ev_role_change { __u8 status; bdaddr_t bdaddr; __u8 role; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_NUM_COMP_PKTS 0x13 struct hci_ev_num_comp_pkts { __u8 num_hndl; /* variable length part */ -} __packed; +} __attribute__ ((packed)); #define HCI_EV_MODE_CHANGE 0x14 struct hci_ev_mode_change { @@ -717,44 +714,44 @@ struct hci_ev_mode_change { __le16 handle; __u8 mode; __le16 interval; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_PIN_CODE_REQ 0x16 struct hci_ev_pin_code_req { bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_LINK_KEY_REQ 0x17 struct hci_ev_link_key_req { bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_LINK_KEY_NOTIFY 0x18 struct hci_ev_link_key_notify { bdaddr_t bdaddr; __u8 link_key[16]; __u8 key_type; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_CLOCK_OFFSET 0x1c struct hci_ev_clock_offset { __u8 status; __le16 handle; __le16 clock_offset; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_PKT_TYPE_CHANGE 0x1d struct hci_ev_pkt_type_change { __u8 status; __le16 handle; __le16 pkt_type; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_PSCAN_REP_MODE 0x20 struct hci_ev_pscan_rep_mode { bdaddr_t bdaddr; __u8 pscan_rep_mode; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 struct inquiry_info_with_rssi { @@ -764,7 +761,7 @@ struct inquiry_info_with_rssi { __u8 dev_class[3]; __le16 clock_offset; __s8 rssi; -} __packed; +} __attribute__ ((packed)); struct inquiry_info_with_rssi_and_pscan_mode { bdaddr_t bdaddr; __u8 pscan_rep_mode; @@ -773,7 +770,7 @@ struct inquiry_info_with_rssi_and_pscan_mode { __u8 dev_class[3]; __le16 clock_offset; __s8 rssi; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_REMOTE_EXT_FEATURES 0x23 struct hci_ev_remote_ext_features { @@ -782,7 +779,7 @@ struct hci_ev_remote_ext_features { __u8 page; __u8 max_page; __u8 features[8]; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_SYNC_CONN_COMPLETE 0x2c struct hci_ev_sync_conn_complete { @@ -795,7 +792,7 @@ struct hci_ev_sync_conn_complete { __le16 rx_pkt_len; __le16 tx_pkt_len; __u8 air_mode; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_SYNC_CONN_CHANGED 0x2d struct hci_ev_sync_conn_changed { @@ -805,7 +802,7 @@ struct hci_ev_sync_conn_changed { __u8 retrans_window; __le16 rx_pkt_len; __le16 tx_pkt_len; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_SNIFF_SUBRATE 0x2e struct hci_ev_sniff_subrate { @@ -815,7 +812,7 @@ struct hci_ev_sniff_subrate { __le16 max_rx_latency; __le16 max_remote_timeout; __le16 max_local_timeout; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f struct extended_inquiry_info { @@ -826,37 +823,37 @@ struct extended_inquiry_info { __le16 clock_offset; __s8 rssi; __u8 data[240]; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_IO_CAPA_REQUEST 0x31 struct hci_ev_io_capa_request { bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 struct hci_ev_simple_pair_complete { __u8 status; bdaddr_t bdaddr; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_REMOTE_HOST_FEATURES 0x3d struct hci_ev_remote_host_features { bdaddr_t bdaddr; __u8 features[8]; -} __packed; +} __attribute__ ((packed)); /* Internal events generated by Bluetooth stack */ #define HCI_EV_STACK_INTERNAL 0xfd struct hci_ev_stack_internal { __u16 type; __u8 data[0]; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_SI_DEVICE 0x01 struct hci_ev_si_device { __u16 event; __u16 dev_id; -} __packed; +} __attribute__ ((packed)); #define HCI_EV_SI_SECURITY 0x02 struct hci_ev_si_security { @@ -864,7 +861,7 @@ struct hci_ev_si_security { __u16 proto; __u16 subproto; __u8 incoming; -} __packed; +} __attribute__ ((packed)); /* ---- HCI Packet structures ---- */ #define HCI_COMMAND_HDR_SIZE 3 @@ -875,22 +872,22 @@ struct hci_ev_si_security { struct hci_command_hdr { __le16 opcode; /* OCF & OGF */ __u8 plen; -} __packed; +} __attribute__ ((packed)); struct hci_event_hdr { __u8 evt; __u8 plen; -} __packed; +} __attribute__ ((packed)); struct hci_acl_hdr { __le16 handle; /* Handle & Flags(PB, BC) */ __le16 dlen; -} __packed; +} __attribute__ ((packed)); struct hci_sco_hdr { __le16 handle; __u8 dlen; -} __packed; +} __attribute__ ((packed)); #ifdef __KERNEL__ #include diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index 8b28962e737e..e42f6ed5421c 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -1,6 +1,6 @@ -/* +/* BlueZ - Bluetooth protocol stack for Linux - Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. + Copyright (C) 2000-2001 Qualcomm Incorporated Written 2000,2001 by Maxim Krasnyansky @@ -12,13 +12,13 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ @@ -62,11 +62,6 @@ struct hci_conn_hash { unsigned int sco_num; }; -struct bdaddr_list { - struct list_head list; - bdaddr_t bdaddr; -}; -#define NUM_REASSEMBLY 4 struct hci_dev { struct list_head list; spinlock_t lock; @@ -123,7 +118,7 @@ struct hci_dev { struct sk_buff_head cmd_q; struct sk_buff *sent_cmd; - struct sk_buff *reassembly[NUM_REASSEMBLY]; + struct sk_buff *reassembly[3]; struct mutex req_lock; wait_queue_head_t req_wait_q; @@ -132,7 +127,6 @@ struct hci_dev { struct inquiry_cache inq_cache; struct hci_conn_hash conn_hash; - struct bdaddr_list blacklist; struct hci_dev_stats stat; @@ -256,7 +250,6 @@ enum { HCI_CONN_ENCRYPT_PEND, HCI_CONN_RSWITCH_PEND, HCI_CONN_MODE_CHANGE_PEND, - HCI_CONN_SCO_SETUP_PEND, }; static inline void hci_conn_hash_init(struct hci_dev *hdev) @@ -337,7 +330,6 @@ void hci_acl_connect(struct hci_conn *conn); void hci_acl_disconn(struct hci_conn *conn, __u8 reason); void hci_add_sco(struct hci_conn *conn, __u16 handle); void hci_setup_sync(struct hci_conn *conn, __u16 handle); -void hci_sco_setup(struct hci_conn *conn, __u8 status); struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); int hci_conn_del(struct hci_conn *conn); @@ -388,7 +380,7 @@ static inline void __hci_dev_put(struct hci_dev *d) } static inline void hci_dev_put(struct hci_dev *d) -{ +{ __hci_dev_put(d); module_put(d->owner); } @@ -432,14 +424,10 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); int hci_inquiry(void __user *arg); -struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_blacklist_clear(struct hci_dev *hdev); - void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_frame(struct sk_buff *skb); int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); -int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); int hci_register_sysfs(struct hci_dev *hdev); void hci_unregister_sysfs(struct hci_dev *hdev); diff --git a/trunk/include/net/bluetooth/l2cap.h b/trunk/include/net/bluetooth/l2cap.h index 636724b203ee..7c695bfd853c 100644 --- a/trunk/include/net/bluetooth/l2cap.h +++ b/trunk/include/net/bluetooth/l2cap.h @@ -1,8 +1,6 @@ /* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated - Copyright (C) 2009-2010 Gustavo F. Padovan - Copyright (C) 2010 Google Inc. Written 2000,2001 by Maxim Krasnyansky @@ -131,31 +129,31 @@ struct l2cap_conninfo { struct l2cap_hdr { __le16 len; __le16 cid; -} __packed; +} __attribute__ ((packed)); #define L2CAP_HDR_SIZE 4 struct l2cap_cmd_hdr { __u8 code; __u8 ident; __le16 len; -} __packed; +} __attribute__ ((packed)); #define L2CAP_CMD_HDR_SIZE 4 struct l2cap_cmd_rej { __le16 reason; -} __packed; +} __attribute__ ((packed)); struct l2cap_conn_req { __le16 psm; __le16 scid; -} __packed; +} __attribute__ ((packed)); struct l2cap_conn_rsp { __le16 dcid; __le16 scid; __le16 result; __le16 status; -} __packed; +} __attribute__ ((packed)); /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 @@ -179,14 +177,14 @@ struct l2cap_conf_req { __le16 dcid; __le16 flags; __u8 data[0]; -} __packed; +} __attribute__ ((packed)); struct l2cap_conf_rsp { __le16 scid; __le16 flags; __le16 result; __u8 data[0]; -} __packed; +} __attribute__ ((packed)); #define L2CAP_CONF_SUCCESS 0x0000 #define L2CAP_CONF_UNACCEPT 0x0001 @@ -197,7 +195,7 @@ struct l2cap_conf_opt { __u8 type; __u8 len; __u8 val[0]; -} __packed; +} __attribute__ ((packed)); #define L2CAP_CONF_OPT_SIZE 2 #define L2CAP_CONF_HINT 0x80 @@ -218,7 +216,7 @@ struct l2cap_conf_rfc { __le16 retrans_timeout; __le16 monitor_timeout; __le16 max_pdu_size; -} __packed; +} __attribute__ ((packed)); #define L2CAP_MODE_BASIC 0x00 #define L2CAP_MODE_RETRANS 0x01 @@ -229,22 +227,22 @@ struct l2cap_conf_rfc { struct l2cap_disconn_req { __le16 dcid; __le16 scid; -} __packed; +} __attribute__ ((packed)); struct l2cap_disconn_rsp { __le16 dcid; __le16 scid; -} __packed; +} __attribute__ ((packed)); struct l2cap_info_req { __le16 type; -} __packed; +} __attribute__ ((packed)); struct l2cap_info_rsp { __le16 type; __le16 result; __u8 data[0]; -} __packed; +} __attribute__ ((packed)); /* info type */ #define L2CAP_IT_CL_MTU 0x0001 @@ -289,11 +287,6 @@ struct l2cap_conn { struct l2cap_chan_list chan_list; }; -struct sock_del_list { - struct sock *sk; - struct list_head list; -}; - #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 @@ -360,6 +353,7 @@ struct l2cap_pinfo { __le16 sport; + spinlock_t send_lock; struct timer_list retrans_timer; struct timer_list monitor_timer; struct timer_list ack_timer; diff --git a/trunk/include/net/bluetooth/rfcomm.h b/trunk/include/net/bluetooth/rfcomm.h index a140847d622c..921d7b3c7f8d 100644 --- a/trunk/include/net/bluetooth/rfcomm.h +++ b/trunk/include/net/bluetooth/rfcomm.h @@ -106,19 +106,19 @@ struct rfcomm_hdr { u8 addr; u8 ctrl; u8 len; // Actual size can be 2 bytes -} __packed; +} __attribute__ ((packed)); struct rfcomm_cmd { u8 addr; u8 ctrl; u8 len; u8 fcs; -} __packed; +} __attribute__ ((packed)); struct rfcomm_mcc { u8 type; u8 len; -} __packed; +} __attribute__ ((packed)); struct rfcomm_pn { u8 dlci; @@ -128,7 +128,7 @@ struct rfcomm_pn { __le16 mtu; u8 max_retrans; u8 credits; -} __packed; +} __attribute__ ((packed)); struct rfcomm_rpn { u8 dlci; @@ -138,17 +138,17 @@ struct rfcomm_rpn { u8 xon_char; u8 xoff_char; __le16 param_mask; -} __packed; +} __attribute__ ((packed)); struct rfcomm_rls { u8 dlci; u8 status; -} __packed; +} __attribute__ ((packed)); struct rfcomm_msc { u8 dlci; u8 v24_sig; -} __packed; +} __attribute__ ((packed)); /* ---- Core structures, flags etc ---- */ diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 2fd06c60ffbb..168fe530b214 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -1416,7 +1416,7 @@ static inline struct device *wiphy_dev(struct wiphy *wiphy) * * @wiphy: The wiphy whose name to return */ -static inline const char *wiphy_name(const struct wiphy *wiphy) +static inline const char *wiphy_name(struct wiphy *wiphy) { return dev_name(&wiphy->dev); } @@ -1952,10 +1952,6 @@ int cfg80211_wext_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra); -int cfg80211_wext_siwpmksa(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra); - /* * callbacks for asynchronous cfg80211 methods, notification * functions and BSS handling helpers @@ -2420,67 +2416,4 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); -#ifdef __KERNEL__ - -/* Logging, debugging and troubleshooting/diagnostic helpers. */ - -/* wiphy_printk helpers, similar to dev_printk */ - -#define wiphy_printk(level, wiphy, format, args...) \ - printk(level "%s: " format, wiphy_name(wiphy), ##args) -#define wiphy_emerg(wiphy, format, args...) \ - wiphy_printk(KERN_EMERG, wiphy, format, ##args) -#define wiphy_alert(wiphy, format, args...) \ - wiphy_printk(KERN_ALERT, wiphy, format, ##args) -#define wiphy_crit(wiphy, format, args...) \ - wiphy_printk(KERN_CRIT, wiphy, format, ##args) -#define wiphy_err(wiphy, format, args...) \ - wiphy_printk(KERN_ERR, wiphy, format, ##args) -#define wiphy_warn(wiphy, format, args...) \ - wiphy_printk(KERN_WARNING, wiphy, format, ##args) -#define wiphy_notice(wiphy, format, args...) \ - wiphy_printk(KERN_NOTICE, wiphy, format, ##args) -#define wiphy_info(wiphy, format, args...) \ - wiphy_printk(KERN_INFO, wiphy, format, ##args) - -int wiphy_debug(const struct wiphy *wiphy, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - -#if defined(DEBUG) -#define wiphy_dbg(wiphy, format, args...) \ - wiphy_printk(KERN_DEBUG, wiphy, format, ##args) -#elif defined(CONFIG_DYNAMIC_DEBUG) -#define wiphy_dbg(wiphy, format, args...) \ - dynamic_pr_debug("%s: " format, wiphy_name(wiphy), ##args) -#else -#define wiphy_dbg(wiphy, format, args...) \ -({ \ - if (0) \ - wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ -}) -#endif - -#if defined(VERBOSE_DEBUG) -#define wiphy_vdbg wiphy_dbg -#else - -#define wiphy_vdbg(wiphy, format, args...) \ -({ \ - if (0) \ - wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ -}) -#endif - -/* - * wiphy_WARN() acts like wiphy_printk(), but with the key difference - * of using a WARN/WARN_ON to get the message out, including the - * file/line information and a backtrace. - */ -#define wiphy_WARN(wiphy, format, args...) \ - WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); - -#endif - #endif /* __NET_CFG80211_H */ diff --git a/trunk/include/net/ip_vs.h b/trunk/include/net/ip_vs.h index a4747a0f7303..fe82b1e10a29 100644 --- a/trunk/include/net/ip_vs.h +++ b/trunk/include/net/ip_vs.h @@ -632,22 +632,10 @@ extern struct ip_vs_conn *ip_vs_ct_in_get (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, const union nf_inet_addr *d_addr, __be16 d_port); -struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, - struct ip_vs_protocol *pp, - const struct ip_vs_iphdr *iph, - unsigned int proto_off, - int inverse); - extern struct ip_vs_conn *ip_vs_conn_out_get (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, const union nf_inet_addr *d_addr, __be16 d_port); -struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, - struct ip_vs_protocol *pp, - const struct ip_vs_iphdr *iph, - unsigned int proto_off, - int inverse); - /* put back the conn without restarting its timer */ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) { @@ -748,6 +736,8 @@ extern void ip_vs_app_inc_put(struct ip_vs_app *inc); extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb); extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb); +extern int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri, + char *o_buf, int o_len, char *n_buf, int n_len); extern int ip_vs_app_init(void); extern void ip_vs_app_cleanup(void); diff --git a/trunk/include/net/lib80211.h b/trunk/include/net/lib80211.h index 848cce1bb7a5..fb4e2784857d 100644 --- a/trunk/include/net/lib80211.h +++ b/trunk/include/net/lib80211.h @@ -54,6 +54,9 @@ struct lib80211_crypto_ops { /* deinitialize crypto context and free allocated private data */ void (*deinit) (void *priv); + int (*build_iv) (struct sk_buff * skb, int hdr_len, + u8 *key, int keylen, void *priv); + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return * value from decrypt_mpdu is passed as the keyidx value for * decrypt_msdu. skb must have enough head and tail room for the diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index b0787a1dea90..23e46cee06f9 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -147,8 +147,6 @@ struct ieee80211_low_level_stats { * @BSS_CHANGED_CQM: Connection quality monitor config changed * @BSS_CHANGED_IBSS: IBSS join status changed * @BSS_CHANGED_ARP_FILTER: Hardware ARP filter address list or state changed. - * @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note - * that it is only ever disabled for station mode. */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -164,7 +162,6 @@ enum ieee80211_bss_change { BSS_CHANGED_CQM = 1<<10, BSS_CHANGED_IBSS = 1<<11, BSS_CHANGED_ARP_FILTER = 1<<12, - BSS_CHANGED_QOS = 1<<13, /* when adding here, make sure to change ieee80211_reconfig */ }; @@ -194,9 +191,7 @@ enum ieee80211_bss_change { * if the hardware cannot handle this it must set the * IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag * @dtim_period: num of beacons before the next DTIM, for beaconing, - * valid in station mode only while @assoc is true and if also - * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf - * @ps_dtim_period) + * not valid in station mode (cf. hw conf ps_dtim_period) * @timestamp: beacon timestamp * @beacon_int: beacon interval * @assoc_capability: capabilities taken from assoc resp @@ -222,7 +217,6 @@ enum ieee80211_bss_change { * filter ARP queries based on the @arp_addr_list, if disabled, the * hardware must not perform any ARP filtering. Note, that the filter will * be enabled also in promiscuous mode. - * @qos: This is a QoS-enabled BSS. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -246,7 +240,6 @@ struct ieee80211_bss_conf { __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; u8 arp_addr_cnt; bool arp_filter_enabled; - bool qos; }; /** @@ -627,14 +620,15 @@ struct ieee80211_rx_status { * may turn the device off as much as possible. Typically, this flag will * be set when an interface is set UP but not associated or scanning, but * it can also be unset in that case when monitor interfaces are active. - * @IEEE80211_CONF_OFFCHANNEL: The device is currently not on its main - * operating channel. + * @IEEE80211_CONF_QOS: Enable 802.11e QoS also know as WMM (Wireless + * Multimedia). On some drivers (iwlwifi is one of know) we have + * to enable/disable QoS explicitly. */ enum ieee80211_conf_flags { IEEE80211_CONF_MONITOR = (1<<0), IEEE80211_CONF_PS = (1<<1), IEEE80211_CONF_IDLE = (1<<2), - IEEE80211_CONF_OFFCHANNEL = (1<<3), + IEEE80211_CONF_QOS = (1<<3), }; @@ -649,6 +643,7 @@ enum ieee80211_conf_flags { * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed + * @IEEE80211_CONF_CHANGE_QOS: Quality of service was enabled or disabled */ enum ieee80211_conf_changed { IEEE80211_CONF_CHANGE_SMPS = BIT(1), @@ -659,6 +654,7 @@ enum ieee80211_conf_changed { IEEE80211_CONF_CHANGE_CHANNEL = BIT(6), IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7), IEEE80211_CONF_CHANGE_IDLE = BIT(8), + IEEE80211_CONF_CHANGE_QOS = BIT(9), }; /** @@ -1029,9 +1025,6 @@ enum ieee80211_tkip_key_type { * connection quality related parameters, such as the RSSI level and * provide notifications if configured trigger levels are reached. * - * @IEEE80211_HW_NEED_DTIM_PERIOD: - * This device needs to know the DTIM period for the BSS before - * associating. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, @@ -1041,7 +1034,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE = 1<<4, IEEE80211_HW_SIGNAL_UNSPEC = 1<<5, IEEE80211_HW_SIGNAL_DBM = 1<<6, - IEEE80211_HW_NEED_DTIM_PERIOD = 1<<7, + /* use this hole */ IEEE80211_HW_SPECTRUM_MGMT = 1<<8, IEEE80211_HW_AMPDU_AGGREGATION = 1<<9, IEEE80211_HW_SUPPORTS_PS = 1<<10, diff --git a/trunk/include/net/netfilter/nf_conntrack_extend.h b/trunk/include/net/netfilter/nf_conntrack_extend.h index 0772d296dfdb..32d15bd6efa3 100644 --- a/trunk/include/net/netfilter/nf_conntrack_extend.h +++ b/trunk/include/net/netfilter/nf_conntrack_extend.h @@ -28,14 +28,9 @@ struct nf_ct_ext { char data[0]; }; -static inline bool __nf_ct_ext_exist(const struct nf_ct_ext *ext, u8 id) +static inline int nf_ct_ext_exist(const struct nf_conn *ct, u8 id) { - return !!ext->offset[id]; -} - -static inline bool nf_ct_ext_exist(const struct nf_conn *ct, u8 id) -{ - return (ct->ext && __nf_ct_ext_exist(ct->ext, id)); + return (ct->ext && ct->ext->offset[id]); } static inline void *__nf_ct_ext_find(const struct nf_conn *ct, u8 id) diff --git a/trunk/include/net/netfilter/nf_nat_protocol.h b/trunk/include/net/netfilter/nf_nat_protocol.h index df17bac46bf5..c398017ccfa3 100644 --- a/trunk/include/net/netfilter/nf_nat_protocol.h +++ b/trunk/include/net/netfilter/nf_nat_protocol.h @@ -27,9 +27,9 @@ struct nf_nat_protocol { /* Alter the per-proto part of the tuple (depending on maniptype), to give a unique tuple in the given range if - possible. Per-protocol part of tuple is initialized to the - incoming packet. */ - void (*unique_tuple)(struct nf_conntrack_tuple *tuple, + possible; return false if not. Per-protocol part of tuple + is initialized to the incoming packet. */ + bool (*unique_tuple)(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct); @@ -63,7 +63,7 @@ extern bool nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple, const union nf_conntrack_man_proto *min, const union nf_conntrack_man_proto *max); -extern void nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, +extern bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct, diff --git a/trunk/include/net/netfilter/nfnetlink_log.h b/trunk/include/net/netfilter/nfnetlink_log.h index e2dec42c2db2..b0569ff0775e 100644 --- a/trunk/include/net/netfilter/nfnetlink_log.h +++ b/trunk/include/net/netfilter/nfnetlink_log.h @@ -10,7 +10,5 @@ nfulnl_log_packet(u_int8_t pf, const struct nf_loginfo *li_user, const char *prefix); -#define NFULNL_COPY_DISABLED 0xff - #endif /* _KER_NFNETLINK_LOG_H */ diff --git a/trunk/include/net/regulatory.h b/trunk/include/net/regulatory.h index 9e103a4e91ee..f873ee37f7e4 100644 --- a/trunk/include/net/regulatory.h +++ b/trunk/include/net/regulatory.h @@ -54,6 +54,7 @@ struct regulatory_request { enum nl80211_reg_initiator initiator; char alpha2[2]; bool intersect; + u32 country_ie_checksum; enum environment_cap country_ie_env; struct list_head list; }; diff --git a/trunk/include/net/tc_act/tc_mirred.h b/trunk/include/net/tc_act/tc_mirred.h index cfe2943690ff..ceac661cdfd5 100644 --- a/trunk/include/net/tc_act/tc_mirred.h +++ b/trunk/include/net/tc_act/tc_mirred.h @@ -9,7 +9,6 @@ struct tcf_mirred { int tcfm_ifindex; int tcfm_ok_push; struct net_device *tcfm_dev; - struct list_head tcfm_list; }; #define to_mirred(pc) \ container_of(pc, struct tcf_mirred, common) diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index e24fa0873f32..b3250944cde9 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -32,7 +32,7 @@ config WANT_COMPAT_NETLINK_MESSAGES config COMPAT_NETLINK_MESSAGES def_bool y depends on COMPAT - depends on WEXT_CORE || WANT_COMPAT_NETLINK_MESSAGES + depends on WIRELESS_EXT || WANT_COMPAT_NETLINK_MESSAGES help This option makes it possible to send different netlink messages to tasks depending on whether the task is a compat task or not. To diff --git a/trunk/net/bluetooth/Kconfig b/trunk/net/bluetooth/Kconfig index ed371684c133..ee3b3049d385 100644 --- a/trunk/net/bluetooth/Kconfig +++ b/trunk/net/bluetooth/Kconfig @@ -43,6 +43,19 @@ config BT_L2CAP Say Y here to compile L2CAP support into the kernel or say M to compile it as module (l2cap). +config BT_L2CAP_EXT_FEATURES + bool "L2CAP Extended Features support (EXPERIMENTAL)" + depends on BT_L2CAP && EXPERIMENTAL + help + This option enables the L2CAP Extended Features support. These + new features include the Enhanced Retransmission and Streaming + Modes, the Frame Check Sequence (FCS), and Segmentation and + Reassembly (SAR) for L2CAP packets. They are a required for the + new Alternate MAC/PHY and the Bluetooth Medical Profile. + + You should say N unless you know what you are doing. Note that + this is in an experimental state yet. + config BT_SCO tristate "SCO links support" depends on BT diff --git a/trunk/net/bluetooth/hci_conn.c b/trunk/net/bluetooth/hci_conn.c index 0b1e460fe440..800b6b9fbbae 100644 --- a/trunk/net/bluetooth/hci_conn.c +++ b/trunk/net/bluetooth/hci_conn.c @@ -1,6 +1,6 @@ /* BlueZ - Bluetooth protocol stack for Linux - Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. + Copyright (C) 2000-2001 Qualcomm Incorporated Written 2000,2001 by Maxim Krasnyansky @@ -155,27 +155,6 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp); } -/* Device _must_ be locked */ -void hci_sco_setup(struct hci_conn *conn, __u8 status) -{ - struct hci_conn *sco = conn->link; - - BT_DBG("%p", conn); - - if (!sco) - return; - - if (!status) { - if (lmp_esco_capable(conn->hdev)) - hci_setup_sync(sco, conn->handle); - else - hci_add_sco(sco, conn->handle); - } else { - hci_proto_connect_cfm(sco, status); - hci_conn_del(sco); - } -} - static void hci_conn_timeout(unsigned long arg) { struct hci_conn *conn = (void *) arg; @@ -406,13 +385,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 acl->power_save = 1; hci_conn_enter_active_mode(acl); - if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { - /* defer SCO setup until mode change completed */ - set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend); - return sco; - } - - hci_sco_setup(acl, 0x00); + if (lmp_esco_capable(hdev)) + hci_setup_sync(sco, acl->handle); + else + hci_add_sco(sco, acl->handle); } return sco; diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 8303f1c9ef54..2f768de87011 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -562,7 +562,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) hci_dev_lock_bh(hdev); inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); - hci_blacklist_clear(hdev); hci_dev_unlock_bh(hdev); hci_notify(hdev, HCI_DEV_DOWN); @@ -914,7 +913,7 @@ int hci_register_dev(struct hci_dev *hdev) skb_queue_head_init(&hdev->cmd_q); skb_queue_head_init(&hdev->raw_q); - for (i = 0; i < NUM_REASSEMBLY; i++) + for (i = 0; i < 3; i++) hdev->reassembly[i] = NULL; init_waitqueue_head(&hdev->req_wait_q); @@ -924,8 +923,6 @@ int hci_register_dev(struct hci_dev *hdev) hci_conn_hash_init(hdev); - INIT_LIST_HEAD(&hdev->blacklist.list); - memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); atomic_set(&hdev->promisc, 0); @@ -973,7 +970,7 @@ int hci_unregister_dev(struct hci_dev *hdev) hci_dev_do_close(hdev); - for (i = 0; i < NUM_REASSEMBLY; i++) + for (i = 0; i < 3; i++) kfree_skb(hdev->reassembly[i]); hci_notify(hdev, HCI_DEV_UNREG); @@ -1033,170 +1030,89 @@ int hci_recv_frame(struct sk_buff *skb) } EXPORT_SYMBOL(hci_recv_frame); -static int hci_reassembly(struct hci_dev *hdev, int type, void *data, - int count, __u8 index, gfp_t gfp_mask) -{ - int len = 0; - int hlen = 0; - int remain = count; - struct sk_buff *skb; - struct bt_skb_cb *scb; +/* Receive packet type fragment */ +#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2]) - if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || - index >= NUM_REASSEMBLY) +int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) +{ + if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) return -EILSEQ; - skb = hdev->reassembly[index]; - - if (!skb) { - switch (type) { - case HCI_ACLDATA_PKT: - len = HCI_MAX_FRAME_SIZE; - hlen = HCI_ACL_HDR_SIZE; - break; - case HCI_EVENT_PKT: - len = HCI_MAX_EVENT_SIZE; - hlen = HCI_EVENT_HDR_SIZE; - break; - case HCI_SCODATA_PKT: - len = HCI_MAX_SCO_SIZE; - hlen = HCI_SCO_HDR_SIZE; - break; - } - - skb = bt_skb_alloc(len, gfp_mask); - if (!skb) - return -ENOMEM; - - scb = (void *) skb->cb; - scb->expect = hlen; - scb->pkt_type = type; - - skb->dev = (void *) hdev; - hdev->reassembly[index] = skb; - } - while (count) { - scb = (void *) skb->cb; - len = min(scb->expect, (__u16)count); + struct sk_buff *skb = __reassembly(hdev, type); + struct { int expect; } *scb; + int len = 0; - memcpy(skb_put(skb, len), data, len); + if (!skb) { + /* Start of the frame */ - count -= len; - data += len; - scb->expect -= len; - remain = count; + switch (type) { + case HCI_EVENT_PKT: + if (count >= HCI_EVENT_HDR_SIZE) { + struct hci_event_hdr *h = data; + len = HCI_EVENT_HDR_SIZE + h->plen; + } else + return -EILSEQ; + break; - switch (type) { - case HCI_EVENT_PKT: - if (skb->len == HCI_EVENT_HDR_SIZE) { - struct hci_event_hdr *h = hci_event_hdr(skb); - scb->expect = h->plen; - - if (skb_tailroom(skb) < scb->expect) { - kfree_skb(skb); - hdev->reassembly[index] = NULL; - return -ENOMEM; - } - } - break; + case HCI_ACLDATA_PKT: + if (count >= HCI_ACL_HDR_SIZE) { + struct hci_acl_hdr *h = data; + len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen); + } else + return -EILSEQ; + break; - case HCI_ACLDATA_PKT: - if (skb->len == HCI_ACL_HDR_SIZE) { - struct hci_acl_hdr *h = hci_acl_hdr(skb); - scb->expect = __le16_to_cpu(h->dlen); - - if (skb_tailroom(skb) < scb->expect) { - kfree_skb(skb); - hdev->reassembly[index] = NULL; - return -ENOMEM; - } + case HCI_SCODATA_PKT: + if (count >= HCI_SCO_HDR_SIZE) { + struct hci_sco_hdr *h = data; + len = HCI_SCO_HDR_SIZE + h->dlen; + } else + return -EILSEQ; + break; } - break; - case HCI_SCODATA_PKT: - if (skb->len == HCI_SCO_HDR_SIZE) { - struct hci_sco_hdr *h = hci_sco_hdr(skb); - scb->expect = h->dlen; - - if (skb_tailroom(skb) < scb->expect) { - kfree_skb(skb); - hdev->reassembly[index] = NULL; - return -ENOMEM; - } + skb = bt_skb_alloc(len, GFP_ATOMIC); + if (!skb) { + BT_ERR("%s no memory for packet", hdev->name); + return -ENOMEM; } - break; - } - - if (scb->expect == 0) { - /* Complete frame */ + skb->dev = (void *) hdev; bt_cb(skb)->pkt_type = type; - hci_recv_frame(skb); - - hdev->reassembly[index] = NULL; - return remain; - } - } - - return remain; -} - -int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) -{ - int rem = 0; - - if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) - return -EILSEQ; - - while (count) { - rem = hci_reassembly(hdev, type, data, count, - type - 1, GFP_ATOMIC); - if (rem < 0) - return rem; - data += (count - rem); - count = rem; - }; + __reassembly(hdev, type) = skb; - return rem; -} -EXPORT_SYMBOL(hci_recv_fragment); + scb = (void *) skb->cb; + scb->expect = len; + } else { + /* Continuation */ -#define STREAM_REASSEMBLY 0 + scb = (void *) skb->cb; + len = scb->expect; + } -int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) -{ - int type; - int rem = 0; + len = min(len, count); - while (count) { - struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY]; + memcpy(skb_put(skb, len), data, len); - if (!skb) { - struct { char type; } *pkt; + scb->expect -= len; - /* Start of the frame */ - pkt = data; - type = pkt->type; + if (scb->expect == 0) { + /* Complete frame */ - data++; - count--; - } else - type = bt_cb(skb)->pkt_type; + __reassembly(hdev, type) = NULL; - rem = hci_reassembly(hdev, type, data, - count, STREAM_REASSEMBLY, GFP_ATOMIC); - if (rem < 0) - return rem; + bt_cb(skb)->pkt_type = type; + hci_recv_frame(skb); + } - data += (count - rem); - count = rem; - }; + count -= len; data += len; + } - return rem; + return 0; } -EXPORT_SYMBOL(hci_recv_stream_fragment); +EXPORT_SYMBOL(hci_recv_fragment); /* ---- Interface to upper protocols ---- */ diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index bfef5bae0b3a..786b5de0bac4 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -1,6 +1,6 @@ /* BlueZ - Bluetooth protocol stack for Linux - Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. + Copyright (C) 2000-2001 Qualcomm Incorporated Written 2000,2001 by Maxim Krasnyansky @@ -584,7 +584,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) conn->out = 1; conn->link_mode |= HCI_LM_MASTER; } else - BT_ERR("No memory for new connection"); + BT_ERR("No memmory for new connection"); } } @@ -785,13 +785,9 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn) { + if (conn) clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); - if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) - hci_sco_setup(conn, status); - } - hci_dev_unlock(hdev); } @@ -812,13 +808,9 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn) { + if (conn) clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend); - if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) - hci_sco_setup(conn, status); - } - hci_dev_unlock(hdev); } @@ -923,8 +915,20 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s } else conn->state = BT_CLOSED; - if (conn->type == ACL_LINK) - hci_sco_setup(conn, ev->status); + if (conn->type == ACL_LINK) { + struct hci_conn *sco = conn->link; + if (sco) { + if (!ev->status) { + if (lmp_esco_capable(hdev)) + hci_setup_sync(sco, conn->handle); + else + hci_add_sco(sco, conn->handle); + } else { + hci_proto_connect_cfm(sco, ev->status); + hci_conn_del(sco); + } + } + } if (ev->status) { hci_proto_connect_cfm(conn, ev->status); @@ -948,7 +952,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); - if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) { + if (mask & HCI_LM_ACCEPT) { /* Connection accepted */ struct inquiry_entry *ie; struct hci_conn *conn; @@ -961,7 +965,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { - BT_ERR("No memory for new connection"); + BT_ERR("No memmory for new connection"); hci_dev_unlock(hdev); return; } @@ -1477,9 +1481,6 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb else conn->power_save = 0; } - - if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend)) - hci_sco_setup(conn, ev->status); } hci_dev_unlock(hdev); diff --git a/trunk/net/bluetooth/hci_sock.c b/trunk/net/bluetooth/hci_sock.c index 4f170a595934..38f08f6b86f6 100644 --- a/trunk/net/bluetooth/hci_sock.c +++ b/trunk/net/bluetooth/hci_sock.c @@ -165,86 +165,6 @@ static int hci_sock_release(struct socket *sock) return 0; } -struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) -{ - struct list_head *p; - struct bdaddr_list *blacklist = &hdev->blacklist; - - list_for_each(p, &blacklist->list) { - struct bdaddr_list *b; - - b = list_entry(p, struct bdaddr_list, list); - - if (bacmp(bdaddr, &b->bdaddr) == 0) - return b; - } - - return NULL; -} - -static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg) -{ - bdaddr_t bdaddr; - struct bdaddr_list *entry; - - if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) - return -EFAULT; - - if (bacmp(&bdaddr, BDADDR_ANY) == 0) - return -EBADF; - - if (hci_blacklist_lookup(hdev, &bdaddr)) - return -EEXIST; - - entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - bacpy(&entry->bdaddr, &bdaddr); - - list_add(&entry->list, &hdev->blacklist.list); - - return 0; -} - -int hci_blacklist_clear(struct hci_dev *hdev) -{ - struct list_head *p, *n; - struct bdaddr_list *blacklist = &hdev->blacklist; - - list_for_each_safe(p, n, &blacklist->list) { - struct bdaddr_list *b; - - b = list_entry(p, struct bdaddr_list, list); - - list_del(p); - kfree(b); - } - - return 0; -} - -static int hci_blacklist_del(struct hci_dev *hdev, void __user *arg) -{ - bdaddr_t bdaddr; - struct bdaddr_list *entry; - - if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) - return -EFAULT; - - if (bacmp(&bdaddr, BDADDR_ANY) == 0) - return hci_blacklist_clear(hdev); - - entry = hci_blacklist_lookup(hdev, &bdaddr); - if (!entry) - return -ENOENT; - - list_del(&entry->list); - kfree(entry); - - return 0; -} - /* Ioctls that require bound socket */ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) { @@ -274,16 +194,6 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign case HCIGETAUTHINFO: return hci_get_auth_info(hdev, (void __user *) arg); - case HCIBLOCKADDR: - if (!capable(CAP_NET_ADMIN)) - return -EACCES; - return hci_blacklist_add(hdev, (void __user *) arg); - - case HCIUNBLOCKADDR: - if (!capable(CAP_NET_ADMIN)) - return -EACCES; - return hci_blacklist_del(hdev, (void __user *) arg); - default: if (hdev->ioctl) return hdev->ioctl(hdev, cmd, arg); diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index ce44c47eeac1..463ffa4fe042 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -436,41 +436,6 @@ static const struct file_operations inquiry_cache_fops = { .release = single_release, }; -static int blacklist_show(struct seq_file *f, void *p) -{ - struct hci_dev *hdev = f->private; - struct bdaddr_list *blacklist = &hdev->blacklist; - struct list_head *l; - - hci_dev_lock_bh(hdev); - - list_for_each(l, &blacklist->list) { - struct bdaddr_list *b; - bdaddr_t bdaddr; - - b = list_entry(l, struct bdaddr_list, list); - - baswap(&bdaddr, &b->bdaddr); - - seq_printf(f, "%s\n", batostr(&bdaddr)); - } - - hci_dev_unlock_bh(hdev); - - return 0; -} - -static int blacklist_open(struct inode *inode, struct file *file) -{ - return single_open(file, blacklist_show, inode->i_private); -} - -static const struct file_operations blacklist_fops = { - .open = blacklist_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; int hci_register_sysfs(struct hci_dev *hdev) { struct device *dev = &hdev->dev; @@ -500,9 +465,6 @@ int hci_register_sysfs(struct hci_dev *hdev) debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, hdev, &inquiry_cache_fops); - debugfs_create_file("blacklist", 0444, hdev->debugfs, - hdev, &blacklist_fops); - return 0; } diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index 9ba1e8eee37c..cf3c4073a8a6 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -1,8 +1,6 @@ /* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated - Copyright (C) 2009-2010 Gustavo F. Padovan - Copyright (C) 2010 Google Inc. Written 2000,2001 by Maxim Krasnyansky @@ -55,9 +53,15 @@ #include #include -#define VERSION "2.15" +#define VERSION "2.14" -static int disable_ertm = 0; +#ifdef CONFIG_BT_L2CAP_EXT_FEATURES +static int enable_ertm = 1; +#else +static int enable_ertm = 0; +#endif +static int max_transmit = L2CAP_DEFAULT_MAX_TX; +static int tx_window = L2CAP_DEFAULT_TX_WINDOW; static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; static u8 l2cap_fixed_chan[8] = { 0x02, }; @@ -76,12 +80,9 @@ static void __l2cap_sock_close(struct sock *sk, int reason); static void l2cap_sock_close(struct sock *sk); static void l2cap_sock_kill(struct sock *sk); -static int l2cap_build_conf_req(struct sock *sk, void *data); static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, u8 ident, u16 dlen, void *data); -static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); - /* ---- L2CAP timers ---- */ static void l2cap_sock_timeout(unsigned long arg) { @@ -277,24 +278,6 @@ static void l2cap_chan_del(struct sock *sk, int err) parent->sk_data_ready(parent, 0); } else sk->sk_state_change(sk); - - skb_queue_purge(TX_QUEUE(sk)); - - if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { - struct srej_list *l, *tmp; - - del_timer(&l2cap_pi(sk)->retrans_timer); - del_timer(&l2cap_pi(sk)->monitor_timer); - del_timer(&l2cap_pi(sk)->ack_timer); - - skb_queue_purge(SREJ_QUEUE(sk)); - skb_queue_purge(BUSY_QUEUE(sk)); - - list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { - list_del(&l->list); - kfree(l); - } - } } /* Service level security */ @@ -368,12 +351,8 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) struct sk_buff *skb; struct l2cap_hdr *lh; struct l2cap_conn *conn = pi->conn; - struct sock *sk = (struct sock *)pi; int count, hlen = L2CAP_HDR_SIZE + 2; - if (sk->sk_state != BT_CONNECTED) - return; - if (pi->fcs == L2CAP_FCS_CRC16) hlen += 2; @@ -461,57 +440,24 @@ static void l2cap_do_start(struct sock *sk) } } -static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) -{ - u32 local_feat_mask = l2cap_feat_mask; - if (!disable_ertm) - local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING; - - switch (mode) { - case L2CAP_MODE_ERTM: - return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask; - case L2CAP_MODE_STREAMING: - return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask; - default: - return 0x00; - } -} - -static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) +static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk) { struct l2cap_disconn_req req; - if (!conn) - return; - - skb_queue_purge(TX_QUEUE(sk)); - - if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { - del_timer(&l2cap_pi(sk)->retrans_timer); - del_timer(&l2cap_pi(sk)->monitor_timer); - del_timer(&l2cap_pi(sk)->ack_timer); - } - req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); req.scid = cpu_to_le16(l2cap_pi(sk)->scid); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ, sizeof(req), &req); - - sk->sk_state = BT_DISCONN; - sk->sk_err = err; } /* ---- L2CAP connections ---- */ static void l2cap_conn_start(struct l2cap_conn *conn) { struct l2cap_chan_list *l = &conn->chan_list; - struct sock_del_list del, *tmp1, *tmp2; struct sock *sk; BT_DBG("conn %p", conn); - INIT_LIST_HEAD(&del.list); - read_lock(&l->lock); for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { @@ -524,38 +470,20 @@ static void l2cap_conn_start(struct l2cap_conn *conn) } if (sk->sk_state == BT_CONNECT) { - struct l2cap_conn_req req; + if (l2cap_check_security(sk) && + __l2cap_no_conn_pending(sk)) { + struct l2cap_conn_req req; + req.scid = cpu_to_le16(l2cap_pi(sk)->scid); + req.psm = l2cap_pi(sk)->psm; - if (!l2cap_check_security(sk) || - !__l2cap_no_conn_pending(sk)) { - bh_unlock_sock(sk); - continue; - } + l2cap_pi(sk)->ident = l2cap_get_ident(conn); + l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; - if (!l2cap_mode_supported(l2cap_pi(sk)->mode, - conn->feat_mask) - && l2cap_pi(sk)->conf_state & - L2CAP_CONF_STATE2_DEVICE) { - tmp1 = kzalloc(sizeof(struct sock_del_list), - GFP_ATOMIC); - tmp1->sk = sk; - list_add_tail(&tmp1->list, &del.list); - bh_unlock_sock(sk); - continue; + l2cap_send_cmd(conn, l2cap_pi(sk)->ident, + L2CAP_CONN_REQ, sizeof(req), &req); } - - req.scid = cpu_to_le16(l2cap_pi(sk)->scid); - req.psm = l2cap_pi(sk)->psm; - - l2cap_pi(sk)->ident = l2cap_get_ident(conn); - l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; - - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_REQ, sizeof(req), &req); - } else if (sk->sk_state == BT_CONNECT2) { struct l2cap_conn_rsp rsp; - char buf[128]; rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); @@ -578,31 +506,12 @@ static void l2cap_conn_start(struct l2cap_conn *conn) l2cap_send_cmd(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); - - if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT || - rsp.result != L2CAP_CR_SUCCESS) { - bh_unlock_sock(sk); - continue; - } - - l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; - l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); - l2cap_pi(sk)->num_conf_req++; } bh_unlock_sock(sk); } read_unlock(&l->lock); - - list_for_each_entry_safe(tmp1, tmp2, &del.list, list) { - bh_lock_sock(tmp1->sk); - __l2cap_sock_close(tmp1->sk, ECONNRESET); - bh_unlock_sock(tmp1->sk); - list_del(&tmp1->list); - kfree(tmp1); - } } static void l2cap_conn_ready(struct l2cap_conn *conn) @@ -831,8 +740,9 @@ static void __l2cap_sock_close(struct sock *sk, int reason) sk->sk_type == SOCK_STREAM) { struct l2cap_conn *conn = l2cap_pi(sk)->conn; + sk->sk_state = BT_DISCONN; l2cap_sock_set_timer(sk, sk->sk_sndtimeo); - l2cap_send_disconn_req(conn, sk, reason); + l2cap_send_disconn_req(conn, sk); } else l2cap_chan_del(sk, reason); break; @@ -892,7 +802,6 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) pi->imtu = l2cap_pi(parent)->imtu; pi->omtu = l2cap_pi(parent)->omtu; - pi->conf_state = l2cap_pi(parent)->conf_state; pi->mode = l2cap_pi(parent)->mode; pi->fcs = l2cap_pi(parent)->fcs; pi->max_tx = l2cap_pi(parent)->max_tx; @@ -903,15 +812,13 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) } else { pi->imtu = L2CAP_DEFAULT_MTU; pi->omtu = 0; - if (!disable_ertm && sk->sk_type == SOCK_STREAM) { + if (enable_ertm && sk->sk_type == SOCK_STREAM) pi->mode = L2CAP_MODE_ERTM; - pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; - } else { + else pi->mode = L2CAP_MODE_BASIC; - } - pi->max_tx = L2CAP_DEFAULT_MAX_TX; + pi->max_tx = max_transmit; pi->fcs = L2CAP_FCS_CRC16; - pi->tx_win = L2CAP_DEFAULT_TX_WINDOW; + pi->tx_win = tx_window; pi->sec_level = BT_SECURITY_LOW; pi->role_switch = 0; pi->force_reliable = 0; @@ -1160,7 +1067,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al break; case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: - if (!disable_ertm) + if (enable_ertm) break; /* fall through */ default: @@ -1177,7 +1084,6 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al case BT_CONNECTED: /* Already connected */ - err = -EISCONN; goto done; case BT_OPEN: @@ -1226,7 +1132,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) break; case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: - if (!disable_ertm) + if (enable_ertm) break; /* fall through */ default: @@ -1379,11 +1285,9 @@ static void l2cap_monitor_timeout(unsigned long arg) { struct sock *sk = (void *) arg; - BT_DBG("sk %p", sk); - bh_lock_sock(sk); if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { - l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED); + l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk); bh_unlock_sock(sk); return; } @@ -1399,8 +1303,6 @@ static void l2cap_retrans_timeout(unsigned long arg) { struct sock *sk = (void *) arg; - BT_DBG("sk %p", sk); - bh_lock_sock(sk); l2cap_pi(sk)->retry_count = 1; __mod_monitor_timer(); @@ -1439,7 +1341,7 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) hci_send_acl(pi->conn->hcon, skb, 0); } -static void l2cap_streaming_send(struct sock *sk) +static int l2cap_streaming_send(struct sock *sk) { struct sk_buff *skb, *tx_skb; struct l2cap_pinfo *pi = l2cap_pi(sk); @@ -1469,6 +1371,7 @@ static void l2cap_streaming_send(struct sock *sk) skb = skb_dequeue(TX_QUEUE(sk)); kfree_skb(skb); } + return 0; } static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) @@ -1492,22 +1395,15 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) if (pi->remote_max_tx && bt_cb(skb)->retries == pi->remote_max_tx) { - l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); + l2cap_send_disconn_req(pi->conn, sk); return; } tx_skb = skb_clone(skb, GFP_ATOMIC); bt_cb(skb)->retries++; control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); - - if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { - control |= L2CAP_CTRL_FINAL; - pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; - } - control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); - put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); if (pi->fcs == L2CAP_FCS_CRC16) { @@ -1525,14 +1421,15 @@ static int l2cap_ertm_send(struct sock *sk) u16 control, fcs; int nsent = 0; - if (sk->sk_state != BT_CONNECTED) - return -ENOTCONN; + if (pi->conn_state & L2CAP_CONN_WAIT_F) + return 0; - while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { + while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) && + !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) { if (pi->remote_max_tx && bt_cb(skb)->retries == pi->remote_max_tx) { - l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); + l2cap_send_disconn_req(pi->conn, sk); break; } @@ -1541,8 +1438,6 @@ static int l2cap_ertm_send(struct sock *sk) bt_cb(skb)->retries++; control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); - control &= L2CAP_CTRL_SAR; - if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { control |= L2CAP_CTRL_FINAL; pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; @@ -1583,11 +1478,16 @@ static int l2cap_retransmit_frames(struct sock *sk) struct l2cap_pinfo *pi = l2cap_pi(sk); int ret; + spin_lock_bh(&pi->send_lock); + if (!skb_queue_empty(TX_QUEUE(sk))) sk->sk_send_head = TX_QUEUE(sk)->next; pi->next_tx_seq = pi->expected_ack_seq; ret = l2cap_ertm_send(sk); + + spin_unlock_bh(&pi->send_lock); + return ret; } @@ -1595,6 +1495,7 @@ static void l2cap_send_ack(struct l2cap_pinfo *pi) { struct sock *sk = (struct sock *)pi; u16 control = 0; + int nframes; control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; @@ -1605,7 +1506,11 @@ static void l2cap_send_ack(struct l2cap_pinfo *pi) return; } - if (l2cap_ertm_send(sk) > 0) + spin_lock_bh(&pi->send_lock); + nframes = l2cap_ertm_send(sk); + spin_unlock_bh(&pi->send_lock); + + if (nframes > 0) return; control |= L2CAP_SUPER_RCV_READY; @@ -1800,8 +1705,10 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz size += buflen; } skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); + spin_lock_bh(&pi->send_lock); if (sk->sk_send_head == NULL) sk->sk_send_head = sar_queue.next; + spin_unlock_bh(&pi->send_lock); return size; } @@ -1846,7 +1753,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms case L2CAP_MODE_BASIC: /* Check outgoing MTU */ if (len > pi->omtu) { - err = -EMSGSIZE; + err = -EINVAL; goto done; } @@ -1873,9 +1780,14 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms } __skb_queue_tail(TX_QUEUE(sk), skb); + if (pi->mode == L2CAP_MODE_ERTM) + spin_lock_bh(&pi->send_lock); + if (sk->sk_send_head == NULL) sk->sk_send_head = skb; + if (pi->mode == L2CAP_MODE_ERTM) + spin_unlock_bh(&pi->send_lock); } else { /* Segment SDU into multiples PDUs */ err = l2cap_sar_segment_sdu(sk, msg, len); @@ -1884,14 +1796,11 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms } if (pi->mode == L2CAP_MODE_STREAMING) { - l2cap_streaming_send(sk); + err = l2cap_streaming_send(sk); } else { - if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && - pi->conn_state && L2CAP_CONN_WAIT_F) { - err = len; - break; - } + spin_lock_bh(&pi->send_lock); err = l2cap_ertm_send(sk); + spin_unlock_bh(&pi->send_lock); } if (err >= 0) @@ -1900,7 +1809,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms default: BT_DBG("bad state %1.1x", pi->mode); - err = -EBADFD; + err = -EINVAL; } done: @@ -1916,8 +1825,6 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { struct l2cap_conn_rsp rsp; - struct l2cap_conn *conn = l2cap_pi(sk)->conn; - u8 buf[128]; sk->sk_state = BT_CONFIG; @@ -1928,16 +1835,6 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); - if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { - release_sock(sk); - return 0; - } - - l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; - l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); - l2cap_pi(sk)->num_conf_req++; - release_sock(sk); return 0; } @@ -1974,19 +1871,13 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us break; } - if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) { - err = -EINVAL; - break; - } - l2cap_pi(sk)->mode = opts.mode; switch (l2cap_pi(sk)->mode) { case L2CAP_MODE_BASIC: - l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; break; case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: - if (!disable_ertm) + if (enable_ertm) break; /* fall through */ default: @@ -2254,10 +2145,6 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); } - - if (!err && sk->sk_err) - err = -sk->sk_err; - release_sock(sk); return err; } @@ -2478,10 +2365,25 @@ static inline void l2cap_ertm_init(struct sock *sk) __skb_queue_head_init(SREJ_QUEUE(sk)); __skb_queue_head_init(BUSY_QUEUE(sk)); + spin_lock_init(&l2cap_pi(sk)->send_lock); INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); +} - sk->sk_backlog_rcv = l2cap_ertm_data_rcv; +static int l2cap_mode_supported(__u8 mode, __u32 feat_mask) +{ + u32 local_feat_mask = l2cap_feat_mask; + if (enable_ertm) + local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING; + + switch (mode) { + case L2CAP_MODE_ERTM: + return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask; + case L2CAP_MODE_STREAMING: + return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask; + default: + return 0x00; + } } static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) @@ -2512,10 +2414,10 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) switch (pi->mode) { case L2CAP_MODE_STREAMING: case L2CAP_MODE_ERTM: - if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE) - break; - - /* fall through */ + pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; + if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask)) + l2cap_send_disconn_req(pi->conn, sk); + break; default: pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask); break; @@ -2526,14 +2428,6 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) case L2CAP_MODE_BASIC: if (pi->imtu != L2CAP_DEFAULT_MTU) l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); - - rfc.mode = L2CAP_MODE_BASIC; - rfc.txwin_size = 0; - rfc.max_transmit = 0; - rfc.retrans_timeout = 0; - rfc.monitor_timeout = 0; - rfc.max_pdu_size = 0; - break; case L2CAP_MODE_ERTM: @@ -2546,6 +2440,9 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, + sizeof(rfc), (unsigned long) &rfc); + if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) break; @@ -2566,6 +2463,9 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, + sizeof(rfc), (unsigned long) &rfc); + if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) break; @@ -2577,9 +2477,6 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) break; } - l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); - /* FIXME: Need actual value of the flush timeout */ //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); @@ -2644,21 +2541,18 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data) } } - if (pi->num_conf_rsp || pi->num_conf_req > 1) + if (pi->num_conf_rsp || pi->num_conf_req) goto done; switch (pi->mode) { case L2CAP_MODE_STREAMING: case L2CAP_MODE_ERTM: - if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) { - pi->mode = l2cap_select_mode(rfc.mode, - pi->conn->feat_mask); - break; - } - - if (pi->mode != rfc.mode) + pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; + if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask)) return -ECONNREFUSED; - + break; + default: + pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask); break; } @@ -2781,6 +2675,7 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, rfc.mode != pi->mode) return -ECONNREFUSED; + pi->mode = rfc.mode; pi->fcs = 0; l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, @@ -2789,11 +2684,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, } } - if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode) - return -ECONNREFUSED; - - pi->mode = rfc.mode; - if (*result == L2CAP_CONF_SUCCESS) { switch (rfc.mode) { case L2CAP_MODE_ERTM: @@ -2888,7 +2778,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd struct l2cap_chan_list *list = &conn->chan_list; struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; - struct sock *parent, *uninitialized_var(sk); + struct sock *sk, *parent; int result, status = L2CAP_CS_NO_INFO; u16 dcid = 0, scid = __le16_to_cpu(req->scid); @@ -2997,15 +2887,6 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd L2CAP_INFO_REQ, sizeof(info), &info); } - if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && - result == L2CAP_CR_SUCCESS) { - u8 buf[128]; - l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; - l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); - l2cap_pi(sk)->num_conf_req++; - } - return 0; } @@ -3026,11 +2907,11 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd if (scid) { sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); if (!sk) - return -EFAULT; + return 0; } else { sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); if (!sk) - return -EFAULT; + return 0; } switch (result) { @@ -3038,12 +2919,8 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd sk->sk_state = BT_CONFIG; l2cap_pi(sk)->ident = 0; l2cap_pi(sk)->dcid = dcid; - l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; - - if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) - break; - l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; + l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req); @@ -3080,14 +2957,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!sk) return -ENOENT; - if (sk->sk_state != BT_CONFIG) { - struct l2cap_cmd_rej rej; - - rej.reason = cpu_to_le16(0x0002); - l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, - sizeof(rej), &rej); + if (sk->sk_state == BT_DISCONN) goto unlock; - } /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); @@ -3113,7 +2984,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr /* Complete config. */ len = l2cap_parse_conf_req(sk, rsp); if (len < 0) { - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, sk); goto unlock; } @@ -3183,7 +3054,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr char req[64]; if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, sk); goto done; } @@ -3192,7 +3063,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr len = l2cap_parse_conf_rsp(sk, rsp->data, len, req, &result); if (len < 0) { - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, sk); goto done; } @@ -3205,9 +3076,10 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr } default: + sk->sk_state = BT_DISCONN; sk->sk_err = ECONNRESET; l2cap_sock_set_timer(sk, HZ * 5); - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, sk); goto done; } @@ -3258,6 +3130,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd sk->sk_shutdown = SHUTDOWN_MASK; + skb_queue_purge(TX_QUEUE(sk)); + + if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { + skb_queue_purge(SREJ_QUEUE(sk)); + skb_queue_purge(BUSY_QUEUE(sk)); + del_timer(&l2cap_pi(sk)->retrans_timer); + del_timer(&l2cap_pi(sk)->monitor_timer); + del_timer(&l2cap_pi(sk)->ack_timer); + } + l2cap_chan_del(sk, ECONNRESET); bh_unlock_sock(sk); @@ -3280,6 +3162,16 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd if (!sk) return 0; + skb_queue_purge(TX_QUEUE(sk)); + + if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { + skb_queue_purge(SREJ_QUEUE(sk)); + skb_queue_purge(BUSY_QUEUE(sk)); + del_timer(&l2cap_pi(sk)->retrans_timer); + del_timer(&l2cap_pi(sk)->monitor_timer); + del_timer(&l2cap_pi(sk)->ack_timer); + } + l2cap_chan_del(sk, 0); bh_unlock_sock(sk); @@ -3302,7 +3194,7 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK); rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); - if (!disable_ertm) + if (enable_ertm) feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | L2CAP_FEAT_FCS; put_unaligned_le32(feat_mask, rsp->data); @@ -3467,7 +3359,7 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb) our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); if (our_fcs != rcv_fcs) - return -EBADMSG; + return -EINVAL; } return 0; } @@ -3478,19 +3370,25 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) u16 control = 0; pi->frames_sent = 0; + pi->conn_state |= L2CAP_CONN_SEND_FBIT; control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { - control |= L2CAP_SUPER_RCV_NOT_READY; + control |= L2CAP_SUPER_RCV_NOT_READY | L2CAP_CTRL_FINAL; l2cap_send_sframe(pi, control); pi->conn_state |= L2CAP_CONN_RNR_SENT; + pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; } - if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY) - l2cap_retransmit_frames(sk); + if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0) + __mod_retrans_timer(); + pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + + spin_lock_bh(&pi->send_lock); l2cap_ertm_send(sk); + spin_unlock_bh(&pi->send_lock); if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && pi->frames_sent == 0) { @@ -3502,8 +3400,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar) { struct sk_buff *next_skb; - struct l2cap_pinfo *pi = l2cap_pi(sk); - int tx_seq_offset, next_tx_seq_offset; bt_cb(skb)->tx_seq = tx_seq; bt_cb(skb)->sar = sar; @@ -3514,20 +3410,11 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s return 0; } - tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; - if (tx_seq_offset < 0) - tx_seq_offset += 64; - do { if (bt_cb(next_skb)->tx_seq == tx_seq) return -EINVAL; - next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - - pi->buffer_seq) % 64; - if (next_tx_seq_offset < 0) - next_tx_seq_offset += 64; - - if (next_tx_seq_offset > tx_seq_offset) { + if (bt_cb(next_skb)->tx_seq > tx_seq) { __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb); return 0; } @@ -3645,51 +3532,11 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c pi->sdu = NULL; disconnect: - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, sk); kfree_skb(skb); return 0; } -static int l2cap_try_push_rx_skb(struct sock *sk) -{ - struct l2cap_pinfo *pi = l2cap_pi(sk); - struct sk_buff *skb; - u16 control; - int err; - - while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { - control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; - err = l2cap_ertm_reassembly_sdu(sk, skb, control); - if (err < 0) { - skb_queue_head(BUSY_QUEUE(sk), skb); - return -EBUSY; - } - - pi->buffer_seq = (pi->buffer_seq + 1) % 64; - } - - if (!(pi->conn_state & L2CAP_CONN_RNR_SENT)) - goto done; - - control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; - control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; - l2cap_send_sframe(pi, control); - l2cap_pi(sk)->retry_count = 1; - - del_timer(&pi->retrans_timer); - __mod_monitor_timer(); - - l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; - -done: - pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; - pi->conn_state &= ~L2CAP_CONN_RNR_SENT; - - BT_DBG("sk %p, Exit local busy", sk); - - return 0; -} - static void l2cap_busy_work(struct work_struct *work) { DECLARE_WAITQUEUE(wait, current); @@ -3698,6 +3545,7 @@ static void l2cap_busy_work(struct work_struct *work) struct sock *sk = (struct sock *)pi; int n_tries = 0, timeo = HZ/5, err; struct sk_buff *skb; + u16 control; lock_sock(sk); @@ -3707,8 +3555,8 @@ static void l2cap_busy_work(struct work_struct *work) if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { err = -EBUSY; - l2cap_send_disconn_req(pi->conn, sk, EBUSY); - break; + l2cap_send_disconn_req(pi->conn, sk); + goto done; } if (!timeo) @@ -3716,7 +3564,7 @@ static void l2cap_busy_work(struct work_struct *work) if (signal_pending(current)) { err = sock_intr_errno(timeo); - break; + goto done; } release_sock(sk); @@ -3725,12 +3573,40 @@ static void l2cap_busy_work(struct work_struct *work) err = sock_error(sk); if (err) - break; + goto done; + + while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { + control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; + err = l2cap_ertm_reassembly_sdu(sk, skb, control); + if (err < 0) { + skb_queue_head(BUSY_QUEUE(sk), skb); + break; + } + + pi->buffer_seq = (pi->buffer_seq + 1) % 64; + } - if (l2cap_try_push_rx_skb(sk) == 0) + if (!skb) break; } + if (!(pi->conn_state & L2CAP_CONN_RNR_SENT)) + goto done; + + control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; + control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; + l2cap_send_sframe(pi, control); + l2cap_pi(sk)->retry_count = 1; + + del_timer(&pi->retrans_timer); + __mod_monitor_timer(); + + l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; + +done: + pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; + pi->conn_state &= ~L2CAP_CONN_RNR_SENT; + set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); @@ -3745,9 +3621,7 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; __skb_queue_tail(BUSY_QUEUE(sk), skb); - return l2cap_try_push_rx_skb(sk); - - + return -EBUSY; } err = l2cap_ertm_reassembly_sdu(sk, skb, control); @@ -3757,8 +3631,6 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) } /* Busy Condition */ - BT_DBG("sk %p, Enter local busy", sk); - pi->conn_state |= L2CAP_CONN_LOCAL_BUSY; bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; __skb_queue_tail(BUSY_QUEUE(sk), skb); @@ -3769,8 +3641,6 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) pi->conn_state |= L2CAP_CONN_RNR_SENT; - del_timer(&pi->ack_timer); - queue_work(_busy_wq, &pi->busy_work); return err; @@ -3884,7 +3754,7 @@ static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq) l2cap_ertm_reassembly_sdu(sk, skb, control); l2cap_pi(sk)->buffer_seq_srej = (l2cap_pi(sk)->buffer_seq_srej + 1) % 64; - tx_seq = (tx_seq + 1) % 64; + tx_seq++; } } @@ -3920,11 +3790,10 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq) l2cap_send_sframe(pi, control); new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); - new->tx_seq = pi->expected_tx_seq; - pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; + new->tx_seq = pi->expected_tx_seq++; list_add_tail(&new->list, SREJ_LIST(sk)); } - pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; + pi->expected_tx_seq++; } static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) @@ -3933,12 +3802,11 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str u8 tx_seq = __get_txseq(rx_control); u8 req_seq = __get_reqseq(rx_control); u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; - int tx_seq_offset, expected_tx_seq_offset; + u8 tx_seq_offset, expected_tx_seq_offset; int num_to_ack = (pi->tx_win/6) + 1; int err = 0; - BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq, - rx_control); + BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); if (L2CAP_CTRL_FINAL & rx_control && l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { @@ -3960,7 +3828,7 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str /* invalid tx_seq */ if (tx_seq_offset >= pi->tx_win) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, sk); goto drop; } @@ -3983,7 +3851,6 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str pi->buffer_seq = pi->buffer_seq_srej; pi->conn_state &= ~L2CAP_CONN_SREJ_SENT; l2cap_send_ack(pi); - BT_DBG("sk %p, Exit SREJ_SENT", sk); } } else { struct srej_list *l; @@ -4012,8 +3879,6 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str pi->conn_state |= L2CAP_CONN_SREJ_SENT; - BT_DBG("sk %p, Enter SREJ", sk); - INIT_LIST_HEAD(SREJ_LIST(sk)); pi->buffer_seq_srej = pi->buffer_seq; @@ -4024,8 +3889,6 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str pi->conn_state |= L2CAP_CONN_SEND_PBIT; l2cap_send_srejframe(sk, tx_seq); - - del_timer(&pi->ack_timer); } return 0; @@ -4039,10 +3902,6 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str return 0; } - err = l2cap_push_rx_skb(sk, skb, rx_control); - if (err < 0) - return 0; - if (rx_control & L2CAP_CTRL_FINAL) { if (pi->conn_state & L2CAP_CONN_REJ_ACT) pi->conn_state &= ~L2CAP_CONN_REJ_ACT; @@ -4050,6 +3909,10 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str l2cap_retransmit_frames(sk); } + err = l2cap_push_rx_skb(sk, skb, rx_control); + if (err < 0) + return 0; + __mod_ack_timer(); pi->num_acked = (pi->num_acked + 1) % num_to_ack; @@ -4067,14 +3930,10 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) { struct l2cap_pinfo *pi = l2cap_pi(sk); - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), - rx_control); - pi->expected_ack_seq = __get_reqseq(rx_control); l2cap_drop_acked_frames(sk); if (rx_control & L2CAP_CTRL_POLL) { - pi->conn_state |= L2CAP_CONN_SEND_FBIT; if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && (pi->unacked_frames > 0)) @@ -4103,7 +3962,9 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { l2cap_send_ack(pi); } else { + spin_lock_bh(&pi->send_lock); l2cap_ertm_send(sk); + spin_unlock_bh(&pi->send_lock); } } } @@ -4113,8 +3974,6 @@ static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control) struct l2cap_pinfo *pi = l2cap_pi(sk); u8 tx_seq = __get_reqseq(rx_control); - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; pi->expected_ack_seq = tx_seq; @@ -4137,18 +3996,16 @@ static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control) struct l2cap_pinfo *pi = l2cap_pi(sk); u8 tx_seq = __get_reqseq(rx_control); - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; if (rx_control & L2CAP_CTRL_POLL) { pi->expected_ack_seq = tx_seq; l2cap_drop_acked_frames(sk); - - pi->conn_state |= L2CAP_CONN_SEND_FBIT; l2cap_retransmit_one_frame(sk, tx_seq); + spin_lock_bh(&pi->send_lock); l2cap_ertm_send(sk); + spin_unlock_bh(&pi->send_lock); if (pi->conn_state & L2CAP_CONN_WAIT_F) { pi->srej_save_reqseq = tx_seq; @@ -4174,15 +4031,10 @@ static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control) struct l2cap_pinfo *pi = l2cap_pi(sk); u8 tx_seq = __get_reqseq(rx_control); - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); - pi->conn_state |= L2CAP_CONN_REMOTE_BUSY; pi->expected_ack_seq = tx_seq; l2cap_drop_acked_frames(sk); - if (rx_control & L2CAP_CTRL_POLL) - pi->conn_state |= L2CAP_CONN_SEND_FBIT; - if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { del_timer(&pi->retrans_timer); if (rx_control & L2CAP_CTRL_POLL) @@ -4230,83 +4082,12 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str return 0; } -static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) -{ - struct l2cap_pinfo *pi = l2cap_pi(sk); - u16 control; - u8 req_seq; - int len, next_tx_seq_offset, req_seq_offset; - - control = get_unaligned_le16(skb->data); - skb_pull(skb, 2); - len = skb->len; - - /* - * We can just drop the corrupted I-frame here. - * Receiver will miss it and start proper recovery - * procedures and ask retransmission. - */ - if (l2cap_check_fcs(pi, skb)) - goto drop; - - if (__is_sar_start(control) && __is_iframe(control)) - len -= 2; - - if (pi->fcs == L2CAP_FCS_CRC16) - len -= 2; - - if (len > pi->mps) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); - goto drop; - } - - req_seq = __get_reqseq(control); - req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; - if (req_seq_offset < 0) - req_seq_offset += 64; - - next_tx_seq_offset = - (pi->next_tx_seq - pi->expected_ack_seq) % 64; - if (next_tx_seq_offset < 0) - next_tx_seq_offset += 64; - - /* check for invalid req-seq */ - if (req_seq_offset > next_tx_seq_offset) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); - goto drop; - } - - if (__is_iframe(control)) { - if (len < 0) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); - goto drop; - } - - l2cap_data_channel_iframe(sk, control, skb); - } else { - if (len != 0) { - BT_ERR("%d", len); - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); - goto drop; - } - - l2cap_data_channel_sframe(sk, control, skb); - } - - return 0; - -drop: - kfree_skb(skb); - return 0; -} - static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) { struct sock *sk; struct l2cap_pinfo *pi; - u16 control; - u8 tx_seq; - int len; + u16 control, len; + u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset; sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); if (!sk) { @@ -4336,11 +4117,59 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk break; case L2CAP_MODE_ERTM: - if (!sock_owned_by_user(sk)) { - l2cap_ertm_data_rcv(sk, skb); + control = get_unaligned_le16(skb->data); + skb_pull(skb, 2); + len = skb->len; + + if (__is_sar_start(control)) + len -= 2; + + if (pi->fcs == L2CAP_FCS_CRC16) + len -= 2; + + /* + * We can just drop the corrupted I-frame here. + * Receiver will miss it and start proper recovery + * procedures and ask retransmission. + */ + if (len > pi->mps) { + l2cap_send_disconn_req(pi->conn, sk); + goto drop; + } + + if (l2cap_check_fcs(pi, skb)) + goto drop; + + req_seq = __get_reqseq(control); + req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; + if (req_seq_offset < 0) + req_seq_offset += 64; + + next_tx_seq_offset = + (pi->next_tx_seq - pi->expected_ack_seq) % 64; + if (next_tx_seq_offset < 0) + next_tx_seq_offset += 64; + + /* check for invalid req-seq */ + if (req_seq_offset > next_tx_seq_offset) { + l2cap_send_disconn_req(pi->conn, sk); + goto drop; + } + + if (__is_iframe(control)) { + if (len < 4) { + l2cap_send_disconn_req(pi->conn, sk); + goto drop; + } + + l2cap_data_channel_iframe(sk, control, skb); } else { - if (sk_add_backlog(sk, skb)) + if (len != 0) { + l2cap_send_disconn_req(pi->conn, sk); goto drop; + } + + l2cap_data_channel_sframe(sk, control, skb); } goto done; @@ -4350,16 +4179,16 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk skb_pull(skb, 2); len = skb->len; - if (l2cap_check_fcs(pi, skb)) - goto drop; - if (__is_sar_start(control)) len -= 2; if (pi->fcs == L2CAP_FCS_CRC16) len -= 2; - if (len > pi->mps || len < 0 || __is_sframe(control)) + if (len > pi->mps || len < 4 || __is_sframe(control)) + goto drop; + + if (l2cap_check_fcs(pi, skb)) goto drop; tx_seq = __get_txseq(control); @@ -4459,7 +4288,7 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) struct hlist_node *node; if (type != ACL_LINK) - return -EINVAL; + return 0; BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); @@ -4492,7 +4321,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); if (hcon->type != ACL_LINK) - return -EINVAL; + return 0; if (!status) { conn = l2cap_conn_add(hcon, status); @@ -4521,7 +4350,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) BT_DBG("hcon %p reason %d", hcon, reason); if (hcon->type != ACL_LINK) - return -EINVAL; + return 0; l2cap_conn_del(hcon, bt_err(reason)); @@ -4850,8 +4679,14 @@ EXPORT_SYMBOL(l2cap_load); module_init(l2cap_init); module_exit(l2cap_exit); -module_param(disable_ertm, bool, 0644); -MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); +module_param(enable_ertm, bool, 0644); +MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode"); + +module_param(max_transmit, uint, 0644); +MODULE_PARM_DESC(max_transmit, "Max transmit value (default = 3)"); + +module_param(tx_window, uint, 0644); +MODULE_PARM_DESC(tx_window, "Transmission window size value (default = 63)"); MODULE_AUTHOR("Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index 44a623275951..43fbf6b4b4bf 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -1152,7 +1152,7 @@ int __init rfcomm_init_sockets(void) return err; } -void __exit rfcomm_cleanup_sockets(void) +void rfcomm_cleanup_sockets(void) { debugfs_remove(rfcomm_sock_debugfs); diff --git a/trunk/net/bluetooth/rfcomm/tty.c b/trunk/net/bluetooth/rfcomm/tty.c index 026205c18b78..309b6c261b25 100644 --- a/trunk/net/bluetooth/rfcomm/tty.c +++ b/trunk/net/bluetooth/rfcomm/tty.c @@ -1153,7 +1153,7 @@ static const struct tty_operations rfcomm_ops = { .tiocmset = rfcomm_tty_tiocmset, }; -int __init rfcomm_init_ttys(void) +int rfcomm_init_ttys(void) { rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); if (!rfcomm_tty_driver) @@ -1183,7 +1183,7 @@ int __init rfcomm_init_ttys(void) return 0; } -void __exit rfcomm_cleanup_ttys(void) +void rfcomm_cleanup_ttys(void) { tty_unregister_driver(rfcomm_tty_driver); put_tty_driver(rfcomm_tty_driver); diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index eb5b256ffc88..85afcdab4921 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -1728,9 +1728,13 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) int br_multicast_toggle(struct net_bridge *br, unsigned long val) { struct net_bridge_port *port; - int err = 0; + int err = -ENOENT; spin_lock(&br->multicast_lock); + if (!netif_running(br->dev)) + goto unlock; + + err = 0; if (br->multicast_disabled == !val) goto unlock; @@ -1738,9 +1742,6 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val) if (br->multicast_disabled) goto unlock; - if (!netif_running(br->dev)) - goto unlock; - if (br->mdb) { if (br->mdb->old) { err = -EEXIST; diff --git a/trunk/net/caif/cfrfml.c b/trunk/net/caif/cfrfml.c index eb1602022ac0..4b04d25b6a3f 100644 --- a/trunk/net/caif/cfrfml.c +++ b/trunk/net/caif/cfrfml.c @@ -193,7 +193,7 @@ static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt) static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) { - caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size); + caif_assert(!cfpkt_getlen(pkt) < rfml->fragment_size); /* Add info for MUX-layer to route the packet out. */ cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 5d1282df2fe3..6e1b4370781c 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1484,7 +1484,6 @@ static inline void net_timestamp_check(struct sk_buff *skb) int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) { skb_orphan(skb); - nf_reset(skb); if (!(dev->flags & IFF_UP) || (skb->len > (dev->mtu + dev->hard_header_len))) { @@ -2646,10 +2645,10 @@ static int ing_filter(struct sk_buff *skb) int result = TC_ACT_OK; struct Qdisc *q; - if (unlikely(MAX_RED_LOOP < ttl++)) { - if (net_ratelimit()) - pr_warning( "Redir loop detected Dropping packet (%d->%d)\n", - skb->skb_iif, dev->ifindex); + if (MAX_RED_LOOP < ttl++) { + printk(KERN_WARNING + "Redir loop detected Dropping packet (%d->%d)\n", + skb->skb_iif, dev->ifindex); return TC_ACT_SHOT; } diff --git a/trunk/net/core/drop_monitor.c b/trunk/net/core/drop_monitor.c index 36e603c78ce9..646ef3bc7200 100644 --- a/trunk/net/core/drop_monitor.c +++ b/trunk/net/core/drop_monitor.c @@ -347,9 +347,9 @@ static struct notifier_block dropmon_net_notifier = { static int __init init_net_drop_monitor(void) { + int cpu; + int rc, i, ret; struct per_cpu_dm_data *data; - int cpu, rc; - printk(KERN_INFO "Initalizing network drop monitor service\n"); if (sizeof(void *) > 8) { @@ -357,12 +357,21 @@ static int __init init_net_drop_monitor(void) return -ENOSPC; } - rc = genl_register_family_with_ops(&net_drop_monitor_family, - dropmon_ops, - ARRAY_SIZE(dropmon_ops)); - if (rc) { + if (genl_register_family(&net_drop_monitor_family) < 0) { printk(KERN_ERR "Could not create drop monitor netlink family\n"); - return rc; + return -EFAULT; + } + + rc = -EFAULT; + + for (i = 0; i < ARRAY_SIZE(dropmon_ops); i++) { + ret = genl_register_ops(&net_drop_monitor_family, + &dropmon_ops[i]); + if (ret) { + printk(KERN_CRIT "Failed to register operation %d\n", + dropmon_ops[i].cmd); + goto out_unreg; + } } rc = register_netdevice_notifier(&dropmon_net_notifier); diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index af4dfbadf2a0..d2b596537d41 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -95,7 +95,6 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, } NETDEVICE_SHOW(dev_id, fmt_hex); -NETDEVICE_SHOW(addr_assign_type, fmt_dec); NETDEVICE_SHOW(addr_len, fmt_dec); NETDEVICE_SHOW(iflink, fmt_dec); NETDEVICE_SHOW(ifindex, fmt_dec); @@ -296,7 +295,6 @@ static ssize_t show_ifalias(struct device *dev, } static struct device_attribute net_class_attributes[] = { - __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL), __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), __ATTR(dev_id, S_IRUGO, show_dev_id, NULL), __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 10a1ea72010d..24a19debda1b 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -1434,12 +1434,18 @@ static ssize_t pktgen_if_write(struct file *file, i += len; for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) { - int value; - - value = hex_to_bin(*v); - if (value >= 0) - *m = *m * 16 + value; - + if (*v >= '0' && *v <= '9') { + *m *= 16; + *m += *v - '0'; + } + if (*v >= 'A' && *v <= 'F') { + *m *= 16; + *m += *v - 'A' + 10; + } + if (*v >= 'a' && *v <= 'f') { + *m *= 16; + *m += *v - 'a' + 10; + } if (*v == ':') { m++; *m = 0; @@ -1470,12 +1476,18 @@ static ssize_t pktgen_if_write(struct file *file, i += len; for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) { - int value; - - value = hex_to_bin(*v); - if (value >= 0) - *m = *m * 16 + value; - + if (*v >= '0' && *v <= '9') { + *m *= 16; + *m += *v - '0'; + } + if (*v >= 'A' && *v <= 'F') { + *m *= 16; + *m += *v - 'A' + 10; + } + if (*v >= 'a' && *v <= 'f') { + *m *= 16; + *m += *v - 'a' + 10; + } if (*v == ':') { m++; *m = 0; diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 3a2513f0d0c3..76d33ca5f037 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -817,7 +817,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, memcpy(data + nhead, skb->head, skb->tail - skb->head); #endif memcpy(data + size, skb_end_pointer(skb), - offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); + sizeof(struct skb_shared_info)); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) get_page(skb_shinfo(skb)->frags[i].page); @@ -843,9 +843,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, skb->network_header += off; if (skb_mac_header_was_set(skb)) skb->mac_header += off; - /* Only adjust this if it actually is csum_start rather than csum */ - if (skb->ip_summed == CHECKSUM_PARTIAL) - skb->csum_start += nhead; + skb->csum_start += nhead; skb->cloned = 0; skb->hdr_len = 0; skb->nohdr = 0; @@ -932,8 +930,7 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, copy_skb_header(n, skb); off = newheadroom - oldheadroom; - if (n->ip_summed == CHECKSUM_PARTIAL) - n->csum_start += off; + n->csum_start += off; #ifdef NET_SKBUFF_DATA_USES_OFFSET n->transport_header += off; n->network_header += off; diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c index 6bccba31d132..16c0ba0a2728 100644 --- a/trunk/net/ipv4/netfilter/arp_tables.c +++ b/trunk/net/ipv4/netfilter/arp_tables.c @@ -283,13 +283,16 @@ unsigned int arpt_do_table(struct sk_buff *skb, arp = arp_hdr(skb); do { const struct arpt_entry_target *t; + int hdr_len; if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { e = arpt_next_entry(e); continue; } - ADD_COUNTER(e->counters, arp_hdr_len(skb->dev), 1); + hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) + + (2 * skb->dev->addr_len); + ADD_COUNTER(e->counters, hdr_len, 1); t = arpt_get_target_c(e); @@ -710,7 +713,7 @@ static void get_counters(const struct xt_table_info *t, struct arpt_entry *iter; unsigned int cpu; unsigned int i; - unsigned int curcpu = get_cpu(); + unsigned int curcpu; /* Instead of clearing (by a previous call to memset()) * the counters and using adds, we set the counters @@ -720,16 +723,14 @@ static void get_counters(const struct xt_table_info *t, * if new softirq were to run and call ipt_do_table */ local_bh_disable(); + curcpu = smp_processor_id(); + i = 0; xt_entry_foreach(iter, t->entries[curcpu], t->size) { SET_COUNTER(counters[i], iter->counters.bcnt, iter->counters.pcnt); ++i; } - local_bh_enable(); - /* Processing counters from other cpus, we can let bottom half enabled, - * (preemption is disabled) - */ for_each_possible_cpu(cpu) { if (cpu == curcpu) @@ -743,7 +744,7 @@ static void get_counters(const struct xt_table_info *t, } xt_info_wrunlock(cpu); } - put_cpu(); + local_bh_enable(); } static struct xt_counters *alloc_counters(const struct xt_table *table) diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c index c439721b165a..b38c11810c65 100644 --- a/trunk/net/ipv4/netfilter/ip_tables.c +++ b/trunk/net/ipv4/netfilter/ip_tables.c @@ -364,7 +364,7 @@ ipt_do_table(struct sk_buff *skb, goto no_match; } - ADD_COUNTER(e->counters, skb->len, 1); + ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); t = ipt_get_target(e); IP_NF_ASSERT(t->u.kernel.target); @@ -884,7 +884,7 @@ get_counters(const struct xt_table_info *t, struct ipt_entry *iter; unsigned int cpu; unsigned int i; - unsigned int curcpu = get_cpu(); + unsigned int curcpu; /* Instead of clearing (by a previous call to memset()) * the counters and using adds, we set the counters @@ -894,16 +894,14 @@ get_counters(const struct xt_table_info *t, * if new softirq were to run and call ipt_do_table */ local_bh_disable(); + curcpu = smp_processor_id(); + i = 0; xt_entry_foreach(iter, t->entries[curcpu], t->size) { SET_COUNTER(counters[i], iter->counters.bcnt, iter->counters.pcnt); ++i; } - local_bh_enable(); - /* Processing counters from other cpus, we can let bottom half enabled, - * (preemption is disabled) - */ for_each_possible_cpu(cpu) { if (cpu == curcpu) @@ -917,7 +915,7 @@ get_counters(const struct xt_table_info *t, } xt_info_wrunlock(cpu); } - put_cpu(); + local_bh_enable(); } static struct xt_counters *alloc_counters(const struct xt_table *table) diff --git a/trunk/net/ipv4/netfilter/ipt_REJECT.c b/trunk/net/ipv4/netfilter/ipt_REJECT.c index b254dafaf429..bbbd2736c549 100644 --- a/trunk/net/ipv4/netfilter/ipt_REJECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REJECT.c @@ -95,11 +95,10 @@ static void send_reset(struct sk_buff *oldskb, int hook) } tcph->rst = 1; - tcph->check = ~tcp_v4_check(sizeof(struct tcphdr), niph->saddr, - niph->daddr, 0); - nskb->ip_summed = CHECKSUM_PARTIAL; - nskb->csum_start = (unsigned char *)tcph - nskb->head; - nskb->csum_offset = offsetof(struct tcphdr, check); + tcph->check = tcp_v4_check(sizeof(struct tcphdr), + niph->saddr, niph->daddr, + csum_partial(tcph, + sizeof(struct tcphdr), 0)); addr_type = RTN_UNSPEC; if (hook != NF_INET_FORWARD @@ -116,6 +115,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) goto free_nskb; niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT); + nskb->ip_summed = CHECKSUM_NONE; /* "Never happens" */ if (nskb->len > dst_mtu(skb_dst(nskb))) diff --git a/trunk/net/ipv4/netfilter/nf_nat_core.c b/trunk/net/ipv4/netfilter/nf_nat_core.c index 8c8632d9b93c..c7719b283ada 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_core.c +++ b/trunk/net/ipv4/netfilter/nf_nat_core.c @@ -261,9 +261,14 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, rcu_read_lock(); proto = __nf_nat_proto_find(orig_tuple->dst.protonum); + /* Change protocol info to have some randomization */ + if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) { + proto->unique_tuple(tuple, range, maniptype, ct); + goto out; + } + /* Only bother mapping if it's not already in range and unique */ - if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM) && - (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) || + if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) || proto->in_range(tuple, maniptype, &range->min, &range->max)) && !nf_nat_used_tuple(tuple, ct)) goto out; @@ -435,7 +440,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, if (!skb_make_writable(skb, hdrlen + sizeof(*inside))) return 0; - inside = (void *)skb->data + hdrlen; + inside = (void *)skb->data + ip_hdrlen(skb); /* We're actually going to mangle it beyond trivial checksum adjustment, so make sure the current checksum is correct. */ @@ -465,10 +470,12 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, /* rcu_read_lock()ed by nf_hook_slow */ l4proto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol); - if (!nf_ct_get_tuple(skb, hdrlen + sizeof(struct icmphdr), - (hdrlen + + if (!nf_ct_get_tuple(skb, + ip_hdrlen(skb) + sizeof(struct icmphdr), + (ip_hdrlen(skb) + sizeof(struct icmphdr) + inside->ip.ihl * 4), - (u_int16_t)AF_INET, inside->ip.protocol, + (u_int16_t)AF_INET, + inside->ip.protocol, &inner, l3proto, l4proto)) return 0; @@ -477,13 +484,15 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, pass all hooks (locally-generated ICMP). Consider incoming packet: PREROUTING (DST manip), routing produces ICMP, goes through POSTROUTING (which must correct the DST manip). */ - if (!manip_pkt(inside->ip.protocol, skb, hdrlen + sizeof(inside->icmp), - &ct->tuplehash[!dir].tuple, !manip)) + if (!manip_pkt(inside->ip.protocol, skb, + ip_hdrlen(skb) + sizeof(inside->icmp), + &ct->tuplehash[!dir].tuple, + !manip)) return 0; if (skb->ip_summed != CHECKSUM_PARTIAL) { /* Reloading "inside" here since manip_pkt inner. */ - inside = (void *)skb->data + hdrlen; + inside = (void *)skb->data + ip_hdrlen(skb); inside->icmp.checksum = 0; inside->icmp.checksum = csum_fold(skb_checksum(skb, hdrlen, diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_common.c b/trunk/net/ipv4/netfilter/nf_nat_proto_common.c index 3e61faf23a9a..6c4f11f51446 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_common.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_common.c @@ -34,7 +34,7 @@ bool nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple, } EXPORT_SYMBOL_GPL(nf_nat_proto_in_range); -void nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, +bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct, @@ -53,7 +53,7 @@ void nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { /* If it's dst rewrite, can't change port */ if (maniptype == IP_NAT_MANIP_DST) - return; + return false; if (ntohs(*portptr) < 1024) { /* Loose convention: >> 512 is credential passing */ @@ -81,15 +81,15 @@ void nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple, else off = *rover; - for (i = 0; ; ++off) { + for (i = 0; i < range_size; i++, off++) { *portptr = htons(min + off % range_size); - if (++i != range_size && nf_nat_used_tuple(tuple, ct)) + if (nf_nat_used_tuple(tuple, ct)) continue; if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) *rover = off; - return; + return true; } - return; + return false; } EXPORT_SYMBOL_GPL(nf_nat_proto_unique_tuple); diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_dccp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_dccp.c index 570faf2667b2..22485ce306d4 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_dccp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_dccp.c @@ -22,14 +22,14 @@ static u_int16_t dccp_port_rover; -static void +static bool dccp_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { - nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, - &dccp_port_rover); + return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, + &dccp_port_rover); } static bool diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_gre.c b/trunk/net/ipv4/netfilter/nf_nat_proto_gre.c index bc8d83a31c73..d7e89201351e 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_gre.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_gre.c @@ -37,7 +37,7 @@ MODULE_AUTHOR("Harald Welte "); MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); /* generate unique tuple ... */ -static void +static bool gre_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, @@ -50,7 +50,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, /* If there is no master conntrack we are not PPTP, do not change tuples */ if (!ct->master) - return; + return false; if (maniptype == IP_NAT_MANIP_SRC) keyptr = &tuple->src.u.gre.key; @@ -68,14 +68,14 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, pr_debug("min = %u, range_size = %u\n", min, range_size); - for (i = 0; ; ++key) { + for (i = 0; i < range_size; i++, key++) { *keyptr = htons(min + key % range_size); - if (++i == range_size || !nf_nat_used_tuple(tuple, ct)) - return; + if (!nf_nat_used_tuple(tuple, ct)) + return true; } pr_debug("%p: no NAT mapping\n", ct); - return; + return false; } /* manipulate a GRE packet according to maniptype */ diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_icmp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_icmp.c index 5744c3ec847c..19a8b0b07d8e 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_icmp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_icmp.c @@ -27,7 +27,7 @@ icmp_in_range(const struct nf_conntrack_tuple *tuple, ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id); } -static void +static bool icmp_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, @@ -42,13 +42,13 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple, if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) range_size = 0xFFFF; - for (i = 0; ; ++id) { + for (i = 0; i < range_size; i++, id++) { tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) + (id % range_size)); - if (++i == range_size || !nf_nat_used_tuple(tuple, ct)) - return; + if (!nf_nat_used_tuple(tuple, ct)) + return true; } - return; + return false; } static bool diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c index 756331d42661..3fc598eeeb1a 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c @@ -16,14 +16,14 @@ static u_int16_t nf_sctp_port_rover; -static void +static bool sctp_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { - nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, - &nf_sctp_port_rover); + return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, + &nf_sctp_port_rover); } static bool diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c index aa460a595d5d..399e2cfa263b 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c @@ -20,13 +20,14 @@ static u_int16_t tcp_port_rover; -static void +static bool tcp_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { - nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, &tcp_port_rover); + return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, + &tcp_port_rover); } static bool diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c index dfe65c7e2925..9e61c79492e4 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c @@ -19,13 +19,14 @@ static u_int16_t udp_port_rover; -static void +static bool udp_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { - nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, &udp_port_rover); + return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, + &udp_port_rover); } static bool diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_udplite.c b/trunk/net/ipv4/netfilter/nf_nat_proto_udplite.c index 3cc8c8af39ef..440a229bbd87 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_udplite.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_udplite.c @@ -18,14 +18,14 @@ static u_int16_t udplite_port_rover; -static void +static bool udplite_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { - nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, - &udplite_port_rover); + return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct, + &udplite_port_rover); } static bool diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_unknown.c b/trunk/net/ipv4/netfilter/nf_nat_proto_unknown.c index a50f2bc1c732..14381c62acea 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_unknown.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_unknown.c @@ -26,14 +26,14 @@ static bool unknown_in_range(const struct nf_conntrack_tuple *tuple, return true; } -static void unknown_unique_tuple(struct nf_conntrack_tuple *tuple, +static bool unknown_unique_tuple(struct nf_conntrack_tuple *tuple, const struct nf_nat_range *range, enum nf_nat_manip_type maniptype, const struct nf_conn *ct) { /* Sorry: we can't help you; if it's not unique, we can't frob anything. */ - return; + return false; } static bool diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 3f56b6e6c6aa..562ce92de2a6 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -2878,9 +2878,6 @@ static int rt_fill_info(struct net *net, if (rtnetlink_put_metrics(skb, rt->dst.metrics) < 0) goto nla_put_failure; - if (rt->fl.mark) - NLA_PUT_BE32(skb, RTA_MARK, rt->fl.mark); - error = rt->dst.error; expires = rt->dst.expires ? rt->dst.expires - jiffies : 0; if (rt->peer) { @@ -2936,7 +2933,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void __be32 src = 0; u32 iif; int err; - int mark; struct sk_buff *skb; err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy); @@ -2964,7 +2960,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void src = tb[RTA_SRC] ? nla_get_be32(tb[RTA_SRC]) : 0; dst = tb[RTA_DST] ? nla_get_be32(tb[RTA_DST]) : 0; iif = tb[RTA_IIF] ? nla_get_u32(tb[RTA_IIF]) : 0; - mark = tb[RTA_MARK] ? nla_get_u32(tb[RTA_MARK]) : 0; if (iif) { struct net_device *dev; @@ -2977,7 +2972,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void skb->protocol = htons(ETH_P_IP); skb->dev = dev; - skb->mark = mark; local_bh_disable(); err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); local_bh_enable(); @@ -2995,7 +2989,6 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void }, }, .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, - .mark = mark, }; err = ip_route_output_key(net, &rt, &fl); } diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index ab70a3fbcafa..e81155d2f251 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -1763,10 +1763,7 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev) idev = ipv6_find_idev(dev); if (!idev) - return ERR_PTR(-ENOBUFS); - - if (idev->cnf.disable_ipv6) - return ERR_PTR(-EACCES); + return NULL; /* Add default multicast route */ addrconf_add_mroute(dev); @@ -2135,9 +2132,8 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, if (!dev) return -ENODEV; - idev = addrconf_add_dev(dev); - if (IS_ERR(idev)) - return PTR_ERR(idev); + if ((idev = addrconf_add_dev(dev)) == NULL) + return -ENOBUFS; scope = ipv6_addr_scope(pfx); @@ -2384,7 +2380,7 @@ static void addrconf_dev_config(struct net_device *dev) } idev = addrconf_add_dev(dev); - if (IS_ERR(idev)) + if (idev == NULL) return; memset(&addr, 0, sizeof(struct in6_addr)); @@ -2475,7 +2471,7 @@ static void addrconf_ip6_tnl_config(struct net_device *dev) ASSERT_RTNL(); idev = addrconf_add_dev(dev); - if (IS_ERR(idev)) { + if (!idev) { printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); return; } diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 5359ef4daac5..dc41d6d3c6c6 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -387,7 +387,9 @@ ip6t_do_table(struct sk_buff *skb, goto no_match; } - ADD_COUNTER(e->counters, skb->len, 1); + ADD_COUNTER(e->counters, + ntohs(ipv6_hdr(skb)->payload_len) + + sizeof(struct ipv6hdr), 1); t = ip6t_get_target_c(e); IP_NF_ASSERT(t->u.kernel.target); @@ -897,7 +899,7 @@ get_counters(const struct xt_table_info *t, struct ip6t_entry *iter; unsigned int cpu; unsigned int i; - unsigned int curcpu = get_cpu(); + unsigned int curcpu; /* Instead of clearing (by a previous call to memset()) * the counters and using adds, we set the counters @@ -907,16 +909,14 @@ get_counters(const struct xt_table_info *t, * if new softirq were to run and call ipt_do_table */ local_bh_disable(); + curcpu = smp_processor_id(); + i = 0; xt_entry_foreach(iter, t->entries[curcpu], t->size) { SET_COUNTER(counters[i], iter->counters.bcnt, iter->counters.pcnt); ++i; } - local_bh_enable(); - /* Processing counters from other cpus, we can let bottom half enabled, - * (preemption is disabled) - */ for_each_possible_cpu(cpu) { if (cpu == curcpu) @@ -930,7 +930,7 @@ get_counters(const struct xt_table_info *t, } xt_info_wrunlock(cpu); } - put_cpu(); + local_bh_enable(); } static struct xt_counters *alloc_counters(const struct xt_table *table) diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 098a050a20b0..9254008602d4 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -269,11 +269,6 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, * in the chain of fragments so far. We must know where to put * this fragment, right? */ - prev = fq->q.fragments_tail; - if (!prev || NFCT_FRAG6_CB(prev)->offset < offset) { - next = NULL; - goto found; - } prev = NULL; for (next = fq->q.fragments; next != NULL; next = next->next) { if (NFCT_FRAG6_CB(next)->offset >= offset) @@ -281,7 +276,6 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, prev = next; } -found: /* We found where to put this one. Check for overlap with * preceding fragment, and, if needed, align things so that * any overlaps are eliminated. @@ -347,8 +341,6 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, /* Insert this fragment in the chain of fragments. */ skb->next = next; - if (!next) - fq->q.fragments_tail = skb; if (prev) prev->next = skb; else @@ -472,7 +464,6 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) head->csum); fq->q.fragments = NULL; - fq->q.fragments_tail = NULL; /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ fp = skb_shinfo(head)->frag_list; diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 29ac8e1a509e..5e56e91c92c4 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -158,7 +158,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, if (mac_addr) { sta = sta_info_get_bss(sdata, mac_addr); if (!sta) { - ieee80211_key_free(sdata->local, key); + ieee80211_key_free(key); err = -ENOENT; goto out_unlock; } @@ -192,7 +192,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, goto out_unlock; if (sta->key) { - ieee80211_key_free(sdata->local, sta->key); + ieee80211_key_free(sta->key); WARN_ON(sta->key); ret = 0; } @@ -205,7 +205,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, goto out_unlock; } - ieee80211_key_free(sdata->local, sdata->keys[key_idx]); + ieee80211_key_free(sdata->keys[key_idx]); WARN_ON(sdata->keys[key_idx]); ret = 0; @@ -324,10 +324,15 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx) { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_sub_if_data *sdata; + + rcu_read_lock(); + sdata = IEEE80211_DEV_TO_SUB_IF(dev); ieee80211_set_default_mgmt_key(sdata, key_idx); + rcu_read_unlock(); + return 0; } @@ -627,7 +632,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta) skb->dev = sta->sdata->dev; skb->protocol = eth_type_trans(skb, sta->sdata->dev); memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx_ni(skb); + netif_rx(skb); } static void sta_apply_parameters(struct ieee80211_local *local, @@ -1149,6 +1154,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, return -EINVAL; } + /* enable WMM or activate new settings */ + local->hw.conf.flags |= IEEE80211_CONF_QOS; + drv_config(local, IEEE80211_CONF_CHANGE_QOS); + return 0; } diff --git a/trunk/net/mac80211/ht.c b/trunk/net/mac80211/ht.c index 9d101fb33861..be928ef7ef51 100644 --- a/trunk/net/mac80211/ht.c +++ b/trunk/net/mac80211/ht.c @@ -29,7 +29,7 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, memset(ht_cap, 0, sizeof(*ht_cap)); - if (!ht_cap_ie || !sband->ht_cap.ht_supported) + if (!ht_cap_ie) return; ht_cap->ht_supported = true; diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index c691780725a7..d4e84b22a66d 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -43,8 +43,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, { u16 auth_alg, auth_transaction, status_code; - lockdep_assert_held(&sdata->u.ibss.mtx); - if (len < 24 + 6) return; @@ -80,8 +78,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, u32 bss_change; u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; - lockdep_assert_held(&ifibss->mtx); - /* Reset own TSF to allow time synchronization work. */ drv_reset_tsf(local); @@ -209,8 +205,6 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, int i, j; u16 beacon_int = cbss->beacon_interval; - lockdep_assert_held(&sdata->u.ibss.mtx); - if (beacon_int < 10) beacon_int = 10; @@ -455,8 +449,6 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata) int active = 0; struct sta_info *sta; - lockdep_assert_held(&sdata->u.ibss.mtx); - rcu_read_lock(); list_for_each_entry_rcu(sta, &local->sta_list, list) { @@ -481,8 +473,6 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - lockdep_assert_held(&ifibss->mtx); - mod_timer(&ifibss->timer, round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); @@ -515,8 +505,6 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) u16 capability; int i; - lockdep_assert_held(&ifibss->mtx); - if (ifibss->fixed_bssid) { memcpy(bssid, ifibss->bssid, ETH_ALEN); } else { @@ -561,8 +549,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) int active_ibss; u16 capability; - lockdep_assert_held(&ifibss->mtx); - active_ibss = ieee80211_sta_active_ibss(sdata); #ifdef CONFIG_MAC80211_IBSS_DEBUG printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", @@ -651,8 +637,6 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *resp; u8 *pos, *end; - lockdep_assert_held(&ifibss->mtx); - if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || len < 24 + 2 || !ifibss->presp) return; @@ -756,8 +740,6 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, mgmt = (struct ieee80211_mgmt *) skb->data; fc = le16_to_cpu(mgmt->frame_control); - mutex_lock(&sdata->u.ibss.mtx); - switch (fc & IEEE80211_FCTL_STYPE) { case IEEE80211_STYPE_PROBE_REQ: ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); @@ -774,23 +756,14 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ieee80211_rx_mgmt_auth_ibss(sdata, mgmt, skb->len); break; } - - mutex_unlock(&sdata->u.ibss.mtx); } void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - mutex_lock(&ifibss->mtx); - - /* - * Work could be scheduled after scan or similar - * when we aren't even joined (or trying) with a - * network. - */ - if (!ifibss->ssid_len) - goto out; + if (!test_and_clear_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request)) + return; switch (ifibss->state) { case IEEE80211_IBSS_MLME_SEARCH: @@ -803,9 +776,15 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) WARN_ON(1); break; } +} - out: - mutex_unlock(&ifibss->mtx); +static void ieee80211_queue_ibss_work(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; + struct ieee80211_local *local = sdata->local; + + set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); + ieee80211_queue_work(&local->hw, &sdata->work); } static void ieee80211_ibss_timer(unsigned long data) @@ -820,7 +799,7 @@ static void ieee80211_ibss_timer(unsigned long data) return; } - ieee80211_queue_work(&local->hw, &sdata->work); + ieee80211_queue_ibss_work(sdata); } #ifdef CONFIG_PM @@ -849,7 +828,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) setup_timer(&ifibss->timer, ieee80211_ibss_timer, (unsigned long) sdata); - mutex_init(&ifibss->mtx); } /* scan finished notification */ @@ -863,8 +841,10 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) continue; if (sdata->vif.type != NL80211_IFTYPE_ADHOC) continue; + if (!sdata->u.ibss.ssid_len) + continue; sdata->u.ibss.last_scan_completed = jiffies; - ieee80211_queue_work(&local->hw, &sdata->work); + ieee80211_queue_ibss_work(sdata); } mutex_unlock(&local->iflist_mtx); } @@ -874,17 +854,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, { struct sk_buff *skb; - skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + - 36 /* bitrates */ + - 34 /* SSID */ + - 3 /* DS params */ + - 4 /* IBSS params */ + - params->ie_len); - if (!skb) - return -ENOMEM; - - mutex_lock(&sdata->u.ibss.mtx); - if (params->bssid) { memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); sdata->u.ibss.fixed_bssid = true; @@ -913,19 +882,35 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.ie_len = params->ie_len; } + skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + + 36 /* bitrates */ + + 34 /* SSID */ + + 3 /* DS params */ + + 4 /* IBSS params */ + + params->ie_len); + if (!skb) + return -ENOMEM; + sdata->u.ibss.skb = skb; sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; sdata->u.ibss.ibss_join_req = jiffies; memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); + + /* + * The ssid_len setting below is used to see whether + * we are active, and we need all other settings + * before that may get visible. + */ + mb(); + sdata->u.ibss.ssid_len = params->ssid_len; ieee80211_recalc_idle(sdata->local); + set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); ieee80211_queue_work(&sdata->local->hw, &sdata->work); - mutex_unlock(&sdata->u.ibss.mtx); - return 0; } @@ -936,9 +921,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) struct ieee80211_local *local = sdata->local; struct cfg80211_bss *cbss; u16 capability; - int active_ibss; - - mutex_lock(&sdata->u.ibss.mtx); + int active_ibss = 0; active_ibss = ieee80211_sta_active_ibss(sdata); @@ -960,6 +943,11 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) } } + del_timer_sync(&sdata->u.ibss.timer); + clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); + cancel_work_sync(&sdata->work); + clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); + sta_info_flush(sdata->local, sdata); /* remove beacon */ @@ -976,10 +964,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) memset(sdata->u.ibss.bssid, 0, ETH_ALEN); sdata->u.ibss.ssid_len = 0; - del_timer_sync(&sdata->u.ibss.timer); - - mutex_unlock(&sdata->u.ibss.mtx); - ieee80211_recalc_idle(sdata->local); return 0; diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 65e0ed6c2975..a3649a86a784 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -238,7 +238,6 @@ enum ieee80211_work_type { IEEE80211_WORK_ABORT, IEEE80211_WORK_DIRECT_PROBE, IEEE80211_WORK_AUTH, - IEEE80211_WORK_ASSOC_BEACON_WAIT, IEEE80211_WORK_ASSOC, IEEE80211_WORK_REMAIN_ON_CHANNEL, }; @@ -378,11 +377,14 @@ struct ieee80211_if_managed { int last_cqm_event_signal; }; +enum ieee80211_ibss_request { + IEEE80211_IBSS_REQ_RUN = 0, +}; + struct ieee80211_if_ibss { struct timer_list timer; - struct mutex mtx; - + unsigned long request; unsigned long last_scan_completed; u32 basic_rates; diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index ebbe264e2b0b..910729fc18cd 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -249,8 +249,6 @@ static int ieee80211_open(struct net_device *dev) local->fif_other_bss++; ieee80211_configure_filter(local); - - netif_carrier_on(dev); break; default: res = drv_add_interface(local, &sdata->vif); @@ -743,7 +741,7 @@ static void ieee80211_iface_work(struct work_struct *work) int len = skb->len; mutex_lock(&local->sta_mtx); - sta = sta_info_get_bss(sdata, mgmt->sa); + sta = sta_info_get(sdata, mgmt->sa); if (sta) { switch (mgmt->u.action.u.addba_req.action_code) { case WLAN_ACTION_ADDBA_REQ: @@ -784,7 +782,7 @@ static void ieee80211_iface_work(struct work_struct *work) * right, so terminate the session. */ mutex_lock(&local->sta_mtx); - sta = sta_info_get_bss(sdata, mgmt->sa); + sta = sta_info_get(sdata, mgmt->sa); if (sta) { u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; diff --git a/trunk/net/mac80211/key.c b/trunk/net/mac80211/key.c index 1b9d87ed143a..50d1cff23d8e 100644 --- a/trunk/net/mac80211/key.c +++ b/trunk/net/mac80211/key.c @@ -323,15 +323,13 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) if (!key) return; - if (key->local) - ieee80211_key_disable_hw_accel(key); + ieee80211_key_disable_hw_accel(key); if (key->conf.alg == ALG_CCMP) ieee80211_aes_key_free(key->u.ccmp.tfm); if (key->conf.alg == ALG_AES_CMAC) ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); - if (key->local) - ieee80211_debugfs_key_remove(key); + ieee80211_debugfs_key_remove(key); kfree(key); } @@ -412,12 +410,15 @@ static void __ieee80211_key_free(struct ieee80211_key *key) __ieee80211_key_destroy(key); } -void ieee80211_key_free(struct ieee80211_local *local, - struct ieee80211_key *key) +void ieee80211_key_free(struct ieee80211_key *key) { + struct ieee80211_local *local; + if (!key) return; + local = key->sdata->local; + mutex_lock(&local->key_mtx); __ieee80211_key_free(key); mutex_unlock(&local->key_mtx); diff --git a/trunk/net/mac80211/key.h b/trunk/net/mac80211/key.h index b665bbb7a471..a3849fa3fce8 100644 --- a/trunk/net/mac80211/key.h +++ b/trunk/net/mac80211/key.h @@ -135,8 +135,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, void ieee80211_key_link(struct ieee80211_key *key, struct ieee80211_sub_if_data *sdata, struct sta_info *sta); -void ieee80211_key_free(struct ieee80211_local *local, - struct ieee80211_key *key); +void ieee80211_key_free(struct ieee80211_key *key); void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index 7cc4f913a431..0e95c750ded9 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -107,15 +107,12 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) if (scan_chan) { chan = scan_chan; channel_type = NL80211_CHAN_NO_HT; - local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; } else if (local->tmp_channel) { chan = scan_chan = local->tmp_channel; channel_type = local->tmp_channel_type; - local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; } else { chan = local->oper_channel; channel_type = local->_oper_channel_type; - local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; } if (chan != local->hw.conf.channel || diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index b6c163ac22da..d1962650b254 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -698,11 +698,10 @@ void ieee80211_dynamic_ps_timer(unsigned long data) /* MLME */ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, + struct ieee80211_if_managed *ifmgd, u8 *wmm_param, size_t wmm_param_len) { struct ieee80211_tx_queue_params params; - struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; size_t left; int count; u8 *pos, uapsd_queues = 0; @@ -791,8 +790,8 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, } /* enable WMM or activate new settings */ - sdata->vif.bss_conf.qos = true; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); + local->hw.conf.flags |= IEEE80211_CONF_QOS; + drv_config(local, IEEE80211_CONF_CHANGE_QOS); } static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, @@ -870,11 +869,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ieee80211_led_assoc(local, 1); - if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) - bss_conf->dtim_period = bss->dtim_period; - else - bss_conf->dtim_period = 0; - bss_conf->assoc = 1; /* * For now just always ask the driver to update the basic rateset @@ -1331,7 +1325,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, } if (elems.wmm_param) - ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, + ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, elems.wmm_param_len); else ieee80211_set_wmm_default(sdata); @@ -1603,7 +1597,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true); - ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, + ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, elems.wmm_param_len); } @@ -1756,8 +1750,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, if (wk->sdata != sdata) continue; - if (wk->type != IEEE80211_WORK_ASSOC && - wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) + if (wk->type != IEEE80211_WORK_ASSOC) continue; if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) @@ -2037,8 +2030,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, auth_alg = WLAN_AUTH_OPEN; break; case NL80211_AUTHTYPE_SHARED_KEY: - if (IS_ERR(sdata->local->wep_tx_tfm)) - return -EOPNOTSUPP; auth_alg = WLAN_AUTH_SHARED_KEY; break; case NL80211_AUTHTYPE_FT: @@ -2092,8 +2083,6 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, struct sk_buff *skb) { struct ieee80211_mgmt *mgmt; - struct ieee80211_rx_status *rx_status; - struct ieee802_11_elems elems; u16 status; if (!skb) { @@ -2101,19 +2090,6 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, return WORK_DONE_DESTROY; } - if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) { - mutex_lock(&wk->sdata->u.mgd.mtx); - rx_status = (void *) skb->cb; - ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems); - ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status, - &elems, true); - mutex_unlock(&wk->sdata->u.mgd.mtx); - - wk->type = IEEE80211_WORK_ASSOC; - /* not really done yet */ - return WORK_DONE_REQUEUE; - } - mgmt = (void *)skb->data; status = le16_to_cpu(mgmt->u.assoc_resp.status_code); @@ -2227,14 +2203,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, if (req->prev_bssid) memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); + wk->type = IEEE80211_WORK_ASSOC; wk->chan = req->bss->channel; wk->sdata = sdata; wk->done = ieee80211_assoc_done; - if (!bss->dtim_period && - sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) - wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT; - else - wk->type = IEEE80211_WORK_ASSOC; if (req->use_mfp) { ifmgd->mfp = IEEE80211_MFP_REQUIRED; @@ -2282,8 +2254,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, if (wk->type != IEEE80211_WORK_DIRECT_PROBE && wk->type != IEEE80211_WORK_AUTH && - wk->type != IEEE80211_WORK_ASSOC && - wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) + wk->type != IEEE80211_WORK_ASSOC) continue; if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) diff --git a/trunk/net/mac80211/rc80211_minstrel.c b/trunk/net/mac80211/rc80211_minstrel.c index 778c604d7939..f65ce6dcc8e2 100644 --- a/trunk/net/mac80211/rc80211_minstrel.c +++ b/trunk/net/mac80211/rc80211_minstrel.c @@ -67,6 +67,7 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix) for (i = rix; i >= 0; i--) if (mi->r[i].rix == rix) break; + WARN_ON(i < 0); return i; } diff --git a/trunk/net/mac80211/rc80211_minstrel_ht.c b/trunk/net/mac80211/rc80211_minstrel_ht.c index c5b465904e3b..b5ace243546c 100644 --- a/trunk/net/mac80211/rc80211_minstrel_ht.c +++ b/trunk/net/mac80211/rc80211_minstrel_ht.c @@ -636,7 +636,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, int i; /* fall back to the old minstrel for legacy stations */ - if (!sta->ht_cap.ht_supported) { + if (sta && !sta->ht_cap.ht_supported) { msp->is_ht = false; memset(&msp->legacy, 0, sizeof(msp->legacy)); msp->legacy.r = msp->ratelist; @@ -748,7 +748,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) return msp; error1: - kfree(msp->ratelist); + kfree(msp->sample_table); error: kfree(msp); return NULL; diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index 41f20fb7e670..439c98d93a79 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -114,10 +114,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local, bss->dtim_period = tim_ie->dtim_period; } - /* If the beacon had no TIM IE, or it was invalid, use 1 */ - if (beacon && !bss->dtim_period) - bss->dtim_period = 1; - /* replace old supported rates if we get new values */ srlen = 0; if (elems->supp_rates) { @@ -290,6 +286,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) local->scanning = 0; local->scan_channel = NULL; + drv_sw_scan_complete(local); + /* we only have to protect scan_req and hw/sw scan */ mutex_unlock(&local->scan_mtx); @@ -299,8 +297,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) ieee80211_configure_filter(local); - drv_sw_scan_complete(local); - ieee80211_offchannel_return(local, true); done: diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index 6d86f0c1ad04..67656cbf2b15 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -647,7 +647,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) return ret; if (sta->key) { - ieee80211_key_free(local, sta->key); + ieee80211_key_free(sta->key); WARN_ON(sta->key); } diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index c54db966926b..698d4718b1a4 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -575,6 +575,17 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) return TX_CONTINUE; } +static ieee80211_tx_result debug_noinline +ieee80211_tx_h_sta(struct ieee80211_tx_data *tx) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); + + if (tx->sta && tx->sta->uploaded) + info->control.sta = &tx->sta->sta; + + return TX_CONTINUE; +} + static ieee80211_tx_result debug_noinline ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) { @@ -1296,11 +1307,6 @@ static int __ieee80211_tx(struct ieee80211_local *local, break; } - if (sta && sta->uploaded) - info->control.sta = &sta->sta; - else - info->control.sta = NULL; - ret = drv_tx(local, skb); if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { dev_kfree_skb(skb); @@ -1340,6 +1346,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) CALL_TXH(ieee80211_tx_h_check_assoc); CALL_TXH(ieee80211_tx_h_ps_buf); CALL_TXH(ieee80211_tx_h_select_key); + CALL_TXH(ieee80211_tx_h_sta); if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) CALL_TXH(ieee80211_tx_h_rate_ctrl); @@ -1935,13 +1942,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, h_pos += encaps_len; } -#ifdef CONFIG_MAC80211_MESH if (meshhdrlen > 0) { memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); nh_pos += meshhdrlen; h_pos += meshhdrlen; } -#endif if (ieee80211_is_data_qos(fc)) { __le16 *qos_control; diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 748387d45bc0..a54cf146ed50 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -803,12 +803,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) /* after reinitialize QoS TX queues setting to default, * disable QoS at all */ - - if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { - sdata->vif.bss_conf.qos = - sdata->vif.type != NL80211_IFTYPE_STATION; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); - } + local->hw.conf.flags &= ~IEEE80211_CONF_QOS; + drv_config(local, IEEE80211_CONF_CHANGE_QOS); } void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, @@ -1165,8 +1161,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) BSS_CHANGED_BASIC_RATES | BSS_CHANGED_BEACON_INT | BSS_CHANGED_BSSID | - BSS_CHANGED_CQM | - BSS_CHANGED_QOS; + BSS_CHANGED_CQM; switch (sdata->vif.type) { case NL80211_IFTYPE_STATION: diff --git a/trunk/net/mac80211/wep.c b/trunk/net/mac80211/wep.c index 9ebc8d8a1f5b..6d133b6efce5 100644 --- a/trunk/net/mac80211/wep.c +++ b/trunk/net/mac80211/wep.c @@ -32,16 +32,13 @@ int ieee80211_wep_init(struct ieee80211_local *local) local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(local->wep_tx_tfm)) { - local->wep_rx_tfm = ERR_PTR(-EINVAL); + if (IS_ERR(local->wep_tx_tfm)) return PTR_ERR(local->wep_tx_tfm); - } local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(local->wep_rx_tfm)) { crypto_free_blkcipher(local->wep_tx_tfm); - local->wep_tx_tfm = ERR_PTR(-EINVAL); return PTR_ERR(local->wep_rx_tfm); } diff --git a/trunk/net/mac80211/work.c b/trunk/net/mac80211/work.c index 81d4ad64184a..c22a71c5cb45 100644 --- a/trunk/net/mac80211/work.c +++ b/trunk/net/mac80211/work.c @@ -560,22 +560,6 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk) return WORK_ACT_TIMEOUT; } -static enum work_action __must_check -ieee80211_assoc_beacon_wait(struct ieee80211_work *wk) -{ - if (wk->started) - return WORK_ACT_TIMEOUT; - - /* - * Wait up to one beacon interval ... - * should this be more if we miss one? - */ - printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", - wk->sdata->name, wk->filter_ta); - wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval); - return WORK_ACT_NONE; -} - static void ieee80211_auth_challenge(struct ieee80211_work *wk, struct ieee80211_mgmt *mgmt, size_t len) @@ -725,25 +709,6 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk, return WORK_ACT_DONE; } -static enum work_action __must_check -ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk, - struct ieee80211_mgmt *mgmt, size_t len) -{ - struct ieee80211_sub_if_data *sdata = wk->sdata; - struct ieee80211_local *local = sdata->local; - - ASSERT_WORK_MTX(local); - - if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) - return WORK_ACT_MISMATCH; - - if (len < 24 + 12) - return WORK_ACT_NONE; - - printk(KERN_DEBUG "%s: beacon received\n", sdata->name); - return WORK_ACT_DONE; -} - static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, struct sk_buff *skb) { @@ -766,7 +731,6 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, case IEEE80211_WORK_DIRECT_PROBE: case IEEE80211_WORK_AUTH: case IEEE80211_WORK_ASSOC: - case IEEE80211_WORK_ASSOC_BEACON_WAIT: bssid = wk->filter_ta; break; default: @@ -781,9 +745,6 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, continue; switch (fc & IEEE80211_FCTL_STYPE) { - case IEEE80211_STYPE_BEACON: - rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len); - break; case IEEE80211_STYPE_PROBE_RESP: rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len, rx_status); @@ -955,9 +916,6 @@ static void ieee80211_work_work(struct work_struct *work) case IEEE80211_WORK_REMAIN_ON_CHANNEL: rma = ieee80211_remain_on_channel_timeout(wk); break; - case IEEE80211_WORK_ASSOC_BEACON_WAIT: - rma = ieee80211_assoc_beacon_wait(wk); - break; } wk->started = started; @@ -1107,7 +1065,6 @@ ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, case IEEE80211_STYPE_PROBE_RESP: case IEEE80211_STYPE_ASSOC_RESP: case IEEE80211_STYPE_REASSOC_RESP: - case IEEE80211_STYPE_BEACON: skb_queue_tail(&local->work_skb_queue, skb); ieee80211_queue_work(&local->hw, &local->work_work); return RX_QUEUED; diff --git a/trunk/net/netfilter/Kconfig b/trunk/net/netfilter/Kconfig index 43288259f4a1..aa2f106347e4 100644 --- a/trunk/net/netfilter/Kconfig +++ b/trunk/net/netfilter/Kconfig @@ -326,22 +326,6 @@ config NETFILTER_XT_CONNMARK comment "Xtables targets" -config NETFILTER_XT_TARGET_CHECKSUM - tristate "CHECKSUM target support" - depends on IP_NF_MANGLE || IP6_NF_MANGLE - depends on NETFILTER_ADVANCED - ---help--- - This option adds a `CHECKSUM' target, which can be used in the iptables mangle - table. - - You can use this target to compute and fill in the checksum in - a packet that lacks a checksum. This is particularly useful, - if you need to work around old applications such as dhcp clients, - that do not work well with checksum offloads, but don't want to disable - checksum offload in your device. - - To compile it as a module, choose M here. If unsure, say N. - config NETFILTER_XT_TARGET_CLASSIFY tristate '"CLASSIFY" target support' depends on NETFILTER_ADVANCED @@ -663,15 +647,6 @@ config NETFILTER_XT_MATCH_CONNTRACK To compile it as a module, choose M here. If unsure, say N. -config NETFILTER_XT_MATCH_CPU - tristate '"cpu" match support' - depends on NETFILTER_ADVANCED - help - CPU matching allows you to match packets based on the CPU - currently handling the packet. - - To compile it as a module, choose M here. If unsure, say N. - config NETFILTER_XT_MATCH_DCCP tristate '"dccp" protocol match support' depends on NETFILTER_ADVANCED @@ -751,16 +726,6 @@ config NETFILTER_XT_MATCH_IPRANGE If unsure, say M. -config NETFILTER_XT_MATCH_IPVS - tristate '"ipvs" match support' - depends on IP_VS - depends on NETFILTER_ADVANCED - depends on NF_CONNTRACK - help - This option allows you to match against IPVS properties of a packet. - - If unsure, say N. - config NETFILTER_XT_MATCH_LENGTH tristate '"length" match support' depends on NETFILTER_ADVANCED diff --git a/trunk/net/netfilter/Makefile b/trunk/net/netfilter/Makefile index 441050f31111..e28420aac5ef 100644 --- a/trunk/net/netfilter/Makefile +++ b/trunk/net/netfilter/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o # targets -obj-$(CONFIG_NETFILTER_XT_TARGET_CHECKSUM) += xt_CHECKSUM.o obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o @@ -70,7 +69,6 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o -obj-$(CONFIG_NETFILTER_XT_MATCH_CPU) += xt_cpu.o obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o @@ -78,7 +76,6 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o -obj-$(CONFIG_NETFILTER_XT_MATCH_IPVS) += xt_ipvs.o obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o diff --git a/trunk/net/netfilter/ipvs/Kconfig b/trunk/net/netfilter/ipvs/Kconfig index 46a77d5c3887..712ccad13344 100644 --- a/trunk/net/netfilter/ipvs/Kconfig +++ b/trunk/net/netfilter/ipvs/Kconfig @@ -3,7 +3,7 @@ # menuconfig IP_VS tristate "IP virtual server support" - depends on NET && INET && NETFILTER && NF_CONNTRACK + depends on NET && INET && NETFILTER ---help--- IP Virtual Server support will let you build a high-performance virtual server based on cluster of two or more real servers. This @@ -26,7 +26,7 @@ if IP_VS config IP_VS_IPV6 bool "IPv6 support for IPVS" - depends on IPV6 = y || IP_VS = IPV6 + depends on EXPERIMENTAL && (IPV6 = y || IP_VS = IPV6) ---help--- Add IPv6 support to IPVS. This is incomplete and might be dangerous. @@ -87,16 +87,19 @@ config IP_VS_PROTO_UDP protocol. Say Y if unsure. config IP_VS_PROTO_AH_ESP - def_bool IP_VS_PROTO_ESP || IP_VS_PROTO_AH + bool + depends on UNDEFINED config IP_VS_PROTO_ESP bool "ESP load balancing support" + select IP_VS_PROTO_AH_ESP ---help--- This option enables support for load balancing ESP (Encapsulation Security Payload) transport protocol. Say Y if unsure. config IP_VS_PROTO_AH bool "AH load balancing support" + select IP_VS_PROTO_AH_ESP ---help--- This option enables support for load balancing AH (Authentication Header) transport protocol. Say Y if unsure. @@ -235,7 +238,7 @@ comment 'IPVS application helper' config IP_VS_FTP tristate "FTP protocol helper" - depends on IP_VS_PROTO_TCP && NF_NAT + depends on IP_VS_PROTO_TCP ---help--- FTP is a protocol that transfers IP address and/or port number in the payload. In the virtual server via Network Address Translation, diff --git a/trunk/net/netfilter/ipvs/ip_vs_app.c b/trunk/net/netfilter/ipvs/ip_vs_app.c index e76f87f4aca8..1cb0e834f8ff 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_app.c +++ b/trunk/net/netfilter/ipvs/ip_vs_app.c @@ -569,6 +569,49 @@ static const struct file_operations ip_vs_app_fops = { }; #endif + +/* + * Replace a segment of data with a new segment + */ +int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri, + char *o_buf, int o_len, char *n_buf, int n_len) +{ + int diff; + int o_offset; + int o_left; + + EnterFunction(9); + + diff = n_len - o_len; + o_offset = o_buf - (char *)skb->data; + /* The length of left data after o_buf+o_len in the skb data */ + o_left = skb->len - (o_offset + o_len); + + if (diff <= 0) { + memmove(o_buf + n_len, o_buf + o_len, o_left); + memcpy(o_buf, n_buf, n_len); + skb_trim(skb, skb->len + diff); + } else if (diff <= skb_tailroom(skb)) { + skb_put(skb, diff); + memmove(o_buf + n_len, o_buf + o_len, o_left); + memcpy(o_buf, n_buf, n_len); + } else { + if (pskb_expand_head(skb, skb_headroom(skb), diff, pri)) + return -ENOMEM; + skb_put(skb, diff); + memmove(skb->data + o_offset + n_len, + skb->data + o_offset + o_len, o_left); + skb_copy_to_linear_data_offset(skb, o_offset, n_buf, n_len); + } + + /* must update the iph total length here */ + ip_hdr(skb)->tot_len = htons(skb->len); + + LeaveFunction(9); + return 0; +} + + int __init ip_vs_app_init(void) { /* we will replace it with proc_net_ipvs_create() soon */ diff --git a/trunk/net/netfilter/ipvs/ip_vs_conn.c b/trunk/net/netfilter/ipvs/ip_vs_conn.c index b71c69a2db13..654544e72264 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_conn.c +++ b/trunk/net/netfilter/ipvs/ip_vs_conn.c @@ -271,29 +271,6 @@ struct ip_vs_conn *ip_vs_conn_in_get return cp; } -struct ip_vs_conn * -ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, - struct ip_vs_protocol *pp, - const struct ip_vs_iphdr *iph, - unsigned int proto_off, int inverse) -{ - __be16 _ports[2], *pptr; - - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); - if (pptr == NULL) - return NULL; - - if (likely(!inverse)) - return ip_vs_conn_in_get(af, iph->protocol, - &iph->saddr, pptr[0], - &iph->daddr, pptr[1]); - else - return ip_vs_conn_in_get(af, iph->protocol, - &iph->daddr, pptr[1], - &iph->saddr, pptr[0]); -} -EXPORT_SYMBOL_GPL(ip_vs_conn_in_get_proto); - /* Get reference to connection template */ struct ip_vs_conn *ip_vs_ct_in_get (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, @@ -379,28 +356,6 @@ struct ip_vs_conn *ip_vs_conn_out_get return ret; } -struct ip_vs_conn * -ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, - struct ip_vs_protocol *pp, - const struct ip_vs_iphdr *iph, - unsigned int proto_off, int inverse) -{ - __be16 _ports[2], *pptr; - - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); - if (pptr == NULL) - return NULL; - - if (likely(!inverse)) - return ip_vs_conn_out_get(af, iph->protocol, - &iph->saddr, pptr[0], - &iph->daddr, pptr[1]); - else - return ip_vs_conn_out_get(af, iph->protocol, - &iph->daddr, pptr[1], - &iph->saddr, pptr[0]); -} -EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto); /* * Put back the conn and restart its timer with its timeout diff --git a/trunk/net/netfilter/ipvs/ip_vs_core.c b/trunk/net/netfilter/ipvs/ip_vs_core.c index 4f8ddba48011..50907d8472a3 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_core.c +++ b/trunk/net/netfilter/ipvs/ip_vs_core.c @@ -54,6 +54,7 @@ EXPORT_SYMBOL(register_ip_vs_scheduler); EXPORT_SYMBOL(unregister_ip_vs_scheduler); +EXPORT_SYMBOL(ip_vs_skb_replace); EXPORT_SYMBOL(ip_vs_proto_name); EXPORT_SYMBOL(ip_vs_conn_new); EXPORT_SYMBOL(ip_vs_conn_in_get); @@ -535,6 +536,26 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, return NF_DROP; } + +/* + * It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING + * chain, and is used for VS/NAT. + * It detects packets for VS/NAT connections and sends the packets + * immediately. This can avoid that iptable_nat mangles the packets + * for VS/NAT. + */ +static unsigned int ip_vs_post_routing(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + if (!skb->ipvs_property) + return NF_ACCEPT; + /* The packet was sent from IPVS, exit this chain */ + return NF_STOP; +} + __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) { return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); @@ -1478,6 +1499,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, + /* Before the netfilter connection tracking, exit from POST_ROUTING */ + { + .hook = ip_vs_post_routing, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP_PRI_NAT_SRC-1, + }, #ifdef CONFIG_IP_VS_IPV6 /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be @@ -1506,6 +1535,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hooknum = NF_INET_FORWARD, .priority = 99, }, + /* Before the netfilter connection tracking, exit from POST_ROUTING */ + { + .hook = ip_vs_post_routing, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP6_PRI_NAT_SRC-1, + }, #endif }; diff --git a/trunk/net/netfilter/ipvs/ip_vs_ftp.c b/trunk/net/netfilter/ipvs/ip_vs_ftp.c index f228a17ec649..2ae747a376a5 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ftp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ftp.c @@ -20,17 +20,6 @@ * * Author: Wouter Gadeyne * - * - * Code for ip_vs_expect_related and ip_vs_expect_callback is taken from - * http://www.ssi.bg/~ja/nfct/: - * - * ip_vs_nfct.c: Netfilter connection tracking support for IPVS - * - * Portions Copyright (C) 2001-2002 - * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland. - * - * Portions Copyright (C) 2003-2008 - * Julian Anastasov */ #define KMSG_COMPONENT "IPVS" @@ -43,9 +32,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -57,16 +43,6 @@ #define SERVER_STRING "227 Entering Passive Mode (" #define CLIENT_STRING "PORT " -#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u" -#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \ - &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \ - (T)->dst.protonum - -#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u" -#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \ - &((C)->vaddr.ip), ntohs((C)->vport), \ - &((C)->daddr.ip), ntohs((C)->dport), \ - (C)->protocol, (C)->state /* * List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper @@ -147,119 +123,6 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit, return 1; } -/* - * Called from init_conntrack() as expectfn handler. - */ -static void -ip_vs_expect_callback(struct nf_conn *ct, - struct nf_conntrack_expect *exp) -{ - struct nf_conntrack_tuple *orig, new_reply; - struct ip_vs_conn *cp; - - if (exp->tuple.src.l3num != PF_INET) - return; - - /* - * We assume that no NF locks are held before this callback. - * ip_vs_conn_out_get and ip_vs_conn_in_get should match their - * expectations even if they use wildcard values, now we provide the - * actual values from the newly created original conntrack direction. - * The conntrack is confirmed when packet reaches IPVS hooks. - */ - - /* RS->CLIENT */ - orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); - if (cp) { - /* Change reply CLIENT->RS to CLIENT->VS */ - new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " - FMT_TUPLE ", found inout cp=" FMT_CONN "\n", - __func__, ct, ct->status, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - new_reply.dst.u3 = cp->vaddr; - new_reply.dst.u.tcp.port = cp->vport; - IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE - ", inout cp=" FMT_CONN "\n", - __func__, ct, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - goto alter; - } - - /* CLIENT->VS */ - cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); - if (cp) { - /* Change reply VS->CLIENT to RS->CLIENT */ - new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " - FMT_TUPLE ", found outin cp=" FMT_CONN "\n", - __func__, ct, ct->status, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - new_reply.src.u3 = cp->daddr; - new_reply.src.u.tcp.port = cp->dport; - IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " - FMT_TUPLE ", outin cp=" FMT_CONN "\n", - __func__, ct, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - goto alter; - } - - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuple=" FMT_TUPLE - " - unknown expect\n", - __func__, ct, ct->status, ARG_TUPLE(orig)); - return; - -alter: - /* Never alter conntrack for non-NAT conns */ - if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ) - nf_conntrack_alter_reply(ct, &new_reply); - ip_vs_conn_put(cp); - return; -} - -/* - * Create NF conntrack expectation with wildcard (optional) source port. - * Then the default callback function will alter the reply and will confirm - * the conntrack entry when the first packet comes. - */ -static void -ip_vs_expect_related(struct sk_buff *skb, struct nf_conn *ct, - struct ip_vs_conn *cp, u_int8_t proto, - const __be16 *port, int from_rs) -{ - struct nf_conntrack_expect *exp; - - BUG_ON(!ct || ct == &nf_conntrack_untracked); - - exp = nf_ct_expect_alloc(ct); - if (!exp) - return; - - if (from_rs) - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, - nf_ct_l3num(ct), &cp->daddr, &cp->caddr, - proto, port, &cp->cport); - else - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, - nf_ct_l3num(ct), &cp->caddr, &cp->vaddr, - proto, port, &cp->vport); - - exp->expectfn = ip_vs_expect_callback; - - IP_VS_DBG(7, "%s(): ct=%p, expect tuple=" FMT_TUPLE "\n", - __func__, ct, ARG_TUPLE(&exp->tuple)); - nf_ct_expect_related(exp); - nf_ct_expect_put(exp); -} /* * Look at outgoing ftp packets to catch the response to a PASV command @@ -286,9 +149,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, struct ip_vs_conn *n_cp; char buf[24]; /* xxx.xxx.xxx.xxx,ppp,ppp\000 */ unsigned buf_len; - int ret = 0; - enum ip_conntrack_info ctinfo; - struct nf_conn *ct; + int ret; #ifdef CONFIG_IP_VS_IPV6 /* This application helper doesn't work with IPv6 yet, @@ -358,26 +219,19 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, buf_len = strlen(buf); - ct = nf_ct_get(skb, &ctinfo); - if (ct && !nf_ct_is_untracked(ct)) { - /* If mangling fails this function will return 0 - * which will cause the packet to be dropped. - * Mangling can only fail under memory pressure, - * hopefully it will succeed on the retransmitted - * packet. - */ - ret = nf_nat_mangle_tcp_packet(skb, ct, ctinfo, - start-data, end-start, - buf, buf_len); - if (ret) - ip_vs_expect_related(skb, ct, n_cp, - IPPROTO_TCP, NULL, 0); - } - /* - * Not setting 'diff' is intentional, otherwise the sequence - * would be adjusted twice. + * Calculate required delta-offset to keep TCP happy */ + *diff = buf_len - (end-start); + + if (*diff == 0) { + /* simply replace it with new passive address */ + memcpy(start, buf, buf_len); + ret = 1; + } else { + ret = !ip_vs_skb_replace(skb, GFP_ATOMIC, start, + end-start, buf, buf_len); + } cp->app_data = NULL; ip_vs_tcp_conn_listen(n_cp); @@ -409,7 +263,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, union nf_inet_addr to; __be16 port; struct ip_vs_conn *n_cp; - struct nf_conn *ct; #ifdef CONFIG_IP_VS_IPV6 /* This application helper doesn't work with IPv6 yet, @@ -496,11 +349,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ip_vs_control_add(n_cp, cp); } - ct = (struct nf_conn *)skb->nfct; - if (ct && ct != &nf_conntrack_untracked) - ip_vs_expect_related(skb, ct, n_cp, - IPPROTO_TCP, &n_cp->dport, 1); - /* * Move tunnel to listen state */ diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto.c b/trunk/net/netfilter/ipvs/ip_vs_proto.c index 027f654799fe..2d3d5e4b35f8 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto.c @@ -98,7 +98,6 @@ struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto) return NULL; } -EXPORT_SYMBOL(ip_vs_proto_get); /* diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c index 4c0855cb006e..c9a3f7a21d53 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -8,6 +8,55 @@ #include #include + +static struct ip_vs_conn * +sctp_conn_in_get(int af, + const struct sk_buff *skb, + struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, + unsigned int proto_off, + int inverse) +{ + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return NULL; + + if (likely(!inverse)) + return ip_vs_conn_in_get(af, iph->protocol, + &iph->saddr, pptr[0], + &iph->daddr, pptr[1]); + else + return ip_vs_conn_in_get(af, iph->protocol, + &iph->daddr, pptr[1], + &iph->saddr, pptr[0]); +} + +static struct ip_vs_conn * +sctp_conn_out_get(int af, + const struct sk_buff *skb, + struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, + unsigned int proto_off, + int inverse) +{ + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return NULL; + + if (likely(!inverse)) + return ip_vs_conn_out_get(af, iph->protocol, + &iph->saddr, pptr[0], + &iph->daddr, pptr[1]); + else + return ip_vs_conn_out_get(af, iph->protocol, + &iph->daddr, pptr[1], + &iph->saddr, pptr[0]); +} + static int sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, int *verdict, struct ip_vs_conn **cpp) @@ -124,7 +173,7 @@ sctp_dnat_handler(struct sk_buff *skb, return 0; /* Call application helper if needed */ - if (!ip_vs_app_pkt_in(cp, skb)) + if (!ip_vs_app_pkt_out(cp, skb)) return 0; } @@ -1120,8 +1169,8 @@ struct ip_vs_protocol ip_vs_protocol_sctp = { .register_app = sctp_register_app, .unregister_app = sctp_unregister_app, .conn_schedule = sctp_conn_schedule, - .conn_in_get = ip_vs_conn_in_get_proto, - .conn_out_get = ip_vs_conn_out_get_proto, + .conn_in_get = sctp_conn_in_get, + .conn_out_get = sctp_conn_out_get, .snat_handler = sctp_snat_handler, .dnat_handler = sctp_dnat_handler, .csum_check = sctp_csum_check, diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c index 282d24de8592..91d28e073742 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -27,6 +27,52 @@ #include + +static struct ip_vs_conn * +tcp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, unsigned int proto_off, + int inverse) +{ + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return NULL; + + if (likely(!inverse)) { + return ip_vs_conn_in_get(af, iph->protocol, + &iph->saddr, pptr[0], + &iph->daddr, pptr[1]); + } else { + return ip_vs_conn_in_get(af, iph->protocol, + &iph->daddr, pptr[1], + &iph->saddr, pptr[0]); + } +} + +static struct ip_vs_conn * +tcp_conn_out_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, unsigned int proto_off, + int inverse) +{ + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return NULL; + + if (likely(!inverse)) { + return ip_vs_conn_out_get(af, iph->protocol, + &iph->saddr, pptr[0], + &iph->daddr, pptr[1]); + } else { + return ip_vs_conn_out_get(af, iph->protocol, + &iph->daddr, pptr[1], + &iph->saddr, pptr[0]); + } +} + + static int tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, int *verdict, struct ip_vs_conn **cpp) @@ -675,8 +721,8 @@ struct ip_vs_protocol ip_vs_protocol_tcp = { .register_app = tcp_register_app, .unregister_app = tcp_unregister_app, .conn_schedule = tcp_conn_schedule, - .conn_in_get = ip_vs_conn_in_get_proto, - .conn_out_get = ip_vs_conn_out_get_proto, + .conn_in_get = tcp_conn_in_get, + .conn_out_get = tcp_conn_out_get, .snat_handler = tcp_snat_handler, .dnat_handler = tcp_dnat_handler, .csum_check = tcp_csum_check, diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c index 8553231b5d41..e7a6885e0167 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -27,6 +27,58 @@ #include #include +static struct ip_vs_conn * +udp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, unsigned int proto_off, + int inverse) +{ + struct ip_vs_conn *cp; + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return NULL; + + if (likely(!inverse)) { + cp = ip_vs_conn_in_get(af, iph->protocol, + &iph->saddr, pptr[0], + &iph->daddr, pptr[1]); + } else { + cp = ip_vs_conn_in_get(af, iph->protocol, + &iph->daddr, pptr[1], + &iph->saddr, pptr[0]); + } + + return cp; +} + + +static struct ip_vs_conn * +udp_conn_out_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, + const struct ip_vs_iphdr *iph, unsigned int proto_off, + int inverse) +{ + struct ip_vs_conn *cp; + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return NULL; + + if (likely(!inverse)) { + cp = ip_vs_conn_out_get(af, iph->protocol, + &iph->saddr, pptr[0], + &iph->daddr, pptr[1]); + } else { + cp = ip_vs_conn_out_get(af, iph->protocol, + &iph->daddr, pptr[1], + &iph->saddr, pptr[0]); + } + + return cp; +} + + static int udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, int *verdict, struct ip_vs_conn **cpp) @@ -468,8 +520,8 @@ struct ip_vs_protocol ip_vs_protocol_udp = { .init = udp_init, .exit = udp_exit, .conn_schedule = udp_conn_schedule, - .conn_in_get = ip_vs_conn_in_get_proto, - .conn_out_get = ip_vs_conn_out_get_proto, + .conn_in_get = udp_conn_in_get, + .conn_out_get = udp_conn_out_get, .snat_handler = udp_snat_handler, .dnat_handler = udp_dnat_handler, .csum_check = udp_csum_check, diff --git a/trunk/net/netfilter/ipvs/ip_vs_xmit.c b/trunk/net/netfilter/ipvs/ip_vs_xmit.c index 21e1a5e9b9d3..02b078e11cf3 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_xmit.c +++ b/trunk/net/netfilter/ipvs/ip_vs_xmit.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -349,30 +348,6 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, } #endif -static void -ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) -{ - struct nf_conn *ct = (struct nf_conn *)skb->nfct; - struct nf_conntrack_tuple new_tuple; - - if (ct == NULL || nf_ct_is_untracked(ct) || nf_ct_is_confirmed(ct)) - return; - - /* - * The connection is not yet in the hashtable, so we update it. - * CIP->VIP will remain the same, so leave the tuple in - * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the - * real-server we will see RIP->DIP. - */ - new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - new_tuple.src.u3 = cp->daddr; - /* - * This will also take care of UDP and other protocols. - */ - new_tuple.src.u.tcp.port = cp->dport; - nf_conntrack_alter_reply(ct, &new_tuple); -} - /* * NAT transmitter (only for outside-to-inside nat forwarding) * Not used for related ICMP @@ -428,8 +403,6 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); - ip_vs_update_conntrack(skb, cp); - /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still MTU problem. */ @@ -506,8 +479,6 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); - ip_vs_update_conntrack(skb, cp); - /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still MTU problem. */ diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index df3eedb142ff..16b41b4e2a3c 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -966,7 +966,8 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, if (acct) { spin_lock_bh(&ct->lock); acct[CTINFO2DIR(ctinfo)].packets++; - acct[CTINFO2DIR(ctinfo)].bytes += skb->len; + acct[CTINFO2DIR(ctinfo)].bytes += + skb->len - skb_network_offset(skb); spin_unlock_bh(&ct->lock); } } diff --git a/trunk/net/netfilter/nf_conntrack_extend.c b/trunk/net/netfilter/nf_conntrack_extend.c index 7dcf7a404190..fdc8fb4ae10f 100644 --- a/trunk/net/netfilter/nf_conntrack_extend.c +++ b/trunk/net/netfilter/nf_conntrack_extend.c @@ -23,10 +23,9 @@ void __nf_ct_ext_destroy(struct nf_conn *ct) { unsigned int i; struct nf_ct_ext_type *t; - struct nf_ct_ext *ext = ct->ext; for (i = 0; i < NF_CT_EXT_NUM; i++) { - if (!__nf_ct_ext_exist(ext, i)) + if (!nf_ct_ext_exist(ct, i)) continue; rcu_read_lock(); @@ -74,45 +73,44 @@ static void __nf_ct_ext_free_rcu(struct rcu_head *head) void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) { - struct nf_ct_ext *old, *new; + struct nf_ct_ext *new; int i, newlen, newoff; struct nf_ct_ext_type *t; /* Conntrack must not be confirmed to avoid races on reallocation. */ NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); - old = ct->ext; - if (!old) + if (!ct->ext) return nf_ct_ext_create(&ct->ext, id, gfp); - if (__nf_ct_ext_exist(old, id)) + if (nf_ct_ext_exist(ct, id)) return NULL; rcu_read_lock(); t = rcu_dereference(nf_ct_ext_types[id]); BUG_ON(t == NULL); - newoff = ALIGN(old->len, t->align); + newoff = ALIGN(ct->ext->len, t->align); newlen = newoff + t->len; rcu_read_unlock(); - new = __krealloc(old, newlen, gfp); + new = __krealloc(ct->ext, newlen, gfp); if (!new) return NULL; - if (new != old) { + if (new != ct->ext) { for (i = 0; i < NF_CT_EXT_NUM; i++) { - if (!__nf_ct_ext_exist(old, i)) + if (!nf_ct_ext_exist(ct, i)) continue; rcu_read_lock(); t = rcu_dereference(nf_ct_ext_types[i]); if (t && t->move) t->move((void *)new + new->offset[i], - (void *)old + old->offset[i]); + (void *)ct->ext + ct->ext->offset[i]); rcu_read_unlock(); } - call_rcu(&old->rcu, __nf_ct_ext_free_rcu); + call_rcu(&ct->ext->rcu, __nf_ct_ext_free_rcu); ct->ext = new; } diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index c4c885dca3bd..802dbffae8b4 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -585,16 +585,8 @@ static bool tcp_in_window(const struct nf_conn *ct, * Let's try to use the data from the packet. */ sender->td_end = end; - win <<= sender->td_scale; sender->td_maxwin = (win == 0 ? 1 : win); sender->td_maxend = end + sender->td_maxwin; - /* - * We haven't seen traffic in the other direction yet - * but we have to tweak window tracking to pass III - * and IV until that happens. - */ - if (receiver->td_maxwin == 0) - receiver->td_end = receiver->td_maxend = sack; } } else if (((state->state == TCP_CONNTRACK_SYN_SENT && dir == IP_CT_DIR_ORIGINAL) @@ -688,7 +680,7 @@ static bool tcp_in_window(const struct nf_conn *ct, /* * Update receiver data. */ - if (receiver->td_maxwin != 0 && after(end, sender->td_maxend)) + if (after(end, sender->td_maxend)) receiver->td_maxwin += end - sender->td_maxend; if (after(sack + win, receiver->td_maxend - 1)) { receiver->td_maxend = sack + win; diff --git a/trunk/net/netfilter/xt_CHECKSUM.c b/trunk/net/netfilter/xt_CHECKSUM.c deleted file mode 100644 index 0f642ef8cd26..000000000000 --- a/trunk/net/netfilter/xt_CHECKSUM.c +++ /dev/null @@ -1,70 +0,0 @@ -/* iptables module for the packet checksum mangling - * - * (C) 2002 by Harald Welte - * (C) 2010 Red Hat, Inc. - * - * Author: Michael S. Tsirkin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include - -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Michael S. Tsirkin "); -MODULE_DESCRIPTION("Xtables: checksum modification"); -MODULE_ALIAS("ipt_CHECKSUM"); -MODULE_ALIAS("ip6t_CHECKSUM"); - -static unsigned int -checksum_tg(struct sk_buff *skb, const struct xt_action_param *par) -{ - if (skb->ip_summed == CHECKSUM_PARTIAL) - skb_checksum_help(skb); - - return XT_CONTINUE; -} - -static int checksum_tg_check(const struct xt_tgchk_param *par) -{ - const struct xt_CHECKSUM_info *einfo = par->targinfo; - - if (einfo->operation & ~XT_CHECKSUM_OP_FILL) { - pr_info("unsupported CHECKSUM operation %x\n", einfo->operation); - return -EINVAL; - } - if (!einfo->operation) { - pr_info("no CHECKSUM operation enabled\n"); - return -EINVAL; - } - return 0; -} - -static struct xt_target checksum_tg_reg __read_mostly = { - .name = "CHECKSUM", - .family = NFPROTO_UNSPEC, - .target = checksum_tg, - .targetsize = sizeof(struct xt_CHECKSUM_info), - .table = "mangle", - .checkentry = checksum_tg_check, - .me = THIS_MODULE, -}; - -static int __init checksum_tg_init(void) -{ - return xt_register_target(&checksum_tg_reg); -} - -static void __exit checksum_tg_exit(void) -{ - xt_unregister_target(&checksum_tg_reg); -} - -module_init(checksum_tg_init); -module_exit(checksum_tg_exit); diff --git a/trunk/net/netfilter/xt_TPROXY.c b/trunk/net/netfilter/xt_TPROXY.c index c61294d85fda..e1a0dedac258 100644 --- a/trunk/net/netfilter/xt_TPROXY.c +++ b/trunk/net/netfilter/xt_TPROXY.c @@ -37,10 +37,8 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) return NF_DROP; sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, - iph->saddr, - tgi->laddr ? tgi->laddr : iph->daddr, - hp->source, - tgi->lport ? tgi->lport : hp->dest, + iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr, + hp->source, tgi->lport ? tgi->lport : hp->dest, par->in, true); /* NOTE: assign_sock consumes our sk reference */ diff --git a/trunk/net/netfilter/xt_cpu.c b/trunk/net/netfilter/xt_cpu.c deleted file mode 100644 index b39db8a5cbae..000000000000 --- a/trunk/net/netfilter/xt_cpu.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Kernel module to match running CPU */ - -/* - * Might be used to distribute connections on several daemons, if - * RPS (Remote Packet Steering) is enabled or NIC is multiqueue capable, - * each RX queue IRQ affined to one CPU (1:1 mapping) - * - */ - -/* (C) 2010 Eric Dumazet - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Eric Dumazet "); -MODULE_DESCRIPTION("Xtables: CPU match"); - -static int cpu_mt_check(const struct xt_mtchk_param *par) -{ - const struct xt_cpu_info *info = par->matchinfo; - - if (info->invert & ~1) - return -EINVAL; - return 0; -} - -static bool cpu_mt(const struct sk_buff *skb, struct xt_action_param *par) -{ - const struct xt_cpu_info *info = par->matchinfo; - - return (info->cpu == smp_processor_id()) ^ info->invert; -} - -static struct xt_match cpu_mt_reg __read_mostly = { - .name = "cpu", - .revision = 0, - .family = NFPROTO_UNSPEC, - .checkentry = cpu_mt_check, - .match = cpu_mt, - .matchsize = sizeof(struct xt_cpu_info), - .me = THIS_MODULE, -}; - -static int __init cpu_mt_init(void) -{ - return xt_register_match(&cpu_mt_reg); -} - -static void __exit cpu_mt_exit(void) -{ - xt_unregister_match(&cpu_mt_reg); -} - -module_init(cpu_mt_init); -module_exit(cpu_mt_exit); diff --git a/trunk/net/netfilter/xt_ipvs.c b/trunk/net/netfilter/xt_ipvs.c deleted file mode 100644 index 7a4d66db95ae..000000000000 --- a/trunk/net/netfilter/xt_ipvs.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * xt_ipvs - kernel module to match IPVS connection properties - * - * Author: Hannes Eder - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#ifdef CONFIG_IP_VS_IPV6 -#include -#endif -#include -#include -#include -#include -#include -#include - -#include - -MODULE_AUTHOR("Hannes Eder "); -MODULE_DESCRIPTION("Xtables: match IPVS connection properties"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_ipvs"); -MODULE_ALIAS("ip6t_ipvs"); - -/* borrowed from xt_conntrack */ -static bool ipvs_mt_addrcmp(const union nf_inet_addr *kaddr, - const union nf_inet_addr *uaddr, - const union nf_inet_addr *umask, - unsigned int l3proto) -{ - if (l3proto == NFPROTO_IPV4) - return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0; -#ifdef CONFIG_IP_VS_IPV6 - else if (l3proto == NFPROTO_IPV6) - return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6, - &uaddr->in6) == 0; -#endif - else - return false; -} - -static bool -ipvs_mt(const struct sk_buff *skb, struct xt_action_param *par) -{ - const struct xt_ipvs_mtinfo *data = par->matchinfo; - /* ipvs_mt_check ensures that family is only NFPROTO_IPV[46]. */ - const u_int8_t family = par->family; - struct ip_vs_iphdr iph; - struct ip_vs_protocol *pp; - struct ip_vs_conn *cp; - bool match = true; - - if (data->bitmask == XT_IPVS_IPVS_PROPERTY) { - match = skb->ipvs_property ^ - !!(data->invert & XT_IPVS_IPVS_PROPERTY); - goto out; - } - - /* other flags than XT_IPVS_IPVS_PROPERTY are set */ - if (!skb->ipvs_property) { - match = false; - goto out; - } - - ip_vs_fill_iphdr(family, skb_network_header(skb), &iph); - - if (data->bitmask & XT_IPVS_PROTO) - if ((iph.protocol == data->l4proto) ^ - !(data->invert & XT_IPVS_PROTO)) { - match = false; - goto out; - } - - pp = ip_vs_proto_get(iph.protocol); - if (unlikely(!pp)) { - match = false; - goto out; - } - - /* - * Check if the packet belongs to an existing entry - */ - cp = pp->conn_out_get(family, skb, pp, &iph, iph.len, 1 /* inverse */); - if (unlikely(cp == NULL)) { - match = false; - goto out; - } - - /* - * We found a connection, i.e. ct != 0, make sure to call - * __ip_vs_conn_put before returning. In our case jump to out_put_con. - */ - - if (data->bitmask & XT_IPVS_VPORT) - if ((cp->vport == data->vport) ^ - !(data->invert & XT_IPVS_VPORT)) { - match = false; - goto out_put_cp; - } - - if (data->bitmask & XT_IPVS_VPORTCTL) - if ((cp->control != NULL && - cp->control->vport == data->vportctl) ^ - !(data->invert & XT_IPVS_VPORTCTL)) { - match = false; - goto out_put_cp; - } - - if (data->bitmask & XT_IPVS_DIR) { - enum ip_conntrack_info ctinfo; - struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - - if (ct == NULL || nf_ct_is_untracked(ct)) { - match = false; - goto out_put_cp; - } - - if ((ctinfo >= IP_CT_IS_REPLY) ^ - !!(data->invert & XT_IPVS_DIR)) { - match = false; - goto out_put_cp; - } - } - - if (data->bitmask & XT_IPVS_METHOD) - if (((cp->flags & IP_VS_CONN_F_FWD_MASK) == data->fwd_method) ^ - !(data->invert & XT_IPVS_METHOD)) { - match = false; - goto out_put_cp; - } - - if (data->bitmask & XT_IPVS_VADDR) { - if (ipvs_mt_addrcmp(&cp->vaddr, &data->vaddr, - &data->vmask, family) ^ - !(data->invert & XT_IPVS_VADDR)) { - match = false; - goto out_put_cp; - } - } - -out_put_cp: - __ip_vs_conn_put(cp); -out: - pr_debug("match=%d\n", match); - return match; -} - -static int ipvs_mt_check(const struct xt_mtchk_param *par) -{ - if (par->family != NFPROTO_IPV4 -#ifdef CONFIG_IP_VS_IPV6 - && par->family != NFPROTO_IPV6 -#endif - ) { - pr_info("protocol family %u not supported\n", par->family); - return -EINVAL; - } - - return 0; -} - -static struct xt_match xt_ipvs_mt_reg __read_mostly = { - .name = "ipvs", - .revision = 0, - .family = NFPROTO_UNSPEC, - .match = ipvs_mt, - .checkentry = ipvs_mt_check, - .matchsize = XT_ALIGN(sizeof(struct xt_ipvs_mtinfo)), - .me = THIS_MODULE, -}; - -static int __init ipvs_mt_init(void) -{ - return xt_register_match(&xt_ipvs_mt_reg); -} - -static void __exit ipvs_mt_exit(void) -{ - xt_unregister_match(&xt_ipvs_mt_reg); -} - -module_init(ipvs_mt_init); -module_exit(ipvs_mt_exit); diff --git a/trunk/net/netfilter/xt_quota.c b/trunk/net/netfilter/xt_quota.c index 70eb2b4984dd..b4f7dfea5980 100644 --- a/trunk/net/netfilter/xt_quota.c +++ b/trunk/net/netfilter/xt_quota.c @@ -11,8 +11,7 @@ #include struct xt_quota_priv { - spinlock_t lock; - uint64_t quota; + uint64_t quota; }; MODULE_LICENSE("GPL"); @@ -21,6 +20,8 @@ MODULE_DESCRIPTION("Xtables: countdown quota match"); MODULE_ALIAS("ipt_quota"); MODULE_ALIAS("ip6t_quota"); +static DEFINE_SPINLOCK(quota_lock); + static bool quota_mt(const struct sk_buff *skb, struct xt_action_param *par) { @@ -28,7 +29,7 @@ quota_mt(const struct sk_buff *skb, struct xt_action_param *par) struct xt_quota_priv *priv = q->master; bool ret = q->flags & XT_QUOTA_INVERT; - spin_lock_bh(&priv->lock); + spin_lock_bh("a_lock); if (priv->quota >= skb->len) { priv->quota -= skb->len; ret = !ret; @@ -36,7 +37,9 @@ quota_mt(const struct sk_buff *skb, struct xt_action_param *par) /* we do not allow even small packets from now on */ priv->quota = 0; } - spin_unlock_bh(&priv->lock); + /* Copy quota back to matchinfo so that iptables can display it */ + q->quota = priv->quota; + spin_unlock_bh("a_lock); return ret; } @@ -52,7 +55,6 @@ static int quota_mt_check(const struct xt_mtchk_param *par) if (q->master == NULL) return -ENOMEM; - spin_lock_init(&q->master->lock); q->master->quota = q->quota; return 0; } diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 2cbf380377d5..8648a9922aab 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -1406,7 +1406,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, struct netlink_sock *nlk = nlk_sk(sk); int noblock = flags&MSG_DONTWAIT; size_t copied; - struct sk_buff *skb; + struct sk_buff *skb, *frag __maybe_unused = NULL; int err; if (flags&MSG_OOB) @@ -1441,21 +1441,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, kfree_skb(skb); skb = compskb; } else { - /* - * Before setting frag_list to NULL, we must get a - * private copy of skb if shared (because of MSG_PEEK) - */ - if (skb_shared(skb)) { - struct sk_buff *nskb; - - nskb = pskb_copy(skb, GFP_KERNEL); - kfree_skb(skb); - skb = nskb; - err = -ENOMEM; - if (!skb) - goto out; - } - kfree_skb(skb_shinfo(skb)->frag_list); + frag = skb_shinfo(skb)->frag_list; skb_shinfo(skb)->frag_list = NULL; } } @@ -1492,6 +1478,10 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, if (flags & MSG_TRUNC) copied = skb->len; +#ifdef CONFIG_COMPAT_NETLINK_MESSAGES + skb_shinfo(skb)->frag_list = frag; +#endif + skb_free_datagram(sk, skb); if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) diff --git a/trunk/net/netlink/genetlink.c b/trunk/net/netlink/genetlink.c index 26ed3e8587c2..aa4308afcc7f 100644 --- a/trunk/net/netlink/genetlink.c +++ b/trunk/net/netlink/genetlink.c @@ -303,7 +303,6 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops) errout: return err; } -EXPORT_SYMBOL(genl_register_ops); /** * genl_unregister_ops - unregister generic netlink operations @@ -338,7 +337,6 @@ int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops) return -ENOENT; } -EXPORT_SYMBOL(genl_unregister_ops); /** * genl_register_family - register a generic netlink family @@ -407,7 +405,6 @@ int genl_register_family(struct genl_family *family) errout: return err; } -EXPORT_SYMBOL(genl_register_family); /** * genl_register_family_with_ops - register a generic netlink family @@ -488,7 +485,6 @@ int genl_unregister_family(struct genl_family *family) return -ENOENT; } -EXPORT_SYMBOL(genl_unregister_family); static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { @@ -877,7 +873,11 @@ static int __init genl_init(void) for (i = 0; i < GENL_FAM_TAB_SIZE; i++) INIT_LIST_HEAD(&family_ht[i]); - err = genl_register_family_with_ops(&genl_ctrl, &genl_ctrl_ops, 1); + err = genl_register_family(&genl_ctrl); + if (err < 0) + goto problem; + + err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops); if (err < 0) goto problem; @@ -899,6 +899,11 @@ static int __init genl_init(void) subsys_initcall(genl_init); +EXPORT_SYMBOL(genl_register_ops); +EXPORT_SYMBOL(genl_unregister_ops); +EXPORT_SYMBOL(genl_register_family); +EXPORT_SYMBOL(genl_unregister_family); + static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group, gfp_t flags) { diff --git a/trunk/net/rose/rose_route.c b/trunk/net/rose/rose_route.c index b4fdaac233f7..cbc244a128bd 100644 --- a/trunk/net/rose/rose_route.c +++ b/trunk/net/rose/rose_route.c @@ -109,9 +109,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, init_timer(&rose_neigh->t0timer); if (rose_route->ndigis != 0) { - rose_neigh->digipeat = - kmalloc(sizeof(ax25_digi), GFP_ATOMIC); - if (rose_neigh->digipeat == NULL) { + if ((rose_neigh->digipeat = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) { kfree(rose_neigh); res = -ENOMEM; goto out; diff --git a/trunk/net/sched/act_mirred.c b/trunk/net/sched/act_mirred.c index 11f195af2da0..a16b0175f890 100644 --- a/trunk/net/sched/act_mirred.c +++ b/trunk/net/sched/act_mirred.c @@ -33,7 +33,6 @@ static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1]; static u32 mirred_idx_gen; static DEFINE_RWLOCK(mirred_lock); -static LIST_HEAD(mirred_list); static struct tcf_hashinfo mirred_hash_info = { .htab = tcf_mirred_ht, @@ -48,9 +47,7 @@ static inline int tcf_mirred_release(struct tcf_mirred *m, int bind) m->tcf_bindcnt--; m->tcf_refcnt--; if(!m->tcf_bindcnt && m->tcf_refcnt <= 0) { - list_del(&m->tcfm_list); - if (m->tcfm_dev) - dev_put(m->tcfm_dev); + dev_put(m->tcfm_dev); tcf_hash_destroy(&m->common, &mirred_hash_info); return 1; } @@ -137,10 +134,8 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est, m->tcfm_ok_push = ok_push; } spin_unlock_bh(&m->tcf_lock); - if (ret == ACT_P_CREATED) { - list_add(&m->tcfm_list, &mirred_list); + if (ret == ACT_P_CREATED) tcf_hash_insert(pc, &mirred_hash_info); - } return ret; } @@ -169,14 +164,9 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a, m->tcf_bstats.packets++; dev = m->tcfm_dev; - if (!dev) { - printk_once(KERN_NOTICE "tc mirred: target device is gone\n"); - goto out; - } - if (!(dev->flags & IFF_UP)) { if (net_ratelimit()) - pr_notice("tc mirred to Houston: device %s is down\n", + pr_notice("tc mirred to Houston: device %s is gone!\n", dev->name); goto out; } @@ -240,28 +230,6 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, i return -1; } -static int mirred_device_event(struct notifier_block *unused, - unsigned long event, void *ptr) -{ - struct net_device *dev = ptr; - struct tcf_mirred *m; - - if (event == NETDEV_UNREGISTER) - list_for_each_entry(m, &mirred_list, tcfm_list) { - if (m->tcfm_dev == dev) { - dev_put(dev); - m->tcfm_dev = NULL; - } - } - - return NOTIFY_DONE; -} - -static struct notifier_block mirred_device_notifier = { - .notifier_call = mirred_device_event, -}; - - static struct tc_action_ops act_mirred_ops = { .kind = "mirred", .hinfo = &mirred_hash_info, @@ -282,17 +250,12 @@ MODULE_LICENSE("GPL"); static int __init mirred_init_module(void) { - int err = register_netdevice_notifier(&mirred_device_notifier); - if (err) - return err; - pr_info("Mirror/redirect action on\n"); return tcf_register_action(&act_mirred_ops); } static void __exit mirred_cleanup_module(void) { - unregister_netdevice_notifier(&mirred_device_notifier); tcf_unregister_action(&act_mirred_ops); } diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 541e2fff5e9c..47fcfd0eebc2 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -472,22 +472,24 @@ int wiphy_register(struct wiphy *wiphy) /* check and set up bitrates */ ieee80211_set_bitrate_flags(wiphy); - mutex_lock(&cfg80211_mutex); - res = device_add(&rdev->wiphy.dev); if (res) - goto out_unlock; + return res; res = rfkill_register(rdev->rfkill); if (res) goto out_rm_dev; + mutex_lock(&cfg80211_mutex); + /* set up regulatory info */ wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); list_add_rcu(&rdev->list, &cfg80211_rdev_list); cfg80211_rdev_list_generation++; + mutex_unlock(&cfg80211_mutex); + /* add to debugfs */ rdev->wiphy.debugfsdir = debugfs_create_dir(wiphy_name(&rdev->wiphy), @@ -507,15 +509,11 @@ int wiphy_register(struct wiphy *wiphy) } cfg80211_debugfs_rdev_add(rdev); - mutex_unlock(&cfg80211_mutex); return 0; -out_rm_dev: + out_rm_dev: device_del(&rdev->wiphy.dev); - -out_unlock: - mutex_unlock(&cfg80211_mutex); return res; } EXPORT_SYMBOL(wiphy_register); @@ -907,52 +905,3 @@ static void __exit cfg80211_exit(void) destroy_workqueue(cfg80211_wq); } module_exit(cfg80211_exit); - -static int ___wiphy_printk(const char *level, const struct wiphy *wiphy, - struct va_format *vaf) -{ - if (!wiphy) - return printk("%s(NULL wiphy *): %pV", level, vaf); - - return printk("%s%s: %pV", level, wiphy_name(wiphy), vaf); -} - -int __wiphy_printk(const char *level, const struct wiphy *wiphy, - const char *fmt, ...) -{ - struct va_format vaf; - va_list args; - int r; - - va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - r = ___wiphy_printk(level, wiphy, &vaf); - va_end(args); - - return r; -} -EXPORT_SYMBOL(__wiphy_printk); - -#define define_wiphy_printk_level(func, kern_level) \ -int func(const struct wiphy *wiphy, const char *fmt, ...) \ -{ \ - struct va_format vaf; \ - va_list args; \ - int r; \ - \ - va_start(args, fmt); \ - \ - vaf.fmt = fmt; \ - vaf.va = &args; \ - \ - r = ___wiphy_printk(kern_level, wiphy, &vaf); \ - va_end(args); \ - \ - return r; \ -} \ -EXPORT_SYMBOL(func); - -define_wiphy_printk_level(wiphy_debug, KERN_DEBUG); diff --git a/trunk/net/wireless/genregdb.awk b/trunk/net/wireless/genregdb.awk index 53c143f5e770..3cc9e69880a8 100644 --- a/trunk/net/wireless/genregdb.awk +++ b/trunk/net/wireless/genregdb.awk @@ -21,7 +21,6 @@ BEGIN { print "" print "#include " print "#include " - print "#include \"regdb.h\"" print "" regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n" } diff --git a/trunk/net/wireless/ibss.c b/trunk/net/wireless/ibss.c index 27a8ce9343c3..adcabba02e20 100644 --- a/trunk/net/wireless/ibss.c +++ b/trunk/net/wireless/ibss.c @@ -247,10 +247,8 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, if (!netif_running(wdev->netdev)) return 0; - if (wdev->wext.keys) { + if (wdev->wext.keys) wdev->wext.keys->def = wdev->wext.default_key; - wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; - } wdev->wext.ibss.privacy = wdev->wext.default_key != -1; diff --git a/trunk/net/wireless/lib80211_crypt_ccmp.c b/trunk/net/wireless/lib80211_crypt_ccmp.c index dacb3b4b1bdb..b7fa31d5fd13 100644 --- a/trunk/net/wireless/lib80211_crypt_ccmp.c +++ b/trunk/net/wireless/lib80211_crypt_ccmp.c @@ -467,6 +467,7 @@ static struct lib80211_crypto_ops lib80211_crypt_ccmp = { .name = "CCMP", .init = lib80211_ccmp_init, .deinit = lib80211_ccmp_deinit, + .build_iv = lib80211_ccmp_hdr, .encrypt_mpdu = lib80211_ccmp_encrypt, .decrypt_mpdu = lib80211_ccmp_decrypt, .encrypt_msdu = NULL, diff --git a/trunk/net/wireless/lib80211_crypt_tkip.c b/trunk/net/wireless/lib80211_crypt_tkip.c index 0fe40510e2cb..8cbdb32ff316 100644 --- a/trunk/net/wireless/lib80211_crypt_tkip.c +++ b/trunk/net/wireless/lib80211_crypt_tkip.c @@ -578,7 +578,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) } if (ieee80211_is_data_qos(hdr11->frame_control)) { - hdr[12] = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(hdr11))) + hdr[12] = le16_to_cpu(*ieee80211_get_qos_ctl(hdr11)) & IEEE80211_QOS_CTL_TID_MASK; } else hdr[12] = 0; /* priority */ @@ -757,6 +757,7 @@ static struct lib80211_crypto_ops lib80211_crypt_tkip = { .name = "TKIP", .init = lib80211_tkip_init, .deinit = lib80211_tkip_deinit, + .build_iv = lib80211_tkip_hdr, .encrypt_mpdu = lib80211_tkip_encrypt, .decrypt_mpdu = lib80211_tkip_decrypt, .encrypt_msdu = lib80211_michael_mic_add, diff --git a/trunk/net/wireless/lib80211_crypt_wep.c b/trunk/net/wireless/lib80211_crypt_wep.c index e2e88878ba35..6d41e05ca33b 100644 --- a/trunk/net/wireless/lib80211_crypt_wep.c +++ b/trunk/net/wireless/lib80211_crypt_wep.c @@ -269,6 +269,7 @@ static struct lib80211_crypto_ops lib80211_crypt_wep = { .name = "WEP", .init = lib80211_wep_init, .deinit = lib80211_wep_deinit, + .build_iv = lib80211_wep_build_iv, .encrypt_mpdu = lib80211_wep_encrypt, .decrypt_mpdu = lib80211_wep_decrypt, .encrypt_msdu = NULL, diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 37902a54e9c1..fbfac588297c 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -2769,7 +2769,6 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, nla_put_failure: genlmsg_cancel(msg, hdr); - nlmsg_free(msg); err = -EMSGSIZE; out: /* Cleanup */ @@ -2961,7 +2960,6 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) nla_put_failure: genlmsg_cancel(msg, hdr); - nlmsg_free(msg); err = -EMSGSIZE; out: mutex_unlock(&cfg80211_mutex); diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index f180db0de66c..1ac2bdd46ecf 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -66,10 +66,18 @@ static struct platform_device *reg_pdev; */ const struct ieee80211_regdomain *cfg80211_regdomain; +/* + * We use this as a place for the rd structure built from the + * last parsed country IE to rest until CRDA gets back to us with + * what it thinks should apply for the same country + */ +static const struct ieee80211_regdomain *country_ie_regdomain; + /* * Protects static reg.c components: * - cfg80211_world_regdom * - cfg80211_regdom + * - country_ie_regdomain * - last_request */ static DEFINE_MUTEX(reg_mutex); @@ -267,6 +275,25 @@ static bool is_user_regdom_saved(void) return true; } +/** + * country_ie_integrity_changes - tells us if the country IE has changed + * @checksum: checksum of country IE of fields we are interested in + * + * If the country IE has not changed you can ignore it safely. This is + * useful to determine if two devices are seeing two different country IEs + * even on the same alpha2. Note that this will return false if no IE has + * been set on the wireless core yet. + */ +static bool country_ie_integrity_changes(u32 checksum) +{ + /* If no IE has been set then the checksum doesn't change */ + if (unlikely(!last_request->country_ie_checksum)) + return false; + if (unlikely(last_request->country_ie_checksum != checksum)) + return true; + return false; +} + static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd, const struct ieee80211_regdomain *src_regd) { @@ -478,6 +505,471 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range, #undef ONE_GHZ_IN_KHZ } +/* + * This is a work around for sanity checking ieee80211_channel_to_frequency()'s + * work. ieee80211_channel_to_frequency() can for example currently provide a + * 2 GHz channel when in fact a 5 GHz channel was desired. An example would be + * an AP providing channel 8 on a country IE triplet when it sent this on the + * 5 GHz band, that channel is designed to be channel 8 on 5 GHz, not a 2 GHz + * channel. + * + * This can be removed once ieee80211_channel_to_frequency() takes in a band. + */ +static bool chan_in_band(int chan, enum ieee80211_band band) +{ + int center_freq = ieee80211_channel_to_frequency(chan); + + switch (band) { + case IEEE80211_BAND_2GHZ: + if (center_freq <= 2484) + return true; + return false; + case IEEE80211_BAND_5GHZ: + if (center_freq >= 5005) + return true; + return false; + default: + return false; + } +} + +/* + * Some APs may send a country IE triplet for each channel they + * support and while this is completely overkill and silly we still + * need to support it. We avoid making a single rule for each channel + * though and to help us with this we use this helper to find the + * actual subband end channel. These type of country IE triplet + * scenerios are handled then, all yielding two regulaotry rules from + * parsing a country IE: + * + * [1] + * [2] + * [36] + * [40] + * + * [1] + * [2-4] + * [5-12] + * [36] + * [40-44] + * + * [1-4] + * [5-7] + * [36-44] + * [48-64] + * + * [36-36] + * [40-40] + * [44-44] + * [48-48] + * [52-52] + * [56-56] + * [60-60] + * [64-64] + * [100-100] + * [104-104] + * [108-108] + * [112-112] + * [116-116] + * [120-120] + * [124-124] + * [128-128] + * [132-132] + * [136-136] + * [140-140] + * + * Returns 0 if the IE has been found to be invalid in the middle + * somewhere. + */ +static int max_subband_chan(enum ieee80211_band band, + int orig_cur_chan, + int orig_end_channel, + s8 orig_max_power, + u8 **country_ie, + u8 *country_ie_len) +{ + u8 *triplets_start = *country_ie; + u8 len_at_triplet = *country_ie_len; + int end_subband_chan = orig_end_channel; + + /* + * We'll deal with padding for the caller unless + * its not immediate and we don't process any channels + */ + if (*country_ie_len == 1) { + *country_ie += 1; + *country_ie_len -= 1; + return orig_end_channel; + } + + /* Move to the next triplet and then start search */ + *country_ie += 3; + *country_ie_len -= 3; + + if (!chan_in_band(orig_cur_chan, band)) + return 0; + + while (*country_ie_len >= 3) { + int end_channel = 0; + struct ieee80211_country_ie_triplet *triplet = + (struct ieee80211_country_ie_triplet *) *country_ie; + int cur_channel = 0, next_expected_chan; + + /* means last triplet is completely unrelated to this one */ + if (triplet->ext.reg_extension_id >= + IEEE80211_COUNTRY_EXTENSION_ID) { + *country_ie -= 3; + *country_ie_len += 3; + break; + } + + if (triplet->chans.first_channel == 0) { + *country_ie += 1; + *country_ie_len -= 1; + if (*country_ie_len != 0) + return 0; + break; + } + + if (triplet->chans.num_channels == 0) + return 0; + + /* Monitonically increasing channel order */ + if (triplet->chans.first_channel <= end_subband_chan) + return 0; + + if (!chan_in_band(triplet->chans.first_channel, band)) + return 0; + + /* 2 GHz */ + if (triplet->chans.first_channel <= 14) { + end_channel = triplet->chans.first_channel + + triplet->chans.num_channels - 1; + } + else { + end_channel = triplet->chans.first_channel + + (4 * (triplet->chans.num_channels - 1)); + } + + if (!chan_in_band(end_channel, band)) + return 0; + + if (orig_max_power != triplet->chans.max_power) { + *country_ie -= 3; + *country_ie_len += 3; + break; + } + + cur_channel = triplet->chans.first_channel; + + /* The key is finding the right next expected channel */ + if (band == IEEE80211_BAND_2GHZ) + next_expected_chan = end_subband_chan + 1; + else + next_expected_chan = end_subband_chan + 4; + + if (cur_channel != next_expected_chan) { + *country_ie -= 3; + *country_ie_len += 3; + break; + } + + end_subband_chan = end_channel; + + /* Move to the next one */ + *country_ie += 3; + *country_ie_len -= 3; + + /* + * Padding needs to be dealt with if we processed + * some channels. + */ + if (*country_ie_len == 1) { + *country_ie += 1; + *country_ie_len -= 1; + break; + } + + /* If seen, the IE is invalid */ + if (*country_ie_len == 2) + return 0; + } + + if (end_subband_chan == orig_end_channel) { + *country_ie = triplets_start; + *country_ie_len = len_at_triplet; + return orig_end_channel; + } + + return end_subband_chan; +} + +/* + * Converts a country IE to a regulatory domain. A regulatory domain + * structure has a lot of information which the IE doesn't yet have, + * so for the other values we use upper max values as we will intersect + * with our userspace regulatory agent to get lower bounds. + */ +static struct ieee80211_regdomain *country_ie_2_rd( + enum ieee80211_band band, + u8 *country_ie, + u8 country_ie_len, + u32 *checksum) +{ + struct ieee80211_regdomain *rd = NULL; + unsigned int i = 0; + char alpha2[2]; + u32 flags = 0; + u32 num_rules = 0, size_of_regd = 0; + u8 *triplets_start = NULL; + u8 len_at_triplet = 0; + /* the last channel we have registered in a subband (triplet) */ + int last_sub_max_channel = 0; + + *checksum = 0xDEADBEEF; + + /* Country IE requirements */ + BUG_ON(country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN || + country_ie_len & 0x01); + + alpha2[0] = country_ie[0]; + alpha2[1] = country_ie[1]; + + /* + * Third octet can be: + * 'I' - Indoor + * 'O' - Outdoor + * + * anything else we assume is no restrictions + */ + if (country_ie[2] == 'I') + flags = NL80211_RRF_NO_OUTDOOR; + else if (country_ie[2] == 'O') + flags = NL80211_RRF_NO_INDOOR; + + country_ie += 3; + country_ie_len -= 3; + + triplets_start = country_ie; + len_at_triplet = country_ie_len; + + *checksum ^= ((flags ^ alpha2[0] ^ alpha2[1]) << 8); + + /* + * We need to build a reg rule for each triplet, but first we must + * calculate the number of reg rules we will need. We will need one + * for each channel subband + */ + while (country_ie_len >= 3) { + int end_channel = 0; + struct ieee80211_country_ie_triplet *triplet = + (struct ieee80211_country_ie_triplet *) country_ie; + int cur_sub_max_channel = 0, cur_channel = 0; + + if (triplet->ext.reg_extension_id >= + IEEE80211_COUNTRY_EXTENSION_ID) { + country_ie += 3; + country_ie_len -= 3; + continue; + } + + /* + * APs can add padding to make length divisible + * by two, required by the spec. + */ + if (triplet->chans.first_channel == 0) { + country_ie++; + country_ie_len--; + /* This is expected to be at the very end only */ + if (country_ie_len != 0) + return NULL; + break; + } + + if (triplet->chans.num_channels == 0) + return NULL; + + if (!chan_in_band(triplet->chans.first_channel, band)) + return NULL; + + /* 2 GHz */ + if (band == IEEE80211_BAND_2GHZ) + end_channel = triplet->chans.first_channel + + triplet->chans.num_channels - 1; + else + /* + * 5 GHz -- For example in country IEs if the first + * channel given is 36 and the number of channels is 4 + * then the individual channel numbers defined for the + * 5 GHz PHY by these parameters are: 36, 40, 44, and 48 + * and not 36, 37, 38, 39. + * + * See: http://tinyurl.com/11d-clarification + */ + end_channel = triplet->chans.first_channel + + (4 * (triplet->chans.num_channels - 1)); + + cur_channel = triplet->chans.first_channel; + + /* + * Enhancement for APs that send a triplet for every channel + * or for whatever reason sends triplets with multiple channels + * separated when in fact they should be together. + */ + end_channel = max_subband_chan(band, + cur_channel, + end_channel, + triplet->chans.max_power, + &country_ie, + &country_ie_len); + if (!end_channel) + return NULL; + + if (!chan_in_band(end_channel, band)) + return NULL; + + cur_sub_max_channel = end_channel; + + /* Basic sanity check */ + if (cur_sub_max_channel < cur_channel) + return NULL; + + /* + * Do not allow overlapping channels. Also channels + * passed in each subband must be monotonically + * increasing + */ + if (last_sub_max_channel) { + if (cur_channel <= last_sub_max_channel) + return NULL; + if (cur_sub_max_channel <= last_sub_max_channel) + return NULL; + } + + /* + * When dot11RegulatoryClassesRequired is supported + * we can throw ext triplets as part of this soup, + * for now we don't care when those change as we + * don't support them + */ + *checksum ^= ((cur_channel ^ cur_sub_max_channel) << 8) | + ((cur_sub_max_channel ^ cur_sub_max_channel) << 16) | + ((triplet->chans.max_power ^ cur_sub_max_channel) << 24); + + last_sub_max_channel = cur_sub_max_channel; + + num_rules++; + + if (country_ie_len >= 3) { + country_ie += 3; + country_ie_len -= 3; + } + + /* + * Note: this is not a IEEE requirement but + * simply a memory requirement + */ + if (num_rules > NL80211_MAX_SUPP_REG_RULES) + return NULL; + } + + country_ie = triplets_start; + country_ie_len = len_at_triplet; + + size_of_regd = sizeof(struct ieee80211_regdomain) + + (num_rules * sizeof(struct ieee80211_reg_rule)); + + rd = kzalloc(size_of_regd, GFP_KERNEL); + if (!rd) + return NULL; + + rd->n_reg_rules = num_rules; + rd->alpha2[0] = alpha2[0]; + rd->alpha2[1] = alpha2[1]; + + /* This time around we fill in the rd */ + while (country_ie_len >= 3) { + int end_channel = 0; + struct ieee80211_country_ie_triplet *triplet = + (struct ieee80211_country_ie_triplet *) country_ie; + struct ieee80211_reg_rule *reg_rule = NULL; + struct ieee80211_freq_range *freq_range = NULL; + struct ieee80211_power_rule *power_rule = NULL; + + /* + * Must parse if dot11RegulatoryClassesRequired is true, + * we don't support this yet + */ + if (triplet->ext.reg_extension_id >= + IEEE80211_COUNTRY_EXTENSION_ID) { + country_ie += 3; + country_ie_len -= 3; + continue; + } + + if (triplet->chans.first_channel == 0) { + country_ie++; + country_ie_len--; + break; + } + + reg_rule = &rd->reg_rules[i]; + freq_range = ®_rule->freq_range; + power_rule = ®_rule->power_rule; + + reg_rule->flags = flags; + + /* 2 GHz */ + if (band == IEEE80211_BAND_2GHZ) + end_channel = triplet->chans.first_channel + + triplet->chans.num_channels -1; + else + end_channel = triplet->chans.first_channel + + (4 * (triplet->chans.num_channels - 1)); + + end_channel = max_subband_chan(band, + triplet->chans.first_channel, + end_channel, + triplet->chans.max_power, + &country_ie, + &country_ie_len); + + /* + * The +10 is since the regulatory domain expects + * the actual band edge, not the center of freq for + * its start and end freqs, assuming 20 MHz bandwidth on + * the channels passed + */ + freq_range->start_freq_khz = + MHZ_TO_KHZ(ieee80211_channel_to_frequency( + triplet->chans.first_channel) - 10); + freq_range->end_freq_khz = + MHZ_TO_KHZ(ieee80211_channel_to_frequency( + end_channel) + 10); + + /* + * These are large arbitrary values we use to intersect later. + * Increment this if we ever support >= 40 MHz channels + * in IEEE 802.11 + */ + freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40); + power_rule->max_antenna_gain = DBI_TO_MBI(100); + power_rule->max_eirp = DBM_TO_MBM(triplet->chans.max_power); + + i++; + + if (country_ie_len >= 3) { + country_ie += 3; + country_ie_len -= 3; + } + + BUG_ON(i > NL80211_MAX_SUPP_REG_RULES); + } + + return rd; +} + + /* * Helper for regdom_intersect(), this does the real * mathematical intersection fun @@ -699,6 +1191,7 @@ static int freq_reg_info_regd(struct wiphy *wiphy, return -EINVAL; } +EXPORT_SYMBOL(freq_reg_info); int freq_reg_info(struct wiphy *wiphy, u32 center_freq, @@ -712,7 +1205,6 @@ int freq_reg_info(struct wiphy *wiphy, reg_rule, NULL); } -EXPORT_SYMBOL(freq_reg_info); /* * Note that right now we assume the desired channel bandwidth @@ -751,8 +1243,41 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, desired_bw_khz, ®_rule); - if (r) + if (r) { + /* + * This means no regulatory rule was found in the country IE + * with a frequency range on the center_freq's band, since + * IEEE-802.11 allows for a country IE to have a subset of the + * regulatory information provided in a country we ignore + * disabling the channel unless at least one reg rule was + * found on the center_freq's band. For details see this + * clarification: + * + * http://tinyurl.com/11d-clarification + */ + if (r == -ERANGE && + last_request->initiator == + NL80211_REGDOM_SET_BY_COUNTRY_IE) { + REG_DBG_PRINT("cfg80211: Leaving channel %d MHz " + "intact on %s - no rule found in band on " + "Country IE\n", + chan->center_freq, wiphy_name(wiphy)); + } else { + /* + * In this case we know the country IE has at least one reg rule + * for the band so we respect its band definitions + */ + if (last_request->initiator == + NL80211_REGDOM_SET_BY_COUNTRY_IE) + REG_DBG_PRINT("cfg80211: Disabling " + "channel %d MHz on %s due to " + "Country IE\n", + chan->center_freq, wiphy_name(wiphy)); + flags |= IEEE80211_CHAN_DISABLED; + chan->flags = flags; + } return; + } power_rule = ®_rule->power_rule; freq_range = ®_rule->freq_range; @@ -1306,7 +1831,6 @@ static void reg_process_hint(struct regulatory_request *reg_request) { int r = 0; struct wiphy *wiphy = NULL; - enum nl80211_reg_initiator initiator = reg_request->initiator; BUG_ON(!reg_request->alpha2); @@ -1326,7 +1850,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) /* This is required so that the orig_* parameters are saved */ if (r == -EALREADY && wiphy && wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) - wiphy_update_regulatory(wiphy, initiator); + wiphy_update_regulatory(wiphy, reg_request->initiator); out: mutex_unlock(®_mutex); mutex_unlock(&cfg80211_mutex); @@ -1484,6 +2008,35 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2) } EXPORT_SYMBOL(regulatory_hint); +/* Caller must hold reg_mutex */ +static bool reg_same_country_ie_hint(struct wiphy *wiphy, + u32 country_ie_checksum) +{ + struct wiphy *request_wiphy; + + assert_reg_lock(); + + if (unlikely(last_request->initiator != + NL80211_REGDOM_SET_BY_COUNTRY_IE)) + return false; + + request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); + + if (!request_wiphy) + return false; + + if (likely(request_wiphy != wiphy)) + return !country_ie_integrity_changes(country_ie_checksum); + /* + * We should not have let these through at this point, they + * should have been picked up earlier by the first alpha2 check + * on the device + */ + if (WARN_ON(!country_ie_integrity_changes(country_ie_checksum))) + return true; + return false; +} + /* * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and * therefore cannot iterate over the rdev list here. @@ -1493,7 +2046,9 @@ void regulatory_hint_11d(struct wiphy *wiphy, u8 *country_ie, u8 country_ie_len) { + struct ieee80211_regdomain *rd = NULL; char alpha2[2]; + u32 checksum = 0; enum environment_cap env = ENVIRON_ANY; struct regulatory_request *request; @@ -1509,6 +2064,14 @@ void regulatory_hint_11d(struct wiphy *wiphy, if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) goto out; + /* + * Pending country IE processing, this can happen after we + * call CRDA and wait for a response if a beacon was received before + * we were able to process the last regulatory_hint_11d() call + */ + if (country_ie_regdomain) + goto out; + alpha2[0] = country_ie[0]; alpha2[1] = country_ie[1]; @@ -1527,14 +2090,39 @@ void regulatory_hint_11d(struct wiphy *wiphy, wiphy_idx_valid(last_request->wiphy_idx))) goto out; + rd = country_ie_2_rd(band, country_ie, country_ie_len, &checksum); + if (!rd) { + REG_DBG_PRINT("cfg80211: Ignoring bogus country IE\n"); + goto out; + } + + /* + * This will not happen right now but we leave it here for the + * the future when we want to add suspend/resume support and having + * the user move to another country after doing so, or having the user + * move to another AP. Right now we just trust the first AP. + * + * If we hit this before we add this support we want to be informed of + * it as it would indicate a mistake in the current design + */ + if (WARN_ON(reg_same_country_ie_hint(wiphy, checksum))) + goto free_rd_out; + request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); if (!request) - goto out; + goto free_rd_out; + + /* + * We keep this around for when CRDA comes back with a response so + * we can intersect with that + */ + country_ie_regdomain = rd; request->wiphy_idx = get_wiphy_idx(wiphy); - request->alpha2[0] = alpha2[0]; - request->alpha2[1] = alpha2[1]; + request->alpha2[0] = rd->alpha2[0]; + request->alpha2[1] = rd->alpha2[1]; request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE; + request->country_ie_checksum = checksum; request->country_ie_env = env; mutex_unlock(®_mutex); @@ -1543,6 +2131,8 @@ void regulatory_hint_11d(struct wiphy *wiphy, return; +free_rd_out: + kfree(rd); out: mutex_unlock(®_mutex); } @@ -1793,6 +2383,33 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd) print_rd_rules(rd); } +#ifdef CONFIG_CFG80211_REG_DEBUG +static void reg_country_ie_process_debug( + const struct ieee80211_regdomain *rd, + const struct ieee80211_regdomain *country_ie_regdomain, + const struct ieee80211_regdomain *intersected_rd) +{ + printk(KERN_DEBUG "cfg80211: Received country IE:\n"); + print_regdomain_info(country_ie_regdomain); + printk(KERN_DEBUG "cfg80211: CRDA thinks this should applied:\n"); + print_regdomain_info(rd); + if (intersected_rd) { + printk(KERN_DEBUG "cfg80211: We intersect both of these " + "and get:\n"); + print_regdomain_info(intersected_rd); + return; + } + printk(KERN_DEBUG "cfg80211: Intersection between both failed\n"); +} +#else +static inline void reg_country_ie_process_debug( + const struct ieee80211_regdomain *rd, + const struct ieee80211_regdomain *country_ie_regdomain, + const struct ieee80211_regdomain *intersected_rd) +{ +} +#endif + /* Takes ownership of rd only if it doesn't fail */ static int __set_regdom(const struct ieee80211_regdomain *rd) { @@ -1904,6 +2521,34 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) return 0; } + /* + * Country IE requests are handled a bit differently, we intersect + * the country IE rd with what CRDA believes that country should have + */ + + /* + * Userspace could have sent two replies with only + * one kernel request. By the second reply we would have + * already processed and consumed the country_ie_regdomain. + */ + if (!country_ie_regdomain) + return -EALREADY; + BUG_ON(rd == country_ie_regdomain); + + /* + * Intersect what CRDA returned and our what we + * had built from the Country IE received + */ + + intersected_rd = regdom_intersect(rd, country_ie_regdomain); + + reg_country_ie_process_debug(rd, + country_ie_regdomain, + intersected_rd); + + kfree(country_ie_regdomain); + country_ie_regdomain = NULL; + if (!intersected_rd) return -EINVAL; @@ -2043,6 +2688,9 @@ void /* __init_or_exit */ regulatory_exit(void) reset_regdomains(); + kfree(country_ie_regdomain); + country_ie_regdomain = NULL; + kfree(last_request); platform_device_unregister(reg_pdev); diff --git a/trunk/net/wireless/scan.c b/trunk/net/wireless/scan.c index 5ca8c7180141..58401d246bda 100644 --- a/trunk/net/wireless/scan.c +++ b/trunk/net/wireless/scan.c @@ -275,7 +275,6 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, { struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy); struct cfg80211_internal_bss *bss, *res = NULL; - unsigned long now = jiffies; spin_lock_bh(&dev->bss_lock); @@ -284,10 +283,6 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, continue; if (channel && bss->pub.channel != channel) continue; - /* Don't get expired BSS structs */ - if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) && - !atomic_read(&bss->hold)) - continue; if (is_bss(&bss->pub, bssid, ssid, ssid_len)) { res = bss; kref_get(&res->ref); diff --git a/trunk/net/wireless/sme.c b/trunk/net/wireless/sme.c index a8c2d6b877ae..72222f0074db 100644 --- a/trunk/net/wireless/sme.c +++ b/trunk/net/wireless/sme.c @@ -35,7 +35,7 @@ struct cfg80211_conn { bool auto_auth, prev_bssid_valid; }; -static bool cfg80211_is_all_idle(void) +bool cfg80211_is_all_idle(void) { struct cfg80211_registered_device *rdev; struct wireless_dev *wdev; diff --git a/trunk/net/wireless/wext-compat.c b/trunk/net/wireless/wext-compat.c index bb5e0a5ecfa1..1ff1e9f49136 100644 --- a/trunk/net/wireless/wext-compat.c +++ b/trunk/net/wireless/wext-compat.c @@ -1471,7 +1471,6 @@ int cfg80211_wext_siwpmksa(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa); static const iw_handler cfg80211_handlers[] = { [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,