From e136e3036bf27569dbfeae245cc09c7167cdc749 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 2 Jan 2009 13:47:39 +0000 Subject: hso: net driver using tty without locking Checking tty == NULL doesn't help us unless we have a clear semantic for the locking of the tty object in the driver. Use the tty kref objects so that we can take references to the tty in the USB event handling paths. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 54 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 9f7896a25f1..d345a6eec4c 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1015,7 +1015,7 @@ static void _hso_serial_set_termios(struct tty_struct *tty, struct hso_serial *serial = get_serial_by_tty(tty); struct ktermios *termios; - if ((!tty) || (!tty->termios) || (!serial)) { + if (!serial) { printk(KERN_ERR "%s: no tty structures", __func__); return; } @@ -1057,14 +1057,14 @@ static void _hso_serial_set_termios(struct tty_struct *tty, termios->c_cflag |= CS8; /* character size 8 bits */ /* baud rate 115200 */ - tty_encode_baud_rate(serial->tty, 115200, 115200); + tty_encode_baud_rate(tty, 115200, 115200); /* * Force low_latency on; otherwise the pushes are scheduled; * this is bad as it opens up the possibility of dropping bytes * on the floor. We don't want to drop bytes on the floor. :) */ - serial->tty->low_latency = 1; + tty->low_latency = 1; return; } @@ -1228,6 +1228,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) /* sanity check */ if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) { + WARN_ON(1); tty->driver_data = NULL; D1("Failed to open port"); return -ENODEV; @@ -1242,8 +1243,10 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) kref_get(&serial->parent->ref); /* setup */ + spin_lock_irq(&serial->serial_lock); tty->driver_data = serial; - serial->tty = tty; + serial->tty = tty_kref_get(tty); + spin_unlock_irq(&serial->serial_lock); /* check for port already opened, if not set the termios */ serial->open_count++; @@ -1285,6 +1288,10 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) D1("Closing serial port"); + /* Open failed, no close cleanup required */ + if (serial == NULL) + return; + mutex_lock(&serial->parent->mutex); usb_gone = serial->parent->usb_gone; @@ -1297,10 +1304,13 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) kref_put(&serial->parent->ref, hso_serial_ref_free); if (serial->open_count <= 0) { serial->open_count = 0; - if (serial->tty) { + spin_lock_irq(&serial->serial_lock); + if (serial->tty == tty) { serial->tty->driver_data = NULL; serial->tty = NULL; + tty_kref_put(tty); } + spin_unlock_irq(&serial->serial_lock); if (!usb_gone) hso_stop_serial_device(serial->parent); tasklet_kill(&serial->unthrottle_tasklet); @@ -1653,6 +1663,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) { struct hso_serial *serial = urb->context; int status = urb->status; + struct tty_struct *tty; /* sanity check */ if (!serial) { @@ -1662,14 +1673,18 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) spin_lock(&serial->serial_lock); serial->tx_urb_used = 0; + tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { log_usb_status(status, __func__); + tty_kref_put(tty); return; } hso_put_activity(serial->parent); - if (serial->tty) - tty_wakeup(serial->tty); + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } hso_kick_transmit(serial); D1(" "); @@ -1706,6 +1721,7 @@ static void ctrl_callback(struct urb *urb) struct hso_serial *serial = urb->context; struct usb_ctrlrequest *req; int status = urb->status; + struct tty_struct *tty; /* sanity check */ if (!serial) @@ -1713,9 +1729,11 @@ static void ctrl_callback(struct urb *urb) spin_lock(&serial->serial_lock); serial->tx_urb_used = 0; + tty = tty_kref_get(serial->tty); spin_unlock(&serial->serial_lock); if (status) { log_usb_status(status, __func__); + tty_kref_put(tty); return; } @@ -1734,25 +1752,31 @@ static void ctrl_callback(struct urb *urb) spin_unlock(&serial->serial_lock); } else { hso_put_activity(serial->parent); - if (serial->tty) - tty_wakeup(serial->tty); + if (tty) + tty_wakeup(tty); /* response to a write command */ hso_kick_transmit(serial); } + tty_kref_put(tty); } /* handle RX data for serial port */ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) { - struct tty_struct *tty = serial->tty; + struct tty_struct *tty; int write_length_remaining = 0; int curr_write_len; + /* Sanity check */ if (urb == NULL || serial == NULL) { D1("serial = NULL"); return -2; } + spin_lock(&serial->serial_lock); + tty = tty_kref_get(serial->tty); + spin_unlock(&serial->serial_lock); + /* Push data to tty */ if (tty) { write_length_remaining = urb->actual_length - @@ -1774,6 +1798,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) serial->curr_rx_urb_offset = 0; serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; } + tty_kref_put(tty); return write_length_remaining; } @@ -2786,15 +2811,20 @@ static void hso_serial_ref_free(struct kref *ref) static void hso_free_interface(struct usb_interface *interface) { struct hso_serial *hso_dev; + struct tty_struct *tty; int i; for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { if (serial_table[i] && (serial_table[i]->interface == interface)) { hso_dev = dev2ser(serial_table[i]); - if (hso_dev->tty) - tty_hangup(hso_dev->tty); + spin_lock_irq(&hso_dev->serial_lock); + tty = tty_kref_get(hso_dev->tty); + spin_unlock_irq(&hso_dev->serial_lock); + if (tty) + tty_hangup(tty); mutex_lock(&hso_dev->parent->mutex); + tty_kref_put(tty); hso_dev->parent->usb_gone = 1; mutex_unlock(&hso_dev->parent->mutex); kref_put(&serial_table[i]->ref, hso_serial_ref_free); -- cgit From ac9720c37e8795317e8be3adad63cb0d5522a640 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 2 Jan 2009 13:47:45 +0000 Subject: tty: Fix the HSO termios handling a bit Init the tty structure once Don't set ->low_latency twice in a row Don't force bits we should be leaving to the user Don't allocate termios arrays as these are in fact allocated by the tty layer for you and just overwrite the ones allocated in the driver Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 55 +++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index d345a6eec4c..7373fb6b3f8 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -362,8 +362,6 @@ static struct tty_driver *tty_drv; static struct hso_device *serial_table[HSO_SERIAL_TTY_MINORS]; static struct hso_device *network_table[HSO_MAX_NET_DEVICES]; static spinlock_t serial_table_lock; -static struct ktermios *hso_serial_termios[HSO_SERIAL_TTY_MINORS]; -static struct ktermios *hso_serial_termios_locked[HSO_SERIAL_TTY_MINORS]; static const s32 default_port_spec[] = { HSO_INTF_MUX | HSO_PORT_NETWORK, @@ -1009,23 +1007,11 @@ static void read_bulk_callback(struct urb *urb) /* Serial driver functions */ -static void _hso_serial_set_termios(struct tty_struct *tty, - struct ktermios *old) +static void hso_init_termios(struct ktermios *termios) { - struct hso_serial *serial = get_serial_by_tty(tty); - struct ktermios *termios; - - if (!serial) { - printk(KERN_ERR "%s: no tty structures", __func__); - return; - } - - D4("port %d", serial->minor); - /* * The default requirements for this device are: */ - termios = tty->termios; termios->c_iflag &= ~(IGNBRK /* disable ignore break */ | BRKINT /* disable break causes interrupt */ @@ -1057,15 +1043,38 @@ static void _hso_serial_set_termios(struct tty_struct *tty, termios->c_cflag |= CS8; /* character size 8 bits */ /* baud rate 115200 */ - tty_encode_baud_rate(tty, 115200, 115200); + tty_termios_encode_baud_rate(termios, 115200, 115200); +} + +static void _hso_serial_set_termios(struct tty_struct *tty, + struct ktermios *old) +{ + struct hso_serial *serial = get_serial_by_tty(tty); + struct ktermios *termios; + + if (!serial) { + printk(KERN_ERR "%s: no tty structures", __func__); + return; + } + + D4("port %d", serial->minor); /* - * Force low_latency on; otherwise the pushes are scheduled; - * this is bad as it opens up the possibility of dropping bytes - * on the floor. We don't want to drop bytes on the floor. :) + * Fix up unsupported bits */ - tty->low_latency = 1; - return; + termios = tty->termios; + termios->c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */ + + termios->c_cflag &= + ~(CSIZE /* no size */ + | PARENB /* disable parity bit */ + | CBAUD /* clear current baud rate */ + | CBAUDEX); /* clear current buad rate */ + + termios->c_cflag |= CS8; /* character size 8 bits */ + + /* baud rate 115200 */ + tty_encode_baud_rate(tty, 115200, 115200); } static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) @@ -2969,9 +2978,7 @@ static int __init hso_init(void) tty_drv->subtype = SERIAL_TYPE_NORMAL; tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_drv->init_termios = tty_std_termios; - tty_drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - tty_drv->termios = hso_serial_termios; - tty_drv->termios_locked = hso_serial_termios_locked; + hso_init_termios(&tty_drv->init_termios); tty_set_operations(tty_drv, &hso_serial_ops); /* register the tty driver */ -- cgit From 542f54823614915780c3459b0e6062f06c0c0f99 Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Fri, 2 Jan 2009 13:47:52 +0000 Subject: tty: Modem functions for the HSO driver Makes TIOCM ioctls for Data Carrier Detect & related functions work like /drivers/serial/serial-core.c potentially needed for pppd & similar user programs. Signed-off-by: Denis Joseph Barrow Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 318 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 7373fb6b3f8..d974d970e5f 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -39,8 +39,11 @@ * port is opened, as this have a huge impact on the network port * throughput. * - * Interface 2: Standard modem interface - circuit switched interface, should - * not be used. + * Interface 2: Standard modem interface - circuit switched interface, this + * can be used to make a standard ppp connection however it + * should not be used in conjunction with the IP network interface + * enabled for USB performance reasons i.e. if using this set + * ideally disable_net=1. * *****************************************************************************/ @@ -63,6 +66,8 @@ #include #include #include +#include +#include #define DRIVER_VERSION "1.2" @@ -182,6 +187,41 @@ enum rx_ctrl_state{ RX_PENDING }; +#define BM_REQUEST_TYPE (0xa1) +#define B_NOTIFICATION (0x20) +#define W_VALUE (0x0) +#define W_INDEX (0x2) +#define W_LENGTH (0x2) + +#define B_OVERRUN (0x1<<6) +#define B_PARITY (0x1<<5) +#define B_FRAMING (0x1<<4) +#define B_RING_SIGNAL (0x1<<3) +#define B_BREAK (0x1<<2) +#define B_TX_CARRIER (0x1<<1) +#define B_RX_CARRIER (0x1<<0) + +struct hso_serial_state_notification { + u8 bmRequestType; + u8 bNotification; + u16 wValue; + u16 wIndex; + u16 wLength; + u16 UART_state_bitmap; +} __attribute__((packed)); + +struct hso_tiocmget { + struct mutex mutex; + wait_queue_head_t waitq; + int intr_completed; + struct usb_endpoint_descriptor *endp; + struct urb *urb; + struct hso_serial_state_notification serial_state_notification; + u16 prev_UART_state_bitmap; + struct uart_icount icount; +}; + + struct hso_serial { struct hso_device *parent; int magic; @@ -219,6 +259,7 @@ struct hso_serial { spinlock_t serial_lock; int (*write_data) (struct hso_serial *serial); + struct hso_tiocmget *tiocmget; /* Hacks required to get flow control * working on the serial receive buffers * so as not to drop characters on the floor. @@ -305,7 +346,7 @@ static void async_get_intf(struct work_struct *data); static void async_put_intf(struct work_struct *data); static int hso_put_activity(struct hso_device *hso_dev); static int hso_get_activity(struct hso_device *hso_dev); - +static void tiocmget_intr_callback(struct urb *urb); /*****************************************************************************/ /* Helping functions */ /*****************************************************************************/ @@ -1419,25 +1460,217 @@ static int hso_serial_chars_in_buffer(struct tty_struct *tty) return chars; } +int tiocmget_submit_urb(struct hso_serial *serial, + struct hso_tiocmget *tiocmget, + struct usb_device *usb) +{ + int result; + + if (serial->parent->usb_gone) + return -ENODEV; + usb_fill_int_urb(tiocmget->urb, usb, + usb_rcvintpipe(usb, + tiocmget->endp-> + bEndpointAddress & 0x7F), + &tiocmget->serial_state_notification, + sizeof(struct hso_serial_state_notification), + tiocmget_intr_callback, serial, + tiocmget->endp->bInterval); + result = usb_submit_urb(tiocmget->urb, GFP_ATOMIC); + if (result) { + dev_warn(&usb->dev, "%s usb_submit_urb failed %d\n", __func__, + result); + } + return result; + +} + +static void tiocmget_intr_callback(struct urb *urb) +{ + struct hso_serial *serial = urb->context; + struct hso_tiocmget *tiocmget; + int status = urb->status; + u16 UART_state_bitmap, prev_UART_state_bitmap; + struct uart_icount *icount; + struct hso_serial_state_notification *serial_state_notification; + struct usb_device *usb; + + /* Sanity checks */ + if (!serial) + return; + if (status) { + log_usb_status(status, __func__); + return; + } + tiocmget = serial->tiocmget; + if (!tiocmget) + return; + usb = serial->parent->usb; + serial_state_notification = &tiocmget->serial_state_notification; + if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || + serial_state_notification->bNotification != B_NOTIFICATION || + le16_to_cpu(serial_state_notification->wValue) != W_VALUE || + le16_to_cpu(serial_state_notification->wIndex) != W_INDEX || + le16_to_cpu(serial_state_notification->wLength) != W_LENGTH) { + dev_warn(&usb->dev, + "hso received invalid serial state notification\n"); + DUMP(serial_state_notification, + sizeof(hso_serial_state_notifation)) + } else { + + UART_state_bitmap = le16_to_cpu(serial_state_notification-> + UART_state_bitmap); + prev_UART_state_bitmap = tiocmget->prev_UART_state_bitmap; + icount = &tiocmget->icount; + spin_lock(&serial->serial_lock); + if ((UART_state_bitmap & B_OVERRUN) != + (prev_UART_state_bitmap & B_OVERRUN)) + icount->parity++; + if ((UART_state_bitmap & B_PARITY) != + (prev_UART_state_bitmap & B_PARITY)) + icount->parity++; + if ((UART_state_bitmap & B_FRAMING) != + (prev_UART_state_bitmap & B_FRAMING)) + icount->frame++; + if ((UART_state_bitmap & B_RING_SIGNAL) && + !(prev_UART_state_bitmap & B_RING_SIGNAL)) + icount->rng++; + if ((UART_state_bitmap & B_BREAK) != + (prev_UART_state_bitmap & B_BREAK)) + icount->brk++; + if ((UART_state_bitmap & B_TX_CARRIER) != + (prev_UART_state_bitmap & B_TX_CARRIER)) + icount->dsr++; + if ((UART_state_bitmap & B_RX_CARRIER) != + (prev_UART_state_bitmap & B_RX_CARRIER)) + icount->dcd++; + tiocmget->prev_UART_state_bitmap = UART_state_bitmap; + spin_unlock(&serial->serial_lock); + tiocmget->intr_completed = 1; + wake_up_interruptible(&tiocmget->waitq); + } + memset(serial_state_notification, 0, + sizeof(struct hso_serial_state_notification)); + tiocmget_submit_urb(serial, + tiocmget, + serial->parent->usb); +} + +/* + * next few functions largely stolen from drivers/serial/serial_core.c + */ +/* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ +static int +hso_wait_modem_status(struct hso_serial *serial, unsigned long arg) +{ + DECLARE_WAITQUEUE(wait, current); + struct uart_icount cprev, cnow; + struct hso_tiocmget *tiocmget; + int ret; + + tiocmget = serial->tiocmget; + if (!tiocmget) + return -ENOENT; + /* + * note the counters on entry + */ + spin_lock_irq(&serial->serial_lock); + memcpy(&cprev, &tiocmget->icount, sizeof(struct uart_icount)); + spin_unlock_irq(&serial->serial_lock); + add_wait_queue(&tiocmget->waitq, &wait); + for (;;) { + spin_lock_irq(&serial->serial_lock); + memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); + spin_unlock_irq(&serial->serial_lock); + set_current_state(TASK_INTERRUPTIBLE); + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd))) { + ret = 0; + break; + } + schedule(); + /* see if a signal did it */ + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + cprev = cnow; + } + current->state = TASK_RUNNING; + remove_wait_queue(&tiocmget->waitq, &wait); + + return ret; +} + +/* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ +static int hso_get_count(struct hso_serial *serial, + struct serial_icounter_struct __user *icnt) +{ + struct serial_icounter_struct icount; + struct uart_icount cnow; + struct hso_tiocmget *tiocmget = serial->tiocmget; + + if (!tiocmget) + return -ENOENT; + spin_lock_irq(&serial->serial_lock); + memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); + spin_unlock_irq(&serial->serial_lock); + + icount.cts = cnow.cts; + icount.dsr = cnow.dsr; + icount.rng = cnow.rng; + icount.dcd = cnow.dcd; + icount.rx = cnow.rx; + icount.tx = cnow.tx; + icount.frame = cnow.frame; + icount.overrun = cnow.overrun; + icount.parity = cnow.parity; + icount.brk = cnow.brk; + icount.buf_overrun = cnow.buf_overrun; + + return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0; +} + static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) { - unsigned int value; + int retval; struct hso_serial *serial = get_serial_by_tty(tty); - unsigned long flags; + struct hso_tiocmget *tiocmget; + u16 UART_state_bitmap; /* sanity check */ if (!serial) { D1("no tty structures"); return -EINVAL; } - - spin_lock_irqsave(&serial->serial_lock, flags); - value = ((serial->rts_state) ? TIOCM_RTS : 0) | + spin_lock_irq(&serial->serial_lock); + retval = ((serial->rts_state) ? TIOCM_RTS : 0) | ((serial->dtr_state) ? TIOCM_DTR : 0); - spin_unlock_irqrestore(&serial->serial_lock, flags); - - return value; + tiocmget = serial->tiocmget; + if (tiocmget) { + + UART_state_bitmap = le16_to_cpu( + tiocmget->prev_UART_state_bitmap); + if (UART_state_bitmap & B_RING_SIGNAL) + retval |= TIOCM_RNG; + if (UART_state_bitmap & B_RX_CARRIER) + retval |= TIOCM_CD; + if (UART_state_bitmap & B_TX_CARRIER) + retval |= TIOCM_DSR; + } + spin_unlock_irq(&serial->serial_lock); + return retval; } static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, @@ -1479,6 +1712,32 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, USB_CTRL_SET_TIMEOUT); } +static int hso_serial_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct hso_serial *serial = get_serial_by_tty(tty); + void __user *uarg = (void __user *)arg; + int ret = 0; + D4("IOCTL cmd: %d, arg: %ld", cmd, arg); + + if (!serial) + return -ENODEV; + switch (cmd) { + case TIOCMIWAIT: + ret = hso_wait_modem_status(serial, arg); + break; + + case TIOCGICOUNT: + ret = hso_get_count(serial, uarg); + break; + default: + ret = -ENOIOCTLCMD; + break; + } + return ret; +} + + /* starts a transmit */ static void hso_kick_transmit(struct hso_serial *serial) { @@ -1956,7 +2215,10 @@ static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags) serial->shared_int->use_count++; mutex_unlock(&serial->shared_int->shared_int_lock); } - + if (serial->tiocmget) + tiocmget_submit_urb(serial, + serial->tiocmget, + serial->parent->usb); return result; } @@ -1964,6 +2226,7 @@ static int hso_stop_serial_device(struct hso_device *hso_dev) { int i; struct hso_serial *serial = dev2ser(hso_dev); + struct hso_tiocmget *tiocmget; if (!serial) return -ENODEV; @@ -1992,6 +2255,11 @@ static int hso_stop_serial_device(struct hso_device *hso_dev) } mutex_unlock(&serial->shared_int->shared_int_lock); } + tiocmget = serial->tiocmget; + if (tiocmget) { + wake_up_interruptible(&tiocmget->waitq); + usb_kill_urb(tiocmget->urb); + } return 0; } @@ -2338,6 +2606,20 @@ exit: return NULL; } +static void hso_free_tiomget(struct hso_serial *serial) +{ + struct hso_tiocmget *tiocmget = serial->tiocmget; + if (tiocmget) { + kfree(tiocmget); + if (tiocmget->urb) { + usb_free_urb(tiocmget->urb); + tiocmget->urb = NULL; + } + serial->tiocmget = NULL; + + } +} + /* Frees an AT channel ( goes for both mux and non-mux ) */ static void hso_free_serial_device(struct hso_device *hso_dev) { @@ -2356,6 +2638,7 @@ static void hso_free_serial_device(struct hso_device *hso_dev) else mutex_unlock(&serial->shared_int->shared_int_lock); } + hso_free_tiomget(serial); kfree(serial); hso_free_device(hso_dev); } @@ -2367,6 +2650,7 @@ static struct hso_device *hso_create_bulk_serial_device( struct hso_device *hso_dev; struct hso_serial *serial; int num_urbs; + struct hso_tiocmget *tiocmget; hso_dev = hso_create_device(interface, port); if (!hso_dev) @@ -2379,8 +2663,27 @@ static struct hso_device *hso_create_bulk_serial_device( serial->parent = hso_dev; hso_dev->port_data.dev_serial = serial; - if (port & HSO_PORT_MODEM) + if (port & HSO_PORT_MODEM) { num_urbs = 2; + serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), + GFP_KERNEL); + /* it isn't going to break our heart if serial->tiocmget + * allocation fails don't bother checking this. + */ + if (serial->tiocmget) { + tiocmget = serial->tiocmget; + tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); + if (tiocmget->urb) { + mutex_init(&tiocmget->mutex); + init_waitqueue_head(&tiocmget->waitq); + tiocmget->endp = hso_get_ep( + interface, + USB_ENDPOINT_XFER_INT, + USB_DIR_IN); + } else + hso_free_tiomget(serial); + } + } else num_urbs = 1; @@ -2416,6 +2719,7 @@ static struct hso_device *hso_create_bulk_serial_device( exit2: hso_serial_common_free(serial); exit: + hso_free_tiomget(serial); kfree(serial); hso_free_device(hso_dev); return NULL; @@ -2926,6 +3230,7 @@ static const struct tty_operations hso_serial_ops = { .close = hso_serial_close, .write = hso_serial_write, .write_room = hso_serial_write_room, + .ioctl = hso_serial_ioctl, .set_termios = hso_serial_set_termios, .chars_in_buffer = hso_serial_chars_in_buffer, .tiocmget = hso_serial_tiocmget, -- cgit From 58eb17f155704062d76729d1fb7e23d3559ca86a Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Fri, 2 Jan 2009 13:50:29 +0000 Subject: hso modem detect fix patch against Alan Cox'es tty tree Fixed incorrect check for the modem port, this prevents crashes caused by issueing a tiocmget_submit_urb on endpoints which don't exist for non modem devices. Signed-off-by: Denis Joseph Barrow Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index d974d970e5f..148af34837f 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2663,7 +2663,7 @@ static struct hso_device *hso_create_bulk_serial_device( serial->parent = hso_dev; hso_dev->port_data.dev_serial = serial; - if (port & HSO_PORT_MODEM) { + if ((port & HSO_PORT_MASK) == HSO_PORT_MODEM) { num_urbs = 2; serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), GFP_KERNEL); -- cgit From 11cd29b028be88b13717401496fe4953fb96be03 Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Fri, 2 Jan 2009 13:50:36 +0000 Subject: hso maintainers update patch Added D.J. Barrow as maintainer of hso driver. Signed-off-by: Denis Joseph Barrow Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 148af34837f..c4918b86ed1 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -3,6 +3,8 @@ * Driver for Option High Speed Mobile Devices. * * Copyright (C) 2008 Option International + * Filip Aben + * Denis Joseph Barrow * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd) * * Copyright (C) 2008 Greg Kroah-Hartman -- cgit From 949b42544a20fb22800e244a004ff45bd359a21b Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Sun, 4 Jan 2009 16:09:40 -0800 Subject: firmware: convert acenic driver to request_firmware() We store the firmware in its native big-endian form now, so the loop in ace_copy() is modified to use be32_to_cpup() when writing it out. We can forget the BSS,SBSS sections of the firmware, since we were clearing all the device's RAM anyway. And the text,rodata,data sections can all be loaded as a single chunk since they're contiguous (give or take a few dozen bytes in between). Signed-off-by: Jaswinder Singh Signed-off-by: David Woodhouse Acked-by: Jes Sorensen Signed-off-by: David S. Miller --- drivers/net/acenic.c | 117 +++++++++++++++++++++++++++++++-------------------- drivers/net/acenic.h | 4 ++ 2 files changed, 75 insertions(+), 46 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 517fce48d94..5b396ff6c83 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -66,6 +66,7 @@ #include #include #include +#include #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include @@ -186,8 +187,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); #define MAX_RODATA_LEN 8*1024 #define MAX_DATA_LEN 2*1024 -#include "acenic_firmware.h" - #ifndef tigon2FwReleaseLocal #define tigon2FwReleaseLocal 0 #endif @@ -417,6 +416,10 @@ static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1}; MODULE_AUTHOR("Jes Sorensen "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver"); +#ifndef CONFIG_ACENIC_OMIT_TIGON_I +MODULE_FIRMWARE("acenic/tg1.bin"); +#endif +MODULE_FIRMWARE("acenic/tg2.bin"); module_param_array_named(link, link_state, int, NULL, 0); module_param_array(trace, int, NULL, 0); @@ -943,8 +946,8 @@ static int __devinit ace_init(struct net_device *dev) case 4: case 5: printk(KERN_INFO " Tigon I (Rev. %i), Firmware: %i.%i.%i, ", - tig_ver, tigonFwReleaseMajor, tigonFwReleaseMinor, - tigonFwReleaseFix); + tig_ver, ap->firmware_major, ap->firmware_minor, + ap->firmware_fix); writel(0, ®s->LocalCtrl); ap->version = 1; ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES; @@ -952,8 +955,8 @@ static int __devinit ace_init(struct net_device *dev) #endif case 6: printk(KERN_INFO " Tigon II (Rev. %i), Firmware: %i.%i.%i, ", - tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor, - tigon2FwReleaseFix); + tig_ver, ap->firmware_major, ap->firmware_minor, + ap->firmware_fix); writel(readl(®s->CpuBCtrl) | CPU_HALT, ®s->CpuBCtrl); readl(®s->CpuBCtrl); /* PCI write posting */ /* @@ -1205,7 +1208,9 @@ static int __devinit ace_init(struct net_device *dev) memset(ap->info, 0, sizeof(struct ace_info)); memset(ap->skb, 0, sizeof(struct ace_skb)); - ace_load_firmware(dev); + if (ace_load_firmware(dev)) + goto init_error; + ap->fw_running = 0; tmp_ptr = ap->info_dma; @@ -1441,10 +1446,7 @@ static int __devinit ace_init(struct net_device *dev) if (ap->version >= 2) writel(tmp, ®s->TuneFastLink); - if (ACE_IS_TIGON_I(ap)) - writel(tigonFwStartAddr, ®s->Pc); - if (ap->version == 2) - writel(tigon2FwStartAddr, ®s->Pc); + writel(ap->firmware_start, ®s->Pc); writel(0, ®s->Mb0Lo); @@ -2761,8 +2763,8 @@ static void ace_get_drvinfo(struct net_device *dev, strlcpy(info->driver, "acenic", sizeof(info->driver)); snprintf(info->version, sizeof(info->version), "%i.%i.%i", - tigonFwReleaseMajor, tigonFwReleaseMinor, - tigonFwReleaseFix); + ap->firmware_major, ap->firmware_minor, + ap->firmware_fix); if (ap->pdev) strlcpy(info->bus_info, pci_name(ap->pdev), @@ -2869,11 +2871,10 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev) } -static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src, - u32 dest, int size) +static void __devinit ace_copy(struct ace_regs __iomem *regs, const __be32 *src, + u32 dest, int size) { void __iomem *tdest; - u32 *wsrc; short tsize, i; if (size <= 0) @@ -2885,20 +2886,15 @@ static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src, tdest = (void __iomem *) ®s->Window + (dest & (ACE_WINDOW_SIZE - 1)); writel(dest & ~(ACE_WINDOW_SIZE - 1), ®s->WinBase); - /* - * This requires byte swapping on big endian, however - * writel does that for us - */ - wsrc = src; for (i = 0; i < (tsize / 4); i++) { - writel(wsrc[i], tdest + i*4); + /* Firmware is big-endian */ + writel(be32_to_cpup(src), tdest); + src++; + tdest += 4; + dest += 4; + size -= 4; } - dest += tsize; - src += tsize; - size -= tsize; } - - return; } @@ -2937,8 +2933,13 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz */ static int __devinit ace_load_firmware(struct net_device *dev) { + const struct firmware *fw; + const char *fw_name = "acenic/tg2.bin"; struct ace_private *ap = netdev_priv(dev); struct ace_regs __iomem *regs = ap->regs; + const __be32 *fw_data; + u32 load_addr; + int ret; if (!(readl(®s->CpuCtrl) & CPU_HALTED)) { printk(KERN_ERR "%s: trying to download firmware while the " @@ -2946,28 +2947,52 @@ static int __devinit ace_load_firmware(struct net_device *dev) return -EFAULT; } + if (ACE_IS_TIGON_I(ap)) + fw_name = "acenic/tg1.bin"; + + ret = request_firmware(&fw, fw_name, &ap->pdev->dev); + if (ret) { + printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", + ap->name, fw_name); + return ret; + } + + fw_data = (void *)fw->data; + + /* Firmware blob starts with version numbers, followed by + load and start address. Remainder is the blob to be loaded + contiguously from load address. We don't bother to represent + the BSS/SBSS sections any more, since we were clearing the + whole thing anyway. */ + ap->firmware_major = fw->data[0]; + ap->firmware_minor = fw->data[1]; + ap->firmware_fix = fw->data[2]; + + ap->firmware_start = be32_to_cpu(fw_data[1]); + if (ap->firmware_start < 0x4000 || ap->firmware_start >= 0x80000) { + printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n", + ap->name, ap->firmware_start, fw_name); + ret = -EINVAL; + goto out; + } + + load_addr = be32_to_cpu(fw_data[2]); + if (load_addr < 0x4000 || load_addr >= 0x80000) { + printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n", + ap->name, load_addr, fw_name); + ret = -EINVAL; + goto out; + } + /* - * Do not try to clear more than 512KB or we end up seeing - * funny things on NICs with only 512KB SRAM + * Do not try to clear more than 512KiB or we end up seeing + * funny things on NICs with only 512KiB SRAM */ ace_clear(regs, 0x2000, 0x80000-0x2000); - if (ACE_IS_TIGON_I(ap)) { - ace_copy(regs, tigonFwText, tigonFwTextAddr, tigonFwTextLen); - ace_copy(regs, tigonFwData, tigonFwDataAddr, tigonFwDataLen); - ace_copy(regs, tigonFwRodata, tigonFwRodataAddr, - tigonFwRodataLen); - ace_clear(regs, tigonFwBssAddr, tigonFwBssLen); - ace_clear(regs, tigonFwSbssAddr, tigonFwSbssLen); - }else if (ap->version == 2) { - ace_clear(regs, tigon2FwBssAddr, tigon2FwBssLen); - ace_clear(regs, tigon2FwSbssAddr, tigon2FwSbssLen); - ace_copy(regs, tigon2FwText, tigon2FwTextAddr,tigon2FwTextLen); - ace_copy(regs, tigon2FwRodata, tigon2FwRodataAddr, - tigon2FwRodataLen); - ace_copy(regs, tigon2FwData, tigon2FwDataAddr,tigon2FwDataLen); - } - - return 0; + ace_copy(regs, &fw_data[3], load_addr, fw->size-12); + out: + release_firmware(fw); + return ret; } diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h index 4487f32759a..c987c9b5a13 100644 --- a/drivers/net/acenic.h +++ b/drivers/net/acenic.h @@ -694,6 +694,10 @@ struct ace_private u32 last_tx, last_std_rx, last_mini_rx; #endif int pci_using_dac; + u8 firmware_major; + u8 firmware_minor; + u8 firmware_fix; + u32 firmware_start; }; -- cgit From 077f849de42e58172e25ccb24df4c1a13e82420c Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sun, 4 Jan 2009 16:11:25 -0800 Subject: firmware: convert tg3 driver to request_firmware() Firmware blob looks like this... u8 firmware_major u8 firmware_minor u8 firmware_fix u8 pad __be32 start_address __be32 length (total, including BSS sections to be zeroed) data... (in __be32 words, which is native for the firmware) Signed-off-by: Jaswinder Singh Rajput Signed-off-by: David S. Miller --- drivers/net/tg3.c | 792 +++++++----------------------------------------------- drivers/net/tg3.h | 4 + 2 files changed, 98 insertions(+), 698 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 04ae1e86aea..5e2dbaee125 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -137,6 +138,10 @@ #define TG3_NUM_TEST 6 +#define FIRMWARE_TG3 "tigon/tg3.bin" +#define FIRMWARE_TG3TSO "tigon/tg3_tso.bin" +#define FIRMWARE_TG3TSO5 "tigon/tg3_tso5.bin" + static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -144,6 +149,10 @@ MODULE_AUTHOR("David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); +MODULE_FIRMWARE(FIRMWARE_TG3); +MODULE_FIRMWARE(FIRMWARE_TG3TSO); +MODULE_FIRMWARE(FIRMWARE_TG3TSO5); + static int tg3_debug = -1; /* -1 == use TG3_DEF_MSG_ENABLE as value */ module_param(tg3_debug, int, 0); @@ -6205,130 +6214,6 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent) return 0; } -#define TG3_FW_RELEASE_MAJOR 0x0 -#define TG3_FW_RELASE_MINOR 0x0 -#define TG3_FW_RELEASE_FIX 0x0 -#define TG3_FW_START_ADDR 0x08000000 -#define TG3_FW_TEXT_ADDR 0x08000000 -#define TG3_FW_TEXT_LEN 0x9c0 -#define TG3_FW_RODATA_ADDR 0x080009c0 -#define TG3_FW_RODATA_LEN 0x60 -#define TG3_FW_DATA_ADDR 0x08000a40 -#define TG3_FW_DATA_LEN 0x20 -#define TG3_FW_SBSS_ADDR 0x08000a60 -#define TG3_FW_SBSS_LEN 0xc -#define TG3_FW_BSS_ADDR 0x08000a70 -#define TG3_FW_BSS_LEN 0x10 - -static const u32 tg3FwText[(TG3_FW_TEXT_LEN / sizeof(u32)) + 1] = { - 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800, - 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000018, 0x00000000, - 0x0000000d, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100034, - 0x0e00021c, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, 0x00000000, - 0x27bdffe0, 0x3c1cc000, 0xafbf0018, 0xaf80680c, 0x0e00004c, 0x241b2105, - 0x97850000, 0x97870002, 0x9782002c, 0x9783002e, 0x3c040800, 0x248409c0, - 0xafa00014, 0x00021400, 0x00621825, 0x00052c00, 0xafa30010, 0x8f860010, - 0x00e52825, 0x0e000060, 0x24070102, 0x3c02ac00, 0x34420100, 0x3c03ac01, - 0x34630100, 0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498, 0xaf82049c, - 0x24020001, 0xaf825ce0, 0x0e00003f, 0xaf825d00, 0x0e000140, 0x00000000, - 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x2402ffff, 0xaf825404, 0x8f835400, - 0x34630400, 0xaf835400, 0xaf825404, 0x3c020800, 0x24420034, 0xaf82541c, - 0x03e00008, 0xaf805400, 0x00000000, 0x00000000, 0x3c020800, 0x34423000, - 0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac220a64, - 0x24020040, 0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60, 0xac600000, - 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, - 0x00804821, 0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800, 0x8c840a68, - 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac230a60, 0x14400003, - 0x00004021, 0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60, 0x3c030800, - 0x8c630a64, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, - 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c420a60, - 0x3c030800, 0x8c630a64, 0x8f84680c, 0x00021140, 0x00431021, 0xac440008, - 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0x02000008, 0x00000000, 0x0a0001e3, 0x3c0a0001, 0x0a0001e3, 0x3c0a0002, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, - 0x0a0001e3, 0x3c0a0007, 0x0a0001e3, 0x3c0a0008, 0x0a0001e3, 0x3c0a0009, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a000b, - 0x0a0001e3, 0x3c0a000c, 0x0a0001e3, 0x3c0a000d, 0x0a0001e3, 0x00000000, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a000e, 0x0a0001e3, 0x00000000, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x00000000, - 0x0a0001e3, 0x00000000, 0x0a0001e3, 0x3c0a0013, 0x0a0001e3, 0x3c0a0014, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0x27bdffe0, 0x00001821, 0x00001021, 0xafbf0018, 0xafb10014, 0xafb00010, - 0x3c010800, 0x00220821, 0xac200a70, 0x3c010800, 0x00220821, 0xac200a74, - 0x3c010800, 0x00220821, 0xac200a78, 0x24630001, 0x1860fff5, 0x2442000c, - 0x24110001, 0x8f906810, 0x32020004, 0x14400005, 0x24040001, 0x3c020800, - 0x8c420a78, 0x18400003, 0x00002021, 0x0e000182, 0x00000000, 0x32020001, - 0x10400003, 0x00000000, 0x0e000169, 0x00000000, 0x0a000153, 0xaf915028, - 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c050800, - 0x8ca50a70, 0x3c060800, 0x8cc60a80, 0x3c070800, 0x8ce70a78, 0x27bdffe0, - 0x3c040800, 0x248409d0, 0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014, - 0x0e00017b, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001, - 0x8f836810, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, 0xaf836810, - 0x27bdffd8, 0xafbf0024, 0x1080002e, 0xafb00020, 0x8f825cec, 0xafa20018, - 0x8f825cec, 0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000, 0xaf825cec, - 0x8e020000, 0x18400016, 0x00000000, 0x3c020800, 0x94420a74, 0x8fa3001c, - 0x000221c0, 0xac830004, 0x8fa2001c, 0x3c010800, 0x0e000201, 0xac220a74, - 0x10400005, 0x00000000, 0x8e020000, 0x24420001, 0x0a0001df, 0xae020000, - 0x3c020800, 0x8c420a70, 0x00021c02, 0x000321c0, 0x0a0001c5, 0xafa2001c, - 0x0e000201, 0x00000000, 0x1040001f, 0x00000000, 0x8e020000, 0x8fa3001c, - 0x24420001, 0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74, 0x0a0001df, - 0xae020000, 0x3c100800, 0x26100a78, 0x8e020000, 0x18400028, 0x00000000, - 0x0e000201, 0x00000000, 0x14400024, 0x00000000, 0x8e020000, 0x3c030800, - 0x8c630a70, 0x2442ffff, 0xafa3001c, 0x18400006, 0xae020000, 0x00031402, - 0x000221c0, 0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e, 0x2442ff00, - 0x2c420300, 0x1440000b, 0x24024000, 0x3c040800, 0x248409dc, 0xafa00010, - 0xafa00014, 0x8fa6001c, 0x24050008, 0x0e000060, 0x00003821, 0x0a0001df, - 0x00000000, 0xaf825cf8, 0x3c020800, 0x8c420a40, 0x8fa3001c, 0x24420001, - 0xaf835cf8, 0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020, 0x03e00008, - 0x27bd0028, 0x27bdffe0, 0x3c040800, 0x248409e8, 0x00002821, 0x00003021, - 0x00003821, 0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014, 0x8fbf0018, - 0x03e00008, 0x27bd0020, 0x8f82680c, 0x8f85680c, 0x00021827, 0x0003182b, - 0x00031823, 0x00431024, 0x00441021, 0x00a2282b, 0x10a00006, 0x00000000, - 0x00401821, 0x8f82680c, 0x0043102b, 0x1440fffd, 0x00000000, 0x03e00008, - 0x00000000, 0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40, 0x0064102b, - 0x54400002, 0x00831023, 0x00641023, 0x2c420008, 0x03e00008, 0x38420001, - 0x27bdffe0, 0x00802821, 0x3c040800, 0x24840a00, 0x00003021, 0x00003821, - 0xafbf0018, 0xafa00010, 0x0e000060, 0xafa00014, 0x0a000216, 0x00000000, - 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, 0x27bdffe0, 0x3c1cc000, - 0xafbf0018, 0x0e00004c, 0xaf80680c, 0x3c040800, 0x24840a10, 0x03802821, - 0x00003021, 0x00003821, 0xafa00010, 0x0e000060, 0xafa00014, 0x2402ffff, - 0xaf825404, 0x3c0200aa, 0x0e000234, 0xaf825434, 0x8fbf0018, 0x03e00008, - 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe8, 0xafb00010, - 0x24100001, 0xafbf0014, 0x3c01c003, 0xac200000, 0x8f826810, 0x30422000, - 0x10400003, 0x00000000, 0x0e000246, 0x00000000, 0x0a00023a, 0xaf905428, - 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdfff8, 0x8f845d0c, - 0x3c0200ff, 0x3c030800, 0x8c630a50, 0x3442fff8, 0x00821024, 0x1043001e, - 0x3c0500ff, 0x34a5fff8, 0x3c06c003, 0x3c074000, 0x00851824, 0x8c620010, - 0x3c010800, 0xac230a50, 0x30420008, 0x10400005, 0x00871025, 0x8cc20000, - 0x24420001, 0xacc20000, 0x00871025, 0xaf825d0c, 0x8fa20000, 0x24420001, - 0xafa20000, 0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000, 0x8fa20000, - 0x8f845d0c, 0x3c030800, 0x8c630a50, 0x00851024, 0x1443ffe8, 0x00851824, - 0x27bd0008, 0x03e00008, 0x00000000, 0x00000000, 0x00000000 -}; - -static const u32 tg3FwRodata[(TG3_FW_RODATA_LEN / sizeof(u32)) + 1] = { - 0x35373031, 0x726c7341, 0x00000000, 0x00000000, 0x53774576, 0x656e7430, - 0x00000000, 0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e, 0x45766e74, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, - 0x00000000, 0x00000000, 0x4d61696e, 0x43707542, 0x00000000, 0x00000000, - 0x00000000 -}; - -#if 0 /* All zeros, don't eat up space with it. */ -u32 tg3FwData[(TG3_FW_DATA_LEN / sizeof(u32)) + 1] = { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 -}; -#endif - #define RX_CPU_SCRATCH_BASE 0x30000 #define RX_CPU_SCRATCH_SIZE 0x04000 #define TX_CPU_SCRATCH_BASE 0x34000 @@ -6383,15 +6268,9 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) } struct fw_info { - unsigned int text_base; - unsigned int text_len; - const u32 *text_data; - unsigned int rodata_base; - unsigned int rodata_len; - const u32 *rodata_data; - unsigned int data_base; - unsigned int data_len; - const u32 *data_data; + unsigned int fw_base; + unsigned int fw_len; + const __be32 *fw_data; }; /* tp->lock is held. */ @@ -6428,24 +6307,11 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b write_op(tp, cpu_scratch_base + i, 0); tw32(cpu_base + CPU_STATE, 0xffffffff); tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT); - for (i = 0; i < (info->text_len / sizeof(u32)); i++) - write_op(tp, (cpu_scratch_base + - (info->text_base & 0xffff) + - (i * sizeof(u32))), - (info->text_data ? - info->text_data[i] : 0)); - for (i = 0; i < (info->rodata_len / sizeof(u32)); i++) - write_op(tp, (cpu_scratch_base + - (info->rodata_base & 0xffff) + - (i * sizeof(u32))), - (info->rodata_data ? - info->rodata_data[i] : 0)); - for (i = 0; i < (info->data_len / sizeof(u32)); i++) + for (i = 0; i < (info->fw_len / sizeof(u32)); i++) write_op(tp, (cpu_scratch_base + - (info->data_base & 0xffff) + + (info->fw_base & 0xffff) + (i * sizeof(u32))), - (info->data_data ? - info->data_data[i] : 0)); + be32_to_cpu(info->fw_data[i])); err = 0; @@ -6457,17 +6323,20 @@ out: static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) { struct fw_info info; + const __be32 *fw_data; int err, i; - info.text_base = TG3_FW_TEXT_ADDR; - info.text_len = TG3_FW_TEXT_LEN; - info.text_data = &tg3FwText[0]; - info.rodata_base = TG3_FW_RODATA_ADDR; - info.rodata_len = TG3_FW_RODATA_LEN; - info.rodata_data = &tg3FwRodata[0]; - info.data_base = TG3_FW_DATA_ADDR; - info.data_len = TG3_FW_DATA_LEN; - info.data_data = NULL; + fw_data = (void *)tp->fw->data; + + /* Firmware blob starts with version numbers, followed by + start address and length. We are setting complete length. + length = end_address_of_bss - start_address_of_text. + Remainder is the blob to be loaded contiguously + from start address. */ + + info.fw_base = be32_to_cpu(fw_data[1]); + info.fw_len = tp->fw->size - 12; + info.fw_data = &fw_data[3]; err = tg3_load_firmware_cpu(tp, RX_CPU_BASE, RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE, @@ -6483,21 +6352,21 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) /* Now startup only the RX cpu. */ tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); - tw32_f(RX_CPU_BASE + CPU_PC, TG3_FW_TEXT_ADDR); + tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base); for (i = 0; i < 5; i++) { - if (tr32(RX_CPU_BASE + CPU_PC) == TG3_FW_TEXT_ADDR) + if (tr32(RX_CPU_BASE + CPU_PC) == info.fw_base) break; tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); tw32(RX_CPU_BASE + CPU_MODE, CPU_MODE_HALT); - tw32_f(RX_CPU_BASE + CPU_PC, TG3_FW_TEXT_ADDR); + tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base); udelay(1000); } if (i >= 5) { printk(KERN_ERR PFX "tg3_load_firmware fails for %s " "to set RX CPU PC, is %08x should be %08x\n", tp->dev->name, tr32(RX_CPU_BASE + CPU_PC), - TG3_FW_TEXT_ADDR); + info.fw_base); return -ENODEV; } tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff); @@ -6506,547 +6375,36 @@ static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp) return 0; } - -#define TG3_TSO_FW_RELEASE_MAJOR 0x1 -#define TG3_TSO_FW_RELASE_MINOR 0x6 -#define TG3_TSO_FW_RELEASE_FIX 0x0 -#define TG3_TSO_FW_START_ADDR 0x08000000 -#define TG3_TSO_FW_TEXT_ADDR 0x08000000 -#define TG3_TSO_FW_TEXT_LEN 0x1aa0 -#define TG3_TSO_FW_RODATA_ADDR 0x08001aa0 -#define TG3_TSO_FW_RODATA_LEN 0x60 -#define TG3_TSO_FW_DATA_ADDR 0x08001b20 -#define TG3_TSO_FW_DATA_LEN 0x30 -#define TG3_TSO_FW_SBSS_ADDR 0x08001b50 -#define TG3_TSO_FW_SBSS_LEN 0x2c -#define TG3_TSO_FW_BSS_ADDR 0x08001b80 -#define TG3_TSO_FW_BSS_LEN 0x894 - -static const u32 tg3TsoFwText[(TG3_TSO_FW_TEXT_LEN / 4) + 1] = { - 0x0e000003, 0x00000000, 0x08001b24, 0x00000000, 0x10000003, 0x00000000, - 0x0000000d, 0x0000000d, 0x3c1d0800, 0x37bd4000, 0x03a0f021, 0x3c100800, - 0x26100000, 0x0e000010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, - 0xafbf0018, 0x0e0005d8, 0x34840002, 0x0e000668, 0x00000000, 0x3c030800, - 0x90631b68, 0x24020002, 0x3c040800, 0x24841aac, 0x14620003, 0x24050001, - 0x3c040800, 0x24841aa0, 0x24060006, 0x00003821, 0xafa00010, 0x0e00067c, - 0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001, - 0xaf625c90, 0x2402ffff, 0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008, - 0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, - 0xafb20018, 0xafb10014, 0x0e00005b, 0xafb00010, 0x24120002, 0x24110001, - 0x8f706820, 0x32020100, 0x10400003, 0x00000000, 0x0e0000bb, 0x00000000, - 0x8f706820, 0x32022000, 0x10400004, 0x32020001, 0x0e0001f0, 0x24040001, - 0x32020001, 0x10400003, 0x00000000, 0x0e0000a3, 0x00000000, 0x3c020800, - 0x90421b98, 0x14520003, 0x00000000, 0x0e0004c0, 0x00000000, 0x0a00003c, - 0xaf715028, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, - 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ac0, 0x00002821, 0x00003021, - 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, 0xafa00014, 0x3c040800, - 0x248423d8, 0xa4800000, 0x3c010800, 0xa0201b98, 0x3c010800, 0xac201b9c, - 0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, 0x3c010800, 0xac201bac, - 0x3c010800, 0xac201bb8, 0x3c010800, 0xac201bbc, 0x8f624434, 0x3c010800, - 0xac221b88, 0x8f624438, 0x3c010800, 0xac221b8c, 0x8f624410, 0xac80f7a8, - 0x3c010800, 0xac201b84, 0x3c010800, 0xac2023e0, 0x3c010800, 0xac2023c8, - 0x3c010800, 0xac2023cc, 0x3c010800, 0xac202400, 0x3c010800, 0xac221b90, - 0x8f620068, 0x24030007, 0x00021702, 0x10430005, 0x00000000, 0x8f620068, - 0x00021702, 0x14400004, 0x24020001, 0x3c010800, 0x0a000097, 0xac20240c, - 0xac820034, 0x3c040800, 0x24841acc, 0x3c050800, 0x8ca5240c, 0x00003021, - 0x00003821, 0xafa00010, 0x0e00067c, 0xafa00014, 0x8fbf0018, 0x03e00008, - 0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ad8, 0x00002821, 0x00003021, - 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, 0xafa00014, 0x0e00005b, - 0x00000000, 0x0e0000b4, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020, - 0x24020001, 0x8f636820, 0x00821004, 0x00021027, 0x00621824, 0x03e00008, - 0xaf636820, 0x27bdffd0, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, - 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f675c5c, 0x3c030800, - 0x24631bbc, 0x8c620000, 0x14470005, 0x3c0200ff, 0x3c020800, 0x90421b98, - 0x14400119, 0x3c0200ff, 0x3442fff8, 0x00e28824, 0xac670000, 0x00111902, - 0x306300ff, 0x30e20003, 0x000211c0, 0x00622825, 0x00a04021, 0x00071602, - 0x3c030800, 0x90631b98, 0x3044000f, 0x14600036, 0x00804821, 0x24020001, - 0x3c010800, 0xa0221b98, 0x00051100, 0x00821025, 0x3c010800, 0xac201b9c, - 0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4, 0x3c010800, 0xac201bac, - 0x3c010800, 0xac201bb8, 0x3c010800, 0xac201bb0, 0x3c010800, 0xac201bb4, - 0x3c010800, 0xa42223d8, 0x9622000c, 0x30437fff, 0x3c010800, 0xa4222410, - 0x30428000, 0x3c010800, 0xa4231bc6, 0x10400005, 0x24020001, 0x3c010800, - 0xac2223f4, 0x0a000102, 0x2406003e, 0x24060036, 0x3c010800, 0xac2023f4, - 0x9622000a, 0x3c030800, 0x94631bc6, 0x3c010800, 0xac2023f0, 0x3c010800, - 0xac2023f8, 0x00021302, 0x00021080, 0x00c21021, 0x00621821, 0x3c010800, - 0xa42223d0, 0x3c010800, 0x0a000115, 0xa4231b96, 0x9622000c, 0x3c010800, - 0xa42223ec, 0x3c040800, 0x24841b9c, 0x8c820000, 0x00021100, 0x3c010800, - 0x00220821, 0xac311bc8, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, - 0xac271bcc, 0x8c820000, 0x25030001, 0x306601ff, 0x00021100, 0x3c010800, - 0x00220821, 0xac261bd0, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, - 0xac291bd4, 0x96230008, 0x3c020800, 0x8c421bac, 0x00432821, 0x3c010800, - 0xac251bac, 0x9622000a, 0x30420004, 0x14400018, 0x00061100, 0x8f630c14, - 0x3063000f, 0x2c620002, 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, - 0x8c421b40, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b40, 0x2c620002, - 0x1040fff7, 0x3c02c000, 0x00e21825, 0xaf635c5c, 0x8f625c50, 0x30420002, - 0x10400014, 0x00000000, 0x0a000147, 0x00000000, 0x3c030800, 0x8c631b80, - 0x3c040800, 0x94841b94, 0x01221025, 0x3c010800, 0xa42223da, 0x24020001, - 0x3c010800, 0xac221bb8, 0x24630001, 0x0085202a, 0x3c010800, 0x10800003, - 0xac231b80, 0x3c010800, 0xa4251b94, 0x3c060800, 0x24c61b9c, 0x8cc20000, - 0x24420001, 0xacc20000, 0x28420080, 0x14400005, 0x00000000, 0x0e000656, - 0x24040002, 0x0a0001e6, 0x00000000, 0x3c020800, 0x8c421bb8, 0x10400078, - 0x24020001, 0x3c050800, 0x90a51b98, 0x14a20072, 0x00000000, 0x3c150800, - 0x96b51b96, 0x3c040800, 0x8c841bac, 0x32a3ffff, 0x0083102a, 0x1440006c, - 0x00000000, 0x14830003, 0x00000000, 0x3c010800, 0xac2523f0, 0x1060005c, - 0x00009021, 0x24d60004, 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, - 0x3c110800, 0x02308821, 0x0e000625, 0x8e311bc8, 0x00402821, 0x10a00054, - 0x00000000, 0x9628000a, 0x31020040, 0x10400005, 0x2407180c, 0x8e22000c, - 0x2407188c, 0x00021400, 0xaca20018, 0x3c030800, 0x00701821, 0x8c631bd0, - 0x3c020800, 0x00501021, 0x8c421bd4, 0x00031d00, 0x00021400, 0x00621825, - 0xaca30014, 0x8ec30004, 0x96220008, 0x00432023, 0x3242ffff, 0x3083ffff, - 0x00431021, 0x0282102a, 0x14400002, 0x02b23023, 0x00803021, 0x8e620000, - 0x30c4ffff, 0x00441021, 0xae620000, 0x8e220000, 0xaca20000, 0x8e220004, - 0x8e63fff4, 0x00431021, 0xaca20004, 0xa4a6000e, 0x8e62fff4, 0x00441021, - 0xae62fff4, 0x96230008, 0x0043102a, 0x14400005, 0x02469021, 0x8e62fff0, - 0xae60fff4, 0x24420001, 0xae62fff0, 0xaca00008, 0x3242ffff, 0x14540008, - 0x24020305, 0x31020080, 0x54400001, 0x34e70010, 0x24020905, 0xa4a2000c, - 0x0a0001cb, 0x34e70020, 0xa4a2000c, 0x3c020800, 0x8c4223f0, 0x10400003, - 0x3c024b65, 0x0a0001d3, 0x34427654, 0x3c02b49a, 0x344289ab, 0xaca2001c, - 0x30e2ffff, 0xaca20010, 0x0e0005a2, 0x00a02021, 0x3242ffff, 0x0054102b, - 0x1440ffa9, 0x00000000, 0x24020002, 0x3c010800, 0x0a0001e6, 0xa0221b98, - 0x8ec2083c, 0x24420001, 0x0a0001e6, 0xaec2083c, 0x0e0004c0, 0x00000000, - 0x8fbf002c, 0x8fb60028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, - 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0030, 0x27bdffd0, 0xafbf0028, - 0xafb30024, 0xafb20020, 0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff, - 0x3442fff8, 0x3c070800, 0x24e71bb4, 0x02428824, 0x9623000e, 0x8ce20000, - 0x00431021, 0xace20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, - 0x0e00063b, 0x02202021, 0x3c02c000, 0x02421825, 0xaf635c9c, 0x8f625c90, - 0x30420002, 0x1040011e, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, - 0x10400119, 0x00000000, 0x0a00020d, 0x00000000, 0x8e240008, 0x8e230014, - 0x00041402, 0x000231c0, 0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f, - 0x00031942, 0x30637800, 0x00021100, 0x24424000, 0x00624821, 0x9522000a, - 0x3084ffff, 0x30420008, 0x104000b0, 0x000429c0, 0x3c020800, 0x8c422400, - 0x14400024, 0x24c50008, 0x94c20014, 0x3c010800, 0xa42223d0, 0x8cc40010, - 0x00041402, 0x3c010800, 0xa42223d2, 0x3c010800, 0xa42423d4, 0x94c2000e, - 0x3083ffff, 0x00431023, 0x3c010800, 0xac222408, 0x94c2001a, 0x3c010800, - 0xac262400, 0x3c010800, 0xac322404, 0x3c010800, 0xac2223fc, 0x3c02c000, - 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000e5, 0x00000000, - 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000e0, 0x00000000, 0x0a000246, - 0x00000000, 0x94c2000e, 0x3c030800, 0x946323d4, 0x00434023, 0x3103ffff, - 0x2c620008, 0x1040001c, 0x00000000, 0x94c20014, 0x24420028, 0x00a22821, - 0x00031042, 0x1840000b, 0x00002021, 0x24e60848, 0x00403821, 0x94a30000, - 0x8cc20000, 0x24840001, 0x00431021, 0xacc20000, 0x0087102a, 0x1440fff9, - 0x24a50002, 0x31020001, 0x1040001f, 0x3c024000, 0x3c040800, 0x248423fc, - 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021, 0x0a000285, 0xac820000, - 0x8f626800, 0x3c030010, 0x00431024, 0x10400009, 0x00000000, 0x94c2001a, - 0x3c030800, 0x8c6323fc, 0x00431021, 0x3c010800, 0xac2223fc, 0x0a000286, - 0x3c024000, 0x94c2001a, 0x94c4001c, 0x3c030800, 0x8c6323fc, 0x00441023, - 0x00621821, 0x3c010800, 0xac2323fc, 0x3c024000, 0x02421825, 0xaf635c9c, - 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, 0x9522000a, 0x30420010, - 0x1040009b, 0x00000000, 0x3c030800, 0x946323d4, 0x3c070800, 0x24e72400, - 0x8ce40000, 0x8f626800, 0x24630030, 0x00832821, 0x3c030010, 0x00431024, - 0x1440000a, 0x00000000, 0x94a20004, 0x3c040800, 0x8c842408, 0x3c030800, - 0x8c6323fc, 0x00441023, 0x00621821, 0x3c010800, 0xac2323fc, 0x3c040800, - 0x8c8423fc, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, 0x00822021, - 0x00041027, 0xa4a20006, 0x3c030800, 0x8c632404, 0x3c0200ff, 0x3442fff8, - 0x00628824, 0x96220008, 0x24050001, 0x24034000, 0x000231c0, 0x00801021, - 0xa4c2001a, 0xa4c0001c, 0xace00000, 0x3c010800, 0xac251b60, 0xaf635cb8, - 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, 0x3c010800, 0xac201b60, - 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000, - 0x3c010800, 0xac201b60, 0x3c020800, 0x8c421b60, 0x1040ffec, 0x00000000, - 0x3c040800, 0x0e00063b, 0x8c842404, 0x0a00032a, 0x00000000, 0x3c030800, - 0x90631b98, 0x24020002, 0x14620003, 0x3c034b65, 0x0a0002e1, 0x00008021, - 0x8e22001c, 0x34637654, 0x10430002, 0x24100002, 0x24100001, 0x00c02021, - 0x0e000350, 0x02003021, 0x24020003, 0x3c010800, 0xa0221b98, 0x24020002, - 0x1202000a, 0x24020001, 0x3c030800, 0x8c6323f0, 0x10620006, 0x00000000, - 0x3c020800, 0x944223d8, 0x00021400, 0x0a00031f, 0xae220014, 0x3c040800, - 0x248423da, 0x94820000, 0x00021400, 0xae220014, 0x3c020800, 0x8c421bbc, - 0x3c03c000, 0x3c010800, 0xa0201b98, 0x00431025, 0xaf625c5c, 0x8f625c50, - 0x30420002, 0x10400009, 0x00000000, 0x2484f7e2, 0x8c820000, 0x00431025, - 0xaf625c5c, 0x8f625c50, 0x30420002, 0x1440fffa, 0x00000000, 0x3c020800, - 0x24421b84, 0x8c430000, 0x24630001, 0xac430000, 0x8f630c14, 0x3063000f, - 0x2c620002, 0x1440000c, 0x3c024000, 0x8f630c14, 0x3c020800, 0x8c421b40, - 0x3063000f, 0x24420001, 0x3c010800, 0xac221b40, 0x2c620002, 0x1040fff7, - 0x00000000, 0x3c024000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, - 0x1440fffc, 0x00000000, 0x12600003, 0x00000000, 0x0e0004c0, 0x00000000, - 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x03e00008, - 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b88, 0x8c820000, 0x00031c02, - 0x0043102b, 0x14400007, 0x3c038000, 0x8c840004, 0x8f624450, 0x00021c02, - 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, - 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3c024000, - 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00000000, - 0x03e00008, 0x00000000, 0x27bdffe0, 0x00805821, 0x14c00011, 0x256e0008, - 0x3c020800, 0x8c4223f4, 0x10400007, 0x24020016, 0x3c010800, 0xa42223d2, - 0x2402002a, 0x3c010800, 0x0a000364, 0xa42223d4, 0x8d670010, 0x00071402, - 0x3c010800, 0xa42223d2, 0x3c010800, 0xa42723d4, 0x3c040800, 0x948423d4, - 0x3c030800, 0x946323d2, 0x95cf0006, 0x3c020800, 0x944223d0, 0x00832023, - 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821, 0x3082ffff, 0x14c0001a, - 0x01226021, 0x9582000c, 0x3042003f, 0x3c010800, 0xa42223d6, 0x95820004, - 0x95830006, 0x3c010800, 0xac2023e4, 0x3c010800, 0xac2023e8, 0x00021400, - 0x00431025, 0x3c010800, 0xac221bc0, 0x95220004, 0x3c010800, 0xa4221bc4, - 0x95230002, 0x01e51023, 0x0043102a, 0x10400010, 0x24020001, 0x3c010800, - 0x0a000398, 0xac2223f8, 0x3c030800, 0x8c6323e8, 0x3c020800, 0x94421bc4, - 0x00431021, 0xa5220004, 0x3c020800, 0x94421bc0, 0xa5820004, 0x3c020800, - 0x8c421bc0, 0xa5820006, 0x3c020800, 0x8c4223f0, 0x3c0d0800, 0x8dad23e4, - 0x3c0a0800, 0x144000e5, 0x8d4a23e8, 0x3c020800, 0x94421bc4, 0x004a1821, - 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d, 0x01435023, 0x3c020800, - 0x944223d6, 0x30420009, 0x10400008, 0x00000000, 0x9582000c, 0x3042fff6, - 0xa582000c, 0x3c020800, 0x944223d6, 0x30420009, 0x01a26823, 0x3c020800, - 0x8c4223f8, 0x1040004a, 0x01203821, 0x3c020800, 0x944223d2, 0x00004021, - 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff, 0x00021042, 0x18400008, - 0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021, 0x0103102a, - 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, - 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, 0x00003021, 0x2527000c, - 0x00004021, 0x94e20000, 0x25080001, 0x00c23021, 0x2d020004, 0x1440fffb, - 0x24e70002, 0x95220002, 0x00004021, 0x91230009, 0x00442023, 0x01803821, - 0x3082ffff, 0xa4e00010, 0x00621821, 0x00021042, 0x18400010, 0x00c33021, - 0x00404821, 0x94e20000, 0x24e70002, 0x00c23021, 0x30e2007f, 0x14400006, - 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, - 0x0109102a, 0x1440fff3, 0x00000000, 0x30820001, 0x10400005, 0x00061c02, - 0xa0e00001, 0x94e20000, 0x00c23021, 0x00061c02, 0x30c2ffff, 0x00623021, - 0x00061402, 0x00c23021, 0x0a00047d, 0x30c6ffff, 0x24020002, 0x14c20081, - 0x00000000, 0x3c020800, 0x8c42240c, 0x14400007, 0x00000000, 0x3c020800, - 0x944223d2, 0x95230002, 0x01e21023, 0x10620077, 0x00000000, 0x3c020800, - 0x944223d2, 0x01e21023, 0xa5220002, 0x3c020800, 0x8c42240c, 0x1040001a, - 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421b96, 0x00e04021, 0x00072c02, - 0x00aa2021, 0x00431023, 0x00823823, 0x00072402, 0x30e2ffff, 0x00823821, - 0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800, 0x948423d4, 0x00453023, - 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021, 0x00061c02, 0x30c2ffff, - 0x0a00047d, 0x00623021, 0x01203821, 0x00004021, 0x3082ffff, 0x00021042, - 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001, 0x00c23021, - 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff, 0x00623021, - 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a, 0x00003021, - 0x2527000c, 0x00004021, 0x94e20000, 0x25080001, 0x00c23021, 0x2d020004, - 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021, 0x91230009, 0x00442023, - 0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800, 0x948423d4, 0x00621821, - 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021, 0x00061c02, 0x3c020800, - 0x944223d0, 0x00c34821, 0x00441023, 0x00021fc2, 0x00431021, 0x00021043, - 0x18400010, 0x00003021, 0x00402021, 0x94e20000, 0x24e70002, 0x00c23021, - 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80, - 0x00625824, 0x25670008, 0x0104102a, 0x1440fff3, 0x00000000, 0x3c020800, - 0x944223ec, 0x00c23021, 0x3122ffff, 0x00c23021, 0x00061c02, 0x30c2ffff, - 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, 0x00061027, 0xa5820010, - 0xadc00014, 0x0a00049d, 0xadc00000, 0x8dc70010, 0x00e04021, 0x11400007, - 0x00072c02, 0x00aa3021, 0x00061402, 0x30c3ffff, 0x00433021, 0x00061402, - 0x00c22821, 0x00051027, 0xa522000a, 0x3c030800, 0x946323d4, 0x3102ffff, - 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02, 0x30c2ffff, 0x00623021, - 0x00061402, 0x00c23021, 0x00c04021, 0x00061027, 0xa5820010, 0x3102ffff, - 0x00051c00, 0x00431025, 0xadc20010, 0x3c020800, 0x8c4223f4, 0x10400005, - 0x2de205eb, 0x14400002, 0x25e2fff2, 0x34028870, 0xa5c20034, 0x3c030800, - 0x246323e8, 0x8c620000, 0x24420001, 0xac620000, 0x3c040800, 0x8c8423e4, - 0x3c020800, 0x8c421bc0, 0x3303ffff, 0x00832021, 0x00431821, 0x0062102b, - 0x3c010800, 0xac2423e4, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223e4, - 0x3c010800, 0xac231bc0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, - 0x24a51b96, 0xafbf0044, 0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034, - 0xafb40030, 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x94a90000, - 0x3c020800, 0x944223d0, 0x3c030800, 0x8c631bb0, 0x3c040800, 0x8c841bac, - 0x01221023, 0x0064182a, 0xa7a9001e, 0x106000be, 0xa7a20016, 0x24be0022, - 0x97b6001e, 0x24b3001a, 0x24b70016, 0x8fc20000, 0x14400008, 0x00000000, - 0x8fc2fff8, 0x97a30016, 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000b0, - 0x00000000, 0x97d50818, 0x32a2ffff, 0x104000a3, 0x00009021, 0x0040a021, - 0x00008821, 0x0e000625, 0x00000000, 0x00403021, 0x14c00007, 0x00000000, - 0x3c020800, 0x8c4223dc, 0x24420001, 0x3c010800, 0x0a000596, 0xac2223dc, - 0x3c100800, 0x02118021, 0x8e101bc8, 0x9608000a, 0x31020040, 0x10400005, - 0x2407180c, 0x8e02000c, 0x2407188c, 0x00021400, 0xacc20018, 0x31020080, - 0x54400001, 0x34e70010, 0x3c020800, 0x00511021, 0x8c421bd0, 0x3c030800, - 0x00711821, 0x8c631bd4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, - 0x96040008, 0x3242ffff, 0x00821021, 0x0282102a, 0x14400002, 0x02b22823, - 0x00802821, 0x8e020000, 0x02459021, 0xacc20000, 0x8e020004, 0x00c02021, - 0x26310010, 0xac820004, 0x30e2ffff, 0xac800008, 0xa485000e, 0xac820010, - 0x24020305, 0x0e0005a2, 0xa482000c, 0x3242ffff, 0x0054102b, 0x1440ffc5, - 0x3242ffff, 0x0a00058e, 0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a, - 0x10400067, 0x00000000, 0x8e62fff0, 0x00028900, 0x3c100800, 0x02118021, - 0x0e000625, 0x8e101bc8, 0x00403021, 0x14c00005, 0x00000000, 0x8e62082c, - 0x24420001, 0x0a000596, 0xae62082c, 0x9608000a, 0x31020040, 0x10400005, - 0x2407180c, 0x8e02000c, 0x2407188c, 0x00021400, 0xacc20018, 0x3c020800, - 0x00511021, 0x8c421bd0, 0x3c030800, 0x00711821, 0x8c631bd4, 0x00021500, - 0x00031c00, 0x00431025, 0xacc20014, 0x8e63fff4, 0x96020008, 0x00432023, - 0x3242ffff, 0x3083ffff, 0x00431021, 0x02c2102a, 0x10400003, 0x00802821, - 0x97a9001e, 0x01322823, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000, - 0xa4c5000e, 0x8e020000, 0xacc20000, 0x8e020004, 0x8e63fff4, 0x00431021, - 0xacc20004, 0x8e63fff4, 0x96020008, 0x00641821, 0x0062102a, 0x14400006, - 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0x0a000571, 0xae62fff0, - 0xae63fff4, 0xacc00008, 0x3242ffff, 0x10560003, 0x31020004, 0x10400006, - 0x24020305, 0x31020080, 0x54400001, 0x34e70010, 0x34e70020, 0x24020905, - 0xa4c2000c, 0x8ee30000, 0x8ee20004, 0x14620007, 0x3c02b49a, 0x8ee20860, - 0x54400001, 0x34e70400, 0x3c024b65, 0x0a000588, 0x34427654, 0x344289ab, - 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005a2, 0x00c02021, 0x3242ffff, - 0x0056102b, 0x1440ff9b, 0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a, - 0x1440ff48, 0x00000000, 0x8fbf0044, 0x8fbe0040, 0x8fb7003c, 0x8fb60038, - 0x8fb50034, 0x8fb40030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, - 0x03e00008, 0x27bd0048, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f624450, - 0x8f634410, 0x0a0005b1, 0x00808021, 0x8f626820, 0x30422000, 0x10400003, - 0x00000000, 0x0e0001f0, 0x00002021, 0x8f624450, 0x8f634410, 0x3042ffff, - 0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14, 0x3063000f, 0x2c620002, - 0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800, 0x8c421b40, 0x3063000f, - 0x24420001, 0x3c010800, 0xac221b40, 0x2c620002, 0x1040fff7, 0x00000000, - 0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009, 0x00000000, 0x8f626820, - 0x30422000, 0x1040fff8, 0x00000000, 0x0e0001f0, 0x00002021, 0x0a0005c4, - 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x00000000, - 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, - 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804, 0x8f634000, 0x24020b50, - 0x3c010800, 0xac221b54, 0x24020b78, 0x3c010800, 0xac221b64, 0x34630002, - 0xaf634000, 0x0e000605, 0x00808021, 0x3c010800, 0xa0221b68, 0x304200ff, - 0x24030002, 0x14430005, 0x00000000, 0x3c020800, 0x8c421b54, 0x0a0005f8, - 0xac5000c0, 0x3c020800, 0x8c421b54, 0xac5000bc, 0x8f624434, 0x8f634438, - 0x8f644410, 0x3c010800, 0xac221b5c, 0x3c010800, 0xac231b6c, 0x3c010800, - 0xac241b58, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c040800, - 0x8c870000, 0x3c03aa55, 0x3463aa55, 0x3c06c003, 0xac830000, 0x8cc20000, - 0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa, 0xac830000, 0x8cc20000, - 0x50430001, 0x24050001, 0x3c020800, 0xac470000, 0x03e00008, 0x00a01021, - 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, 0x1043fffe, - 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9, 0x00000000, 0x03e00008, - 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b5c, 0x00031c02, 0x0043102b, - 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b6c, 0x8f624450, 0x00021c02, - 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, - 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3082ffff, - 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000, 0x0a000648, 0x2402ffff, - 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00001021, - 0x03e00008, 0x00000000, 0x8f624450, 0x3c030800, 0x8c631b58, 0x0a000651, - 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, 0x00000000, - 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821, 0x3c040800, 0x24841af0, - 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, 0x0e00067c, 0xafa00014, - 0x0a000660, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x00000000, - 0x00000000, 0x00000000, 0x3c020800, 0x34423000, 0x3c030800, 0x34633000, - 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b74, 0x24020040, 0x3c010800, - 0xac221b78, 0x3c010800, 0xac201b70, 0xac600000, 0x24630004, 0x0083102b, - 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, 0x00804821, 0x8faa0010, - 0x3c020800, 0x8c421b70, 0x3c040800, 0x8c841b78, 0x8fab0014, 0x24430001, - 0x0044102b, 0x3c010800, 0xac231b70, 0x14400003, 0x00004021, 0x3c010800, - 0xac201b70, 0x3c020800, 0x8c421b70, 0x3c030800, 0x8c631b74, 0x91240000, - 0x00021140, 0x00431021, 0x00481021, 0x25080001, 0xa0440000, 0x29020008, - 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b70, 0x3c030800, 0x8c631b74, - 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, 0xac45000c, 0xac460010, - 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, 0x00000000, 0x00000000, -}; - -static const u32 tg3TsoFwRodata[] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, - 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f, - 0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x66617461, 0x6c457272, 0x00000000, 0x00000000, - 0x00000000, -}; - -static const u32 tg3TsoFwData[] = { - 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x362e3000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, -}; - /* 5705 needs a special version of the TSO firmware. */ -#define TG3_TSO5_FW_RELEASE_MAJOR 0x1 -#define TG3_TSO5_FW_RELASE_MINOR 0x2 -#define TG3_TSO5_FW_RELEASE_FIX 0x0 -#define TG3_TSO5_FW_START_ADDR 0x00010000 -#define TG3_TSO5_FW_TEXT_ADDR 0x00010000 -#define TG3_TSO5_FW_TEXT_LEN 0xe90 -#define TG3_TSO5_FW_RODATA_ADDR 0x00010e90 -#define TG3_TSO5_FW_RODATA_LEN 0x50 -#define TG3_TSO5_FW_DATA_ADDR 0x00010f00 -#define TG3_TSO5_FW_DATA_LEN 0x20 -#define TG3_TSO5_FW_SBSS_ADDR 0x00010f20 -#define TG3_TSO5_FW_SBSS_LEN 0x28 -#define TG3_TSO5_FW_BSS_ADDR 0x00010f50 -#define TG3_TSO5_FW_BSS_LEN 0x88 - -static const u32 tg3Tso5FwText[(TG3_TSO5_FW_TEXT_LEN / 4) + 1] = { - 0x0c004003, 0x00000000, 0x00010f04, 0x00000000, 0x10000003, 0x00000000, - 0x0000000d, 0x0000000d, 0x3c1d0001, 0x37bde000, 0x03a0f021, 0x3c100001, - 0x26100000, 0x0c004010, 0x00000000, 0x0000000d, 0x27bdffe0, 0x3c04fefe, - 0xafbf0018, 0x0c0042e8, 0x34840002, 0x0c004364, 0x00000000, 0x3c030001, - 0x90630f34, 0x24020002, 0x3c040001, 0x24840e9c, 0x14620003, 0x24050001, - 0x3c040001, 0x24840e90, 0x24060002, 0x00003821, 0xafa00010, 0x0c004378, - 0xafa00014, 0x0c00402c, 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, - 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c, 0xafb20018, 0xafb10014, - 0x0c0042d4, 0xafb00010, 0x3c128000, 0x24110001, 0x8f706810, 0x32020400, - 0x10400007, 0x00000000, 0x8f641008, 0x00921024, 0x14400003, 0x00000000, - 0x0c004064, 0x00000000, 0x3c020001, 0x90420f56, 0x10510003, 0x32020200, - 0x1040fff1, 0x00000000, 0x0c0041b4, 0x00000000, 0x08004034, 0x00000000, - 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, - 0x27bdffe0, 0x3c040001, 0x24840eb0, 0x00002821, 0x00003021, 0x00003821, - 0xafbf0018, 0xafa00010, 0x0c004378, 0xafa00014, 0x0000d021, 0x24020130, - 0xaf625000, 0x3c010001, 0xa4200f50, 0x3c010001, 0xa0200f57, 0x8fbf0018, - 0x03e00008, 0x27bd0020, 0x00000000, 0x00000000, 0x3c030001, 0x24630f60, - 0x90620000, 0x27bdfff0, 0x14400003, 0x0080c021, 0x08004073, 0x00004821, - 0x3c022000, 0x03021024, 0x10400003, 0x24090002, 0x08004073, 0xa0600000, - 0x24090001, 0x00181040, 0x30431f80, 0x346f8008, 0x1520004b, 0x25eb0028, - 0x3c040001, 0x00832021, 0x8c848010, 0x3c050001, 0x24a50f7a, 0x00041402, - 0xa0a20000, 0x3c010001, 0xa0240f7b, 0x3c020001, 0x00431021, 0x94428014, - 0x3c010001, 0xa0220f7c, 0x3c0c0001, 0x01836021, 0x8d8c8018, 0x304200ff, - 0x24420008, 0x000220c3, 0x24020001, 0x3c010001, 0xa0220f60, 0x0124102b, - 0x1040000c, 0x00003821, 0x24a6000e, 0x01602821, 0x8ca20000, 0x8ca30004, - 0x24a50008, 0x24e70001, 0xacc20000, 0xacc30004, 0x00e4102b, 0x1440fff8, - 0x24c60008, 0x00003821, 0x3c080001, 0x25080f7b, 0x91060000, 0x3c020001, - 0x90420f7c, 0x2503000d, 0x00c32821, 0x00461023, 0x00021fc2, 0x00431021, - 0x00021043, 0x1840000c, 0x00002021, 0x91020001, 0x00461023, 0x00021fc2, - 0x00431021, 0x00021843, 0x94a20000, 0x24e70001, 0x00822021, 0x00e3102a, - 0x1440fffb, 0x24a50002, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, - 0x00822021, 0x3c02ffff, 0x01821024, 0x3083ffff, 0x00431025, 0x3c010001, - 0x080040fa, 0xac220f80, 0x3c050001, 0x24a50f7c, 0x90a20000, 0x3c0c0001, - 0x01836021, 0x8d8c8018, 0x000220c2, 0x1080000e, 0x00003821, 0x01603021, - 0x24a5000c, 0x8ca20000, 0x8ca30004, 0x24a50008, 0x24e70001, 0xacc20000, - 0xacc30004, 0x00e4102b, 0x1440fff8, 0x24c60008, 0x3c050001, 0x24a50f7c, - 0x90a20000, 0x30430007, 0x24020004, 0x10620011, 0x28620005, 0x10400005, - 0x24020002, 0x10620008, 0x000710c0, 0x080040fa, 0x00000000, 0x24020006, - 0x1062000e, 0x000710c0, 0x080040fa, 0x00000000, 0x00a21821, 0x9463000c, - 0x004b1021, 0x080040fa, 0xa4430000, 0x000710c0, 0x00a21821, 0x8c63000c, - 0x004b1021, 0x080040fa, 0xac430000, 0x00a21821, 0x8c63000c, 0x004b2021, - 0x00a21021, 0xac830000, 0x94420010, 0xa4820004, 0x95e70006, 0x3c020001, - 0x90420f7c, 0x3c030001, 0x90630f7a, 0x00e2c823, 0x3c020001, 0x90420f7b, - 0x24630028, 0x01e34021, 0x24420028, 0x15200012, 0x01e23021, 0x94c2000c, - 0x3c010001, 0xa4220f78, 0x94c20004, 0x94c30006, 0x3c010001, 0xa4200f76, - 0x3c010001, 0xa4200f72, 0x00021400, 0x00431025, 0x3c010001, 0xac220f6c, - 0x95020004, 0x3c010001, 0x08004124, 0xa4220f70, 0x3c020001, 0x94420f70, - 0x3c030001, 0x94630f72, 0x00431021, 0xa5020004, 0x3c020001, 0x94420f6c, - 0xa4c20004, 0x3c020001, 0x8c420f6c, 0xa4c20006, 0x3c040001, 0x94840f72, - 0x3c020001, 0x94420f70, 0x3c0a0001, 0x954a0f76, 0x00441821, 0x3063ffff, - 0x0062182a, 0x24020002, 0x1122000b, 0x00832023, 0x3c030001, 0x94630f78, - 0x30620009, 0x10400006, 0x3062fff6, 0xa4c2000c, 0x3c020001, 0x94420f78, - 0x30420009, 0x01425023, 0x24020001, 0x1122001b, 0x29220002, 0x50400005, - 0x24020002, 0x11200007, 0x31a2ffff, 0x08004197, 0x00000000, 0x1122001d, - 0x24020016, 0x08004197, 0x31a2ffff, 0x3c0e0001, 0x95ce0f80, 0x10800005, - 0x01806821, 0x01c42021, 0x00041c02, 0x3082ffff, 0x00627021, 0x000e1027, - 0xa502000a, 0x3c030001, 0x90630f7b, 0x31a2ffff, 0x00e21021, 0x0800418d, - 0x00432023, 0x3c020001, 0x94420f80, 0x00442021, 0x00041c02, 0x3082ffff, - 0x00622021, 0x00807021, 0x00041027, 0x08004185, 0xa502000a, 0x3c050001, - 0x24a50f7a, 0x90a30000, 0x14620002, 0x24e2fff2, 0xa5e20034, 0x90a20000, - 0x00e21023, 0xa5020002, 0x3c030001, 0x94630f80, 0x3c020001, 0x94420f5a, - 0x30e5ffff, 0x00641821, 0x00451023, 0x00622023, 0x00041c02, 0x3082ffff, - 0x00622021, 0x00041027, 0xa502000a, 0x3c030001, 0x90630f7c, 0x24620001, - 0x14a20005, 0x00807021, 0x01631021, 0x90420000, 0x08004185, 0x00026200, - 0x24620002, 0x14a20003, 0x306200fe, 0x004b1021, 0x944c0000, 0x3c020001, - 0x94420f82, 0x3183ffff, 0x3c040001, 0x90840f7b, 0x00431021, 0x00e21021, - 0x00442023, 0x008a2021, 0x00041c02, 0x3082ffff, 0x00622021, 0x00041402, - 0x00822021, 0x00806821, 0x00041027, 0xa4c20010, 0x31a2ffff, 0x000e1c00, - 0x00431025, 0x3c040001, 0x24840f72, 0xade20010, 0x94820000, 0x3c050001, - 0x94a50f76, 0x3c030001, 0x8c630f6c, 0x24420001, 0x00b92821, 0xa4820000, - 0x3322ffff, 0x00622021, 0x0083182b, 0x3c010001, 0xa4250f76, 0x10600003, - 0x24a2ffff, 0x3c010001, 0xa4220f76, 0x3c024000, 0x03021025, 0x3c010001, - 0xac240f6c, 0xaf621008, 0x03e00008, 0x27bd0010, 0x3c030001, 0x90630f56, - 0x27bdffe8, 0x24020001, 0xafbf0014, 0x10620026, 0xafb00010, 0x8f620cf4, - 0x2442ffff, 0x3042007f, 0x00021100, 0x8c434000, 0x3c010001, 0xac230f64, - 0x8c434008, 0x24444000, 0x8c5c4004, 0x30620040, 0x14400002, 0x24020088, - 0x24020008, 0x3c010001, 0xa4220f68, 0x30620004, 0x10400005, 0x24020001, - 0x3c010001, 0xa0220f57, 0x080041d5, 0x00031402, 0x3c010001, 0xa0200f57, - 0x00031402, 0x3c010001, 0xa4220f54, 0x9483000c, 0x24020001, 0x3c010001, - 0xa4200f50, 0x3c010001, 0xa0220f56, 0x3c010001, 0xa4230f62, 0x24020001, - 0x1342001e, 0x00000000, 0x13400005, 0x24020003, 0x13420067, 0x00000000, - 0x080042cf, 0x00000000, 0x3c020001, 0x94420f62, 0x241a0001, 0x3c010001, - 0xa4200f5e, 0x3c010001, 0xa4200f52, 0x304407ff, 0x00021bc2, 0x00031823, - 0x3063003e, 0x34630036, 0x00021242, 0x3042003c, 0x00621821, 0x3c010001, - 0xa4240f58, 0x00832021, 0x24630030, 0x3c010001, 0xa4240f5a, 0x3c010001, - 0xa4230f5c, 0x3c060001, 0x24c60f52, 0x94c50000, 0x94c30002, 0x3c040001, - 0x94840f5a, 0x00651021, 0x0044102a, 0x10400013, 0x3c108000, 0x00a31021, - 0xa4c20000, 0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f56, 0x8f641008, - 0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, - 0x00501024, 0x104000b7, 0x00000000, 0x0800420f, 0x00000000, 0x3c030001, - 0x94630f50, 0x00851023, 0xa4c40000, 0x00621821, 0x3042ffff, 0x3c010001, - 0xa4230f50, 0xaf620ce8, 0x3c020001, 0x94420f68, 0x34420024, 0xaf620cec, - 0x94c30002, 0x3c020001, 0x94420f50, 0x14620012, 0x3c028000, 0x3c108000, - 0x3c02a000, 0xaf620cf4, 0x3c010001, 0xa0200f56, 0x8f641008, 0x00901024, - 0x14400003, 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, - 0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, 0xaf620cf4, 0x3c108000, - 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, 0x00000000, - 0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x080042cf, 0x241a0003, - 0x3c070001, 0x24e70f50, 0x94e20000, 0x03821021, 0xaf620ce0, 0x3c020001, - 0x8c420f64, 0xaf620ce4, 0x3c050001, 0x94a50f54, 0x94e30000, 0x3c040001, - 0x94840f58, 0x3c020001, 0x94420f5e, 0x00a32823, 0x00822023, 0x30a6ffff, - 0x3083ffff, 0x00c3102b, 0x14400043, 0x00000000, 0x3c020001, 0x94420f5c, - 0x00021400, 0x00621025, 0xaf620ce8, 0x94e20000, 0x3c030001, 0x94630f54, - 0x00441021, 0xa4e20000, 0x3042ffff, 0x14430021, 0x3c020008, 0x3c020001, - 0x90420f57, 0x10400006, 0x3c03000c, 0x3c020001, 0x94420f68, 0x34630624, - 0x0800427c, 0x0000d021, 0x3c020001, 0x94420f68, 0x3c030008, 0x34630624, - 0x00431025, 0xaf620cec, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001, - 0xa0200f56, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, - 0x00000000, 0x8f620cf4, 0x00501024, 0x10400015, 0x00000000, 0x08004283, - 0x00000000, 0x3c030001, 0x94630f68, 0x34420624, 0x3c108000, 0x00621825, - 0x3c028000, 0xaf630cec, 0xaf620cf4, 0x8f641008, 0x00901024, 0x14400003, - 0x00000000, 0x0c004064, 0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, - 0x00000000, 0x3c010001, 0x080042cf, 0xa4200f5e, 0x3c020001, 0x94420f5c, - 0x00021400, 0x00c21025, 0xaf620ce8, 0x3c020001, 0x90420f57, 0x10400009, - 0x3c03000c, 0x3c020001, 0x94420f68, 0x34630624, 0x0000d021, 0x00431025, - 0xaf620cec, 0x080042c1, 0x3c108000, 0x3c020001, 0x94420f68, 0x3c030008, - 0x34630604, 0x00431025, 0xaf620cec, 0x3c020001, 0x94420f5e, 0x00451021, - 0x3c010001, 0xa4220f5e, 0x3c108000, 0x3c02a000, 0xaf620cf4, 0x3c010001, - 0xa0200f56, 0x8f641008, 0x00901024, 0x14400003, 0x00000000, 0x0c004064, - 0x00000000, 0x8f620cf4, 0x00501024, 0x1440fff7, 0x00000000, 0x8fbf0014, - 0x8fb00010, 0x03e00008, 0x27bd0018, 0x00000000, 0x27bdffe0, 0x3c040001, - 0x24840ec0, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010, - 0x0c004378, 0xafa00014, 0x0000d021, 0x24020130, 0xaf625000, 0x3c010001, - 0xa4200f50, 0x3c010001, 0xa0200f57, 0x8fbf0018, 0x03e00008, 0x27bd0020, - 0x27bdffe8, 0x3c1bc000, 0xafbf0014, 0xafb00010, 0xaf60680c, 0x8f626804, - 0x34420082, 0xaf626804, 0x8f634000, 0x24020b50, 0x3c010001, 0xac220f20, - 0x24020b78, 0x3c010001, 0xac220f30, 0x34630002, 0xaf634000, 0x0c004315, - 0x00808021, 0x3c010001, 0xa0220f34, 0x304200ff, 0x24030002, 0x14430005, - 0x00000000, 0x3c020001, 0x8c420f20, 0x08004308, 0xac5000c0, 0x3c020001, - 0x8c420f20, 0xac5000bc, 0x8f624434, 0x8f634438, 0x8f644410, 0x3c010001, - 0xac220f28, 0x3c010001, 0xac230f38, 0x3c010001, 0xac240f24, 0x8fbf0014, - 0x8fb00010, 0x03e00008, 0x27bd0018, 0x03e00008, 0x24020001, 0x27bdfff8, - 0x18800009, 0x00002821, 0x8f63680c, 0x8f62680c, 0x1043fffe, 0x00000000, - 0x24a50001, 0x00a4102a, 0x1440fff9, 0x00000000, 0x03e00008, 0x27bd0008, - 0x8f634450, 0x3c020001, 0x8c420f28, 0x00031c02, 0x0043102b, 0x14400008, - 0x3c038000, 0x3c040001, 0x8c840f38, 0x8f624450, 0x00021c02, 0x0083102b, - 0x1040fffc, 0x3c038000, 0xaf634444, 0x8f624444, 0x00431024, 0x1440fffd, - 0x00000000, 0x8f624448, 0x03e00008, 0x3042ffff, 0x3082ffff, 0x2442e000, - 0x2c422001, 0x14400003, 0x3c024000, 0x08004347, 0x2402ffff, 0x00822025, - 0xaf645c38, 0x8f625c30, 0x30420002, 0x1440fffc, 0x00001021, 0x03e00008, - 0x00000000, 0x8f624450, 0x3c030001, 0x8c630f24, 0x08004350, 0x3042ffff, - 0x8f624450, 0x3042ffff, 0x0043102b, 0x1440fffc, 0x00000000, 0x03e00008, - 0x00000000, 0x27bdffe0, 0x00802821, 0x3c040001, 0x24840ed0, 0x00003021, - 0x00003821, 0xafbf0018, 0xafa00010, 0x0c004378, 0xafa00014, 0x0800435f, - 0x00000000, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x3c020001, 0x3442d600, - 0x3c030001, 0x3463d600, 0x3c040001, 0x3484ddff, 0x3c010001, 0xac220f40, - 0x24020040, 0x3c010001, 0xac220f44, 0x3c010001, 0xac200f3c, 0xac600000, - 0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000, - 0x00804821, 0x8faa0010, 0x3c020001, 0x8c420f3c, 0x3c040001, 0x8c840f44, - 0x8fab0014, 0x24430001, 0x0044102b, 0x3c010001, 0xac230f3c, 0x14400003, - 0x00004021, 0x3c010001, 0xac200f3c, 0x3c020001, 0x8c420f3c, 0x3c030001, - 0x8c630f40, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001, - 0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020001, 0x8c420f3c, - 0x3c030001, 0x8c630f40, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008, - 0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c, - 0x00000000, 0x00000000, 0x00000000, -}; - -static const u32 tg3Tso5FwRodata[(TG3_TSO5_FW_RODATA_LEN / 4) + 1] = { - 0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000, - 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, - 0x73746b6f, 0x66666c64, 0x00000000, 0x00000000, 0x66617461, 0x6c457272, - 0x00000000, 0x00000000, 0x00000000, -}; - -static const u32 tg3Tso5FwData[(TG3_TSO5_FW_DATA_LEN / 4) + 1] = { - 0x00000000, 0x73746b6f, 0x66666c64, 0x5f76312e, 0x322e3000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, -}; /* tp->lock is held. */ static int tg3_load_tso_firmware(struct tg3 *tp) { struct fw_info info; + const __be32 *fw_data; unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size; int err, i; if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) return 0; + fw_data = (void *)tp->fw->data; + + /* Firmware blob starts with version numbers, followed by + start address and length. We are setting complete length. + length = end_address_of_bss - start_address_of_text. + Remainder is the blob to be loaded contiguously + from start address. */ + + info.fw_base = be32_to_cpu(fw_data[1]); + cpu_scratch_size = tp->fw_len; + info.fw_len = tp->fw->size - 12; + info.fw_data = &fw_data[3]; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { - info.text_base = TG3_TSO5_FW_TEXT_ADDR; - info.text_len = TG3_TSO5_FW_TEXT_LEN; - info.text_data = &tg3Tso5FwText[0]; - info.rodata_base = TG3_TSO5_FW_RODATA_ADDR; - info.rodata_len = TG3_TSO5_FW_RODATA_LEN; - info.rodata_data = &tg3Tso5FwRodata[0]; - info.data_base = TG3_TSO5_FW_DATA_ADDR; - info.data_len = TG3_TSO5_FW_DATA_LEN; - info.data_data = &tg3Tso5FwData[0]; cpu_base = RX_CPU_BASE; cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705; - cpu_scratch_size = (info.text_len + - info.rodata_len + - info.data_len + - TG3_TSO5_FW_SBSS_LEN + - TG3_TSO5_FW_BSS_LEN); } else { - info.text_base = TG3_TSO_FW_TEXT_ADDR; - info.text_len = TG3_TSO_FW_TEXT_LEN; - info.text_data = &tg3TsoFwText[0]; - info.rodata_base = TG3_TSO_FW_RODATA_ADDR; - info.rodata_len = TG3_TSO_FW_RODATA_LEN; - info.rodata_data = &tg3TsoFwRodata[0]; - info.data_base = TG3_TSO_FW_DATA_ADDR; - info.data_len = TG3_TSO_FW_DATA_LEN; - info.data_data = &tg3TsoFwData[0]; cpu_base = TX_CPU_BASE; cpu_scratch_base = TX_CPU_SCRATCH_BASE; cpu_scratch_size = TX_CPU_SCRATCH_SIZE; @@ -7060,21 +6418,21 @@ static int tg3_load_tso_firmware(struct tg3 *tp) /* Now startup the cpu. */ tw32(cpu_base + CPU_STATE, 0xffffffff); - tw32_f(cpu_base + CPU_PC, info.text_base); + tw32_f(cpu_base + CPU_PC, info.fw_base); for (i = 0; i < 5; i++) { - if (tr32(cpu_base + CPU_PC) == info.text_base) + if (tr32(cpu_base + CPU_PC) == info.fw_base) break; tw32(cpu_base + CPU_STATE, 0xffffffff); tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); - tw32_f(cpu_base + CPU_PC, info.text_base); + tw32_f(cpu_base + CPU_PC, info.fw_base); udelay(1000); } if (i >= 5) { printk(KERN_ERR PFX "tg3_load_tso_firmware fails for %s " "to set CPU PC, is %08x should be %08x\n", tp->dev->name, tr32(cpu_base + CPU_PC), - info.text_base); + info.fw_base); return -ENODEV; } tw32(cpu_base + CPU_STATE, 0xffffffff); @@ -7299,11 +6657,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { int fw_len; - fw_len = (TG3_TSO5_FW_TEXT_LEN + - TG3_TSO5_FW_RODATA_LEN + - TG3_TSO5_FW_DATA_LEN + - TG3_TSO5_FW_SBSS_LEN + - TG3_TSO5_FW_BSS_LEN); + fw_len = tp->fw_len; fw_len = (fw_len + (0x80 - 1)) & ~(0x80 - 1); tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE5705 + fw_len); @@ -13580,6 +12934,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, struct net_device *dev; struct tg3 *tp; int err, pm_cap; + const char *fw_name = NULL; char str[40]; u64 dma_mask, persist_dma_mask; @@ -13735,6 +13090,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tg3_init_bufmgr_config(tp); + if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) + fw_name = FIRMWARE_TG3; + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; } @@ -13747,6 +13105,37 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } else { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG; } + if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) + fw_name = FIRMWARE_TG3TSO5; + else + fw_name = FIRMWARE_TG3TSO; + } + + if (fw_name) { + const __be32 *fw_data; + + err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev); + if (err) { + printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n", + fw_name); + goto err_out_iounmap; + } + + fw_data = (void *)tp->fw->data; + + /* Firmware blob starts with version numbers, followed by + start address and _full_ length including BSS sections + (which must be longer than the actual data, of course */ + + tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ + if (tp->fw_len < (tp->fw->size - 12)) { + printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n", + tp->fw_len, fw_name); + err = -EINVAL; + goto err_out_fw; + } + } /* TSO is on by default on chips that support hardware TSO. * Firmware TSO on older chips gives lower performance, so it @@ -13778,7 +13167,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if (err) { printk(KERN_ERR PFX "Could not obtain valid ethernet address, " "aborting.\n"); - goto err_out_iounmap; + goto err_out_fw; } if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { @@ -13787,7 +13176,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, printk(KERN_ERR PFX "Cannot map APE registers, " "aborting.\n"); err = -ENOMEM; - goto err_out_iounmap; + goto err_out_fw; } tg3_ape_lock_init(tp); @@ -13867,6 +13256,10 @@ err_out_apeunmap: tp->aperegs = NULL; } +err_out_fw: + if (tp->fw) + release_firmware(tp->fw); + err_out_iounmap: if (tp->regs) { iounmap(tp->regs); @@ -13892,6 +13285,9 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) if (dev) { struct tg3 *tp = netdev_priv(dev); + if (tp->fw) + release_firmware(tp->fw); + flush_scheduled_work(); if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 8936edfb043..ae5da603c6a 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2762,6 +2762,10 @@ struct tg3 { #define SST_25VF0X0_PAGE_SIZE 4098 struct ethtool_coalesce coal; + + /* firmware info */ + const struct firmware *fw; + u32 fw_len; /* includes BSS */ }; #endif /* !(_T3_H) */ -- cgit From cfc3a44c3c32abe48898398d9a92e8524c976803 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sun, 4 Jan 2009 16:12:11 -0800 Subject: starfire: use request_firmware() Firmware blob is big endian Signed-off-by: Jaswinder Singh Rajput Signed-off-by: David S. Miller --- drivers/net/starfire.c | 54 +++++- drivers/net/starfire_firmware.h | 346 --------------------------------------- drivers/net/starfire_firmware.pl | 31 ---- 3 files changed, 48 insertions(+), 383 deletions(-) delete mode 100644 drivers/net/starfire_firmware.h delete mode 100644 drivers/net/starfire_firmware.pl (limited to 'drivers/net') diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index f54ac2389da..57fb1f71c47 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -42,11 +42,11 @@ #include #include #include +#include #include /* Processor type for cache alignment. */ #include #include -#include "starfire_firmware.h" /* * The current frame processor firmware fails to checksum a fragment * of length 1. If and when this is fixed, the #define below can be removed. @@ -173,6 +173,10 @@ static int full_duplex[MAX_UNITS] = {0, }; #define skb_first_frag_len(skb) skb_headlen(skb) #define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1) +/* Firmware names */ +#define FIRMWARE_RX "adaptec/starfire_rx.bin" +#define FIRMWARE_TX "adaptec/starfire_tx.bin" + /* These identify the driver base version and may not be removed. */ static char version[] = KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker \n" @@ -182,6 +186,8 @@ MODULE_AUTHOR("Donald Becker "); MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +MODULE_FIRMWARE(FIRMWARE_RX); +MODULE_FIRMWARE(FIRMWARE_TX); module_param(max_interrupt_work, int, 0); module_param(mtu, int, 0); @@ -902,9 +908,12 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val static int netdev_open(struct net_device *dev) { + const struct firmware *fw_rx, *fw_tx; + const __be32 *fw_rx_data, *fw_tx_data; struct netdev_private *np = netdev_priv(dev); void __iomem *ioaddr = np->base; int i, retval; + size_t tx_size, rx_size; size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size; /* Do we ever need to reset the chip??? */ @@ -1040,11 +1049,40 @@ static int netdev_open(struct net_device *dev) writel(ETH_P_8021Q, ioaddr + VlanType); #endif /* VLAN_SUPPORT */ + retval = request_firmware(&fw_rx, FIRMWARE_RX, &np->pci_dev->dev); + if (retval) { + printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n", + FIRMWARE_RX); + return retval; + } + if (fw_rx->size % 4) { + printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", + fw_rx->size, FIRMWARE_RX); + retval = -EINVAL; + goto out_rx; + } + retval = request_firmware(&fw_tx, FIRMWARE_TX, &np->pci_dev->dev); + if (retval) { + printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n", + FIRMWARE_TX); + goto out_rx; + } + if (fw_tx->size % 4) { + printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", + fw_tx->size, FIRMWARE_TX); + retval = -EINVAL; + goto out_tx; + } + fw_rx_data = (const __be32 *)&fw_rx->data[0]; + fw_tx_data = (const __be32 *)&fw_tx->data[0]; + rx_size = fw_rx->size / 4; + tx_size = fw_tx->size / 4; + /* Load Rx/Tx firmware into the frame processors */ - for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++) - writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4); - for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++) - writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4); + for (i = 0; i < rx_size; i++) + writel(be32_to_cpup(&fw_rx_data[i]), ioaddr + RxGfpMem + i * 4); + for (i = 0; i < tx_size; i++) + writel(be32_to_cpup(&fw_tx_data[i]), ioaddr + TxGfpMem + i * 4); if (enable_hw_cksum) /* Enable the Rx and Tx units, and the Rx/Tx frame processors. */ writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl); @@ -1056,7 +1094,11 @@ static int netdev_open(struct net_device *dev) printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name); - return 0; +out_tx: + release_firmware(fw_tx); +out_rx: + release_firmware(fw_rx); + return retval; } diff --git a/drivers/net/starfire_firmware.h b/drivers/net/starfire_firmware.h deleted file mode 100644 index 0a668528955..00000000000 --- a/drivers/net/starfire_firmware.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2003 Adaptec, Inc. - * - * Please read the following license before using the Adaptec Software - * ("Program"). If you do not agree to the license terms, do not use the - * Program: - * - * You agree to be bound by version 2 of the General Public License ("GPL") - * dated June 1991, which can be found at http://www.fsf.org/licenses/gpl.html. - * If the link is broken, write to Free Software Foundation, 59 Temple Place, - * Boston, Massachusetts 02111-1307. - * - * BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE IT IS LICENSED "AS IS" AND - * THERE IS NO WARRANTY FOR THE PROGRAM, INCLUDING BUT NOT LIMITED TO THE - * IMPLIED WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR A PARTICULAR PURPOSE - * (TO THE EXTENT PERMITTED BY APPLICABLE LAW). USE OF THE PROGRAM IS AT YOUR - * OWN RISK. IN NO EVENT WILL ADAPTEC OR ITS LICENSORS BE LIABLE TO YOU FOR - * DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM. - * - */ - -static const u32 firmware_rx[] = { - 0x010003dc, 0x00000000, - 0x04000421, 0x00000086, - 0x80000015, 0x0000180e, - 0x81000015, 0x00006664, - 0x1a0040ab, 0x00000b06, - 0x14200011, 0x00000000, - 0x14204022, 0x0000aaaa, - 0x14204022, 0x00000300, - 0x14204022, 0x00000000, - 0x1a0040ab, 0x00000b14, - 0x14200011, 0x00000000, - 0x83000015, 0x00000002, - 0x04000021, 0x00000000, - 0x00000010, 0x00000000, - 0x04000421, 0x00000087, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00008015, 0x00000000, - 0x0000003e, 0x00000000, - 0x00000010, 0x00000000, - 0x82000015, 0x00004000, - 0x009e8050, 0x00000000, - 0x03008015, 0x00000000, - 0x86008015, 0x00000000, - 0x82000015, 0x00008000, - 0x0100001c, 0x00000000, - 0x000050a0, 0x0000010c, - 0x4e20d011, 0x00006008, - 0x1420d012, 0x00004008, - 0x0000f090, 0x00007000, - 0x0000c8b0, 0x00003000, - 0x00004040, 0x00000000, - 0x00108015, 0x00000000, - 0x00a2c150, 0x00004000, - 0x00a400b0, 0x00000014, - 0x00000020, 0x00000000, - 0x2500400d, 0x00002525, - 0x00047220, 0x00003100, - 0x00934070, 0x00000000, - 0x00000020, 0x00000000, - 0x00924460, 0x00000184, - 0x2b20c011, 0x00000000, - 0x0000c420, 0x00000540, - 0x36014018, 0x0000422d, - 0x14200011, 0x00000000, - 0x00924460, 0x00000183, - 0x3200001f, 0x00000034, - 0x02ac0015, 0x00000002, - 0x00a60110, 0x00000008, - 0x42200011, 0x00000000, - 0x00924060, 0x00000103, - 0x0000001e, 0x00000000, - 0x00000020, 0x00000100, - 0x0000001e, 0x00000000, - 0x00924460, 0x00000086, - 0x00004080, 0x00000000, - 0x0092c070, 0x00000000, - 0x00924060, 0x00000100, - 0x0000c890, 0x00005000, - 0x00a6c110, 0x00000000, - 0x00b0c090, 0x00000012, - 0x021c0015, 0x00000000, - 0x3200001f, 0x00000034, - 0x00924460, 0x00000510, - 0x44210011, 0x00000000, - 0x42000011, 0x00000000, - 0x83000015, 0x00000040, - 0x00924460, 0x00000508, - 0x45014018, 0x00004545, - 0x00808050, 0x00000000, - 0x62208012, 0x00000000, - 0x82000015, 0x00000800, - 0x15200011, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x80000015, 0x0000eea4, - 0x81000015, 0x0000005f, - 0x00000060, 0x00000000, - 0x00004120, 0x00000000, - 0x00004a00, 0x00004000, - 0x00924460, 0x00000190, - 0x5601401a, 0x00005956, - 0x14000011, 0x00000000, - 0x00934050, 0x00000018, - 0x00930050, 0x00000018, - 0x3601403a, 0x0000002d, - 0x000643a9, 0x00000000, - 0x0000c420, 0x00000140, - 0x5601401a, 0x00005956, - 0x14000011, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x000642a9, 0x00000000, - 0x00024420, 0x00000183, - 0x5601401a, 0x00005956, - 0x82000015, 0x00002000, - 0x15200011, 0x00000000, - 0x82000015, 0x00000010, - 0x15200011, 0x00000000, - 0x82000015, 0x00000010, - 0x15200011, 0x00000000, -}; /* 104 Rx instructions */ -#define FIRMWARE_RX_SIZE 104 - -static const u32 firmware_tx[] = { - 0x010003dc, 0x00000000, - 0x04000421, 0x00000086, - 0x80000015, 0x0000180e, - 0x81000015, 0x00006664, - 0x1a0040ab, 0x00000b06, - 0x14200011, 0x00000000, - 0x14204022, 0x0000aaaa, - 0x14204022, 0x00000300, - 0x14204022, 0x00000000, - 0x1a0040ab, 0x00000b14, - 0x14200011, 0x00000000, - 0x83000015, 0x00000002, - 0x04000021, 0x00000000, - 0x00000010, 0x00000000, - 0x04000421, 0x00000087, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00008015, 0x00000000, - 0x0000003e, 0x00000000, - 0x00000010, 0x00000000, - 0x82000015, 0x00004000, - 0x009e8050, 0x00000000, - 0x03008015, 0x00000000, - 0x86008015, 0x00000000, - 0x82000015, 0x00008000, - 0x0100001c, 0x00000000, - 0x000050a0, 0x0000010c, - 0x4e20d011, 0x00006008, - 0x1420d012, 0x00004008, - 0x0000f090, 0x00007000, - 0x0000c8b0, 0x00003000, - 0x00004040, 0x00000000, - 0x00108015, 0x00000000, - 0x00a2c150, 0x00004000, - 0x00a400b0, 0x00000014, - 0x00000020, 0x00000000, - 0x2500400d, 0x00002525, - 0x00047220, 0x00003100, - 0x00934070, 0x00000000, - 0x00000020, 0x00000000, - 0x00924460, 0x00000184, - 0x2b20c011, 0x00000000, - 0x0000c420, 0x00000540, - 0x36014018, 0x0000422d, - 0x14200011, 0x00000000, - 0x00924460, 0x00000183, - 0x3200001f, 0x00000034, - 0x02ac0015, 0x00000002, - 0x00a60110, 0x00000008, - 0x42200011, 0x00000000, - 0x00924060, 0x00000103, - 0x0000001e, 0x00000000, - 0x00000020, 0x00000100, - 0x0000001e, 0x00000000, - 0x00924460, 0x00000086, - 0x00004080, 0x00000000, - 0x0092c070, 0x00000000, - 0x00924060, 0x00000100, - 0x0000c890, 0x00005000, - 0x00a6c110, 0x00000000, - 0x00b0c090, 0x00000012, - 0x021c0015, 0x00000000, - 0x3200001f, 0x00000034, - 0x00924460, 0x00000510, - 0x44210011, 0x00000000, - 0x42000011, 0x00000000, - 0x83000015, 0x00000040, - 0x00924460, 0x00000508, - 0x45014018, 0x00004545, - 0x00808050, 0x00000000, - 0x62208012, 0x00000000, - 0x82000015, 0x00000800, - 0x15200011, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x80000015, 0x0000eea4, - 0x81000015, 0x0000005f, - 0x00000060, 0x00000000, - 0x00004120, 0x00000000, - 0x00004a00, 0x00004000, - 0x00924460, 0x00000190, - 0x5601401a, 0x00005956, - 0x14000011, 0x00000000, - 0x00934050, 0x00000018, - 0x00930050, 0x00000018, - 0x3601403a, 0x0000002d, - 0x000643a9, 0x00000000, - 0x0000c420, 0x00000140, - 0x5601401a, 0x00005956, - 0x14000011, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x000642a9, 0x00000000, - 0x00024420, 0x00000183, - 0x5601401a, 0x00005956, - 0x82000015, 0x00002000, - 0x15200011, 0x00000000, - 0x82000015, 0x00000010, - 0x15200011, 0x00000000, - 0x82000015, 0x00000010, - 0x15200011, 0x00000000, -}; /* 104 Tx instructions */ -#define FIRMWARE_TX_SIZE 104 -#if 0 -static const u32 firmware_wol[] = { - 0x010003dc, 0x00000000, - 0x19000421, 0x00000087, - 0x80000015, 0x00001a1a, - 0x81000015, 0x00001a1a, - 0x1a0040ab, 0x00000b06, - 0x15200011, 0x00000000, - 0x15204022, 0x0000aaaa, - 0x15204022, 0x00000300, - 0x15204022, 0x00000000, - 0x1a0040ab, 0x00000b15, - 0x15200011, 0x00000000, - 0x83000015, 0x00000002, - 0x04000021, 0x00000000, - 0x00000010, 0x00000000, - 0x04000421, 0x00000087, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00008015, 0x00000000, - 0x0000003e, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x82000015, 0x00004000, - 0x82000015, 0x00008000, - 0x0000000c, 0x00000000, - 0x00000010, 0x00000000, - 0x00004080, 0x00000100, - 0x1f20c011, 0x00001122, - 0x2720f011, 0x00003011, - 0x19200071, 0x00000000, - 0x1a200051, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x1d2040a4, 0x00003344, - 0x1d2040a2, 0x00005566, - 0x000040a0, 0x00000100, - 0x00108050, 0x00000001, - 0x1a208012, 0x00000006, - 0x82000015, 0x00008080, - 0x010003dc, 0x00000000, - 0x1d2040a4, 0x00002233, - 0x1d2040a4, 0x00004455, - 0x2d208011, 0x00000005, - 0x1d2040a4, 0x00006611, - 0x00108050, 0x00000001, - 0x27200011, 0x00000000, - 0x1d2050a4, 0x00006600, - 0x82000015, 0x00008080, - 0x010003dc, 0x00000000, - 0x00000050, 0x00000000, - 0x1b200031, 0x00000000, - 0x0000001e, 0x00000000, - 0x0000001e, 0x00000000, - 0x0000001e, 0x00000000, - 0x0000001e, 0x00000000, - 0x00924460, 0x00000086, - 0x00004080, 0x00000000, - 0x0092c070, 0x00000000, - 0x00924060, 0x00000100, - 0x0000c890, 0x00005000, - 0x00a6c110, 0x00000000, - 0x00b0c090, 0x00000012, - 0x021c0015, 0x00000000, - 0x3200001f, 0x00000034, - 0x00924460, 0x00000510, - 0x44210011, 0x00000000, - 0x42000011, 0x00000000, - 0x83000015, 0x00000040, - 0x00924460, 0x00000508, - 0x476a0012, 0x00000100, - 0x83000015, 0x00000008, - 0x16200011, 0x00000000, - 0x001e8050, 0x00000000, - 0x001e8050, 0x00000000, - 0x00808050, 0x00000000, - 0x03008015, 0x00000000, - 0x62208012, 0x00000000, - 0x82000015, 0x00000800, - 0x16200011, 0x00000000, - 0x80000015, 0x0000eea4, - 0x81000015, 0x0000005f, - 0x00000020, 0x00000000, - 0x00004120, 0x00000000, - 0x00004a00, 0x00004000, - 0x00924460, 0x00000190, - 0x5c01401a, 0x0000595c, - 0x15000011, 0x00000000, - 0x00934050, 0x00000018, - 0x00930050, 0x00000018, - 0x3601403a, 0x0000002d, - 0x00064029, 0x00000000, - 0x0000c420, 0x00000140, - 0x5c01401a, 0x0000595c, - 0x15000011, 0x00000000, - 0x00000010, 0x00000000, - 0x00000010, 0x00000000, - 0x00064029, 0x00000000, - 0x00024420, 0x00000183, - 0x5c01401a, 0x0000595c, - 0x82000015, 0x00002000, - 0x16200011, 0x00000000, - 0x82000015, 0x00000010, - 0x16200011, 0x00000000, - 0x82000015, 0x00000010, - 0x16200011, 0x00000000, -}; /* 104 WoL instructions */ -#define FIRMWARE_WOL_SIZE 104 -#endif diff --git a/drivers/net/starfire_firmware.pl b/drivers/net/starfire_firmware.pl deleted file mode 100644 index 0c82b80e107..00000000000 --- a/drivers/net/starfire_firmware.pl +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/perl - -# This script can be used to generate a new starfire_firmware.h -# from GFP_RX.DAT and GFP_TX.DAT, files included with the DDK -# and also with the Novell drivers. - -open FW, "GFP_RX.DAT" || die; -open FWH, ">starfire_firmware.h" || die; - -printf(FWH "static u32 firmware_rx[] = {\n"); -$counter = 0; -while ($foo = ) { - chomp; - printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4)); - $counter++; -} - -close FW; -open FW, "GFP_TX.DAT" || die; - -printf(FWH "};\t/* %d Rx instructions */\n#define FIRMWARE_RX_SIZE %d\n\nstatic u32 firmware_tx[] = {\n", $counter, $counter); -$counter = 0; -while ($foo = ) { - chomp; - printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4)); - $counter++; -} - -close FW; -printf(FWH "};\t/* %d Tx instructions */\n#define FIRMWARE_TX_SIZE %d\n", $counter, $counter); -close(FWH); -- cgit From 22692018b93f0782cda5a843cecfffda1854eb8d Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Sun, 4 Jan 2009 16:23:01 -0800 Subject: enc28j60: fix RX buffer overflow The enc28j60 driver doesn't check whether the length of the packet as reported by the hardware fits into the preallocated buffer. When stressed, the hardware may report insanely large packets even tough the "Receive OK" bit is set. Fix this. Signed-off-by: Baruch Siach Signed-off-by: David S. Miller --- drivers/net/enc28j60.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index b0ef46c51a9..cefe1d98f93 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -944,7 +944,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) if (netif_msg_rx_status(priv)) enc28j60_dump_rsv(priv, __func__, next_packet, len, rxstat); - if (!RSV_GETBIT(rxstat, RSV_RXOK)) { + if (!RSV_GETBIT(rxstat, RSV_RXOK) || len > MAX_FRAMELEN) { if (netif_msg_rx_err(priv)) dev_err(&ndev->dev, "Rx Error (%04x)\n", rxstat); ndev->stats.rx_errors++; @@ -952,6 +952,8 @@ static void enc28j60_hw_rx(struct net_device *ndev) ndev->stats.rx_crc_errors++; if (RSV_GETBIT(rxstat, RSV_LENCHECKERR)) ndev->stats.rx_frame_errors++; + if (len > MAX_FRAMELEN) + ndev->stats.rx_over_errors++; } else { skb = dev_alloc_skb(len + NET_IP_ALIGN); if (!skb) { -- cgit From c907a35acf0e964dfd0753519b3dc7689727e175 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Sun, 4 Jan 2009 17:06:46 -0800 Subject: qlge: bugfix: Add missing pci_mapping_err checking. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 718a7bd0cd1..c6ab6a493e7 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -963,6 +963,11 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) sbq_desc->p.skb->data, rx_ring->sbq_buf_size / 2, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(qdev->pdev, map)) { + QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n"); + rx_ring->sbq_clean_idx = clean_idx; + return; + } pci_unmap_addr_set(sbq_desc, mapaddr, map); pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2); -- cgit From 4055c7d495f2502718bbbea871e6504ae95add14 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Sun, 4 Jan 2009 17:07:09 -0800 Subject: qlge: bugfix: Add missing pci_unmap_page call in receive path. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c6ab6a493e7..9ceedfc4b56 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1308,6 +1308,11 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, "No skb available, drop the packet.\n"); return NULL; } + pci_unmap_page(qdev->pdev, + pci_unmap_addr(lbq_desc, + mapaddr), + pci_unmap_len(lbq_desc, maplen), + PCI_DMA_FROMDEVICE); skb_reserve(skb, NET_IP_ALIGN); QPRINTK(qdev, RX_STATUS, DEBUG, "%d bytes of headers and data in large. Chain page to new skb and pull tail.\n", length); -- cgit From 2b72c7849f9a091c1e5d7255732faf14ac7d5123 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Sun, 4 Jan 2009 17:07:50 -0800 Subject: qlge: bugfix: Fix shadow register endian issue. Shadow registers are consistent memory locations to which the chip echos ring indexes in little endian format. These values need to be endian swapped before referencing. Note: The register pointer declaration uses the volatile modifier which causes warnings in checkpatch. Per Documentation/volatile-considered-harmful.txt: - Pointers to data structures in coherent memory which might be modified by I/O devices can, sometimes, legitimately be volatile. A ring buffer used by a network adapter, where that adapter changes pointers to indicate which descriptors have been processed, is an example of this type of situation. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 17 +---------------- drivers/net/qlge/qlge_main.c | 12 ++++++------ 2 files changed, 7 insertions(+), 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index ba2e1c5b6bc..97321bb9600 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -1189,7 +1189,7 @@ struct rx_ring { u32 cq_size; u32 cq_len; u16 cq_id; - u32 *prod_idx_sh_reg; /* Shadowed producer register. */ + volatile __le32 *prod_idx_sh_reg; /* Shadowed producer register. */ dma_addr_t prod_idx_sh_reg_dma; void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */ u32 cnsmr_idx; /* current sw idx */ @@ -1467,21 +1467,6 @@ static inline void ql_write_db_reg(u32 val, void __iomem *addr) mmiowb(); } -/* - * Shadow Registers: - * Outbound queues have a consumer index that is maintained by the chip. - * Inbound queues have a producer index that is maintained by the chip. - * For lower overhead, these registers are "shadowed" to host memory - * which allows the device driver to track the queue progress without - * PCI reads. When an entry is placed on an inbound queue, the chip will - * update the relevant index register and then copy the value to the - * shadow register in host memory. - */ -static inline unsigned int ql_read_sh_reg(const volatile void *addr) -{ - return *(volatile unsigned int __force *)addr; -} - extern char qlge_driver_name[]; extern const char qlge_driver_version[]; extern const struct ethtool_ops qlge_ethtool_ops; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 9ceedfc4b56..c0e43c552d1 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1559,7 +1559,7 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) { struct ql_adapter *qdev = rx_ring->qdev; - u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); + u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); struct ob_mac_iocb_rsp *net_rsp = NULL; int count = 0; @@ -1585,7 +1585,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) } count++; ql_update_cq(rx_ring); - prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); + prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); } ql_write_cq_idx(rx_ring); if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) { @@ -1605,7 +1605,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) { struct ql_adapter *qdev = rx_ring->qdev; - u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); + u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); struct ql_net_rsp_iocb *net_rsp; int count = 0; @@ -1638,7 +1638,7 @@ static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) } count++; ql_update_cq(rx_ring); - prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); + prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); if (count == budget) break; } @@ -1801,7 +1801,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) * Check the default queue and wake handler if active. */ rx_ring = &qdev->rx_ring[0]; - if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { + if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n"); ql_disable_completion_interrupt(qdev, intr_context->intr); queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue, @@ -1815,7 +1815,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) */ for (i = 1; i < qdev->rx_ring_count; i++) { rx_ring = &qdev->rx_ring[i]; - if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != + if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[%d].\n", i); -- cgit From 459caf5a99cd066598192a86f8f63d73f0b423a6 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Sun, 4 Jan 2009 17:08:11 -0800 Subject: qlge: bugfix: Fix ring length setting for rx ring, large/small The length field for these rings is 16-bits. If the length is the max supported 65536 then the setting should be zero. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c0e43c552d1..ffa21007442 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2491,7 +2491,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) memset((void *)cqicb, 0, sizeof(struct cqicb)); cqicb->msix_vect = rx_ring->irq; - cqicb->len = cpu_to_le16(rx_ring->cq_len | LEN_V | LEN_CPP_CONT); + bq_len = (rx_ring->cq_len == 65536) ? 0 : (u16) rx_ring->cq_len; + cqicb->len = cpu_to_le16(bq_len | LEN_V | LEN_CPP_CONT); cqicb->addr_lo = cpu_to_le32(rx_ring->cq_base_dma); cqicb->addr_hi = cpu_to_le32((u64) rx_ring->cq_base_dma >> 32); @@ -2513,8 +2514,11 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) cpu_to_le32(rx_ring->lbq_base_indirect_dma); cqicb->lbq_addr_hi = cpu_to_le32((u64) rx_ring->lbq_base_indirect_dma >> 32); - cqicb->lbq_buf_size = cpu_to_le32(rx_ring->lbq_buf_size); - bq_len = (u16) rx_ring->lbq_len; + bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 : + (u16) rx_ring->lbq_buf_size; + cqicb->lbq_buf_size = cpu_to_le16(bq_len); + bq_len = (rx_ring->lbq_len == 65536) ? 0 : + (u16) rx_ring->lbq_len; cqicb->lbq_len = cpu_to_le16(bq_len); rx_ring->lbq_prod_idx = rx_ring->lbq_len - 16; rx_ring->lbq_curr_idx = 0; @@ -2530,7 +2534,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) cpu_to_le32((u64) rx_ring->sbq_base_indirect_dma >> 32); cqicb->sbq_buf_size = cpu_to_le16(((rx_ring->sbq_buf_size / 2) + 8) & 0xfffffff8); - bq_len = (u16) rx_ring->sbq_len; + bq_len = (rx_ring->sbq_len == 65536) ? 0 : + (u16) rx_ring->sbq_len; cqicb->sbq_len = cpu_to_le16(bq_len); rx_ring->sbq_prod_idx = rx_ring->sbq_len - 16; rx_ring->sbq_curr_idx = 0; -- cgit From 939678f81a55c839ae58c9cc3d4ec6d0f60e7dc7 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Sun, 4 Jan 2009 17:08:29 -0800 Subject: qlge: bugfix: Fix register access error checking. Some indexed registers do not have error bits. In these cases a value of zero should be used for error checking. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index ffa21007442..837be72efb0 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -257,7 +257,7 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, { status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MW, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MW, 0); if (status) goto exit; ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */ @@ -265,13 +265,13 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, MAC_ADDR_ADR | MAC_ADDR_RS | type); /* type */ status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MR, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MR, 0); if (status) goto exit; *value++ = ql_read32(qdev, MAC_ADDR_DATA); status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MW, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MW, 0); if (status) goto exit; ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */ @@ -279,14 +279,14 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, MAC_ADDR_ADR | MAC_ADDR_RS | type); /* type */ status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MR, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MR, 0); if (status) goto exit; *value++ = ql_read32(qdev, MAC_ADDR_DATA); if (type == MAC_ADDR_TYPE_CAM_MAC) { status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MW, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MW, 0); if (status) goto exit; ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */ @@ -294,7 +294,7 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index, MAC_ADDR_ADR | MAC_ADDR_RS | type); /* type */ status = ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, - MAC_ADDR_MR, MAC_ADDR_E); + MAC_ADDR_MR, 0); if (status) goto exit; *value++ = ql_read32(qdev, MAC_ADDR_DATA); @@ -344,7 +344,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MW, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MW, 0); if (status) goto exit; ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */ @@ -353,7 +353,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, ql_write32(qdev, MAC_ADDR_DATA, lower); status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MW, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MW, 0); if (status) goto exit; ql_write32(qdev, MAC_ADDR_IDX, (offset++) | /* offset */ @@ -362,7 +362,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, ql_write32(qdev, MAC_ADDR_DATA, upper); status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MW, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MW, 0); if (status) goto exit; ql_write32(qdev, MAC_ADDR_IDX, (offset) | /* offset */ @@ -400,7 +400,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, status = ql_wait_reg_rdy(qdev, - MAC_ADDR_IDX, MAC_ADDR_MW, MAC_ADDR_E); + MAC_ADDR_IDX, MAC_ADDR_MW, 0); if (status) goto exit; ql_write32(qdev, MAC_ADDR_IDX, offset | /* offset */ @@ -431,13 +431,13 @@ int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value) if (status) goto exit; - status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, RT_IDX_E); + status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, 0); if (status) goto exit; ql_write32(qdev, RT_IDX, RT_IDX_TYPE_NICQ | RT_IDX_RS | (index << RT_IDX_IDX_SHIFT)); - status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MR, RT_IDX_E); + status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MR, 0); if (status) goto exit; *value = ql_read32(qdev, RT_DATA); -- cgit From f26251eb68ea766a98fed922593c154d15127621 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sun, 4 Jan 2009 17:12:04 -0800 Subject: e100: cosmetic cleanup Add missing space after if, switch, for and while keywords. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e100.c | 268 ++++++++++++++++++++++++++--------------------------- 1 file changed, 134 insertions(+), 134 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 9f38b16ccbb..134b2d60b47 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -658,12 +658,12 @@ static int e100_self_test(struct nic *nic) e100_disable_irq(nic); /* Check results of self-test */ - if(nic->mem->selftest.result != 0) { + if (nic->mem->selftest.result != 0) { DPRINTK(HW, ERR, "Self-test failed: result=0x%08X\n", nic->mem->selftest.result); return -ETIMEDOUT; } - if(nic->mem->selftest.signature == 0) { + if (nic->mem->selftest.signature == 0) { DPRINTK(HW, ERR, "Self-test failed: timed out\n"); return -ETIMEDOUT; } @@ -684,13 +684,13 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, __le16 da cmd_addr_data[2] = op_ewds << (addr_len - 2); /* Bit-bang cmds to write word to eeprom */ - for(j = 0; j < 3; j++) { + for (j = 0; j < 3; j++) { /* Chip select */ iowrite8(eecs | eesk, &nic->csr->eeprom_ctrl_lo); e100_write_flush(nic); udelay(4); - for(i = 31; i >= 0; i--) { + for (i = 31; i >= 0; i--) { ctrl = (cmd_addr_data[j] & (1 << i)) ? eecs | eedi : eecs; iowrite8(ctrl, &nic->csr->eeprom_ctrl_lo); @@ -723,7 +723,7 @@ static __le16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr) e100_write_flush(nic); udelay(4); /* Bit-bang to read word from eeprom */ - for(i = 31; i >= 0; i--) { + for (i = 31; i >= 0; i--) { ctrl = (cmd_addr_data & (1 << i)) ? eecs | eedi : eecs; iowrite8(ctrl, &nic->csr->eeprom_ctrl_lo); e100_write_flush(nic); udelay(4); @@ -734,7 +734,7 @@ static __le16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr) /* Eeprom drives a dummy zero to EEDO after receiving * complete address. Use this to adjust addr_len. */ ctrl = ioread8(&nic->csr->eeprom_ctrl_lo); - if(!(ctrl & eedo) && i > 16) { + if (!(ctrl & eedo) && i > 16) { *addr_len -= (i - 16); i = 17; } @@ -758,9 +758,9 @@ static int e100_eeprom_load(struct nic *nic) e100_eeprom_read(nic, &addr_len, 0); nic->eeprom_wc = 1 << addr_len; - for(addr = 0; addr < nic->eeprom_wc; addr++) { + for (addr = 0; addr < nic->eeprom_wc; addr++) { nic->eeprom[addr] = e100_eeprom_read(nic, &addr_len, addr); - if(addr < nic->eeprom_wc - 1) + if (addr < nic->eeprom_wc - 1) checksum += le16_to_cpu(nic->eeprom[addr]); } @@ -784,15 +784,15 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count) e100_eeprom_read(nic, &addr_len, 0); nic->eeprom_wc = 1 << addr_len; - if(start + count >= nic->eeprom_wc) + if (start + count >= nic->eeprom_wc) return -EINVAL; - for(addr = start; addr < start + count; addr++) + for (addr = start; addr < start + count; addr++) e100_eeprom_write(nic, addr_len, addr, nic->eeprom[addr]); /* The checksum, stored in the last word, is calculated such that * the sum of words should be 0xBABA */ - for(addr = 0; addr < nic->eeprom_wc - 1; addr++) + for (addr = 0; addr < nic->eeprom_wc - 1; addr++) checksum += le16_to_cpu(nic->eeprom[addr]); nic->eeprom[nic->eeprom_wc - 1] = cpu_to_le16(0xBABA - checksum); e100_eeprom_write(nic, addr_len, nic->eeprom_wc - 1, @@ -812,19 +812,19 @@ static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) spin_lock_irqsave(&nic->cmd_lock, flags); /* Previous command is accepted when SCB clears */ - for(i = 0; i < E100_WAIT_SCB_TIMEOUT; i++) { - if(likely(!ioread8(&nic->csr->scb.cmd_lo))) + for (i = 0; i < E100_WAIT_SCB_TIMEOUT; i++) { + if (likely(!ioread8(&nic->csr->scb.cmd_lo))) break; cpu_relax(); - if(unlikely(i > E100_WAIT_SCB_FAST)) + if (unlikely(i > E100_WAIT_SCB_FAST)) udelay(5); } - if(unlikely(i == E100_WAIT_SCB_TIMEOUT)) { + if (unlikely(i == E100_WAIT_SCB_TIMEOUT)) { err = -EAGAIN; goto err_unlock; } - if(unlikely(cmd != cuc_resume)) + if (unlikely(cmd != cuc_resume)) iowrite32(dma_addr, &nic->csr->scb.gen_ptr); iowrite8(cmd, &nic->csr->scb.cmd_lo); @@ -843,7 +843,7 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, spin_lock_irqsave(&nic->cb_lock, flags); - if(unlikely(!nic->cbs_avail)) { + if (unlikely(!nic->cbs_avail)) { err = -ENOMEM; goto err_unlock; } @@ -853,7 +853,7 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, nic->cbs_avail--; cb->skb = skb; - if(unlikely(!nic->cbs_avail)) + if (unlikely(!nic->cbs_avail)) err = -ENOSPC; cb_prepare(nic, cb, skb); @@ -864,15 +864,15 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, wmb(); cb->prev->command &= cpu_to_le16(~cb_s); - while(nic->cb_to_send != nic->cb_to_use) { - if(unlikely(e100_exec_cmd(nic, nic->cuc_cmd, + while (nic->cb_to_send != nic->cb_to_use) { + if (unlikely(e100_exec_cmd(nic, nic->cuc_cmd, nic->cb_to_send->dma_addr))) { /* Ok, here's where things get sticky. It's * possible that we can't schedule the command * because the controller is too busy, so * let's just queue the command and try again * when another command is scheduled. */ - if(err == -ENOSPC) { + if (err == -ENOSPC) { //request a reset schedule_work(&nic->tx_timeout_task); } @@ -945,7 +945,7 @@ static void e100_get_defaults(struct nic *nic) /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */ nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->pdev->revision; - if(nic->mac == mac_unknown) + if (nic->mac == mac_unknown) nic->mac = mac_82557_D100_A; nic->params.rfds = rfds; @@ -1008,23 +1008,23 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) config->adaptive_ifs = nic->adaptive_ifs; config->loopback = nic->loopback; - if(nic->mii.force_media && nic->mii.full_duplex) + if (nic->mii.force_media && nic->mii.full_duplex) config->full_duplex_force = 0x1; /* 1=force, 0=auto */ - if(nic->flags & promiscuous || nic->loopback) { + if (nic->flags & promiscuous || nic->loopback) { config->rx_save_bad_frames = 0x1; /* 1=save, 0=discard */ config->rx_discard_short_frames = 0x0; /* 1=discard, 0=save */ config->promiscuous_mode = 0x1; /* 1=on, 0=off */ } - if(nic->flags & multicast_all) + if (nic->flags & multicast_all) config->multicast_all = 0x1; /* 1=accept, 0=no */ /* disable WoL when up */ - if(netif_running(nic->netdev) || !(nic->flags & wol_magic)) + if (netif_running(nic->netdev) || !(nic->flags & wol_magic)) config->magic_packet_disable = 0x1; /* 1=off, 0=on */ - if(nic->mac >= mac_82558_D101_A4) { + if (nic->mac >= mac_82558_D101_A4) { config->fc_disable = 0x1; /* 1=Tx fc off, 0=Tx fc on */ config->mwi_enable = 0x1; /* 1=enable, 0=disable */ config->standard_tcb = 0x0; /* 1=standard, 0=extended */ @@ -1369,21 +1369,21 @@ static int e100_phy_init(struct nic *nic) u16 bmcr, stat, id_lo, id_hi, cong; /* Discover phy addr by searching addrs in order {1,0,2,..., 31} */ - for(addr = 0; addr < 32; addr++) { + for (addr = 0; addr < 32; addr++) { nic->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr; bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR); stat = mdio_read(netdev, nic->mii.phy_id, MII_BMSR); stat = mdio_read(netdev, nic->mii.phy_id, MII_BMSR); - if(!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) + if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) break; } DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); - if(addr == 32) + if (addr == 32) return -EAGAIN; /* Selected the phy and isolate the rest */ - for(addr = 0; addr < 32; addr++) { - if(addr != nic->mii.phy_id) { + for (addr = 0; addr < 32; addr++) { + if (addr != nic->mii.phy_id) { mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE); } else { bmcr = mdio_read(netdev, addr, MII_BMCR); @@ -1400,7 +1400,7 @@ static int e100_phy_init(struct nic *nic) /* Handle National tx phys */ #define NCS_PHY_MODEL_MASK 0xFFF0FFFF - if((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { + if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { /* Disable congestion control */ cong = mdio_read(netdev, nic->mii.phy_id, MII_NSC_CONG); cong |= NSC_CONG_TXREADY; @@ -1408,7 +1408,7 @@ static int e100_phy_init(struct nic *nic) mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong); } - if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && + if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { /* enable/disable MDI/MDI-X auto-switching. */ @@ -1426,25 +1426,25 @@ static int e100_hw_init(struct nic *nic) e100_hw_reset(nic); DPRINTK(HW, ERR, "e100_hw_init\n"); - if(!in_interrupt() && (err = e100_self_test(nic))) + if (!in_interrupt() && (err = e100_self_test(nic))) return err; - if((err = e100_phy_init(nic))) + if ((err = e100_phy_init(nic))) return err; - if((err = e100_exec_cmd(nic, cuc_load_base, 0))) + if ((err = e100_exec_cmd(nic, cuc_load_base, 0))) return err; - if((err = e100_exec_cmd(nic, ruc_load_base, 0))) + if ((err = e100_exec_cmd(nic, ruc_load_base, 0))) return err; if ((err = e100_exec_cb_wait(nic, NULL, e100_setup_ucode))) return err; - if((err = e100_exec_cb(nic, NULL, e100_configure))) + if ((err = e100_exec_cb(nic, NULL, e100_configure))) return err; - if((err = e100_exec_cb(nic, NULL, e100_setup_iaaddr))) + if ((err = e100_exec_cb(nic, NULL, e100_setup_iaaddr))) return err; - if((err = e100_exec_cmd(nic, cuc_dump_addr, + if ((err = e100_exec_cmd(nic, cuc_dump_addr, nic->dma_addr + offsetof(struct mem, stats)))) return err; - if((err = e100_exec_cmd(nic, cuc_dump_reset, 0))) + if ((err = e100_exec_cmd(nic, cuc_dump_reset, 0))) return err; e100_disable_irq(nic); @@ -1460,7 +1460,7 @@ static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) cb->command = cpu_to_le16(cb_multi); cb->u.multi.count = cpu_to_le16(count * ETH_ALEN); - for(i = 0; list && i < count; i++, list = list->next) + for (i = 0; list && i < count; i++, list = list->next) memcpy(&cb->u.multi.addr[i*ETH_ALEN], &list->dmi_addr, ETH_ALEN); } @@ -1472,12 +1472,12 @@ static void e100_set_multicast_list(struct net_device *netdev) DPRINTK(HW, DEBUG, "mc_count=%d, flags=0x%04X\n", netdev->mc_count, netdev->flags); - if(netdev->flags & IFF_PROMISC) + if (netdev->flags & IFF_PROMISC) nic->flags |= promiscuous; else nic->flags &= ~promiscuous; - if(netdev->flags & IFF_ALLMULTI || + if (netdev->flags & IFF_ALLMULTI || netdev->mc_count > E100_MAX_MULTICAST_ADDRS) nic->flags |= multicast_all; else @@ -1500,7 +1500,7 @@ static void e100_update_stats(struct nic *nic) * complete, so we're always waiting for results of the * previous command. */ - if(*complete == cpu_to_le32(cuc_dump_reset_complete)) { + if (*complete == cpu_to_le32(cuc_dump_reset_complete)) { *complete = 0; nic->tx_frames = le32_to_cpu(s->tx_good_frames); nic->tx_collisions = le32_to_cpu(s->tx_total_collisions); @@ -1527,12 +1527,12 @@ static void e100_update_stats(struct nic *nic) le32_to_cpu(s->tx_single_collisions); nic->tx_multiple_collisions += le32_to_cpu(s->tx_multiple_collisions); - if(nic->mac >= mac_82558_D101_A4) { + if (nic->mac >= mac_82558_D101_A4) { nic->tx_fc_pause += le32_to_cpu(s->fc_xmt_pause); nic->rx_fc_pause += le32_to_cpu(s->fc_rcv_pause); nic->rx_fc_unsupported += le32_to_cpu(s->fc_rcv_unsupported); - if(nic->mac >= mac_82559_D101M) { + if (nic->mac >= mac_82559_D101M) { nic->tx_tco_frames += le16_to_cpu(s->xmt_tco_frames); nic->rx_tco_frames += @@ -1542,7 +1542,7 @@ static void e100_update_stats(struct nic *nic) } - if(e100_exec_cmd(nic, cuc_dump_reset, 0)) + if (e100_exec_cmd(nic, cuc_dump_reset, 0)) DPRINTK(TX_ERR, DEBUG, "exec cuc_dump_reset failed\n"); } @@ -1551,19 +1551,19 @@ static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex) /* Adjust inter-frame-spacing (IFS) between two transmits if * we're getting collisions on a half-duplex connection. */ - if(duplex == DUPLEX_HALF) { + if (duplex == DUPLEX_HALF) { u32 prev = nic->adaptive_ifs; u32 min_frames = (speed == SPEED_100) ? 1000 : 100; - if((nic->tx_frames / 32 < nic->tx_collisions) && + if ((nic->tx_frames / 32 < nic->tx_collisions) && (nic->tx_frames > min_frames)) { - if(nic->adaptive_ifs < 60) + if (nic->adaptive_ifs < 60) nic->adaptive_ifs += 5; } else if (nic->tx_frames < min_frames) { - if(nic->adaptive_ifs >= 5) + if (nic->adaptive_ifs >= 5) nic->adaptive_ifs -= 5; } - if(nic->adaptive_ifs != prev) + if (nic->adaptive_ifs != prev) e100_exec_cb(nic, NULL, e100_configure); } } @@ -1579,12 +1579,12 @@ static void e100_watchdog(unsigned long data) mii_ethtool_gset(&nic->mii, &cmd); - if(mii_link_ok(&nic->mii) && !netif_carrier_ok(nic->netdev)) { + if (mii_link_ok(&nic->mii) && !netif_carrier_ok(nic->netdev)) { printk(KERN_INFO "e100: %s NIC Link is Up %s Mbps %s Duplex\n", nic->netdev->name, cmd.speed == SPEED_100 ? "100" : "10", cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); - } else if(!mii_link_ok(&nic->mii) && netif_carrier_ok(nic->netdev)) { + } else if (!mii_link_ok(&nic->mii) && netif_carrier_ok(nic->netdev)) { printk(KERN_INFO "e100: %s NIC Link is Down\n", nic->netdev->name); } @@ -1604,11 +1604,11 @@ static void e100_watchdog(unsigned long data) e100_update_stats(nic); e100_adjust_adaptive_ifs(nic, cmd.speed, cmd.duplex); - if(nic->mac <= mac_82557_D100_C) + if (nic->mac <= mac_82557_D100_C) /* Issue a multicast command to workaround a 557 lock up */ e100_set_multicast_list(nic->netdev); - if(nic->flags & ich && cmd.speed==SPEED_10 && cmd.duplex==DUPLEX_HALF) + if (nic->flags & ich && cmd.speed==SPEED_10 && cmd.duplex==DUPLEX_HALF) /* Need SW workaround for ICH[x] 10Mbps/half duplex Tx hang. */ nic->flags |= ich_10h_workaround; else @@ -1623,7 +1623,7 @@ static void e100_xmit_prepare(struct nic *nic, struct cb *cb, { cb->command = nic->tx_command; /* interrupt every 16 packets regardless of delay */ - if((nic->cbs_avail & ~15) == nic->cbs_avail) + if ((nic->cbs_avail & ~15) == nic->cbs_avail) cb->command |= cpu_to_le16(cb_i); cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd); cb->u.tcb.tcb_byte_count = 0; @@ -1640,18 +1640,18 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct nic *nic = netdev_priv(netdev); int err; - if(nic->flags & ich_10h_workaround) { + if (nic->flags & ich_10h_workaround) { /* SW workaround for ICH[x] 10Mbps/half duplex Tx hang. Issue a NOP command followed by a 1us delay before issuing the Tx command. */ - if(e100_exec_cmd(nic, cuc_nop, 0)) + if (e100_exec_cmd(nic, cuc_nop, 0)) DPRINTK(TX_ERR, DEBUG, "exec cuc_nop failed\n"); udelay(1); } err = e100_exec_cb(nic, skb, e100_xmit_prepare); - switch(err) { + switch (err) { case -ENOSPC: /* We queued the skb, but now we're out of space. */ DPRINTK(TX_ERR, DEBUG, "No space for CB\n"); @@ -1677,14 +1677,14 @@ static int e100_tx_clean(struct nic *nic) spin_lock(&nic->cb_lock); /* Clean CBs marked complete */ - for(cb = nic->cb_to_clean; + for (cb = nic->cb_to_clean; cb->status & cpu_to_le16(cb_complete); cb = nic->cb_to_clean = cb->next) { DPRINTK(TX_DONE, DEBUG, "cb[%d]->status = 0x%04X\n", (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)), cb->status); - if(likely(cb->skb != NULL)) { + if (likely(cb->skb != NULL)) { dev->stats.tx_packets++; dev->stats.tx_bytes += cb->skb->len; @@ -1703,7 +1703,7 @@ static int e100_tx_clean(struct nic *nic) spin_unlock(&nic->cb_lock); /* Recover from running out of Tx resources in xmit_frame */ - if(unlikely(tx_cleaned && netif_queue_stopped(nic->netdev))) + if (unlikely(tx_cleaned && netif_queue_stopped(nic->netdev))) netif_wake_queue(nic->netdev); return tx_cleaned; @@ -1711,10 +1711,10 @@ static int e100_tx_clean(struct nic *nic) static void e100_clean_cbs(struct nic *nic) { - if(nic->cbs) { - while(nic->cbs_avail != nic->params.cbs.count) { + if (nic->cbs) { + while (nic->cbs_avail != nic->params.cbs.count) { struct cb *cb = nic->cb_to_clean; - if(cb->skb) { + if (cb->skb) { pci_unmap_single(nic->pdev, le32_to_cpu(cb->u.tcb.tbd.buf_addr), le16_to_cpu(cb->u.tcb.tbd.size), @@ -1746,10 +1746,10 @@ static int e100_alloc_cbs(struct nic *nic) nic->cbs = pci_alloc_consistent(nic->pdev, sizeof(struct cb) * count, &nic->cbs_dma_addr); - if(!nic->cbs) + if (!nic->cbs) return -ENOMEM; - for(cb = nic->cbs, i = 0; i < count; cb++, i++) { + for (cb = nic->cbs, i = 0; i < count; cb++, i++) { cb->next = (i + 1 < count) ? cb + 1 : nic->cbs; cb->prev = (i == 0) ? nic->cbs + count - 1 : cb - 1; @@ -1767,14 +1767,14 @@ static int e100_alloc_cbs(struct nic *nic) static inline void e100_start_receiver(struct nic *nic, struct rx *rx) { - if(!nic->rxs) return; - if(RU_SUSPENDED != nic->ru_running) return; + if (!nic->rxs) return; + if (RU_SUSPENDED != nic->ru_running) return; /* handle init time starts */ - if(!rx) rx = nic->rxs; + if (!rx) rx = nic->rxs; /* (Re)start RU if suspended or idle and RFA is non-NULL */ - if(rx->skb) { + if (rx->skb) { e100_exec_cmd(nic, ruc_start, rx->dma_addr); nic->ru_running = RU_RUNNING; } @@ -1783,7 +1783,7 @@ static inline void e100_start_receiver(struct nic *nic, struct rx *rx) #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) { - if(!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN))) + if (!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN))) return -ENOMEM; /* Align, init, and map the RFD. */ @@ -1820,7 +1820,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, struct rfd *rfd = (struct rfd *)skb->data; u16 rfd_status, actual_size; - if(unlikely(work_done && *work_done >= work_to_do)) + if (unlikely(work_done && *work_done >= work_to_do)) return -EAGAIN; /* Need to sync before taking a peek at cb_complete bit */ @@ -1847,7 +1847,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, /* Get actual data size */ actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF; - if(unlikely(actual_size > RFD_BUF_LEN - sizeof(struct rfd))) + if (unlikely(actual_size > RFD_BUF_LEN - sizeof(struct rfd))) actual_size = RFD_BUF_LEN - sizeof(struct rfd); /* Get data */ @@ -1872,10 +1872,10 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, skb_put(skb, actual_size); skb->protocol = eth_type_trans(skb, nic->netdev); - if(unlikely(!(rfd_status & cb_ok))) { + if (unlikely(!(rfd_status & cb_ok))) { /* Don't indicate if hardware indicates errors */ dev_kfree_skb_any(skb); - } else if(actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) { + } else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) { /* Don't indicate oversized frames */ nic->rx_over_length_errors++; dev_kfree_skb_any(skb); @@ -1883,7 +1883,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, dev->stats.rx_packets++; dev->stats.rx_bytes += actual_size; netif_receive_skb(skb); - if(work_done) + if (work_done) (*work_done)++; } @@ -1901,7 +1901,7 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, struct rfd *old_before_last_rfd, *new_before_last_rfd; /* Indicate newly arrived packets */ - for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) { + for (rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) { err = e100_rx_indicate(nic, rx, work_done, work_to_do); /* Hit quota or no more to clean */ if (-EAGAIN == err || -ENODATA == err) @@ -1922,8 +1922,8 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, old_before_last_rfd = (struct rfd *)old_before_last_rx->skb->data; /* Alloc new skbs to refill list */ - for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { - if(unlikely(e100_rx_alloc_skb(nic, rx))) + for (rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { + if (unlikely(e100_rx_alloc_skb(nic, rx))) break; /* Better luck next time (see watchdog) */ } @@ -1959,11 +1959,11 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, PCI_DMA_BIDIRECTIONAL); } - if(restart_required) { + if (restart_required) { // ack the rnr? iowrite8(stat_ack_rnr, &nic->csr->scb.stat_ack); e100_start_receiver(nic, nic->rx_to_clean); - if(work_done) + if (work_done) (*work_done)++; } } @@ -1975,9 +1975,9 @@ static void e100_rx_clean_list(struct nic *nic) nic->ru_running = RU_UNINITIALIZED; - if(nic->rxs) { - for(rx = nic->rxs, i = 0; i < count; rx++, i++) { - if(rx->skb) { + if (nic->rxs) { + for (rx = nic->rxs, i = 0; i < count; rx++, i++) { + if (rx->skb) { pci_unmap_single(nic->pdev, rx->dma_addr, RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); dev_kfree_skb(rx->skb); @@ -1999,13 +1999,13 @@ static int e100_rx_alloc_list(struct nic *nic) nic->rx_to_use = nic->rx_to_clean = NULL; nic->ru_running = RU_UNINITIALIZED; - if(!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC))) + if (!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC))) return -ENOMEM; - for(rx = nic->rxs, i = 0; i < count; rx++, i++) { + for (rx = nic->rxs, i = 0; i < count; rx++, i++) { rx->next = (i + 1 < count) ? rx + 1 : nic->rxs; rx->prev = (i == 0) ? nic->rxs + count - 1 : rx - 1; - if(e100_rx_alloc_skb(nic, rx)) { + if (e100_rx_alloc_skb(nic, rx)) { e100_rx_clean_list(nic); return -ENOMEM; } @@ -2038,7 +2038,7 @@ static irqreturn_t e100_intr(int irq, void *dev_id) DPRINTK(INTR, DEBUG, "stat_ack = 0x%02X\n", stat_ack); - if(stat_ack == stat_ack_not_ours || /* Not our interrupt */ + if (stat_ack == stat_ack_not_ours || /* Not our interrupt */ stat_ack == stat_ack_not_present) /* Hardware is ejected */ return IRQ_NONE; @@ -2046,10 +2046,10 @@ static irqreturn_t e100_intr(int irq, void *dev_id) iowrite8(stat_ack, &nic->csr->scb.stat_ack); /* We hit Receive No Resource (RNR); restart RU after cleaning */ - if(stat_ack & stat_ack_rnr) + if (stat_ack & stat_ack_rnr) nic->ru_running = RU_SUSPENDED; - if(likely(netif_rx_schedule_prep(&nic->napi))) { + if (likely(netif_rx_schedule_prep(&nic->napi))) { e100_disable_irq(nic); __netif_rx_schedule(&nic->napi); } @@ -2102,7 +2102,7 @@ static int e100_set_mac_address(struct net_device *netdev, void *p) static int e100_change_mtu(struct net_device *netdev, int new_mtu) { - if(new_mtu < ETH_ZLEN || new_mtu > ETH_DATA_LEN) + if (new_mtu < ETH_ZLEN || new_mtu > ETH_DATA_LEN) return -EINVAL; netdev->mtu = new_mtu; return 0; @@ -2121,16 +2121,16 @@ static int e100_up(struct nic *nic) { int err; - if((err = e100_rx_alloc_list(nic))) + if ((err = e100_rx_alloc_list(nic))) return err; - if((err = e100_alloc_cbs(nic))) + if ((err = e100_alloc_cbs(nic))) goto err_rx_clean_list; - if((err = e100_hw_init(nic))) + if ((err = e100_hw_init(nic))) goto err_clean_cbs; e100_set_multicast_list(nic->netdev); e100_start_receiver(nic, NULL); mod_timer(&nic->watchdog, jiffies); - if((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, + if ((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, nic->netdev->name, nic->netdev))) goto err_no_irq; netif_wake_queue(nic->netdev); @@ -2192,26 +2192,26 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) * in loopback mode, and the test passes if the received * packet compares byte-for-byte to the transmitted packet. */ - if((err = e100_rx_alloc_list(nic))) + if ((err = e100_rx_alloc_list(nic))) return err; - if((err = e100_alloc_cbs(nic))) + if ((err = e100_alloc_cbs(nic))) goto err_clean_rx; /* ICH PHY loopback is broken so do MAC loopback instead */ - if(nic->flags & ich && loopback_mode == lb_phy) + if (nic->flags & ich && loopback_mode == lb_phy) loopback_mode = lb_mac; nic->loopback = loopback_mode; - if((err = e100_hw_init(nic))) + if ((err = e100_hw_init(nic))) goto err_loopback_none; - if(loopback_mode == lb_phy) + if (loopback_mode == lb_phy) mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, BMCR_LOOPBACK); e100_start_receiver(nic, NULL); - if(!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) { + if (!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) { err = -ENOMEM; goto err_loopback_none; } @@ -2224,7 +2224,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) pci_dma_sync_single_for_cpu(nic->pdev, nic->rx_to_clean->dma_addr, RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); - if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd), + if (memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd), skb->data, ETH_DATA_LEN)) err = -EAGAIN; @@ -2301,7 +2301,7 @@ static void e100_get_regs(struct net_device *netdev, buff[0] = ioread8(&nic->csr->scb.cmd_hi) << 24 | ioread8(&nic->csr->scb.cmd_lo) << 16 | ioread16(&nic->csr->scb.status); - for(i = E100_PHY_REGS; i >= 0; i--) + for (i = E100_PHY_REGS; i >= 0; i--) buff[1 + E100_PHY_REGS - i] = mdio_read(netdev, nic->mii.phy_id, i); memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf)); @@ -2326,7 +2326,7 @@ static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) !device_can_wakeup(&nic->pdev->dev)) return -EOPNOTSUPP; - if(wol->wolopts) + if (wol->wolopts) nic->flags |= wol_magic; else nic->flags &= ~wol_magic; @@ -2385,7 +2385,7 @@ static int e100_set_eeprom(struct net_device *netdev, { struct nic *nic = netdev_priv(netdev); - if(eeprom->magic != E100_EEPROM_MAGIC) + if (eeprom->magic != E100_EEPROM_MAGIC) return -EINVAL; memcpy(&((u8 *)nic->eeprom)[eeprom->offset], bytes, eeprom->len); @@ -2421,7 +2421,7 @@ static int e100_set_ringparam(struct net_device *netdev, if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; - if(netif_running(netdev)) + if (netif_running(netdev)) e100_down(nic); rfds->count = max(ring->rx_pending, rfds->min); rfds->count = min(rfds->count, rfds->max); @@ -2429,7 +2429,7 @@ static int e100_set_ringparam(struct net_device *netdev, cbs->count = min(cbs->count, cbs->max); DPRINTK(DRV, INFO, "Ring Param settings: rx: %d, tx %d\n", rfds->count, cbs->count); - if(netif_running(netdev)) + if (netif_running(netdev)) e100_up(nic); return 0; @@ -2454,12 +2454,12 @@ static void e100_diag_test(struct net_device *netdev, memset(data, 0, E100_TEST_LEN * sizeof(u64)); data[0] = !mii_link_ok(&nic->mii); data[1] = e100_eeprom_load(nic); - if(test->flags & ETH_TEST_FL_OFFLINE) { + if (test->flags & ETH_TEST_FL_OFFLINE) { /* save speed, duplex & autoneg settings */ err = mii_ethtool_gset(&nic->mii, &cmd); - if(netif_running(netdev)) + if (netif_running(netdev)) e100_down(nic); data[2] = e100_self_test(nic); data[3] = e100_loopback_test(nic, lb_mac); @@ -2468,10 +2468,10 @@ static void e100_diag_test(struct net_device *netdev, /* restore speed, duplex & autoneg settings */ err = mii_ethtool_sset(&nic->mii, &cmd); - if(netif_running(netdev)) + if (netif_running(netdev)) e100_up(nic); } - for(i = 0; i < E100_TEST_LEN; i++) + for (i = 0; i < E100_TEST_LEN; i++) test->flags |= data[i] ? ETH_TEST_FL_FAILED : 0; msleep_interruptible(4 * 1000); @@ -2481,7 +2481,7 @@ static int e100_phys_id(struct net_device *netdev, u32 data) { struct nic *nic = netdev_priv(netdev); - if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) + if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); mod_timer(&nic->blink_timer, jiffies); msleep_interruptible(data * 1000); @@ -2524,7 +2524,7 @@ static void e100_get_ethtool_stats(struct net_device *netdev, struct nic *nic = netdev_priv(netdev); int i; - for(i = 0; i < E100_NET_STATS_LEN; i++) + for (i = 0; i < E100_NET_STATS_LEN; i++) data[i] = ((unsigned long *)&netdev->stats)[i]; data[i++] = nic->tx_deferred; @@ -2539,7 +2539,7 @@ static void e100_get_ethtool_stats(struct net_device *netdev, static void e100_get_strings(struct net_device *netdev, u32 stringset, u8 *data) { - switch(stringset) { + switch (stringset) { case ETH_SS_TEST: memcpy(data, *e100_gstrings_test, sizeof(e100_gstrings_test)); break; @@ -2589,7 +2589,7 @@ static int e100_alloc(struct nic *nic) static void e100_free(struct nic *nic) { - if(nic->mem) { + if (nic->mem) { pci_free_consistent(nic->pdev, sizeof(struct mem), nic->mem, nic->dma_addr); nic->mem = NULL; @@ -2602,7 +2602,7 @@ static int e100_open(struct net_device *netdev) int err = 0; netif_carrier_off(netdev); - if((err = e100_up(nic))) + if ((err = e100_up(nic))) DPRINTK(IFUP, ERR, "Cannot open interface, aborting.\n"); return err; } @@ -2635,8 +2635,8 @@ static int __devinit e100_probe(struct pci_dev *pdev, struct nic *nic; int err; - if(!(netdev = alloc_etherdev(sizeof(struct nic)))) { - if(((1 << debug) - 1) & NETIF_MSG_PROBE) + if (!(netdev = alloc_etherdev(sizeof(struct nic)))) { + if (((1 << debug) - 1) & NETIF_MSG_PROBE) printk(KERN_ERR PFX "Etherdev alloc failed, abort.\n"); return -ENOMEM; } @@ -2653,24 +2653,24 @@ static int __devinit e100_probe(struct pci_dev *pdev, nic->msg_enable = (1 << debug) - 1; pci_set_drvdata(pdev, netdev); - if((err = pci_enable_device(pdev))) { + if ((err = pci_enable_device(pdev))) { DPRINTK(PROBE, ERR, "Cannot enable PCI device, aborting.\n"); goto err_out_free_dev; } - if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { DPRINTK(PROBE, ERR, "Cannot find proper PCI device " "base address, aborting.\n"); err = -ENODEV; goto err_out_disable_pdev; } - if((err = pci_request_regions(pdev, DRV_NAME))) { + if ((err = pci_request_regions(pdev, DRV_NAME))) { DPRINTK(PROBE, ERR, "Cannot obtain PCI resources, aborting.\n"); goto err_out_disable_pdev; } - if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { + if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n"); goto err_out_free_res; } @@ -2681,13 +2681,13 @@ static int __devinit e100_probe(struct pci_dev *pdev, DPRINTK(PROBE, INFO, "using i/o access mode\n"); nic->csr = pci_iomap(pdev, (use_io ? 1 : 0), sizeof(struct csr)); - if(!nic->csr) { + if (!nic->csr) { DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n"); err = -ENOMEM; goto err_out_free_res; } - if(ent->driver_data) + if (ent->driver_data) nic->flags |= ich; else nic->flags &= ~ich; @@ -2715,12 +2715,12 @@ static int __devinit e100_probe(struct pci_dev *pdev, INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task); - if((err = e100_alloc(nic))) { + if ((err = e100_alloc(nic))) { DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n"); goto err_out_iounmap; } - if((err = e100_eeprom_load(nic))) + if ((err = e100_eeprom_load(nic))) goto err_out_free; e100_phy_init(nic); @@ -2740,7 +2740,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, } /* Wol magic packet can be enabled from eeprom */ - if((nic->mac >= mac_82558_D101_A4) && + if ((nic->mac >= mac_82558_D101_A4) && (nic->eeprom[eeprom_id] & eeprom_id_wol)) { nic->flags |= wol_magic; device_set_wakeup_enable(&pdev->dev, true); @@ -2750,7 +2750,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, pci_pme_active(pdev, false); strcpy(netdev->name, "eth%d"); - if((err = register_netdev(netdev))) { + if ((err = register_netdev(netdev))) { DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); goto err_out_free; } @@ -2779,7 +2779,7 @@ static void __devexit e100_remove(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); - if(netdev) { + if (netdev) { struct nic *nic = netdev_priv(netdev); unregister_netdev(netdev); e100_free(nic); @@ -2932,7 +2932,7 @@ static struct pci_driver e100_driver = { static int __init e100_init_module(void) { - if(((1 << debug) - 1) & NETIF_MSG_DRV) { + if (((1 << debug) - 1) & NETIF_MSG_DRV) { printk(KERN_INFO PFX "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); printk(KERN_INFO PFX "%s\n", DRV_COPYRIGHT); } -- cgit From 745417e20684e4951afcabfe74583a3884e54980 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 4 Jan 2009 17:14:46 -0800 Subject: tun: Eliminate sparse signedness warning register_pernet_gen_device() expects 'int*', found via sparse. CHECK drivers/net/tun.c drivers/net/tun.c:1245:36: warning: incorrect type in argument 1 (different signedness) drivers/net/tun.c:1245:36: expected int *id drivers/net/tun.c:1245:36: got unsigned int static [toplevel] * Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 69f9a0ec764..d7b81e4fdd5 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -213,7 +213,7 @@ static int check_filter(struct tap_filter *filter, const struct sk_buff *skb) /* Network device part of the driver */ -static unsigned int tun_net_id; +static int tun_net_id; struct tun_net { struct list_head dev_list; }; -- cgit From 48e4cc777c091b037acaf39036a77ece43fe1ab9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 5 Jan 2009 16:06:02 -0800 Subject: net/ehea: bitops work on unsigned longs The flags field of struct ehea_port is only used with test_bit(), clear_bit() and set_bit() and these interfaces only work on "unsigned long"s, so change the field to be an "unsigned long". Also, this field only has two bits defined for it (0 and 1) so will still be fine if someone builds this driver for a 32 bit arch (at least as far as this flags field is concerned). Also note that ehea_driver_flags is only used in ehca_main.c, so make it static in there. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/ehea/ehea.h | 3 +-- drivers/net/ehea/ehea_main.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 9930d5f8b9e..6271b9411cc 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -478,7 +478,7 @@ struct ehea_port { int num_add_tx_qps; int num_mcs; int resets; - u64 flags; + unsigned long flags; u64 mac_addr; u32 logical_port_id; u32 port_speed; @@ -510,7 +510,6 @@ void ehea_set_ethtool_ops(struct net_device *netdev); int ehea_sense_port_attr(struct ehea_port *port); int ehea_set_portspeed(struct ehea_port *port, u32 port_speed); -extern u64 ehea_driver_flags; extern struct work_struct ehea_rereg_mr_task; #endif /* __EHEA_H__ */ diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index a2f1905a23d..e3131ea629c 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -99,7 +99,7 @@ MODULE_PARM_DESC(use_lro, " Large Receive Offload, 1: enable, 0: disable, " static int port_name_cnt; static LIST_HEAD(adapter_list); -u64 ehea_driver_flags; +static unsigned long ehea_driver_flags; struct work_struct ehea_rereg_mr_task; static DEFINE_MUTEX(dlpar_mem_lock); struct ehea_fw_handle_array ehea_fw_handles; -- cgit From 0f840011f0396dcb97ca82c64fd43f6990a574dd Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 5 Jan 2009 18:16:14 -0800 Subject: myri10ge: print MAC and serial number on probe failure To help board identification and diagnosis, print the MAC and serial number on probe failure if they are available. Signed-off-by: Brice Goglin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 5e70180bf56..6bb71b687f7 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -75,7 +75,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.4.4-1.395" +#define MYRI10GE_VERSION_STR "1.4.4-1.398" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -3929,6 +3929,10 @@ abort_with_firmware: myri10ge_dummy_rdma(mgp, 0); abort_with_ioremap: + if (mgp->mac_addr_string != NULL) + dev_err(&pdev->dev, + "myri10ge_probe() failed: MAC=%s, SN=%ld\n", + mgp->mac_addr_string, mgp->serial_number); iounmap(mgp->sram); abort_with_mtrr: -- cgit From 8306c952a523ad2f87c101427c3ece91176b822c Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 5 Jan 2009 18:17:33 -0800 Subject: qlge: Fix sparse warnings for byte swapping in qlge_ethool.c drivers/net/qlge/qlge_ethtool.c:59:23: warning: cast to restricted type drivers/net/qlge/qlge_ethtool.c:59:21: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_ethtool.c:59:21: expected restricted unsigned short [usertype] irq_delay drivers/net/qlge/qlge_ethtool.c:59:21: got unsigned short [unsigned] [usertype] drivers/net/qlge/qlge_ethtool.c:61:8: warning: cast to restricted type drivers/net/qlge/qlge_ethtool.c:60:21: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_ethtool.c:60:21: expected restricted unsigned short [usertype] pkt_delay drivers/net/qlge/qlge_ethtool.c:60:21: got unsigned short [unsigned] [usertype] drivers/net/qlge/qlge_ethtool.c:82:23: warning: cast to restricted type drivers/net/qlge/qlge_ethtool.c:82:21: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_ethtool.c:82:21: expected restricted unsigned short [usertype] irq_delay drivers/net/qlge/qlge_ethtool.c:82:21: got unsigned short [unsigned] [usertype] drivers/net/qlge/qlge_ethtool.c:84:8: warning: cast to restricted type drivers/net/qlge/qlge_ethtool.c:83:21: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_ethtool.c:83:21: expected restricted unsigned short [usertype] pkt_delay drivers/net/qlge/qlge_ethtool.c:83:21: got unsigned short [unsigned] [usertype] Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_ethtool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index eefb81b1375..9d922e2ff22 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c @@ -56,9 +56,9 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev) for (i = 1; i < qdev->rss_ring_first_cq_id; i++, rx_ring++) { rx_ring = &qdev->rx_ring[i]; cqicb = (struct cqicb *)rx_ring; - cqicb->irq_delay = le16_to_cpu(qdev->tx_coalesce_usecs); + cqicb->irq_delay = cpu_to_le16(qdev->tx_coalesce_usecs); cqicb->pkt_delay = - le16_to_cpu(qdev->tx_max_coalesced_frames); + cpu_to_le16(qdev->tx_max_coalesced_frames); cqicb->flags = FLAGS_LI; status = ql_write_cfg(qdev, cqicb, sizeof(cqicb), CFG_LCQ, rx_ring->cq_id); @@ -79,9 +79,9 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev) i++) { rx_ring = &qdev->rx_ring[i]; cqicb = (struct cqicb *)rx_ring; - cqicb->irq_delay = le16_to_cpu(qdev->rx_coalesce_usecs); + cqicb->irq_delay = cpu_to_le16(qdev->rx_coalesce_usecs); cqicb->pkt_delay = - le16_to_cpu(qdev->rx_max_coalesced_frames); + cpu_to_le16(qdev->rx_max_coalesced_frames); cqicb->flags = FLAGS_LI; status = ql_write_cfg(qdev, cqicb, sizeof(cqicb), CFG_LCQ, rx_ring->cq_id); -- cgit From a303ce0972d04036316e85568682a2b89fe123d9 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 5 Jan 2009 18:18:22 -0800 Subject: qlge: Fix sparse endian warning for inbound packet control block flags. Changed flags element from __le32 to 3 reserved bytes and one byte of flags. Changed flags bit definitions to reflect byte width instead of __le32 width. Warnings: drivers/net/qlge/qlge_main.c:1206:16: warning: restricted degrades to integer drivers/net/qlge/qlge_main.c:1207:16: warning: restricted degrades to integer drivers/net/qlge/qlge_main.c:1233:17: warning: restricted degrades to integer drivers/net/qlge/qlge_main.c:1276:17: warning: restricted degrades to integer drivers/net/qlge/qlge_main.c:1349:19: warning: restricted degrades to integer Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 9 +++++---- drivers/net/qlge/qlge_dbg.c | 13 +++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 97321bb9600..71cc48799b5 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -979,10 +979,11 @@ struct ib_mac_iocb_rsp { __le16 reserved1; __le32 reserved2[6]; - __le32 flags4; -#define IB_MAC_IOCB_RSP_HV 0x20000000 /* */ -#define IB_MAC_IOCB_RSP_HS 0x40000000 /* */ -#define IB_MAC_IOCB_RSP_HL 0x80000000 /* */ + u8 reserved3[3]; + u8 flags4; +#define IB_MAC_IOCB_RSP_HV 0x20 +#define IB_MAC_IOCB_RSP_HS 0x40 +#define IB_MAC_IOCB_RSP_HL 0x80 __le32 hdr_len; /* */ __le32 hdr_addr_lo; /* */ __le32 hdr_addr_hi; /* */ diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c index 47df304a02c..3f5e02d2e4a 100644 --- a/drivers/net/qlge/qlge_dbg.c +++ b/drivers/net/qlge/qlge_dbg.c @@ -821,14 +821,11 @@ void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp) le16_to_cpu(ib_mac_rsp->vlan_id)); printk(KERN_ERR PFX "flags4 = %s%s%s.\n", - le32_to_cpu(ib_mac_rsp-> - flags4) & IB_MAC_IOCB_RSP_HV ? "HV " : "", - le32_to_cpu(ib_mac_rsp-> - flags4) & IB_MAC_IOCB_RSP_HS ? "HS " : "", - le32_to_cpu(ib_mac_rsp-> - flags4) & IB_MAC_IOCB_RSP_HL ? "HL " : ""); - - if (le32_to_cpu(ib_mac_rsp->flags4) & IB_MAC_IOCB_RSP_HV) { + ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV ? "HV " : "", + ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS ? "HS " : "", + ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HL ? "HL " : ""); + + if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) { printk(KERN_ERR PFX "hdr length = %d.\n", le32_to_cpu(ib_mac_rsp->hdr_len)); printk(KERN_ERR PFX "hdr addr_hi = 0x%x.\n", -- cgit From fd2df4f7439cd3e87090e067d5aec8f1336f4f0e Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 5 Jan 2009 18:18:45 -0800 Subject: qlge: Fix sparse endian warning in ql_hw_csum_setup(). Changed u16 to __sum16 usage. Warnings: drivers/net/qlge/qlge_main.c:1897:9: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:1897:9: expected unsigned short [usertype] *check drivers/net/qlge/qlge_main.c:1897:9: got restricted unsigned short * drivers/net/qlge/qlge_main.c:1903:9: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:1903:9: expected unsigned short [usertype] *check drivers/net/qlge/qlge_main.c:1903:9: got restricted unsigned short * drivers/net/qlge/qlge_main.c:1909:9: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:1909:9: expected unsigned short [unsigned] [short] [usertype] Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 837be72efb0..d7894aa2ebe 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1884,7 +1884,7 @@ static void ql_hw_csum_setup(struct sk_buff *skb, { int len; struct iphdr *iph = ip_hdr(skb); - u16 *check; + __sum16 *check; mac_iocb_ptr->opcode = OPCODE_OB_MAC_TSO_IOCB; mac_iocb_ptr->frame_len = cpu_to_le32((u32) skb->len); mac_iocb_ptr->net_trans_offset = -- cgit From 2c9a0d41e944807bf763f42e4a3526210e98c741 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 5 Jan 2009 18:19:20 -0800 Subject: qlge: Fix sparse warning regarding rx buffer queues. Warnings: drivers/net/qlge/qlge_main.c:909:17: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:909:17: expected unsigned int [unsigned] [usertype] addr_lo drivers/net/qlge/qlge_main.c:909:17: got restricted unsigned int [usertype] drivers/net/qlge/qlge_main.c:911:17: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:911:17: expected unsigned int [unsigned] [usertype] addr_hi drivers/net/qlge/qlge_main.c:911:17: got restricted unsigned int [usertype] drivers/net/qlge/qlge_main.c:974:17: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:974:17: expected unsigned int [unsigned] [usertype] addr_lo drivers/net/qlge/qlge_main.c:974:17: got restricted unsigned int [usertype] drivers/net/qlge/qlge_main.c:975:17: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:975:17: expected unsigned int [unsigned] [usertype] addr_hi drivers/net/qlge/qlge_main.c:975:17: got restricted unsigned int [usertype] drivers/net/qlge/qlge_main.c:2132:16: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:2132:16: expected unsigned int [unsigned] [usertype] addr_lo drivers/net/qlge/qlge_main.c:2132:16: got restricted unsigned int [usertype] drivers/net/qlge/qlge_main.c:2133:16: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:2133:16: expected unsigned int [unsigned] [usertype] addr_hi drivers/net/qlge/qlge_main.c:2133:16: got restricted unsigned int [usertype] drivers/net/qlge/qlge_main.c:2212:15: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:2212:15: expected unsigned int [unsigned] [usertype] addr_lo drivers/net/qlge/qlge_main.c:2212:15: got restricted unsigned int [usertype] drivers/net/qlge/qlge_main.c:2214:15: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:2214:15: expected unsigned int [unsigned] [usertype] addr_hi drivers/net/qlge/qlge_main.c:2214:15: got restricted unsigned int [usertype] Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 11 +-------- drivers/net/qlge/qlge_main.c | 55 +++++++++++--------------------------------- 2 files changed, 15 insertions(+), 51 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 71cc48799b5..76ef2bc297c 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -818,15 +818,6 @@ struct tx_doorbell_context { }; /* DATA STRUCTURES SHARED WITH HARDWARE. */ - -struct bq_element { - u32 addr_lo; -#define BQ_END 0x00000001 -#define BQ_CONT 0x00000002 -#define BQ_MASK 0x00000003 - u32 addr_hi; -} __attribute((packed)); - struct tx_buf_desc { __le64 addr; __le32 len; @@ -1139,7 +1130,7 @@ struct bq_desc { struct page *lbq_page; struct sk_buff *skb; } p; - struct bq_element *bq; + __le64 *addr; int index; DECLARE_PCI_UNMAP_ADDR(mapaddr); DECLARE_PCI_UNMAP_LEN(maplen); diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index d7894aa2ebe..f4c016012f1 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -874,7 +874,6 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) { int clean_idx = rx_ring->lbq_clean_idx; struct bq_desc *lbq_desc; - struct bq_element *bq; u64 map; int i; @@ -884,7 +883,6 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) "lbq: try cleaning clean_idx = %d.\n", clean_idx); lbq_desc = &rx_ring->lbq[clean_idx]; - bq = lbq_desc->bq; if (lbq_desc->p.lbq_page == NULL) { QPRINTK(qdev, RX_STATUS, DEBUG, "lbq: getting new page for index %d.\n", @@ -906,10 +904,7 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) } pci_unmap_addr_set(lbq_desc, mapaddr, map); pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE); - bq->addr_lo = /*lbq_desc->addr_lo = */ - cpu_to_le32(map); - bq->addr_hi = /*lbq_desc->addr_hi = */ - cpu_to_le32(map >> 32); + *lbq_desc->addr = cpu_to_le64(map); } clean_idx++; if (clean_idx == rx_ring->lbq_len) @@ -934,7 +929,6 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) { int clean_idx = rx_ring->sbq_clean_idx; struct bq_desc *sbq_desc; - struct bq_element *bq; u64 map; int i; @@ -944,7 +938,6 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) QPRINTK(qdev, RX_STATUS, DEBUG, "sbq: try cleaning clean_idx = %d.\n", clean_idx); - bq = sbq_desc->bq; if (sbq_desc->p.skb == NULL) { QPRINTK(qdev, RX_STATUS, DEBUG, "sbq: getting new skb for index %d.\n", @@ -971,8 +964,7 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) pci_unmap_addr_set(sbq_desc, mapaddr, map); pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2); - bq->addr_lo = cpu_to_le32(map); - bq->addr_hi = cpu_to_le32(map >> 32); + *sbq_desc->addr = cpu_to_le64(map); } clean_idx++; @@ -1340,7 +1332,7 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, * eventually be in trouble. */ int size, offset, i = 0; - struct bq_element *bq, bq_array[8]; + __le64 *bq, bq_array[8]; sbq_desc = ql_get_curr_sbuf(rx_ring); pci_unmap_single(qdev->pdev, pci_unmap_addr(sbq_desc, mapaddr), @@ -1366,16 +1358,10 @@ static struct sk_buff *ql_build_rx_skb(struct ql_adapter *qdev, } else { QPRINTK(qdev, RX_STATUS, DEBUG, "Headers in small, %d bytes of data in chain of large.\n", length); - bq = (struct bq_element *)sbq_desc->p.skb->data; + bq = (__le64 *)sbq_desc->p.skb->data; } while (length > 0) { lbq_desc = ql_get_curr_lbuf(rx_ring); - if ((bq->addr_lo & ~BQ_MASK) != lbq_desc->bq->addr_lo) { - QPRINTK(qdev, RX_STATUS, ERR, - "Panic!!! bad large buffer address, expected 0x%.08x, got 0x%.08x.\n", - lbq_desc->bq->addr_lo, bq->addr_lo); - return NULL; - } pci_unmap_page(qdev->pdev, pci_unmap_addr(lbq_desc, mapaddr), @@ -2093,8 +2079,6 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring put_page(lbq_desc->p.lbq_page); lbq_desc->p.lbq_page = NULL; } - lbq_desc->bq->addr_lo = 0; - lbq_desc->bq->addr_hi = 0; } } @@ -2107,12 +2091,12 @@ static int ql_alloc_lbq_buffers(struct ql_adapter *qdev, int i; struct bq_desc *lbq_desc; u64 map; - struct bq_element *bq = rx_ring->lbq_base; + __le64 *bq = rx_ring->lbq_base; for (i = 0; i < rx_ring->lbq_len; i++) { lbq_desc = &rx_ring->lbq[i]; memset(lbq_desc, 0, sizeof(lbq_desc)); - lbq_desc->bq = bq; + lbq_desc->addr = bq; lbq_desc->index = i; lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC); if (unlikely(!lbq_desc->p.lbq_page)) { @@ -2129,8 +2113,7 @@ static int ql_alloc_lbq_buffers(struct ql_adapter *qdev, } pci_unmap_addr_set(lbq_desc, mapaddr, map); pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE); - bq->addr_lo = cpu_to_le32(map); - bq->addr_hi = cpu_to_le32(map >> 32); + *lbq_desc->addr = cpu_to_le64(map); } bq++; } @@ -2159,13 +2142,6 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring dev_kfree_skb(sbq_desc->p.skb); sbq_desc->p.skb = NULL; } - if (sbq_desc->bq == NULL) { - QPRINTK(qdev, IFUP, ERR, "sbq_desc->bq %d is NULL.\n", - i); - return; - } - sbq_desc->bq->addr_lo = 0; - sbq_desc->bq->addr_hi = 0; } } @@ -2177,13 +2153,13 @@ static int ql_alloc_sbq_buffers(struct ql_adapter *qdev, struct bq_desc *sbq_desc; struct sk_buff *skb; u64 map; - struct bq_element *bq = rx_ring->sbq_base; + __le64 *bq = rx_ring->sbq_base; for (i = 0; i < rx_ring->sbq_len; i++) { sbq_desc = &rx_ring->sbq[i]; memset(sbq_desc, 0, sizeof(sbq_desc)); sbq_desc->index = i; - sbq_desc->bq = bq; + sbq_desc->addr = bq; skb = netdev_alloc_skb(qdev->ndev, rx_ring->sbq_buf_size); if (unlikely(!skb)) { /* Better luck next round */ @@ -2209,10 +2185,7 @@ static int ql_alloc_sbq_buffers(struct ql_adapter *qdev, } pci_unmap_addr_set(sbq_desc, mapaddr, map); pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2); - bq->addr_lo = /*sbq_desc->addr_lo = */ - cpu_to_le32(map); - bq->addr_hi = /*sbq_desc->addr_hi = */ - cpu_to_le32(map >> 32); + *sbq_desc->addr = cpu_to_le64(map); bq++; } return 0; @@ -3356,11 +3329,11 @@ static int ql_configure_rings(struct ql_adapter *qdev) rx_ring->cq_len * sizeof(struct ql_net_rsp_iocb); rx_ring->lbq_len = NUM_LARGE_BUFFERS; rx_ring->lbq_size = - rx_ring->lbq_len * sizeof(struct bq_element); + rx_ring->lbq_len * sizeof(__le64); rx_ring->lbq_buf_size = LARGE_BUFFER_SIZE; rx_ring->sbq_len = NUM_SMALL_BUFFERS; rx_ring->sbq_size = - rx_ring->sbq_len * sizeof(struct bq_element); + rx_ring->sbq_len * sizeof(__le64); rx_ring->sbq_buf_size = SMALL_BUFFER_SIZE * 2; rx_ring->type = DEFAULT_Q; } else if (i < qdev->rss_ring_first_cq_id) { @@ -3387,11 +3360,11 @@ static int ql_configure_rings(struct ql_adapter *qdev) rx_ring->cq_len * sizeof(struct ql_net_rsp_iocb); rx_ring->lbq_len = NUM_LARGE_BUFFERS; rx_ring->lbq_size = - rx_ring->lbq_len * sizeof(struct bq_element); + rx_ring->lbq_len * sizeof(__le64); rx_ring->lbq_buf_size = LARGE_BUFFER_SIZE; rx_ring->sbq_len = NUM_SMALL_BUFFERS; rx_ring->sbq_size = - rx_ring->sbq_len * sizeof(struct bq_element); + rx_ring->sbq_len * sizeof(__le64); rx_ring->sbq_buf_size = SMALL_BUFFER_SIZE * 2; rx_ring->type = RX_Q; } -- cgit From 3537d54c0c39de5738bba8d19f128478b0b96a71 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 5 Jan 2009 18:19:59 -0800 Subject: qlge: Fix sparse warnings for tx ring indexes. Warnings: drivers/net/qlge/qlge_main.c:1474:34: warning: restricted degrades to integer drivers/net/qlge/qlge_main.c:1475:36: warning: restricted degrades to integer drivers/net/qlge/qlge_main.c:1592:51: warning: restricted degrades to integer drivers/net/qlge/qlge_main.c:1941:20: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:1941:20: expected restricted unsigned int [usertype] tid drivers/net/qlge/qlge_main.c:1941:20: got int [signed] index drivers/net/qlge/qlge_main.c:1945:24: warning: incorrect type in assignment (different base types) drivers/net/qlge/qlge_main.c:1945:24: expected restricted unsigned int [usertype] txq_idx drivers/net/qlge/qlge_main.c:1945:24: got unsigned int [unsigned] [usertype] tx_ring_idx Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 76ef2bc297c..459663a4023 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -851,8 +851,8 @@ struct ob_mac_iocb_req { __le16 frame_len; #define OB_MAC_IOCB_LEN_MASK 0x3ffff __le16 reserved2; - __le32 tid; - __le32 txq_idx; + u32 tid; + u32 txq_idx; __le32 reserved3; __le16 vlan_tci; __le16 reserved4; @@ -871,8 +871,8 @@ struct ob_mac_iocb_rsp { u8 flags2; /* */ u8 flags3; /* */ #define OB_MAC_IOCB_RSP_B 0x80 /* */ - __le32 tid; - __le32 txq_idx; + u32 tid; + u32 txq_idx; __le32 reserved[13]; } __attribute((packed)); @@ -894,8 +894,8 @@ struct ob_mac_tso_iocb_req { #define OB_MAC_TSO_IOCB_V 0x04 __le32 reserved1[2]; __le32 frame_len; - __le32 tid; - __le32 txq_idx; + u32 tid; + u32 txq_idx; __le16 total_hdrs_len; __le16 net_trans_offset; #define OB_MAC_TRANSPORT_HDR_SHIFT 6 @@ -916,8 +916,8 @@ struct ob_mac_tso_iocb_rsp { u8 flags2; /* */ u8 flags3; /* */ #define OB_MAC_TSO_IOCB_RSP_B 0x8000 - __le32 tid; - __le32 txq_idx; + u32 tid; + u32 txq_idx; __le32 reserved2[13]; } __attribute((packed)); @@ -1118,7 +1118,7 @@ struct map_list { struct tx_ring_desc { struct sk_buff *skb; struct ob_mac_iocb_req *queue_entry; - int index; + u32 index; struct oal oal; struct map_list map[MAX_SKB_FRAGS + 1]; int map_cnt; @@ -1131,7 +1131,7 @@ struct bq_desc { struct sk_buff *skb; } p; __le64 *addr; - int index; + u32 index; DECLARE_PCI_UNMAP_ADDR(mapaddr); DECLARE_PCI_UNMAP_LEN(maplen); }; -- cgit From e42e4ba07bc72c0eb7c7ab3bf9e5076db90d0f37 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 5 Jan 2009 18:47:12 -0800 Subject: igb: fix anoying type mismatch warning on rx/tx queue sizing When using "min()", the types of both sides should match. With the cpu mask changes, the type of num_online_cpus() will now depend on config options. Use "min_t()" with an explicit type instead. And make the rx/tx case look the same too, just for sanity. Signed-off-by: Linus Torvalds --- drivers/net/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 022794e579c..b82b0fb2056 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1457,8 +1457,8 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) /* Number of supported queues. */ /* Having more queues than CPUs doesn't make sense. */ - adapter->num_rx_queues = min((u32)IGB_MAX_RX_QUEUES, (u32)num_online_cpus()); - adapter->num_tx_queues = min(IGB_MAX_TX_QUEUES, num_online_cpus()); + adapter->num_rx_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus()); + adapter->num_tx_queues = min_t(u32, IGB_MAX_TX_QUEUES, num_online_cpus()); /* This call may decrease the number of queues depending on * interrupt mode. */ -- cgit From 46377bb311a7682f6240c954c48e81a1e4f51e66 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 5 Jan 2009 20:51:04 -0800 Subject: acenic: Missed delete of acenic_firmware.h When I applied the firmware conversion I made a mistake which caused the acenic_firmware.h deletion to not happen. Fix that up. Noticed by Linus. Signed-off-by: David S. Miller --- drivers/net/acenic_firmware.h | 9456 ----------------------------------------- 1 file changed, 9456 deletions(-) delete mode 100644 drivers/net/acenic_firmware.h (limited to 'drivers/net') diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h deleted file mode 100644 index fd41f7887e2..00000000000 --- a/drivers/net/acenic_firmware.h +++ /dev/null @@ -1,9456 +0,0 @@ -/* - * Declare these here even if Tigon I support is disabled to avoid - * the compiler complaining about undefined symbols. - */ -#define tigonFwReleaseMajor 0xc -#define tigonFwReleaseMinor 0x4 -#define tigonFwReleaseFix 0xb -#define tigonFwStartAddr 0x00004000 -#define tigonFwTextAddr 0x00004000 -#define tigonFwTextLen 0x11140 -#define tigonFwRodataAddr 0x00015140 -#define tigonFwRodataLen 0xac0 -#define tigonFwDataAddr 0x00015c20 -#define tigonFwDataLen 0x170 -#define tigonFwSbssAddr 0x00015d90 -#define tigonFwSbssLen 0x38 -#define tigonFwBssAddr 0x00015dd0 -#define tigonFwBssLen 0x2080 -#ifdef CONFIG_ACENIC_OMIT_TIGON_I -#define tigonFwText NULL -#define tigonFwData NULL -#define tigonFwRodata NULL -#else -/* Generated by genfw.c */ -static u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { -0x10000003, -0x0, 0xd, 0xd, 0x3c1d0001, -0x8fbd5c54, 0x3a0f021, 0x3c100000, 0x26104000, -0xc00100c, 0x0, 0xd, 0x27bdffd8, -0x3c1cc000, 0x3c1b0013, 0x377bd800, 0xd021, -0x3c170013, 0x36f75418, 0x2e02021, 0x340583e8, -0xafbf0024, 0xc002488, 0xafb00020, 0xc0023e8, -0x0, 0x3c040001, 0x248451a4, 0x24050001, -0x2e03021, 0x3821, 0x3c100001, 0x26107e50, -0xafb00010, 0xc002403, 0xafbb0014, 0x3c02000f, -0x3442ffff, 0x2021024, 0x362102b, 0x10400009, -0x24050003, 0x3c040001, 0x248451b0, 0x2003021, -0x3603821, 0x3c020010, 0xafa20010, 0xc002403, -0xafa00014, 0x2021, 0x3405c000, 0x3c010001, -0x370821, 0xa02083b0, 0x3c010001, 0x370821, -0xa02083b2, 0x3c010001, 0x370821, 0xa02083b3, -0x3c010001, 0x370821, 0xac2083b4, 0xa2e004d8, -0x418c0, 0x24840001, 0x771021, 0xac40727c, -0x771021, 0xac407280, 0x2e31021, 0xa445727c, -0x2c820020, 0x1440fff7, 0x418c0, 0x2021, -0x3405c000, 0x418c0, 0x24840001, 0x771021, -0xac40737c, 0x771021, 0xac407380, 0x2e31021, -0xa445737c, 0x2c820080, 0x5440fff7, 0x418c0, -0xaf800054, 0xaf80011c, 0x8f820044, 0x34420040, -0xaf820044, 0x8f820044, 0x34420020, 0xaf820044, -0x8f420218, 0x30420002, 0x10400009, 0x0, -0x8f420220, 0x3c030002, 0x34630004, 0x431025, -0xaee204c4, 0x8f42021c, 0x8001074, 0x34420004, -0x8f420220, 0x3c030002, 0x34630006, 0x431025, -0xaee204c4, 0x8f42021c, 0x34420006, 0xaee204cc, -0x8f420218, 0x30420010, 0x1040000a, 0x0, -0x8f42021c, 0x34420004, 0xaee204c8, 0x8f420220, -0x3c03000a, 0x34630004, 0x431025, 0x800108a, -0xaee204c0, 0x8f420220, 0x3c03000a, 0x34630006, -0x431025, 0xaee204c0, 0x8f42021c, 0x34420006, -0xaee204c8, 0x8f420218, 0x30420200, 0x10400003, -0x24020001, 0x8001091, 0xa2e27248, 0xa2e07248, -0x24020001, 0xaf8200a0, 0xaf8200b0, 0x8f830054, -0x8f820054, 0x8001099, 0x24630064, 0x8f820054, -0x621023, 0x2c420065, 0x1440fffc, 0x0, -0xaf800044, 0x8f420208, 0x8f43020c, 0xaee20010, -0xaee30014, 0x8ee40010, 0x8ee50014, 0x26e20030, -0xaee20028, 0x24020490, 0xaee20018, 0xaf840090, -0xaf850094, 0x8ee20028, 0xaf8200b4, 0x96e2001a, -0xaf82009c, 0x8f8200b0, 0x8ee304cc, 0x431025, -0xaf8200b0, 0x8f8200b0, 0x30420004, 0x1440fffd, -0x0, 0x8ee20450, 0x8ee30454, 0xaee304fc, -0x8ee204fc, 0x2442e000, 0x2c422001, 0x1440000d, -0x26e40030, 0x8ee20450, 0x8ee30454, 0x3c040001, -0x248451bc, 0x3c050001, 0xafa00010, 0xafa00014, -0x8ee704fc, 0x34a5f000, 0xc002403, 0x603021, -0x26e40030, 0xc002488, 0x24050400, 0x27440080, -0xc002488, 0x24050080, 0x26e4777c, 0xc002488, -0x24050400, 0x8f42025c, 0x26e40094, 0xaee20060, -0x8f420260, 0x27450200, 0x24060008, 0xaee20068, -0x24020006, 0xc00249a, 0xaee20064, 0x3c023b9a, -0x3442ca00, 0x2021, 0x24030002, 0xaee30074, -0xaee30070, 0xaee2006c, 0x240203e8, 0xaee20104, -0x24020001, 0xaee30100, 0xaee2010c, 0x3c030001, -0x641821, 0x90635c20, 0x2e41021, 0x24840001, -0xa043009c, 0x2c82000f, 0x1440fff8, 0x0, -0x8f820040, 0x2e41821, 0x24840001, 0x21702, -0x24420030, 0xa062009c, 0x2e41021, 0xa040009c, -0x96e2046a, 0x30420003, 0x14400009, 0x0, -0x96e2047a, 0x30420003, 0x50400131, 0x3c030800, -0x96e2046a, 0x30420003, 0x1040002a, 0x3c020700, -0x96e2047a, 0x30420003, 0x10400026, 0x3c020700, -0x96e3047a, 0x96e2046a, 0x14620022, 0x3c020700, -0x8ee204c0, 0x24030001, 0xa2e34e20, 0x34420e00, -0xaee204c0, 0x8f420218, 0x30420100, 0x10400005, -0x0, 0x3c020001, 0x2442e168, 0x800111d, -0x21100, 0x3c020001, 0x2442d35c, 0x21100, -0x21182, 0x3c030800, 0x431025, 0x3c010001, -0xac221238, 0x3c020001, 0x2442f680, 0x21100, -0x21182, 0x3c030800, 0x431025, 0x3c010001, -0xac221278, 0x8ee20000, 0x34424000, 0x8001238, -0xaee20000, 0x34423000, 0xafa20018, 0x8ee20608, -0x8f430228, 0x24420001, 0x304900ff, 0x512300e2, -0xafa00010, 0x8ee20608, 0x210c0, 0x571021, -0x8fa30018, 0x8fa4001c, 0xac43060c, 0xac440610, -0x8f870120, 0x27623800, 0x24e80020, 0x102102b, -0x50400001, 0x27683000, 0x8f820128, 0x11020004, -0x0, 0x8f820124, 0x15020007, 0x1021, -0x8ee201a4, 0x3021, 0x24420001, 0xaee201a4, -0x80011a0, 0x8ee201a4, 0x8ee40608, 0x420c0, -0x801821, 0x8ee40430, 0x8ee50434, 0xa32821, -0xa3302b, 0x822021, 0x862021, 0xace40000, -0xace50004, 0x8ee30608, 0x24020008, 0xa4e2000e, -0x2402000d, 0xace20018, 0xace9001c, 0x318c0, -0x2463060c, 0x2e31021, 0xace20008, 0x8ee204c4, -0xace20010, 0xaf880120, 0x92e24e20, 0x14400037, -0x24060001, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c830000, 0x24020007, 0x1462001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x24030040, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee54e30, 0x24420001, 0x10430007, -0x0, 0x8ee24e34, 0x24420001, 0x10a20005, -0x0, 0x800118a, 0x0, 0x14a00005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, -0xac800000, 0x80011a0, 0x0, 0x8ee24e30, -0x24030040, 0x24420001, 0x50430003, 0x1021, -0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x24020007, -0xac820000, 0x24020001, 0xac820004, 0x54c0000c, -0xaee90608, 0x3c040001, 0x248451c8, 0xafa00010, -0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002403, 0x34a5f000, 0x8001223, 0x0, -0x8f830120, 0x27623800, 0x24660020, 0xc2102b, -0x50400001, 0x27663000, 0x8f820128, 0x10c20004, -0x0, 0x8f820124, 0x14c20007, 0x0, -0x8ee201a4, 0x3021, 0x24420001, 0xaee201a4, -0x8001207, 0x8ee201a4, 0x8ee20608, 0xac62001c, -0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008, -0x24020008, 0xa462000e, 0x24020011, 0xac620018, -0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, -0xaf860120, 0x92e24e20, 0x14400037, 0x24060001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c830000, 0x24020012, 0x1462001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x24030040, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee54e30, 0x24420001, 0x10430007, 0x0, -0x8ee24e34, 0x24420001, 0x10a20005, 0x0, -0x80011f1, 0x0, 0x14a00005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x8001207, 0x0, 0x8ee24e30, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020012, 0xac820000, -0x24020001, 0xac820004, 0x14c0001b, 0x0, -0x3c040001, 0x248451d0, 0xafa00010, 0xafa00014, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, -0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0, -0x8001223, 0x8ee201b0, 0x3c040001, 0x248451dc, -0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002403, 0x34a5f005, 0x8ee201ac, 0x24420001, -0xaee201ac, 0x8ee201ac, 0x8ee20160, 0x3c040001, -0x248451e8, 0x3405f001, 0x24420001, 0xaee20160, -0x8ee20160, 0x3021, 0x3821, 0xafa00010, -0xc002403, 0xafa00014, 0x8001238, 0x0, -0x3c020001, 0x2442f5a8, 0x21100, 0x21182, -0x431025, 0x3c010001, 0xac221278, 0x96e2045a, -0x30420003, 0x10400025, 0x3c050fff, 0x8ee204c8, -0x34a5ffff, 0x34420a00, 0xaee204c8, 0x8ee304c8, -0x3c040001, 0x248451f4, 0x24020001, 0xa2e204ec, -0xa2e204ed, 0x3c020002, 0x621825, 0x3c020001, -0x2442a390, 0x451024, 0x21082, 0xaee304c8, -0x3c030800, 0x431025, 0x3c010001, 0xac221220, -0x3c020001, 0x2442add4, 0x451024, 0x21082, -0x431025, 0x3c010001, 0xac221280, 0x96e6045a, -0x3821, 0x24050011, 0xafa00010, 0xc002403, -0xafa00014, 0x8001268, 0x0, 0x3c020001, -0x2442a9d4, 0x21100, 0x21182, 0x3c030800, -0x431025, 0x3c010001, 0xac221280, 0x96e2046a, -0x30420010, 0x14400009, 0x0, 0x96e2047a, -0x30420010, 0x10400112, 0x0, 0x96e2046a, -0x30420010, 0x10400005, 0x3c020700, 0x96e2047a, -0x30420010, 0x14400102, 0x3c020700, 0x34423000, -0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001, -0x304900ff, 0x512300e2, 0xafa00010, 0x8ee20608, -0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c, -0xac43060c, 0xac440610, 0x8f870120, 0x27623800, -0x24e80020, 0x102102b, 0x50400001, 0x27683000, -0x8f820128, 0x11020004, 0x0, 0x8f820124, -0x15020007, 0x1021, 0x8ee201a4, 0x3021, -0x24420001, 0xaee201a4, 0x80012ea, 0x8ee201a4, -0x8ee40608, 0x420c0, 0x801821, 0x8ee40430, -0x8ee50434, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xace40000, 0xace50004, 0x8ee30608, -0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018, -0xace9001c, 0x318c0, 0x2463060c, 0x2e31021, -0xace20008, 0x8ee204c4, 0xace20010, 0xaf880120, -0x92e24e20, 0x14400037, 0x24060001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c830000, -0x24020007, 0x1462001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30, -0x24420001, 0x10430007, 0x0, 0x8ee24e34, -0x24420001, 0x10a20005, 0x0, 0x80012d4, -0x0, 0x14a00005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x80012ea, -0x0, 0x8ee24e30, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x24020007, 0xac820000, 0x24020001, -0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001, -0x248451c8, 0xafa00010, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000, -0x800136d, 0x0, 0x8f830120, 0x27623800, -0x24660020, 0xc2102b, 0x50400001, 0x27663000, -0x8f820128, 0x10c20004, 0x0, 0x8f820124, -0x14c20007, 0x0, 0x8ee201a4, 0x3021, -0x24420001, 0xaee201a4, 0x8001351, 0x8ee201a4, -0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4, -0x2462001c, 0xac620008, 0x24020008, 0xa462000e, -0x24020011, 0xac620018, 0xac640000, 0xac650004, -0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, -0x14400037, 0x24060001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c830000, 0x24020012, -0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34, -0x1062001b, 0x24030040, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001, -0x10430007, 0x0, 0x8ee24e34, 0x24420001, -0x10a20005, 0x0, 0x800133b, 0x0, -0x14a00005, 0x0, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400013, 0xac800000, 0x8001351, 0x0, -0x8ee24e30, 0x24030040, 0x24420001, 0x50430003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x24020012, 0xac820000, 0x24020001, 0xac820004, -0x14c0001b, 0x0, 0x3c040001, 0x248451d0, -0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0, -0x24420001, 0xaee201b0, 0x800136d, 0x8ee201b0, -0x3c040001, 0x248451dc, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005, -0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, -0x8ee20160, 0x3c040001, 0x248451e8, 0x3405f002, -0x24420001, 0xaee20160, 0x8ee20160, 0x3021, -0x3821, 0xafa00010, 0xc002403, 0xafa00014, -0x96e6047a, 0x96e7046a, 0x3c040001, 0x24845200, -0x24050012, 0xafa00010, 0xc002403, 0xafa00014, -0xc004500, 0x0, 0xc002318, 0x0, -0x3c060001, 0x34c63800, 0xaee00608, 0xaf400228, -0xaf40022c, 0x96e30458, 0x8ee40000, 0x3c0512d8, -0x34a5c358, 0x27623800, 0xaee27258, 0x27623800, -0xaee27260, 0x27623800, 0xaee27264, 0x3661021, -0xaee27270, 0x2402ffff, 0xaee004d4, 0xaee004e0, -0xaee004e4, 0xaee004f0, 0xa2e004f4, 0xaee00e0c, -0xaee00e18, 0xaee00e10, 0xaee00e14, 0xaee00e1c, -0xaee0724c, 0xaee05244, 0xaee05240, 0xaee0523c, -0xaee07250, 0xaee07254, 0xaee0725c, 0xaee07268, -0xaee004d0, 0x2463ffff, 0x852025, 0xaee304f8, -0xaee40000, 0xaf800060, 0xaf820064, 0x3c020100, -0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001, -0x304900ff, 0x512300e2, 0xafa00010, 0x8ee20608, -0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c, -0xac43060c, 0xac440610, 0x8f870120, 0x27623800, -0x24e80020, 0x102102b, 0x50400001, 0x27683000, -0x8f820128, 0x11020004, 0x0, 0x8f820124, -0x15020007, 0x1021, 0x8ee201a4, 0x3021, -0x24420001, 0xaee201a4, 0x8001422, 0x8ee201a4, -0x8ee40608, 0x420c0, 0x801821, 0x8ee40430, -0x8ee50434, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xace40000, 0xace50004, 0x8ee30608, -0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018, -0xace9001c, 0x318c0, 0x2463060c, 0x2e31021, -0xace20008, 0x8ee204c4, 0xace20010, 0xaf880120, -0x92e24e20, 0x14400037, 0x24060001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c830000, -0x24020007, 0x1462001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30, -0x24420001, 0x10430007, 0x0, 0x8ee24e34, -0x24420001, 0x10a20005, 0x0, 0x800140c, -0x0, 0x14a00005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8001422, -0x0, 0x8ee24e30, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x24020007, 0xac820000, 0x24020001, -0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001, -0x248451c8, 0xafa00010, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000, -0x80014a5, 0x0, 0x8f830120, 0x27623800, -0x24660020, 0xc2102b, 0x50400001, 0x27663000, -0x8f820128, 0x10c20004, 0x0, 0x8f820124, -0x14c20007, 0x0, 0x8ee201a4, 0x3021, -0x24420001, 0xaee201a4, 0x8001489, 0x8ee201a4, -0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4, -0x2462001c, 0xac620008, 0x24020008, 0xa462000e, -0x24020011, 0xac620018, 0xac640000, 0xac650004, -0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, -0x14400037, 0x24060001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c830000, 0x24020012, -0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34, -0x1062001b, 0x24030040, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001, -0x10430007, 0x0, 0x8ee24e34, 0x24420001, -0x10a20005, 0x0, 0x8001473, 0x0, -0x14a00005, 0x0, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400013, 0xac800000, 0x8001489, 0x0, -0x8ee24e30, 0x24030040, 0x24420001, 0x50430003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x24020012, 0xac820000, 0x24020001, 0xac820004, -0x14c0001b, 0x0, 0x3c040001, 0x248451d0, -0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0, -0x24420001, 0xaee201b0, 0x80014a5, 0x8ee201b0, -0x3c040001, 0x248451dc, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005, -0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, -0x8ee20154, 0x24420001, 0xaee20154, 0xc0014dc, -0x8ee20154, 0x8f8200a0, 0x30420004, 0x1440fffd, -0x0, 0x8f820040, 0x30420001, 0x14400008, -0x0, 0x8f430104, 0x24020001, 0x10620004, -0x0, 0x8f420264, 0x10400006, 0x0, -0x8ee2017c, 0x24420001, 0xaee2017c, 0x80014c5, -0x8ee2017c, 0x8f820044, 0x34420004, 0xaf820044, -0x8ee20178, 0x24420001, 0xaee20178, 0x8ee20178, -0x8f8200d8, 0x8f8300d4, 0x431023, 0xaee2726c, -0x8ee2726c, 0x1c400003, 0x3c030001, 0x431021, -0xaee2726c, 0xc004064, 0x0, 0xc004440, -0xaf800228, 0x8fbf0024, 0x8fb00020, 0x3e00008, -0x27bd0028, 0x3e00008, 0x0, 0x3e00008, -0x0, 0x0, 0x0, 0x2402002c, -0xaf820050, 0xaee07274, 0x8f420238, 0xaee27278, -0x8f820054, 0x24420067, 0xaf820058, 0xaee07b88, -0xaee07b8c, 0xaee07b84, 0x3c010001, 0x370821, -0xac2083bc, 0x3c010001, 0x370821, 0x3e00008, -0xa02083b9, 0x27bdffd8, 0xafbf0024, 0xafb00020, -0x8f820054, 0x3c030001, 0x8c635cd8, 0x24420067, -0x1060000d, 0xaf820058, 0x3c020001, 0x571021, -0x904283b8, 0x10400005, 0x3c030200, 0x3c010001, -0x370821, 0x8001503, 0xa02083b8, 0x8ee20000, -0x431025, 0xaee20000, 0x8f420218, 0x30420100, -0x104000c6, 0x0, 0x8f8200b0, 0x30420004, -0x104000c2, 0x0, 0x3c030001, 0x771821, -0x8c6383d0, 0x8f820104, 0x146200b4, 0x0, -0x3c030001, 0x771821, 0x8c6383d4, 0x8f8200b4, -0x146200ae, 0x0, 0x8f8200b0, 0x3c030080, -0x431024, 0x1040000d, 0x0, 0x8f82011c, -0x34420002, 0xaf82011c, 0x8f8200b0, 0x2403fffb, -0x431024, 0xaf8200b0, 0x8f82011c, 0x2403fffd, -0x431024, 0x80015cc, 0xaf82011c, 0x3c030001, -0x771821, 0x8c6383d0, 0x8f820104, 0x14620082, -0x0, 0x3c030001, 0x771821, 0x8c6383d4, -0x8f8200b4, 0x1462007c, 0x0, 0x3c070001, -0xf73821, 0x8ce783d0, 0x8f8200b0, 0x3c040001, -0x24845270, 0xafa00014, 0xafa20010, 0x8f8600b0, -0x3c050005, 0xc002403, 0x34a50900, 0x8f82011c, -0x34420002, 0xaf82011c, 0x8f830104, 0x8f8200b0, -0x34420001, 0xaf8200b0, 0xaf830104, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20006, 0x0, 0x8ee201a4, -0x24420001, 0xaee201a4, 0x80015a0, 0x8ee201a4, -0x8f440208, 0x8f45020c, 0x26e20030, 0xac620008, -0x24020400, 0xa462000e, 0x2402000f, 0xac620018, -0xac60001c, 0xac640000, 0xac650004, 0x8ee204c4, -0xac620010, 0xaf860120, 0x92e24e20, 0x14400037, -0x0, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c830000, 0x24020007, 0x1462001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x24030040, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee54e30, 0x24420001, 0x10430007, -0x0, 0x8ee24e34, 0x24420001, 0x10a20005, -0x0, 0x800158a, 0x0, 0x14a00005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, -0xac800000, 0x80015a0, 0x0, 0x8ee24e30, -0x24030040, 0x24420001, 0x50430003, 0x1021, -0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x24020007, -0xac820000, 0x24020001, 0xac820004, 0x8f82011c, -0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201e4, -0x3c070001, 0xf73821, 0x8ce783d0, 0x24420001, -0xaee201e4, 0x8ee201e4, 0x3c040001, 0x2484527c, -0x80015bd, 0xafa00010, 0x8f820104, 0x3c010001, -0x370821, 0xac2283d0, 0x8f8200b4, 0x3c070001, -0xf73821, 0x8ce783d0, 0x3c040001, 0x24845284, -0x3c010001, 0x370821, 0xac2283d4, 0xafa00010, -0xafa00014, 0x8f8600b0, 0x3c050005, 0xc002403, -0x34a50900, 0x80015cc, 0x0, 0x8f820104, -0x3c010001, 0x370821, 0xac2283d0, 0x8f8200b4, -0x3c010001, 0x370821, 0xac2283d4, 0x8ee27274, -0x92e304f4, 0x24420067, 0x14600006, 0xaee27274, -0x8ee27274, 0x8f430234, 0x43102b, 0x1440007b, -0x0, 0x8ee304e4, 0x8ee204f8, 0x14620004, -0x0, 0x92e204f4, 0x50400074, 0xa2e004f4, -0x8f830120, 0x27623800, 0x24660020, 0xc2102b, -0x50400001, 0x27663000, 0x8f820128, 0x10c20004, -0x0, 0x8f820124, 0x14c20007, 0x0, -0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4, -0x8001637, 0x8ee201a4, 0x8ee204e4, 0xac62001c, -0x8ee404b0, 0x8ee504b4, 0x2462001c, 0xac620008, -0x24020008, 0xa462000e, 0x24020011, 0xac620018, -0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, -0xaf860120, 0x92e24e20, 0x14400037, 0x24100001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c830000, 0x24020012, 0x1462001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x24030040, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee54e30, 0x24420001, 0x10430007, 0x0, -0x8ee24e34, 0x24420001, 0x10a20005, 0x0, -0x8001621, 0x0, 0x14a00005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x8001637, 0x0, 0x8ee24e30, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020012, 0xac820000, -0x24020001, 0xac820004, 0x5600000b, 0x24100001, -0x8ee204e4, 0x3c040001, 0x2484528c, 0xafa00014, -0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002403, 0x34a5f006, 0x16000003, 0x24020001, -0x8001650, 0xa2e204f4, 0x8ee20170, 0x24420001, -0xaee20170, 0x8ee20170, 0x8ee204e4, 0xa2e004f4, -0xaee004f0, 0xaee07274, 0xaee204f8, 0x8ee20e1c, -0x1040006d, 0x0, 0x8f830120, 0x27623800, -0x24660020, 0xc2102b, 0x50400001, 0x27663000, -0x8f820128, 0x10c20004, 0x0, 0x8f820124, -0x14c20007, 0x0, 0x8ee201a4, 0x8021, -0x24420001, 0xaee201a4, 0x80016ad, 0x8ee201a4, -0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac, -0x2462001c, 0xac620008, 0x24020008, 0xa462000e, -0x24020011, 0xac620018, 0xac640000, 0xac650004, -0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, -0x14400037, 0x24100001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c830000, 0x24020012, -0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34, -0x1062001b, 0x24030040, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001, -0x10430007, 0x0, 0x8ee24e34, 0x24420001, -0x10a20005, 0x0, 0x8001697, 0x0, -0x14a00005, 0x0, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400013, 0xac800000, 0x80016ad, 0x0, -0x8ee24e30, 0x24030040, 0x24420001, 0x50430003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x24020012, 0xac820000, 0x24020001, 0xac820004, -0x5600000b, 0x24100001, 0x8ee2724c, 0x3c040001, -0x24845298, 0xafa00014, 0xafa20010, 0x8ee6724c, -0x8f470280, 0x3c050009, 0xc002403, 0x34a5f008, -0x56000001, 0xaee00e1c, 0x8ee20174, 0x24420001, -0xaee20174, 0x8ee20174, 0x8ee24e24, 0x10400019, -0x0, 0xaee04e24, 0x8f820040, 0x30420001, -0x14400008, 0x0, 0x8f430104, 0x24020001, -0x10620004, 0x0, 0x8f420264, 0x10400006, -0x0, 0x8ee2017c, 0x24420001, 0xaee2017c, -0x80016da, 0x8ee2017c, 0x8f820044, 0x34420004, -0xaf820044, 0x8ee20178, 0x24420001, 0xaee20178, -0x8ee20178, 0x8ee27278, 0x2442ff99, 0xaee27278, -0x8ee27278, 0x1c4002ad, 0x0, 0x8f420238, -0x104002aa, 0x0, 0x3c020001, 0x571021, -0x904283e0, 0x144002a5, 0x0, 0x8f420080, -0xaee2004c, 0x8f4200c0, 0xaee20048, 0x8f420084, -0xaee20038, 0x8f420084, 0xaee20244, 0x8f420088, -0xaee20248, 0x8f42008c, 0xaee2024c, 0x8f420090, -0xaee20250, 0x8f420094, 0xaee20254, 0x8f420098, -0xaee20258, 0x8f42009c, 0xaee2025c, 0x8f4200a0, -0xaee20260, 0x8f4200a4, 0xaee20264, 0x8f4200a8, -0xaee20268, 0x8f4200ac, 0xaee2026c, 0x8f4200b0, -0xaee20270, 0x8f4200b4, 0xaee20274, 0x8f4200b8, -0xaee20278, 0x8f4200bc, 0x24040001, 0xaee2027c, -0xaee0003c, 0x41080, 0x571021, 0x8ee3003c, -0x8c420244, 0x24840001, 0x621821, 0x2c82000f, -0xaee3003c, 0x1440fff8, 0x41080, 0x8f4200cc, -0xaee20050, 0x8f4200d0, 0xaee20054, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x8001775, -0x8ee201a4, 0x8f440208, 0x8f45020c, 0x26e20030, -0xac620008, 0x24020400, 0xa462000e, 0x2402000f, -0xac620018, 0xac60001c, 0xac640000, 0xac650004, -0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, -0x14400037, 0x24100001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c830000, 0x24020007, -0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34, -0x1062001b, 0x24030040, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001, -0x10430007, 0x0, 0x8ee24e34, 0x24420001, -0x10a20005, 0x0, 0x800175f, 0x0, -0x14a00005, 0x0, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400013, 0xac800000, 0x8001775, 0x0, -0x8ee24e30, 0x24030040, 0x24420001, 0x50430003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x24020007, 0xac820000, 0x24020001, 0xac820004, -0x12000212, 0x3c020400, 0xafa20018, 0x3c020001, -0x571021, 0x904283b0, 0x1040010b, 0x0, -0x8ee20608, 0x8f430228, 0x24420001, 0x304a00ff, -0x514300fd, 0xafa00010, 0x8ee20608, 0x210c0, -0x571021, 0x8fa30018, 0x8fa4001c, 0xac43060c, -0xac440610, 0x8f830054, 0x8f820054, 0x24690032, -0x1221023, 0x2c420033, 0x1040006a, 0x5821, -0x24180008, 0x240f000d, 0x240d0007, 0x240c0040, -0x240e0001, 0x8f870120, 0x27623800, 0x24e80020, -0x102102b, 0x50400001, 0x27683000, 0x8f820128, -0x11020004, 0x0, 0x8f820124, 0x15020007, -0x1021, 0x8ee201a4, 0x8021, 0x24420001, -0xaee201a4, 0x80017f3, 0x8ee201a4, 0x8ee40608, -0x420c0, 0x801821, 0x8ee40430, 0x8ee50434, -0xa32821, 0xa3302b, 0x822021, 0x862021, -0xace40000, 0xace50004, 0x8ee20608, 0xa4f8000e, -0xacef0018, 0xacea001c, 0x210c0, 0x2442060c, -0x2e21021, 0xace20008, 0x8ee204c4, 0xace20010, -0xaf880120, 0x92e24e20, 0x14400033, 0x24100001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c820000, 0x144d001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x104c0007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x80017e0, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x80017f3, -0x0, 0x8ee24e30, 0x24420001, 0x504c0003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0xac8d0000, 0xac8e0004, 0x56000006, 0x240b0001, -0x8f820054, 0x1221023, 0x2c420033, 0x1440ff9d, -0x0, 0x316300ff, 0x24020001, 0x14620077, -0x3c050009, 0xaeea0608, 0x8f830054, 0x8f820054, -0x24690032, 0x1221023, 0x2c420033, 0x10400061, -0x5821, 0x240d0008, 0x240c0011, 0x24080012, -0x24070040, 0x240a0001, 0x8f830120, 0x27623800, -0x24660020, 0xc2102b, 0x50400001, 0x27663000, -0x8f820128, 0x10c20004, 0x0, 0x8f820124, -0x14c20007, 0x0, 0x8ee201a4, 0x8021, -0x24420001, 0xaee201a4, 0x800185f, 0x8ee201a4, -0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4, -0x2462001c, 0xac620008, 0xa46d000e, 0xac6c0018, -0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, -0xaf860120, 0x92e24e20, 0x14400033, 0x24100001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c820000, 0x1448001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x10470007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x800184c, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x800185f, -0x0, 0x8ee24e30, 0x24420001, 0x50470003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0xac880000, 0xac8a0004, 0x56000006, 0x240b0001, -0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, -0x0, 0x316300ff, 0x24020001, 0x14620003, -0x3c050009, 0x800197c, 0x24100001, 0x3c040001, -0x248452a4, 0xafa00010, 0xafa00014, 0x8f860120, -0x8f870124, 0x800187b, 0x34a5f011, 0x3c040001, -0x248452b0, 0xafa00010, 0xafa00014, 0x8f860120, -0x8f870124, 0x34a5f010, 0xc002403, 0x8021, -0x800197c, 0x0, 0x3c040001, 0x248452bc, -0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0x8001975, 0x34a5f00f, 0x8ee20608, 0x8f430228, -0x24420001, 0x304900ff, 0x512300e2, 0xafa00010, -0x8ee20608, 0x210c0, 0x571021, 0x8fa30018, -0x8fa4001c, 0xac43060c, 0xac440610, 0x8f870120, -0x27623800, 0x24e80020, 0x102102b, 0x50400001, -0x27683000, 0x8f820128, 0x11020004, 0x0, -0x8f820124, 0x15020007, 0x1021, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x80018f7, -0x8ee201a4, 0x8ee40608, 0x420c0, 0x801821, -0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0xace40000, 0xace50004, -0x8ee30608, 0x24020008, 0xa4e2000e, 0x2402000d, -0xace20018, 0xace9001c, 0x318c0, 0x2463060c, -0x2e31021, 0xace20008, 0x8ee204c4, 0xace20010, -0xaf880120, 0x92e24e20, 0x14400037, 0x24100001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c830000, 0x24020007, 0x1462001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x24030040, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee54e30, 0x24420001, 0x10430007, 0x0, -0x8ee24e34, 0x24420001, 0x10a20005, 0x0, -0x80018e1, 0x0, 0x14a00005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x80018f7, 0x0, 0x8ee24e30, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020007, 0xac820000, -0x24020001, 0xac820004, 0x5600000c, 0xaee90608, -0x3c040001, 0x248452c8, 0xafa00010, 0xafa00014, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, -0x34a5f000, 0x800197c, 0x0, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x800195e, -0x8ee201a4, 0x8ee20608, 0xac62001c, 0x8ee404a0, -0x8ee504a4, 0x2462001c, 0xac620008, 0x24020008, -0xa462000e, 0x24020011, 0xac620018, 0xac640000, -0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120, -0x92e24e20, 0x14400037, 0x24100001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c830000, -0x24020012, 0x1462001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30, -0x24420001, 0x10430007, 0x0, 0x8ee24e34, -0x24420001, 0x10a20005, 0x0, 0x8001948, -0x0, 0x14a00005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x800195e, -0x0, 0x8ee24e30, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x24020012, 0xac820000, 0x24020001, -0xac820004, 0x5600001d, 0x24100001, 0x3c040001, -0x248452d0, 0xafa00010, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002403, 0x34a5f001, -0x8ee201b0, 0x24420001, 0xaee201b0, 0x800197c, -0x8ee201b0, 0x3c040001, 0x248452dc, 0xafa00014, -0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f005, -0xc002403, 0x0, 0x8ee201ac, 0x8021, -0x24420001, 0xaee201ac, 0x8ee201ac, 0x1200000c, -0x24020001, 0x3c010001, 0x370821, 0xa02083b0, -0x8f420238, 0x8ee30158, 0x24630001, 0xaee30158, -0x8ee30158, 0x800198c, 0xaee27278, 0x24020001, -0x3c010001, 0x370821, 0xa02283b0, 0x3c020001, -0x8c425cd8, 0x10400187, 0x0, 0x8ee27b84, -0x24430001, 0x284200c9, 0x144001a4, 0xaee37b84, -0x8ee204d4, 0x30420002, 0x14400119, 0xaee07b84, -0x8ee204d4, 0x3c030600, 0x34631000, 0x34420002, -0xaee204d4, 0xafa30018, 0x8ee20608, 0x8f430228, -0x24420001, 0x304a00ff, 0x514300fd, 0xafa00010, -0x8ee20608, 0x210c0, 0x571021, 0x8fa30018, -0x8fa4001c, 0xac43060c, 0xac440610, 0x8f830054, -0x8f820054, 0x24690032, 0x1221023, 0x2c420033, -0x1040006a, 0x5821, 0x24180008, 0x240f000d, -0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120, -0x27623800, 0x24e80020, 0x102102b, 0x50400001, -0x27683000, 0x8f820128, 0x11020004, 0x0, -0x8f820124, 0x15020007, 0x1021, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x8001a15, -0x8ee201a4, 0x8ee40608, 0x420c0, 0x801821, -0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0xace40000, 0xace50004, -0x8ee20608, 0xa4f8000e, 0xacef0018, 0xacea001c, -0x210c0, 0x2442060c, 0x2e21021, 0xace20008, -0x8ee204c4, 0xace20010, 0xaf880120, 0x92e24e20, -0x14400033, 0x24100001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c820000, 0x144d001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x0, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee34e30, 0x24420001, 0x104c0007, -0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x8001a02, 0x0, 0x14600005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, -0xac800000, 0x8001a15, 0x0, 0x8ee24e30, -0x24420001, 0x504c0003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0xac8d0000, 0xac8e0004, -0x56000006, 0x240b0001, 0x8f820054, 0x1221023, -0x2c420033, 0x1440ff9d, 0x0, 0x316300ff, -0x24020001, 0x54620078, 0xafa00010, 0xaeea0608, -0x8f830054, 0x8f820054, 0x24690032, 0x1221023, -0x2c420033, 0x10400061, 0x5821, 0x240d0008, -0x240c0011, 0x24080012, 0x24070040, 0x240a0001, -0x8f830120, 0x27623800, 0x24660020, 0xc2102b, -0x50400001, 0x27663000, 0x8f820128, 0x10c20004, -0x0, 0x8f820124, 0x14c20007, 0x0, -0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4, -0x8001a81, 0x8ee201a4, 0x8ee20608, 0xac62001c, -0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008, -0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004, -0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, -0x14400033, 0x24100001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c820000, 0x1448001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x0, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10470007, -0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x8001a6e, 0x0, 0x14600005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, -0xac800000, 0x8001a81, 0x0, 0x8ee24e30, -0x24420001, 0x50470003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0xac880000, 0xac8a0004, -0x56000006, 0x240b0001, 0x8f820054, 0x1221023, -0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, -0x24020001, 0x10620022, 0x0, 0x3c040001, -0x248452a4, 0xafa00010, 0xafa00014, 0x8f860120, -0x8f870124, 0x3c050009, 0xc002403, 0x34a5f011, -0x8001aad, 0x0, 0x3c040001, 0x248452b0, -0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, -0xc002403, 0x34a5f010, 0x8001aad, 0x0, -0x3c040001, 0x248452bc, 0xafa00014, 0x8ee60608, -0x8f470228, 0x3c050009, 0xc002403, 0x34a5f00f, -0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac, -0x8ee2015c, 0x24420001, 0xaee2015c, 0x8ee2015c, -0x8ee204d4, 0x30420001, 0x10400055, 0x0, -0x8f420218, 0x30420080, 0x10400029, 0x0, -0x8f820044, 0x34420040, 0xaf820044, 0x8ee27b7c, -0x402821, 0x8ee200c0, 0x8ee300c4, 0x24060000, -0x2407ffff, 0x2021, 0x461024, 0x1444000d, -0x671824, 0x1465000b, 0x0, 0x8ee27b80, -0x402821, 0x8ee200e0, 0x8ee300e4, 0x2021, -0x461024, 0x14440003, 0x671824, 0x1065000b, -0x0, 0x8ee200c0, 0x8ee300c4, 0x8ee400e0, -0x8ee500e4, 0xaee37b7c, 0xaee57b80, 0x8f820044, -0x38420020, 0x8001b38, 0xaf820044, 0x8f820044, -0x2403ffdf, 0x431024, 0x8001b38, 0xaf820044, -0x8f820044, 0x2403ffdf, 0x431024, 0xaf820044, -0x8ee27b7c, 0x402821, 0x8ee200c0, 0x8ee300c4, -0x24060000, 0x2407ffff, 0x2021, 0x461024, -0x1444000d, 0x671824, 0x1465000b, 0x0, -0x8ee27b80, 0x402821, 0x8ee200e0, 0x8ee300e4, -0x2021, 0x461024, 0x14440003, 0x671824, -0x1065000b, 0x0, 0x8ee200c0, 0x8ee300c4, -0x8ee400e0, 0x8ee500e4, 0xaee37b7c, 0xaee57b80, -0x8f820044, 0x38420040, 0x8001b38, 0xaf820044, -0x8f820044, 0x34420040, 0x8001b38, 0xaf820044, -0x8f820044, 0x34420040, 0xaf820044, 0x8ee27b8c, -0x24430001, 0x28420015, 0x14400028, 0xaee37b8c, -0x8f820044, 0x38420020, 0xaf820044, 0x8001b38, -0xaee07b8c, 0x8ee204d4, 0x30420001, 0x10400011, -0x0, 0x8f420218, 0x30420080, 0x10400009, -0x0, 0x8f820044, 0x34420020, 0xaf820044, -0x8f820044, 0x2403ffbf, 0x431024, 0x8001b36, -0xaf820044, 0x8f820044, 0x34420060, 0x8001b36, -0xaf820044, 0x8f820044, 0x34420040, 0xaf820044, -0x8ee27b88, 0x24430001, 0x28421389, 0x14400005, -0xaee37b88, 0x8f820044, 0x38420020, 0xaf820044, -0xaee07b88, 0xc004603, 0x0, 0x8fbf0024, -0x8fb00020, 0x3e00008, 0x27bd0028, 0x27bdffb8, -0xafbf0044, 0xafb60040, 0xafb5003c, 0xafb40038, -0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028, -0x8f960064, 0x32c20004, 0x1040000c, 0x24020004, -0xaf820064, 0x8f420114, 0xaee204e0, 0x8f820060, -0x34420008, 0xaf820060, 0x8ee2016c, 0x24420001, -0xaee2016c, 0x80022f4, 0x8ee2016c, 0x32c20001, -0x10400004, 0x24020001, 0xaf820064, 0x80022f4, -0x0, 0x32c20002, 0x1440000c, 0x3c050003, -0x3c040001, 0x24845354, 0x34a50001, 0x2c03021, -0x3821, 0xafa00010, 0xc002403, 0xafa00014, -0x2402fff8, 0x80022f4, 0xaf820064, 0x8f43022c, -0x8f42010c, 0x5062000c, 0xafa00010, 0x8f42022c, -0x21080, 0x5a1021, 0x8c420300, 0xafa20020, -0x8f42022c, 0x24070001, 0x24420001, 0x3042003f, -0x8001b80, 0xaf42022c, 0x3c040001, 0x24845360, -0xafa00014, 0x8f46022c, 0x8f47010c, 0x3c050003, -0xc002403, 0x34a5f01f, 0x3821, 0x14e00003, -0x0, 0x80022ed, 0xaf960064, 0x93a20020, -0x2443ffff, 0x2c620011, 0x10400658, 0x31080, -0x3c010001, 0x220821, 0x8c225418, 0x400008, -0x0, 0x8fa20020, 0x30420fff, 0xaee20e0c, -0x8f820060, 0x34420200, 0xaf820060, 0x8ee20118, -0x24420001, 0xaee20118, 0x80022e8, 0x8ee20118, -0x8fa20020, 0x24030001, 0x3c010001, 0x370821, -0xa02383b1, 0x30420fff, 0xaee25238, 0x8f820060, -0x34420100, 0xaf820060, 0x8ee20144, 0x24420001, -0xaee20144, 0x80022e8, 0x8ee20144, 0x8fa20020, -0x21200, 0x22502, 0x24020001, 0x10820005, -0x24020002, 0x10820009, 0x2402fffe, 0x8001bc9, -0xafa00010, 0x8ee204d4, 0xaee40070, 0xaee40074, -0x34420001, 0x8001bbd, 0xaee204d4, 0x8ee304d4, -0xaee40070, 0xaee40074, 0x621824, 0xaee304d4, -0x8f840054, 0x41442, 0x41c82, 0x431021, -0x41cc2, 0x431023, 0x41d02, 0x431021, -0x41d42, 0x431023, 0x8001bd0, 0xaee20078, -0x3c040001, 0x2484536c, 0xafa00014, 0x8fa60020, -0x3c050003, 0xc002403, 0x34a50004, 0x8ee20110, -0x24420001, 0xaee20110, 0x80022e8, 0x8ee20110, -0x27440212, 0xc0022fe, 0x24050006, 0x3049001f, -0x920c0, 0x2e41021, 0x9442727c, 0x30424000, -0x1040000a, 0x971021, 0x97430212, 0xa443727e, -0x8f430214, 0x971021, 0xac437280, 0x2e41821, -0x34028000, 0x8001c79, 0xa462727c, 0x9443727e, -0x97420212, 0x14620006, 0x2e41021, 0x971021, -0x8c437280, 0x8f420214, 0x1062009f, 0x2e41021, -0x9442727c, 0x30428000, 0x1040002a, 0x2406ffff, -0x2021, 0x410c0, 0x2e21021, 0x9442737c, -0x30424000, 0x54400005, 0x803021, 0x24840001, -0x2c820080, 0x1440fff8, 0x410c0, 0x4c10010, -0x618c0, 0x610c0, 0x571821, 0x8c63737c, -0x571021, 0xafa30010, 0x8c427380, 0x3c040001, -0x24845378, 0xafa20014, 0x8f470214, 0x3c050003, -0xc002403, 0x34a50013, 0x8001c90, 0x3c020800, -0x97440212, 0x771021, 0xa444737e, 0x8f440214, -0x771021, 0x2e31821, 0xac447380, 0x34028000, -0xa462737c, 0x910c0, 0x2e21021, 0x8001c79, -0xa446727c, 0x2e41021, 0x9445727c, 0x8001c2e, -0x510c0, 0x9443737e, 0x97420212, 0x14620006, -0x510c0, 0x971021, 0x8c437380, 0x8f420214, -0x10620065, 0x510c0, 0x2e21021, 0x9445737c, -0x510c0, 0x2e21021, 0x9442737c, 0x30428000, -0x1040fff0, 0x971021, 0x520c0, 0x971021, -0x9443737e, 0x97420212, 0x14620006, 0x2406ffff, -0x971021, 0x8c437380, 0x8f420214, 0x10620053, -0x3c020800, 0x2021, 0x410c0, 0x2e21021, -0x9442737c, 0x30424000, 0x54400005, 0x803021, -0x24840001, 0x2c820080, 0x1440fff8, 0x410c0, -0x4c10023, 0x618c0, 0x910c0, 0x571821, -0x8c63727c, 0x571021, 0xafa30010, 0x8c427280, -0x3c040001, 0x24845384, 0xafa20014, 0x8f470214, -0x3c050003, 0xc002403, 0x34a5f017, 0x8001c90, -0x3c020800, 0x8f430210, 0xb71021, 0xac43777c, -0x8f430214, 0xb71021, 0xac437780, 0x3c020001, -0x571021, 0x8c4283b4, 0x24420001, 0x3c010001, -0x370821, 0xac2283b4, 0x3c030001, 0x771821, -0x8c6383b4, 0x2e51021, 0x8001c82, 0xa443777c, -0x97440212, 0x771021, 0xa444737e, 0x8f440214, -0x771021, 0x2e31821, 0xac447380, 0x34028000, -0xa462737c, 0x510c0, 0x2e21021, 0xa446737c, -0x2021, 0x428c0, 0x2e51021, 0x9442777c, -0x1040ffdc, 0x24840001, 0x2c820080, 0x5440fffa, -0x428c0, 0x92e204d8, 0x10400006, 0x24020001, -0x8ee304dc, 0x1221004, 0x621825, 0x8001c8f, -0xaee304dc, 0x8f830228, 0x24020001, 0x1221004, -0x621825, 0xaf830228, 0x3c020800, 0x34421000, -0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001, -0x304a00ff, 0x514300fd, 0xafa00010, 0x8ee20608, -0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c, -0xac43060c, 0xac440610, 0x8f830054, 0x8f820054, -0x24690032, 0x1221023, 0x2c420033, 0x1040006a, -0x5821, 0x24100008, 0x240f000d, 0x240d0007, -0x240c0040, 0x240e0001, 0x8f870120, 0x27623800, -0x24e80020, 0x102102b, 0x50400001, 0x27683000, -0x8f820128, 0x11020004, 0x0, 0x8f820124, -0x15020007, 0x1021, 0x8ee201a4, 0x3821, -0x24420001, 0xaee201a4, 0x8001d08, 0x8ee201a4, -0x8ee40608, 0x420c0, 0x801821, 0x8ee40430, -0x8ee50434, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xace40000, 0xace50004, 0x8ee20608, -0xa4f0000e, 0xacef0018, 0xacea001c, 0x210c0, -0x2442060c, 0x2e21021, 0xace20008, 0x8ee204c4, -0xace20010, 0xaf880120, 0x92e24e20, 0x14400033, -0x24070001, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c820000, 0x144d001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee34e30, 0x24420001, 0x104c0007, 0x0, -0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x8001cf5, 0x0, 0x14600005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400010, 0xac800000, -0x8001d08, 0x0, 0x8ee24e30, 0x24420001, -0x504c0003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0xac8d0000, 0xac8e0004, 0x54e00006, -0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, -0x1440ff9d, 0x0, 0x316300ff, 0x24020001, -0x54620078, 0xafa00010, 0xaeea0608, 0x8f830054, -0x8f820054, 0x24690032, 0x1221023, 0x2c420033, -0x10400061, 0x5821, 0x240e0008, 0x240d0011, -0x240a0012, 0x24080040, 0x240c0001, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x3821, 0x24420001, 0xaee201a4, 0x8001d74, -0x8ee201a4, 0x8ee20608, 0xac62001c, 0x8ee404a0, -0x8ee504a4, 0x2462001c, 0xac620008, 0xa46e000e, -0xac6d0018, 0xac640000, 0xac650004, 0x8ee204c4, -0xac620010, 0xaf860120, 0x92e24e20, 0x14400033, -0x24070001, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c820000, 0x144a001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee34e30, 0x24420001, 0x10480007, 0x0, -0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x8001d61, 0x0, 0x14600005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400010, 0xac800000, -0x8001d74, 0x0, 0x8ee24e30, 0x24420001, -0x50480003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006, -0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, -0x1440ffa6, 0x0, 0x316300ff, 0x24020001, -0x10620022, 0x0, 0x3c040001, 0x24845390, -0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, -0x3c050009, 0xc002403, 0x34a5f011, 0x8001da0, -0x0, 0x3c040001, 0x2484539c, 0xafa00014, -0x8f860120, 0x8f870124, 0x3c050009, 0xc002403, -0x34a5f010, 0x8001da0, 0x0, 0x3c040001, -0x248453a8, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac, -0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20124, -0x24420001, 0xaee20124, 0x8001f97, 0x8ee20124, -0x27440212, 0xc0022fe, 0x24050006, 0x3049001f, -0x928c0, 0x2e51021, 0x9442727c, 0x30428000, -0x1040002f, 0x2e51021, 0x9442727c, 0x30424000, -0x1440001c, 0xb71021, 0x9443727e, 0x97420212, -0x14620018, 0xb71021, 0x8c437280, 0x8f420214, -0x54620016, 0xafa20010, 0x92e204d8, 0x10400007, -0x24020001, 0x8ee304dc, 0x1221004, 0x21027, -0x621824, 0x8001dc9, 0xaee304dc, 0x8f830228, -0x1221004, 0x21027, 0x621824, 0xaf830228, -0x910c0, 0x2e21821, 0x3402c000, 0x8001e4e, -0xa462727c, 0x8f420214, 0xafa20010, 0x910c0, -0x571021, 0x8c42727c, 0x3c040001, 0x248453b4, -0x3c050003, 0xafa20014, 0x8f470210, 0x34a5f01c, -0xc002403, 0x1203021, 0x8001e83, 0x3c020800, -0xb71021, 0x9443727e, 0x97420212, 0x14620019, -0x918c0, 0xb71021, 0x8c437280, 0x8f420214, -0x14620014, 0x918c0, 0x2e51021, 0x9447727c, -0x720c0, 0x971021, 0x9443737e, 0xb71021, -0xa443727e, 0x971021, 0x8c437380, 0xb71021, -0xac437280, 0x2e41021, 0x9443737c, 0x2e51021, -0xa443727c, 0x2e41821, 0x3402c000, 0x8001e4e, -0xa462737c, 0x2e31021, 0x9447727c, 0x3021, -0x720c0, 0x2e41021, 0x9442737c, 0x4021, -0x30428000, 0x14400025, 0xe02821, 0x605021, -0x340bc000, 0x971021, 0x9443737e, 0x97420212, -0x54620015, 0xe02821, 0x971021, 0x8c437380, -0x8f420214, 0x54620010, 0xe02821, 0x11000006, -0x2e41021, 0x9443737c, 0x510c0, 0x2e21021, -0x8001e1a, 0xa443737c, 0x9443737c, 0x2ea1021, -0xa443727c, 0x710c0, 0x2e21021, 0xa44b737c, -0x8001e28, 0x24060001, 0x510c0, 0x2e21021, -0x9447737c, 0x720c0, 0x2e41021, 0x9442737c, -0x30428000, 0x1040ffdf, 0x25080001, 0x30c200ff, -0x14400025, 0x2021, 0x720c0, 0x971021, -0x9443737e, 0x97420212, 0x1462000f, 0x910c0, -0x971021, 0x8c437380, 0x8f420214, 0x1462000a, -0x910c0, 0x2e41821, 0x3402c000, 0x15000015, -0xa462737c, 0x910c0, 0x2e21821, 0x34028000, -0x8001e4e, 0xa462727c, 0x571021, 0x8c42727c, -0x3c040001, 0x248453c0, 0x3c050003, 0xafa20010, -0x710c0, 0x571021, 0x8c42737c, 0x34a5001e, -0x1203021, 0xc002403, 0xafa20014, 0x8001e83, -0x3c020800, 0x2021, 0x428c0, 0xb71021, -0x9443777e, 0x97420212, 0x5462002b, 0x24840001, -0xb71021, 0x8c437780, 0x8f420214, 0x54620026, -0x24840001, 0x3c020001, 0x571021, 0x8c4283b4, -0x2442ffff, 0x3c010001, 0x370821, 0xac2283b4, -0x3c020001, 0x571021, 0x8c4283b4, 0x809021, -0x242102b, 0x1040000e, 0x24b1777c, 0x24b07784, -0x2f02021, 0x2f12821, 0xc002490, 0x24060008, -0x26310008, 0x3c020001, 0x571021, 0x8c4283b4, -0x26520001, 0x242102b, 0x1440fff5, 0x26100008, -0x3c040001, 0x972021, 0x8c8483b4, 0x24050008, -0x420c0, 0x2484777c, 0xc002488, 0x2e42021, -0x8001e83, 0x3c020800, 0x2c820080, 0x1440ffcf, -0x428c0, 0x3c020800, 0x34422000, 0xafa20018, -0x8ee20608, 0x8f430228, 0x24420001, 0x304a00ff, -0x514300fd, 0xafa00010, 0x8ee20608, 0x210c0, -0x571021, 0x8fa30018, 0x8fa4001c, 0xac43060c, -0xac440610, 0x8f830054, 0x8f820054, 0x24690032, -0x1221023, 0x2c420033, 0x1040006a, 0x5821, -0x24100008, 0x240f000d, 0x240d0007, 0x240c0040, -0x240e0001, 0x8f870120, 0x27623800, 0x24e80020, -0x102102b, 0x50400001, 0x27683000, 0x8f820128, -0x11020004, 0x0, 0x8f820124, 0x15020007, -0x1021, 0x8ee201a4, 0x3821, 0x24420001, -0xaee201a4, 0x8001efb, 0x8ee201a4, 0x8ee40608, -0x420c0, 0x801821, 0x8ee40430, 0x8ee50434, -0xa32821, 0xa3302b, 0x822021, 0x862021, -0xace40000, 0xace50004, 0x8ee20608, 0xa4f0000e, -0xacef0018, 0xacea001c, 0x210c0, 0x2442060c, -0x2e21021, 0xace20008, 0x8ee204c4, 0xace20010, -0xaf880120, 0x92e24e20, 0x14400033, 0x24070001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c820000, 0x144d001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x104c0007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8001ee8, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x8001efb, -0x0, 0x8ee24e30, 0x24420001, 0x504c0003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0xac8d0000, 0xac8e0004, 0x54e00006, 0x240b0001, -0x8f820054, 0x1221023, 0x2c420033, 0x1440ff9d, -0x0, 0x316300ff, 0x24020001, 0x54620078, -0xafa00010, 0xaeea0608, 0x8f830054, 0x8f820054, -0x24690032, 0x1221023, 0x2c420033, 0x10400061, -0x5821, 0x240e0008, 0x240d0011, 0x240a0012, -0x24080040, 0x240c0001, 0x8f830120, 0x27623800, -0x24660020, 0xc2102b, 0x50400001, 0x27663000, -0x8f820128, 0x10c20004, 0x0, 0x8f820124, -0x14c20007, 0x0, 0x8ee201a4, 0x3821, -0x24420001, 0xaee201a4, 0x8001f67, 0x8ee201a4, -0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4, -0x2462001c, 0xac620008, 0xa46e000e, 0xac6d0018, -0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, -0xaf860120, 0x92e24e20, 0x14400033, 0x24070001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c820000, 0x144a001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x10480007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8001f54, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x8001f67, -0x0, 0x8ee24e30, 0x24420001, 0x50480003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0xac8a0000, 0xac8c0004, 0x54e00006, 0x240b0001, -0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6, -0x0, 0x316300ff, 0x24020001, 0x10620022, -0x0, 0x3c040001, 0x24845390, 0xafa00010, -0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, -0xc002403, 0x34a5f011, 0x8001f93, 0x0, -0x3c040001, 0x2484539c, 0xafa00014, 0x8f860120, -0x8f870124, 0x3c050009, 0xc002403, 0x34a5f010, -0x8001f93, 0x0, 0x3c040001, 0x248453a8, -0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001, -0xaee201ac, 0x8ee201ac, 0x8ee20128, 0x24420001, -0xaee20128, 0x8ee20128, 0x8ee20164, 0x24420001, -0xaee20164, 0x80022e8, 0x8ee20164, 0x8fa20020, -0x21200, 0x21d02, 0x24020001, 0x10620005, -0x24020002, 0x1062000d, 0x0, 0x8001fb7, -0xafa00010, 0x92e204d8, 0x14400006, 0x24020001, -0x8f820228, 0xaee204dc, 0x2402ffff, 0xaf820228, -0x24020001, 0x8001fbe, 0xa2e204d8, 0x92e204d8, -0x5040000c, 0xa2e004d8, 0x8ee204dc, 0xaf820228, -0x8001fbe, 0xa2e004d8, 0x3c040001, 0x248453c8, -0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403, -0x34a5f009, 0x8ee2013c, 0x24420001, 0xaee2013c, -0x80022e8, 0x8ee2013c, 0x8fa20020, 0x21200, -0x22502, 0x24020001, 0x10820005, 0x24020002, -0x1082000f, 0x0, 0x8001fe3, 0xafa00010, -0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, -0x34420008, 0xaf820220, 0x24020001, 0x3c010001, -0x370821, 0xa02283b2, 0x8001fea, 0xaee40108, -0x8f820220, 0x3c0308ff, 0x3463fff7, 0x431024, -0xaf820220, 0x3c010001, 0x370821, 0xa02083b2, -0x8001fea, 0xaee40108, 0x3c040001, 0x248453d4, -0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403, -0x34a5f00a, 0x8ee2012c, 0x24420001, 0xaee2012c, -0x80022e8, 0x8ee2012c, 0x8fa20020, 0x21200, -0x21d02, 0x24020001, 0x10620005, 0x24020002, -0x1062000e, 0x0, 0x8002011, 0xafa00010, -0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, -0x34420008, 0xaf820220, 0x24020001, 0x3c010001, -0x370821, 0x8002018, 0xa02283b3, 0x3c020001, -0x571021, 0x904283b2, 0x3c010001, 0x370821, -0x1440000e, 0xa02083b3, 0x8f820220, 0x3c0308ff, -0x3463fff7, 0x431024, 0x8002018, 0xaf820220, -0x3c040001, 0x248453e0, 0xafa00014, 0x8fa60020, -0x3c050003, 0xc002403, 0x34a5f00b, 0x8ee20114, -0x24420001, 0xaee20114, 0x80022e8, 0x8ee20114, -0x27840208, 0x27450200, 0xc00249a, 0x24060008, -0x26e40094, 0x27450200, 0xc00249a, 0x24060008, -0x8ee20134, 0x24420001, 0xaee20134, 0x80022e8, -0x8ee20134, 0x8f460248, 0x2021, 0xc005108, -0x24050004, 0x8ee20130, 0x24420001, 0xaee20130, -0x80022e8, 0x8ee20130, 0x8ef301cc, 0x8ef401d0, -0x8ef501d8, 0x8ee20140, 0x26e40030, 0x24420001, -0xaee20140, 0x8ef00140, 0x8ef10074, 0x8ef20070, -0xc002488, 0x24050400, 0xaef301cc, 0xaef401d0, -0xaef501d8, 0xaef00140, 0xaef10074, 0xaef20070, -0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260, -0x27450200, 0x24060008, 0xaee20068, 0x24020006, -0xc00249a, 0xaee20064, 0x3c023b9a, 0x3442ca00, -0xaee2006c, 0x240203e8, 0x24040002, 0x24030001, -0xaee20104, 0xaee40100, 0xaee3010c, 0x8f820220, -0x30420008, 0x10400004, 0x0, 0xaee30108, -0x8002061, 0x2021, 0xaee40108, 0x2021, -0x3c030001, 0x641821, 0x90635c30, 0x2e41021, -0x24840001, 0xa043009c, 0x2c82000f, 0x1440fff8, -0x0, 0x8f820040, 0x2e41821, 0x24840001, -0x21702, 0x24420030, 0xa062009c, 0x2e41021, -0x80022e8, 0xa040009c, 0x24020001, 0x3c010001, -0x370821, 0xa02283e0, 0x240b0400, 0x24080014, -0x240a0040, 0x24090001, 0x8f830100, 0x27623000, -0x24660020, 0xc2102b, 0x50400001, 0x27662800, -0x8f820108, 0x10c20004, 0x0, 0x8f820104, -0x14c20007, 0x26e20030, 0x8ee201a8, 0x3821, -0x24420001, 0xaee201a8, 0x80020a8, 0x8ee201a8, -0x8ee404b8, 0x8ee504bc, 0xac620008, 0xa46b000e, -0xac680018, 0xac60001c, 0xac640000, 0xac650004, -0x8ee204cc, 0xac620010, 0xaf860100, 0x92e204ec, -0x1440000e, 0x24070001, 0x8ee24e28, 0x24420001, -0x504a0003, 0x1021, 0x8ee24e28, 0x24420001, -0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, -0x2e21021, 0xac480000, 0xac490004, 0x10e0ffd2, -0x0, 0x80022e8, 0x0, 0x3c020900, -0xaee05238, 0xaee0523c, 0xaee05240, 0xaee05244, -0xaee001d0, 0x3c010001, 0x370821, 0xa02083b1, -0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001, -0x304a00ff, 0x514300fd, 0xafa00010, 0x8ee20608, -0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c, -0xac43060c, 0xac440610, 0x8f830054, 0x8f820054, -0x24690032, 0x1221023, 0x2c420033, 0x1040006a, -0x5821, 0x24100008, 0x240f000d, 0x240d0007, -0x240c0040, 0x240e0001, 0x8f870120, 0x27623800, -0x24e80020, 0x102102b, 0x50400001, 0x27683000, -0x8f820128, 0x11020004, 0x0, 0x8f820124, -0x15020007, 0x1021, 0x8ee201a4, 0x3821, -0x24420001, 0xaee201a4, 0x800212c, 0x8ee201a4, -0x8ee40608, 0x420c0, 0x801821, 0x8ee40430, -0x8ee50434, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xace40000, 0xace50004, 0x8ee20608, -0xa4f0000e, 0xacef0018, 0xacea001c, 0x210c0, -0x2442060c, 0x2e21021, 0xace20008, 0x8ee204c4, -0xace20010, 0xaf880120, 0x92e24e20, 0x14400033, -0x24070001, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c820000, 0x144d001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee34e30, 0x24420001, 0x104c0007, 0x0, -0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x8002119, 0x0, 0x14600005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400010, 0xac800000, -0x800212c, 0x0, 0x8ee24e30, 0x24420001, -0x504c0003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0xac8d0000, 0xac8e0004, 0x54e00006, -0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, -0x1440ff9d, 0x0, 0x316300ff, 0x24020001, -0x54620078, 0xafa00010, 0xaeea0608, 0x8f830054, -0x8f820054, 0x24690032, 0x1221023, 0x2c420033, -0x10400061, 0x5821, 0x240e0008, 0x240d0011, -0x240a0012, 0x24080040, 0x240c0001, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x3821, 0x24420001, 0xaee201a4, 0x8002198, -0x8ee201a4, 0x8ee20608, 0xac62001c, 0x8ee404a0, -0x8ee504a4, 0x2462001c, 0xac620008, 0xa46e000e, -0xac6d0018, 0xac640000, 0xac650004, 0x8ee204c4, -0xac620010, 0xaf860120, 0x92e24e20, 0x14400033, -0x24070001, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c820000, 0x144a001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee34e30, 0x24420001, 0x10480007, 0x0, -0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x8002185, 0x0, 0x14600005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400010, 0xac800000, -0x8002198, 0x0, 0x8ee24e30, 0x24420001, -0x50480003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006, -0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, -0x1440ffa6, 0x0, 0x316300ff, 0x24020001, -0x10620022, 0x0, 0x3c040001, 0x24845390, -0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, -0x3c050009, 0xc002403, 0x34a5f011, 0x80021c4, -0x0, 0x3c040001, 0x2484539c, 0xafa00014, -0x8f860120, 0x8f870124, 0x3c050009, 0xc002403, -0x34a5f010, 0x80021c4, 0x0, 0x3c040001, -0x248453a8, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac, -0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20120, -0x24420001, 0xaee20120, 0x8ee20120, 0x8ee20168, -0x24420001, 0xaee20168, 0x80022e8, 0x8ee20168, -0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260, -0x27450200, 0x24060008, 0xc00249a, 0xaee20068, -0x8f820220, 0x30420008, 0x14400002, 0x24020001, -0x24020002, 0xaee20108, 0x8ee2011c, 0x24420001, -0xaee2011c, 0x80022e8, 0x8ee2011c, 0x3c040001, -0x248453ec, 0xafa00010, 0xafa00014, 0x8fa60020, -0x3c050003, 0xc002403, 0x34a5f00f, 0x93a20020, -0x3c030700, 0x34631000, 0x431025, 0xafa20018, -0x8ee20608, 0x8f430228, 0x24420001, 0x304900ff, -0x512300e2, 0xafa00010, 0x8ee20608, 0x210c0, -0x571021, 0x8fa30018, 0x8fa4001c, 0xac43060c, -0xac440610, 0x8f870120, 0x27623800, 0x24e80020, -0x102102b, 0x50400001, 0x27683000, 0x8f820128, -0x11020004, 0x0, 0x8f820124, 0x15020007, -0x1021, 0x8ee201a4, 0x3821, 0x24420001, -0xaee201a4, 0x800225d, 0x8ee201a4, 0x8ee40608, -0x420c0, 0x801821, 0x8ee40430, 0x8ee50434, -0xa32821, 0xa3302b, 0x822021, 0x862021, -0xace40000, 0xace50004, 0x8ee30608, 0x24020008, -0xa4e2000e, 0x2402000d, 0xace20018, 0xace9001c, -0x318c0, 0x2463060c, 0x2e31021, 0xace20008, -0x8ee204c4, 0xace20010, 0xaf880120, 0x92e24e20, -0x14400037, 0x24070001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c830000, 0x24020007, -0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34, -0x1062001b, 0x24030040, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001, -0x10430007, 0x0, 0x8ee24e34, 0x24420001, -0x10a20005, 0x0, 0x8002247, 0x0, -0x14a00005, 0x0, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400013, 0xac800000, 0x800225d, 0x0, -0x8ee24e30, 0x24030040, 0x24420001, 0x50430003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x24020007, 0xac820000, 0x24020001, 0xac820004, -0x54e0000c, 0xaee90608, 0x3c040001, 0x248453f4, -0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002403, 0x34a5f000, 0x80022e0, -0x0, 0x8f830120, 0x27623800, 0x24660020, -0xc2102b, 0x50400001, 0x27663000, 0x8f820128, -0x10c20004, 0x0, 0x8f820124, 0x14c20007, -0x0, 0x8ee201a4, 0x3821, 0x24420001, -0xaee201a4, 0x80022c4, 0x8ee201a4, 0x8ee20608, -0xac62001c, 0x8ee404a0, 0x8ee504a4, 0x2462001c, -0xac620008, 0x24020008, 0xa462000e, 0x24020011, -0xac620018, 0xac640000, 0xac650004, 0x8ee204c4, -0xac620010, 0xaf860120, 0x92e24e20, 0x14400037, -0x24070001, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c830000, 0x24020012, 0x1462001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x24030040, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee54e30, 0x24420001, 0x10430007, -0x0, 0x8ee24e34, 0x24420001, 0x10a20005, -0x0, 0x80022ae, 0x0, 0x14a00005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, -0xac800000, 0x80022c4, 0x0, 0x8ee24e30, -0x24030040, 0x24420001, 0x50430003, 0x1021, -0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x24020012, -0xac820000, 0x24020001, 0xac820004, 0x14e0001b, -0x0, 0x3c040001, 0x248453fc, 0xafa00010, -0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009, -0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001, -0xaee201b0, 0x80022e0, 0x8ee201b0, 0x3c040001, -0x24845408, 0xafa00014, 0x8ee60608, 0x8f470228, -0x3c050009, 0xc002403, 0x34a5f005, 0x8ee201ac, -0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20150, -0x24420001, 0xaee20150, 0x8ee20150, 0x8ee20160, -0x24420001, 0xaee20160, 0x8ee20160, 0x8f43022c, -0x8f42010c, 0x14620009, 0x24020002, 0xaf820064, -0x8f820064, 0x14400005, 0x0, 0x8f43022c, -0x8f42010c, 0x1462f875, 0x0, 0x8fbf0044, -0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034, -0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x3e00008, -0x27bd0048, 0x27bdfff8, 0x2408ffff, 0x10a00014, -0x4821, 0x3c0aedb8, 0x354a8320, 0x90870000, -0x24840001, 0x3021, 0x1071026, 0x30420001, -0x10400002, 0x81842, 0x6a1826, 0x604021, -0x24c60001, 0x2cc20008, 0x1440fff7, 0x73842, -0x25290001, 0x125102b, 0x1440fff0, 0x0, -0x1001021, 0x3e00008, 0x27bd0008, 0x27bdffe8, -0x27642800, 0xafbf0010, 0xc002488, 0x24051000, -0x24020021, 0xaf800100, 0xaf800104, 0xaf800108, -0xaf800110, 0xaf800114, 0xaf800118, 0xaf800120, -0xaf800124, 0xaf800128, 0xaf800130, 0xaf800134, -0xaf800138, 0xaee04e28, 0xaee04e2c, 0xaee04e30, -0xaee04e34, 0xaf82011c, 0x8f420218, 0x30420040, -0x10400004, 0x0, 0x8f82011c, 0x34420004, -0xaf82011c, 0x8fbf0010, 0x3e00008, 0x27bd0018, -0x27bdffe0, 0xafbf0018, 0x8f820104, 0xafa20010, -0x8f820100, 0x3c050002, 0xafa20014, 0x8f8600b0, -0x8f87011c, 0x3c040001, 0x248454c0, 0xc002403, -0x34a5f000, 0x8f8300b0, 0x3c027f00, 0x621824, -0x3c020400, 0x10620029, 0x43102b, 0x14400008, -0x3c022000, 0x3c020100, 0x10620024, 0x3c020200, -0x10620011, 0x0, 0x8002374, 0x0, -0x10620008, 0x3c024000, 0x1462001c, 0x0, -0x8ee20190, 0x24420001, 0xaee20190, 0x8002374, -0x8ee20190, 0x8ee2018c, 0x24420001, 0xaee2018c, -0x8002374, 0x8ee2018c, 0x8f82011c, 0x34420002, -0xaf82011c, 0x8f830104, 0x8f8200b0, 0x34420001, -0xaf8200b0, 0xaf830104, 0x8f82011c, 0x2403fffd, -0x431024, 0xaf82011c, 0x8ee201a0, 0x24420001, -0xaee201a0, 0x8002377, 0x8ee201a0, 0x8f8200b0, -0x34420001, 0xaf8200b0, 0x8fbf0018, 0x3e00008, -0x27bd0020, 0x27bdffe0, 0xafbf001c, 0xafb00018, -0x8f820120, 0xafa20010, 0x8f820124, 0x3c050001, -0xafa20014, 0x8f8600a0, 0x8f87011c, 0x3c040001, -0x248454cc, 0xc002403, 0x34a5f000, 0x8f8300a0, -0x3c027f00, 0x621824, 0x3c020400, 0x10620053, -0x8021, 0x43102b, 0x14400008, 0x3c042000, -0x3c020100, 0x1062004d, 0x3c020200, 0x1062003a, -0x0, 0x80023e0, 0x0, 0x10640003, -0x3c024000, 0x14620045, 0x0, 0x8f8200a0, -0x441024, 0x10400006, 0x0, 0x8ee20194, -0x24420001, 0xaee20194, 0x80023a9, 0x8ee20194, -0x8ee20198, 0x24420001, 0xaee20198, 0x8ee20198, -0x8f82011c, 0x34420002, 0xaf82011c, 0x8f82011c, -0x30420200, 0x1040001b, 0x0, 0x8f8300a0, -0x8f840124, 0x8f8200ac, 0x14400007, 0x24020001, -0x3c020001, 0x3442f000, 0x621024, 0x50400001, -0x24100001, 0x24020001, 0x1200000d, 0xaf8200a0, -0x8f820124, 0x2442ffe0, 0xaf820124, 0x8f820124, -0x8f820124, 0x27633000, 0x43102b, 0x10400005, -0x276237e0, 0xaf820124, 0x80023ca, 0x0, -0xaf840124, 0x8f82011c, 0x2403fffd, 0x431024, -0x80023e3, 0xaf82011c, 0x8f82011c, 0x34420002, -0xaf82011c, 0x8f830124, 0x8f8200a0, 0x34420001, -0xaf8200a0, 0xaf830124, 0x8f82011c, 0x2403fffd, -0x431024, 0xaf82011c, 0x8ee2019c, 0x24420001, -0xaee2019c, 0x80023e3, 0x8ee2019c, 0x8f8200a0, -0x34420001, 0xaf8200a0, 0x8fbf001c, 0x8fb00018, -0x3e00008, 0x27bd0020, 0x0, 0x3c020001, -0x8c425c58, 0x27bdffe8, 0xafbf0014, 0x14400012, -0xafb00010, 0x3c100001, 0x26105dd0, 0x2002021, -0xc002488, 0x24052000, 0x26021fe0, 0x3c010001, -0xac225d94, 0x3c010001, 0xac225d90, 0xaf420250, -0x24022000, 0xaf500254, 0xaf420258, 0x24020001, -0x3c010001, 0xac225c58, 0x8fbf0014, 0x8fb00010, -0x3e00008, 0x27bd0018, 0x3c030001, 0x8c635d94, -0x8c820000, 0x8fa80010, 0x8fa90014, 0xac620000, -0x3c020001, 0x8c425d94, 0x8c830004, 0xac430004, -0xac450008, 0x8f840054, 0x2443ffe0, 0xac460010, -0xac470014, 0xac480018, 0xac49001c, 0x3c010001, -0xac235d94, 0xac44000c, 0x3c020001, 0x24425dd0, -0x62182b, 0x10600005, 0x0, 0x3c020001, -0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001, -0x8c635d94, 0x3c020001, 0x8c425c40, 0xac620000, -0x3c030001, 0x8c635d94, 0x3c020001, 0x8c425c40, -0xac620004, 0x3e00008, 0xaf430250, 0x3c030001, -0x8c635d94, 0x3c020001, 0x8c425c40, 0x27bdffd0, -0xafb40020, 0x8fb40040, 0xafb00010, 0x808021, -0xafb50024, 0x8fb50044, 0x8fa40048, 0xafb10014, -0xa08821, 0xafbf0028, 0xafb3001c, 0xafb20018, -0xac620000, 0x3c050001, 0x8ca55d94, 0x3c020001, -0x8c425c40, 0xc09021, 0xe09821, 0x10800006, -0xaca20004, 0x24a50008, 0xc002490, 0x24060018, -0x800244e, 0x0, 0x24a40008, 0xc002488, -0x24050018, 0x3c020001, 0x8c425d94, 0x3c050001, -0x24a55dd0, 0x2442ffe0, 0x3c010001, 0xac225d94, -0x45102b, 0x10400005, 0x0, 0x3c020001, -0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001, -0x8c635d94, 0x8e020000, 0xac620000, 0x3c030001, -0x8c635d94, 0x8e020004, 0xac620004, 0xac710008, -0x8f840054, 0x2462ffe0, 0x3c010001, 0xac225d94, -0x45102b, 0xac720010, 0xac730014, 0xac740018, -0xac75001c, 0x10400005, 0xac64000c, 0x3c020001, -0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001, -0x8c635d94, 0x3c020001, 0x8c425c40, 0xac620000, -0x3c030001, 0x8c635d94, 0x3c020001, 0x8c425c40, -0xac620004, 0xaf430250, 0x8fbf0028, 0x8fb50024, -0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, -0x8fb00010, 0x3e00008, 0x27bd0030, 0x10a00005, -0x0, 0xac800000, 0x24a5fffc, 0x14a0fffd, -0x24840004, 0x3e00008, 0x0, 0x10c00007, -0x0, 0x8c820000, 0x24840004, 0x24c6fffc, -0xaca20000, 0x14c0fffb, 0x24a50004, 0x3e00008, -0x0, 0x10c00007, 0x0, 0x8ca20000, -0x24a50004, 0x24c6fffc, 0xac820000, 0x14c0fffb, -0x24840004, 0x3e00008, 0x0, 0x3e00008, -0x0, 0x27bdffd8, 0xafbf0020, 0x8ee304e4, -0x8ee204e0, 0x10620436, 0x0, 0x8ee204e4, -0x8ee304fc, 0x21100, 0x626021, 0x95870008, -0x8d8a0000, 0x8d8b0004, 0x958d000a, 0x8ee2725c, -0x8ee3726c, 0x30e4ffff, 0x441021, 0x62182b, -0x10600015, 0x31a20004, 0x8f8200d8, 0x8ee37258, -0x431023, 0xaee2726c, 0x8ee2726c, 0x1c400003, -0x3c030001, 0x431021, 0xaee2726c, 0x8ee2725c, -0x8ee3726c, 0x441021, 0x62182b, 0x10600006, -0x31a20004, 0x8ee201b8, 0x24420001, 0xaee201b8, -0x80028e1, 0x8ee201b8, 0x10400240, 0x31a20200, -0x1040014d, 0x4821, 0x96e2045a, 0x30420010, -0x10400149, 0x0, 0x8f840100, 0x27623000, -0x24850020, 0xa2102b, 0x50400001, 0x27652800, -0x8f820108, 0x10a20004, 0x0, 0x8f820104, -0x14a20006, 0x2402000c, 0x8ee201a8, 0x24420001, -0xaee201a8, 0x800252c, 0x8ee201a8, 0xac8a0000, -0xac8b0004, 0x8ee37264, 0x24060005, 0xa482000e, -0xac860018, 0xac830008, 0x8ee204e4, 0xac82001c, -0x8ee204c8, 0xac820010, 0xaf850100, 0x92e204ec, -0x14400036, 0x24090001, 0x8ee24e28, 0x210c0, -0x24424e38, 0x2e22021, 0x8c820000, 0x1446001f, -0x0, 0x8ee34e28, 0x8ee24e2c, 0x1062001b, -0x24030040, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, -0x0, 0x8ee24e2c, 0x24420001, 0x10a20005, -0x0, 0x8002516, 0x0, 0x14a00005, -0x0, 0x8f820108, 0x24420020, 0xaf820108, -0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, -0xac800000, 0x800252c, 0x0, 0x8ee24e28, -0x24030040, 0x24420001, 0x50430003, 0x1021, -0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, -0x210c0, 0x24424e38, 0x2e22021, 0x24020005, -0xac820000, 0x24020001, 0xac820004, 0x1520000a, -0x3c040001, 0xafab0010, 0x8ee27264, 0x3c040001, -0x24845730, 0x3c050004, 0xafa20014, 0x8ee604e4, -0x80028be, 0x34a5f114, 0x8ee27264, 0x34843800, -0x3641821, 0x24420010, 0x43102b, 0x14400073, -0x0, 0x8ee27264, 0x24480010, 0x3641021, -0x102102b, 0x14400002, 0x3c02ffff, 0x1024021, -0x8f850100, 0x27623000, 0x24a60020, 0xc2102b, -0x50400001, 0x27662800, 0x8f820108, 0x10c20004, -0x0, 0x8f820104, 0x14c20007, 0x2563000c, -0x8ee201a8, 0x4821, 0x24420001, 0xaee201a8, -0x80025a0, 0x8ee201a8, 0x2c64000c, 0x1441021, -0xaca20000, 0xaca30004, 0x24e2fff4, 0xa4a2000e, -0x24020006, 0xaca80008, 0xaca20018, 0x8ee204e4, -0xaca2001c, 0x8ee204c8, 0x3c030002, 0x431025, -0xaca20010, 0xaf860100, 0x92e204ec, 0x14400037, -0x24090001, 0x8ee24e28, 0x210c0, 0x24424e38, -0x2e22021, 0x8c830000, 0x24020005, 0x1462001f, -0x0, 0x8ee34e28, 0x8ee24e2c, 0x1062001b, -0x24030040, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007, -0x0, 0x8ee24e2c, 0x24420001, 0x10a20005, -0x0, 0x800258a, 0x0, 0x14a00005, -0x0, 0x8f820108, 0x24420020, 0xaf820108, -0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, -0xac800000, 0x80025a0, 0x0, 0x8ee24e28, -0x24030040, 0x24420001, 0x50430003, 0x1021, -0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28, -0x210c0, 0x24424e38, 0x2e22021, 0x24020005, -0xac820000, 0x24020001, 0xac820004, 0x1520000a, -0x2508fffc, 0xafab0010, 0x8ee27264, 0x3c040001, -0x24845730, 0x3c050004, 0xafa20014, 0x8ee604e4, -0x80028be, 0x34a5f125, 0x34028100, 0xa5020000, -0x9582000e, 0x800261d, 0xa5020002, 0x8f850100, -0x27623000, 0x24a60020, 0xc2102b, 0x50400001, -0x27662800, 0x8f820108, 0x10c20004, 0x0, -0x8f820104, 0x14c20007, 0x2563000c, 0x8ee201a8, -0x4821, 0x24420001, 0xaee201a8, 0x800260d, -0x8ee201a8, 0x2c64000c, 0x1441021, 0xaca20000, -0xaca30004, 0x8ee37264, 0x24e2fff4, 0xa4a2000e, -0x24020006, 0xaca20018, 0x24630010, 0xaca30008, -0x8ee204e4, 0xaca2001c, 0x8ee204c8, 0x3c030002, -0x431025, 0xaca20010, 0xaf860100, 0x92e204ec, -0x14400037, 0x24090001, 0x8ee24e28, 0x210c0, -0x24424e38, 0x2e22021, 0x8c830000, 0x24020005, -0x1462001f, 0x0, 0x8ee34e28, 0x8ee24e2c, -0x1062001b, 0x24030040, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001, -0x10430007, 0x0, 0x8ee24e2c, 0x24420001, -0x10a20005, 0x0, 0x80025f7, 0x0, -0x14a00005, 0x0, 0x8f820108, 0x24420020, -0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, -0x50400013, 0xac800000, 0x800260d, 0x0, -0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, -0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, -0x24020005, 0xac820000, 0x24020001, 0xac820004, -0x1520000a, 0x34028100, 0xafab0010, 0x8ee27264, -0x3c040001, 0x24845730, 0x3c050004, 0xafa20014, -0x8ee604e4, 0x80028be, 0x34a5f015, 0x8ee37264, -0xa462000c, 0x8ee37264, 0x9582000e, 0xa462000e, -0x8002681, 0x24e70004, 0x8f840100, 0x27623000, -0x24850020, 0xa2102b, 0x50400001, 0x27652800, -0x8f820108, 0x10a20004, 0x0, 0x8f820104, -0x14a20007, 0x24020006, 0x8ee201a8, 0x4821, -0x24420001, 0xaee201a8, 0x8002677, 0x8ee201a8, -0xac8a0000, 0xac8b0004, 0x8ee37264, 0xa487000e, -0xac820018, 0xac830008, 0x8ee204e4, 0xac82001c, -0x8ee204c8, 0x3c030002, 0x431025, 0xac820010, -0xaf850100, 0x92e204ec, 0x14400037, 0x24090001, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, -0x8c830000, 0x24020005, 0x1462001f, 0x0, -0x8ee34e28, 0x8ee24e2c, 0x1062001b, 0x24030040, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, -0x8ee54e28, 0x24420001, 0x10430007, 0x0, -0x8ee24e2c, 0x24420001, 0x10a20005, 0x0, -0x8002661, 0x0, 0x14a00005, 0x0, -0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x8002677, 0x0, 0x8ee24e28, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e28, -0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, -0x24424e38, 0x2e22021, 0x24020005, 0xac820000, -0x24020001, 0xac820004, 0x15200009, 0x3c050004, -0xafab0010, 0x8ee27264, 0x3c040001, 0x24845730, -0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f004, -0x8ee2725c, 0x30e7ffff, 0x471021, 0xaee2725c, -0x8ee204e4, 0x8ee304fc, 0x8ee47258, 0x21100, -0x431021, 0xac44000c, 0x8ee27258, 0xafa20018, -0x8ee3725c, 0xafa3001c, 0x8ee2725c, 0x2c42003c, -0x10400004, 0x24620001, 0x2403fffe, 0x431024, -0xafa2001c, 0x8ee27264, 0x3c060001, 0x34c63800, -0x8ee3725c, 0x2405fff8, 0x471021, 0x24420007, -0x451024, 0x24630007, 0xaee27258, 0x8ee2726c, -0x8ee47258, 0x651824, 0x431023, 0xaee2726c, -0x3661021, 0x82202b, 0x14800004, 0x3c03ffff, -0x8ee27258, 0x431021, 0xaee27258, 0x8ee27258, -0xaee27264, 0x8f8200f0, 0x24470008, 0x27621800, -0xe2102b, 0x50400001, 0x27671000, 0x8f8200f4, -0x14e20007, 0x0, 0x8ee201b4, 0x4821, -0x24420001, 0xaee201b4, 0x80026c4, 0x8ee201b4, -0x8f8200f0, 0x24090001, 0x8fa30018, 0x8fa4001c, -0xac430000, 0xac440004, 0xaf8700f0, 0x15200012, -0xd1142, 0x8f8200f0, 0xafa20010, 0x8f8200f4, -0x3c040001, 0x2484573c, 0xafa20014, 0x8fa60018, -0x8fa7001c, 0x3c050004, 0xc002403, 0x34a5f005, -0x8ee20088, 0x24420001, 0xaee20088, 0x8ee20088, -0x80028d3, 0xaee0725c, 0x30430003, 0x24020002, -0x10620016, 0x28620003, 0x10400005, 0x24020001, -0x10620008, 0x0, 0x8002703, 0x0, -0x24020003, 0x10620017, 0x0, 0x8002703, -0x0, 0x8ee200e8, 0x8ee300ec, 0x24630001, -0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec, -0x8ee200e8, 0x8002703, 0x8ee300ec, 0x8ee200f0, -0x8ee300f4, 0x24630001, 0x2c640001, 0x441021, -0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002703, -0x8ee300f4, 0x8ee200f8, 0x8ee300fc, 0x24630001, -0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc, -0x8ee200f8, 0x8ee300fc, 0x8ee2725c, 0x8ee400e0, -0x8ee500e4, 0x401821, 0x1021, 0xa32821, -0xa3302b, 0x822021, 0x862021, 0xaee400e0, -0xaee500e4, 0x80028d3, 0xaee0725c, 0x30e2ffff, -0x104001c1, 0x31a20200, 0x1040014d, 0x4821, -0x96e2045a, 0x30420010, 0x10400149, 0x0, -0x8f840100, 0x27623000, 0x24850020, 0xa2102b, -0x50400001, 0x27652800, 0x8f820108, 0x10a20004, -0x0, 0x8f820104, 0x14a20006, 0x2402000c, -0x8ee201a8, 0x24420001, 0xaee201a8, 0x800276e, -0x8ee201a8, 0xac8a0000, 0xac8b0004, 0x8ee37264, -0x24060005, 0xa482000e, 0xac860018, 0xac830008, -0x8ee204e4, 0xac82001c, 0x8ee204c8, 0xac820010, -0xaf850100, 0x92e204ec, 0x14400036, 0x24090001, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, -0x8c820000, 0x1446001f, 0x0, 0x8ee34e28, -0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, -0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x8002758, -0x0, 0x14a00005, 0x0, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x800276e, -0x0, 0x8ee24e28, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e28, 0x24420001, -0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, -0x2e22021, 0x24020005, 0xac820000, 0x24020001, -0xac820004, 0x1520000a, 0x3c040001, 0xafab0010, -0x8ee27264, 0x3c040001, 0x24845730, 0x3c050004, -0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f014, -0x8ee27264, 0x34843800, 0x3641821, 0x24420010, -0x43102b, 0x14400073, 0x0, 0x8ee27264, -0x24480010, 0x3641021, 0x102102b, 0x14400002, -0x3c02ffff, 0x1024021, 0x8f850100, 0x27623000, -0x24a60020, 0xc2102b, 0x50400001, 0x27662800, -0x8f820108, 0x10c20004, 0x0, 0x8f820104, -0x14c20007, 0x2563000c, 0x8ee201a8, 0x4821, -0x24420001, 0xaee201a8, 0x80027e2, 0x8ee201a8, -0x2c64000c, 0x1441021, 0xaca20000, 0xaca30004, -0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca80008, -0xaca20018, 0x8ee204e4, 0xaca2001c, 0x8ee204c8, -0x3c030002, 0x431025, 0xaca20010, 0xaf860100, -0x92e204ec, 0x14400037, 0x24090001, 0x8ee24e28, -0x210c0, 0x24424e38, 0x2e22021, 0x8c830000, -0x24020005, 0x1462001f, 0x0, 0x8ee34e28, -0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, -0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x80027cc, -0x0, 0x14a00005, 0x0, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x80027e2, -0x0, 0x8ee24e28, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e28, 0x24420001, -0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, -0x2e22021, 0x24020005, 0xac820000, 0x24020001, -0xac820004, 0x1520000a, 0x2508fffc, 0xafab0010, -0x8ee27264, 0x3c040001, 0x24845730, 0x3c050004, -0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f015, -0x34028100, 0xa5020000, 0x9582000e, 0x800285f, -0xa5020002, 0x8f850100, 0x27623000, 0x24a60020, -0xc2102b, 0x50400001, 0x27662800, 0x8f820108, -0x10c20004, 0x0, 0x8f820104, 0x14c20007, -0x2563000c, 0x8ee201a8, 0x4821, 0x24420001, -0xaee201a8, 0x800284f, 0x8ee201a8, 0x2c64000c, -0x1441021, 0xaca20000, 0xaca30004, 0x8ee37264, -0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca20018, -0x24630010, 0xaca30008, 0x8ee204e4, 0xaca2001c, -0x8ee204c8, 0x3c030002, 0x431025, 0xaca20010, -0xaf860100, 0x92e204ec, 0x14400037, 0x24090001, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, -0x8c830000, 0x24020005, 0x1462001f, 0x0, -0x8ee34e28, 0x8ee24e2c, 0x1062001b, 0x24030040, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, -0x8ee54e28, 0x24420001, 0x10430007, 0x0, -0x8ee24e2c, 0x24420001, 0x10a20005, 0x0, -0x8002839, 0x0, 0x14a00005, 0x0, -0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x800284f, 0x0, 0x8ee24e28, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e28, -0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, -0x24424e38, 0x2e22021, 0x24020005, 0xac820000, -0x24020001, 0xac820004, 0x1520000a, 0x34028100, -0xafab0010, 0x8ee27264, 0x3c040001, 0x24845730, -0x3c050004, 0xafa20014, 0x8ee604e4, 0x80028be, -0x34a5f016, 0x8ee37264, 0xa462000c, 0x8ee37264, -0x9582000e, 0xa462000e, 0x80028c2, 0x24e70004, -0x8f830100, 0x27623000, 0x24640020, 0x82102b, -0x50400001, 0x27642800, 0x8f820108, 0x10820004, -0x0, 0x8f820104, 0x14820007, 0x24050005, -0x8ee201a8, 0x4821, 0x24420001, 0xaee201a8, -0x80028b6, 0x8ee201a8, 0xac6a0000, 0xac6b0004, -0x8ee27264, 0xa467000e, 0xac650018, 0xac620008, -0x8ee204e4, 0xac62001c, 0x8ee204c8, 0xac620010, -0xaf840100, 0x92e204ec, 0x14400036, 0x24090001, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, -0x8c820000, 0x1445001f, 0x0, 0x8ee34e28, -0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, -0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x80028a0, -0x0, 0x14a00005, 0x0, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x80028b6, -0x0, 0x8ee24e28, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e28, 0x24420001, -0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, -0x2e22021, 0x24020005, 0xac820000, 0x24020001, -0xac820004, 0x1520000b, 0x3c050004, 0x3c040001, -0x24845748, 0xafab0010, 0xafa00014, 0x8ee604e4, -0x34a5f017, 0xc002403, 0x30e7ffff, 0x80028e1, -0x0, 0x8ee27264, 0x3c050001, 0x30e4ffff, -0x441021, 0xaee27264, 0x8ee2725c, 0x8ee37264, -0x34a53800, 0x441021, 0xaee2725c, 0x3651021, -0x62182b, 0x14600004, 0x3c03ffff, 0x8ee27264, -0x431021, 0xaee27264, 0x8ee304e4, 0x96e20458, -0x24630001, 0x2442ffff, 0x621824, 0xaee304e4, -0x8ee304e4, 0x8ee204e0, 0x14620005, 0x0, -0x8f820060, 0x2403fff7, 0x431024, 0xaf820060, -0x8fbf0020, 0x3e00008, 0x27bd0028, 0x27bdffe0, -0xafbf0018, 0x8ee304e8, 0x8ee204e0, 0x10620189, -0x0, 0x8ee204e8, 0x8ee304fc, 0x21100, -0x621821, 0x94670008, 0x92e204ed, 0x8c680000, -0x8c690004, 0x10400023, 0x946a000a, 0x8ee204c8, -0x34460400, 0x31420200, 0x1040001f, 0x0, -0x96e2045a, 0x30420010, 0x1040001b, 0x3c028000, -0x3c010001, 0x370821, 0xac2283d8, 0x8ee27264, -0x9464000e, 0x3c050001, 0x34a53800, 0x24420004, -0xaee27264, 0x8ee37264, 0x42400, 0x3651021, -0x3c010001, 0x370821, 0xac2483dc, 0x62182b, -0x14600005, 0x24e70004, 0x8ee27264, 0x3c03ffff, -0x431021, 0xaee27264, 0x8ee27264, 0x8002917, -0xaee27258, 0x8ee604c8, 0x8ee2726c, 0x30e4ffff, -0x44102a, 0x10400015, 0x0, 0x8f8200d8, -0x8ee37258, 0x431023, 0xaee2726c, 0x8ee2726c, -0x1c400007, 0x44102a, 0x8ee2726c, 0x3c030001, -0x431021, 0xaee2726c, 0x8ee2726c, 0x44102a, -0x10400006, 0x0, 0x8ee201b8, 0x24420001, -0xaee201b8, 0x8002a72, 0x8ee201b8, 0x3c020001, -0x571021, 0x8c4283d8, 0x54400001, 0x24e7fffc, -0x31420004, 0x104000b9, 0x30e2ffff, 0x3c020001, -0x571021, 0x8c4283d8, 0x1040002f, 0x5021, -0x8f840100, 0x27623000, 0x24850020, 0xa2102b, -0x50400001, 0x27652800, 0x8f820108, 0x10a20032, -0x0, 0x8f820104, 0x10a2002f, 0x24020015, -0xac880000, 0xac890004, 0x8ee37264, 0xa487000e, -0xac820018, 0xac830008, 0x8ee204e8, 0x3c030001, -0x771821, 0x8c6383dc, 0xac860010, 0x431025, -0xac82001c, 0xaf850100, 0x92e204ec, 0x14400066, -0x240a0001, 0x8ee24e28, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e28, 0x24420001, -0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, -0x2e21821, 0x24020015, 0xac620000, 0x24020001, -0x80029bf, 0xac620004, 0x8f840100, 0x27623000, -0x24850020, 0xa2102b, 0x50400001, 0x27652800, -0x8f820108, 0x10a20004, 0x0, 0x8f820104, -0x14a20006, 0x24020006, 0x8ee201a8, 0x24420001, -0xaee201a8, 0x80029bf, 0x8ee201a8, 0xac880000, -0xac890004, 0x8ee37264, 0xa487000e, 0xac820018, -0xac830008, 0x8ee204e8, 0xac860010, 0xac82001c, -0xaf850100, 0x92e204ec, 0x14400037, 0x240a0001, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, -0x8c830000, 0x24020005, 0x1462001f, 0x0, -0x8ee34e28, 0x8ee24e2c, 0x1062001b, 0x24030040, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c, -0x8ee54e28, 0x24420001, 0x10430007, 0x0, -0x8ee24e2c, 0x24420001, 0x10a20005, 0x0, -0x80029a9, 0x0, 0x14a00005, 0x0, -0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x80029bf, 0x0, 0x8ee24e28, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e28, -0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, -0x24424e38, 0x2e22021, 0x24020005, 0xac820000, -0x24020001, 0xac820004, 0x1540000a, 0x24020001, -0xafa90010, 0x8ee27264, 0x3c040001, 0x24845730, -0x3c050004, 0xafa20014, 0x8ee604e4, 0x8002a4f, -0x34a5f204, 0xa2e204ed, 0x8ee204e8, 0x8ee304fc, -0x8ee47258, 0x3c060001, 0x34c63800, 0x3c010001, -0x370821, 0xac2083d8, 0x3c010001, 0x370821, -0xac2083dc, 0x21100, 0x431021, 0xac44000c, -0x8ee27264, 0x2405fff8, 0x30e3ffff, 0x431021, -0x24420007, 0x451024, 0x24630007, 0xaee27258, -0x8ee2726c, 0x8ee47258, 0x651824, 0x431023, -0xaee2726c, 0x3661021, 0x82202b, 0x14800004, -0x3c03ffff, 0x8ee27258, 0x431021, 0xaee27258, -0x8ee27258, 0x8002a64, 0xaee27264, 0x10400073, -0x0, 0x8f830100, 0x27623000, 0x24640020, -0x82102b, 0x14400002, 0x5021, 0x27642800, -0x8f820108, 0x10820004, 0x0, 0x8f820104, -0x14820006, 0x24050005, 0x8ee201a8, 0x24420001, -0xaee201a8, 0x8002a46, 0x8ee201a8, 0xac680000, -0xac690004, 0x8ee27264, 0xa467000e, 0xac650018, -0xac620008, 0x8ee204e8, 0xac660010, 0xac62001c, -0xaf840100, 0x92e204ec, 0x14400036, 0x240a0001, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021, -0x8c820000, 0x1445001f, 0x0, 0x8ee34e28, -0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28, -0x24420001, 0x10430007, 0x0, 0x8ee24e2c, -0x24420001, 0x10a20005, 0x0, 0x8002a30, -0x0, 0x14a00005, 0x0, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8002a46, -0x0, 0x8ee24e28, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e28, 0x24420001, -0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38, -0x2e22021, 0x24020005, 0xac820000, 0x24020001, -0xac820004, 0x1540000c, 0x30e5ffff, 0x3c040001, -0x24845748, 0x3c050004, 0xafa90010, 0xafa00014, -0x8ee604e4, 0x34a5f237, 0xc002403, 0x30e7ffff, -0x8002a72, 0x0, 0x8ee27264, 0x451021, -0xaee27264, 0x8ee2726c, 0x8ee37264, 0x3c040001, -0x34843800, 0xa2e004ed, 0x451023, 0xaee2726c, -0x3641021, 0x62182b, 0x14600004, 0x3c03ffff, -0x8ee27264, 0x431021, 0xaee27264, 0x8ee304e8, -0x96e20458, 0x24630001, 0x2442ffff, 0x621824, -0xaee304e8, 0x8ee304e8, 0x8ee204e0, 0x14620005, -0x0, 0x8f820060, 0x2403fff7, 0x431024, -0xaf820060, 0x8fbf0018, 0x3e00008, 0x27bd0020, -0x27bdffe0, 0xafbf001c, 0xafb00018, 0x8f820100, -0x8ee34e2c, 0x8f820104, 0x8f850108, 0x24020040, -0x24630001, 0x50620003, 0x1021, 0x8ee24e2c, -0x24420001, 0xaee24e2c, 0x8ee24e2c, 0x8ee34e2c, -0x210c0, 0x24424e38, 0x2e22021, 0x8ee24e28, -0x8c870004, 0x14620007, 0xa03021, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x8002aa2, -0xac800000, 0x8ee24e2c, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e2c, 0x24420001, -0x210c0, 0x24424e38, 0x2e22021, 0x8c820004, -0x8f830108, 0x21140, 0x621821, 0xaf830108, -0xac800000, 0x8cc20018, 0x2443fffe, 0x2c620013, -0x104000c1, 0x31080, 0x3c010001, 0x220821, -0x8c225770, 0x400008, 0x0, 0x8ee204f0, -0x471021, 0xaee204f0, 0x8ee204f0, 0x8f43023c, -0x43102b, 0x144000be, 0x0, 0x8ee304e4, -0x8ee204f8, 0x506200ba, 0xa2e004f4, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x8002b12, -0x8ee201a4, 0x8ee204e4, 0xac62001c, 0x8ee404b0, -0x8ee504b4, 0x2462001c, 0xac620008, 0x24020008, -0xa462000e, 0x24020011, 0xac620018, 0xac640000, -0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120, -0x92e24e20, 0x14400037, 0x24100001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c830000, -0x24020012, 0x1462001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30, -0x24420001, 0x10430007, 0x0, 0x8ee24e34, -0x24420001, 0x10a20005, 0x0, 0x8002afc, -0x0, 0x14a00005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8002b12, -0x0, 0x8ee24e30, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x24020012, 0xac820000, 0x24020001, -0xac820004, 0x5600000b, 0x24100001, 0x8ee204e4, -0x3c040001, 0x24845754, 0xafa00014, 0xafa20010, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, -0x34a5f006, 0x16000003, 0x24020001, 0x8002b71, -0xa2e204f4, 0x8ee20170, 0x24420001, 0xaee20170, -0x8ee20170, 0x8ee204e4, 0xa2e004f4, 0xaee004f0, -0xaee204f8, 0x8f42023c, 0x50400045, 0xaee07274, -0x8ee20184, 0x24420001, 0xaee20184, 0x8ee20184, -0x8002b71, 0xaee07274, 0x8ee20504, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee20504, -0x24420001, 0xaee20504, 0x8ee20504, 0x8cc30018, -0x21080, 0x571021, 0x8c440508, 0x24020003, -0x1462000f, 0x0, 0x3c020001, 0x571021, -0x904283b1, 0x10400014, 0x0, 0x8ee201d0, -0x8ee35240, 0x441021, 0xaee201d0, 0x8ee201d8, -0x641821, 0x306300ff, 0x8002b59, 0xaee35240, -0x8ee201cc, 0x8ee30e10, 0x441021, 0xaee201cc, -0x8ee201d8, 0x641821, 0x306301ff, 0xaee30e10, -0x441021, 0xaee201d8, 0x8ee20000, 0x34420040, -0x8002b71, 0xaee20000, 0x8ee2014c, 0x3c010001, -0x370821, 0xa02083e0, 0x24420001, 0xaee2014c, -0x8002b71, 0x8ee2014c, 0x94c7000e, 0x8cc2001c, -0x3c040001, 0x24845760, 0xafa60014, 0xafa20010, -0x8cc60018, 0x3c050008, 0xc002403, 0x34a50910, -0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, -0x27bdff98, 0xafbf0060, 0xafbe005c, 0xafb60058, -0xafb50054, 0xafb40050, 0xafb3004c, 0xafb20048, -0xafb10044, 0xafb00040, 0x8f830108, 0x8f820104, -0xafa00024, 0x106203e7, 0xafa0002c, 0x3c1e0001, -0x37de3800, 0x3c0bffff, 0x8f930108, 0x8e620018, -0x8f830104, 0x2443fffe, 0x2c620014, 0x104003cf, -0x31080, 0x3c010001, 0x220821, 0x8c2257c0, -0x400008, 0x0, 0x9663000e, 0x8ee2725c, -0x8ee404f0, 0x431021, 0xaee2725c, 0x8e63001c, -0x96e20458, 0x24840001, 0xaee404f0, 0x24630001, -0x2442ffff, 0x621824, 0xaee304e4, 0x8f42023c, -0x82202b, 0x148003b9, 0x0, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8021, 0x24420001, 0xaee201a4, 0x8002bfe, -0x8ee201a4, 0x8ee204e4, 0xac62001c, 0x8ee404b0, -0x8ee504b4, 0x2462001c, 0xac620008, 0x24020008, -0xa462000e, 0x24020011, 0xac620018, 0xac640000, -0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120, -0x92e24e20, 0x14400037, 0x24100001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c830000, -0x24020012, 0x1462001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x240c0040, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x104c0007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8002be8, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400013, 0xac800000, 0x8002bfe, -0x0, 0x8ee24e30, 0x240c0040, 0x24420001, -0x504c0003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x24020012, 0x240c0001, 0xac820000, -0xac8c0004, 0x5600000d, 0x24100001, 0x8ee204e4, -0x3c040001, 0x24845754, 0xafa00014, 0xafa20010, -0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f006, -0xc002403, 0xafab0038, 0x8fab0038, 0x1200030a, -0x240c0001, 0x8002f19, 0x0, 0x966c001c, -0xafac002c, 0x9662001e, 0x3c0c8000, 0xafac0024, -0xae62001c, 0x8e75001c, 0x8ee204fc, 0x8ee404fc, -0x151900, 0x621021, 0x8c52000c, 0x92e27b98, -0x641821, 0x9476000a, 0x14400003, 0x32c20002, -0xaef27ba4, 0xaef57b9c, 0x1040004b, 0x8021, -0x96e2045a, 0x30420002, 0x10400047, 0x0, -0x8e63001c, 0x8ee204fc, 0x32100, 0x821021, -0x8c42000c, 0x37e1821, 0x24420022, 0x43102b, -0x1440000a, 0x24050014, 0x8ee204fc, 0x821021, -0x8c44000c, 0xafab0038, 0xc002f75, 0x2484000e, -0x8fab0038, 0x8002c52, 0x3050ffff, 0x8ee204fc, -0x821021, 0x8c42000c, 0x9450000e, 0x94430010, -0x94440012, 0x94450014, 0x2038021, 0x2048021, -0x2058021, 0x94430016, 0x94440018, 0x9445001a, -0x2038021, 0x2048021, 0x2058021, 0x9443001c, -0x9444001e, 0x94420020, 0x2038021, 0x2048021, -0x2028021, 0x101c02, 0x3202ffff, 0x628021, -0x8e63001c, 0x8ee204fc, 0x102402, 0x32900, -0xa21021, 0x8c43000c, 0x3202ffff, 0x828021, -0x37e1021, 0x24630018, 0x62182b, 0x14600009, -0x0, 0x8ee204fc, 0xa21021, 0x8c43000c, -0x101027, 0x3c01ffff, 0x230821, 0x8002c6f, -0xa4220018, 0x8ee204fc, 0xa21021, 0x8c43000c, -0x101027, 0xa4620018, 0x96e2045a, 0x8821, -0x30420008, 0x14400063, 0xa021, 0x8e63001c, -0x8ee204fc, 0x33100, 0xc21021, 0x8c42000c, -0x37e1821, 0x24420022, 0x43102b, 0x14400035, -0x0, 0x8ee204fc, 0xc21021, 0x8c42000c, -0x24470010, 0x37e1021, 0xe2102b, 0x50400001, -0xeb3821, 0x8ee204fc, 0x94f10000, 0xc21021, -0x8c42000c, 0x24470016, 0x37e1021, 0xe2102b, -0x14400002, 0x2634ffec, 0xeb3821, 0x8ee204fc, -0x90e30001, 0xc21021, 0x8c42000c, 0x2447001a, -0x37e1021, 0xe2102b, 0x14400002, 0x2838821, -0xeb3821, 0x94e20000, 0x24e70002, 0x2228821, -0x37e1021, 0xe2102b, 0x50400001, 0xeb3821, -0x94e20000, 0x24e70002, 0x2228821, 0x37e1021, -0xe2102b, 0x50400001, 0xeb3821, 0x94e20000, -0x24e70002, 0x2228821, 0x37e1021, 0xe2102b, -0x50400001, 0xeb3821, 0x94e20000, 0x8002cd0, -0x2228821, 0x8ee204fc, 0xc21021, 0x8c43000c, -0x8ee204fc, 0x94710010, 0x8ee304fc, 0xc21021, -0x8c44000c, 0xc31821, 0x8c62000c, 0x2634ffec, -0x90840017, 0x8ee304fc, 0x9442001a, 0x2848821, -0xc31821, 0x8c65000c, 0x8ee304fc, 0x2228821, -0x8ee204fc, 0xc31821, 0xc21021, 0x8c44000c, -0x8c62000c, 0x94a3001c, 0x9484001e, 0x94420020, -0x2238821, 0x2248821, 0x2228821, 0x111c02, -0x3222ffff, 0x628821, 0x111c02, 0x3222ffff, -0x628821, 0x32c20001, 0x104000b2, 0x0, -0x96e2045a, 0x30420001, 0x104000ae, 0x32c20080, -0x10400008, 0x0, 0x92e27b98, 0x14400005, -0x0, 0x240c0001, 0xa2ec7b98, 0xaef57b9c, -0xaef27ba4, 0x8ee304fc, 0x151100, 0x431021, -0x8c47000c, 0x37e1821, 0x24e2000e, 0x43102b, -0x14400008, 0xe02021, 0x2405000e, 0xc002f75, -0xafab0038, 0x3042ffff, 0x8fab0038, 0x8002d09, -0x2028021, 0x94e60000, 0x24e70002, 0x94e50000, -0x24e70002, 0x94e30000, 0x24e70002, 0x94e20000, -0x24e70002, 0x94e40000, 0x24e70002, 0x2068021, -0x2058021, 0x2038021, 0x2028021, 0x94e20000, -0x94e30002, 0x2048021, 0x2028021, 0x2038021, -0x101c02, 0x3202ffff, 0x628021, 0x101c02, -0x3202ffff, 0x8ee47b9c, 0x628021, 0x14950004, -0x3205ffff, 0x96620016, 0x8002d17, 0x512021, -0x96620016, 0x542021, 0x41402, 0x3083ffff, -0x432021, 0x852023, 0x41402, 0x822021, -0x3084ffff, 0x50800001, 0x3404ffff, 0x8ee27ba4, -0x24430017, 0x37e1021, 0x62102b, 0x50400001, -0x6b1821, 0x90630000, 0x24020011, 0x14620031, -0x24020006, 0x8ee27ba4, 0x37e1821, 0x24420028, -0x43102b, 0x14400018, 0x0, 0x8ee27b9c, -0x12a2000a, 0x32c20100, 0x8ee27ba4, 0x3c01ffff, -0x220821, 0x94220028, 0x822021, 0x41c02, -0x3082ffff, 0x622021, 0x32c20100, 0x14400004, -0x41027, 0x92e27b98, 0x14400002, 0x41027, -0x3044ffff, 0x8ee27ba4, 0x3c01ffff, 0x220821, -0x8002d8a, 0xa4240028, 0x8ee27b9c, 0x12a20008, -0x32c20100, 0x8ee27ba4, 0x94420028, 0x822021, -0x41c02, 0x3082ffff, 0x622021, 0x32c20100, -0x14400004, 0x41027, 0x92e27b98, 0x14400002, -0x41027, 0x3044ffff, 0x8ee27ba4, 0x8002d8a, -0xa4440028, 0x1462002f, 0x37e1821, 0x8ee27ba4, -0x24420032, 0x43102b, 0x14400018, 0x0, -0x8ee27b9c, 0x12a2000a, 0x32c20100, 0x8ee27ba4, -0x3c01ffff, 0x220821, 0x94220032, 0x822021, -0x41c02, 0x3082ffff, 0x622021, 0x32c20100, -0x14400004, 0x41027, 0x92e27b98, 0x14400002, -0x41027, 0x3044ffff, 0x8ee27ba4, 0x3c01ffff, -0x220821, 0x8002d8a, 0xa4240032, 0x8ee27b9c, -0x12a20008, 0x32c20100, 0x8ee27ba4, 0x94420032, -0x822021, 0x41c02, 0x3082ffff, 0x622021, -0x32c20100, 0x14400004, 0x41027, 0x92e27b98, -0x14400002, 0x41027, 0x3044ffff, 0x8ee27ba4, -0xa4440032, 0x8fac0024, 0x1180002c, 0x37e1821, -0x8e420000, 0xae42fffc, 0x2642000a, 0x43102b, -0x1440001b, 0x34038100, 0x26430004, 0x37e1021, -0x62102b, 0x14400003, 0x602021, 0x6b1821, -0x602021, 0x8c620000, 0x24630004, 0xae420000, -0x37e1021, 0x62102b, 0x50400001, 0x6b1821, -0x8c620000, 0xac820000, 0x34028100, 0xa4620000, -0x24630002, 0x37e1021, 0x62102b, 0x50400001, -0x6b1821, 0x97ac002e, 0x8002db4, 0xa46c0000, -0x8e420004, 0x8e440008, 0xa6430008, 0x97ac002e, -0xa64c000a, 0xae420000, 0xae440004, 0x9662000e, -0x2652fffc, 0x24420004, 0xa662000e, 0x9662000e, -0x8ee3725c, 0x621821, 0xaee3725c, 0xafb20018, -0x8ee3725c, 0xafa3001c, 0x8ee2725c, 0x2c42003c, -0x10400004, 0x24620001, 0x2403fffe, 0x431024, -0xafa2001c, 0x32c20080, 0x1040000c, 0x32c20100, -0x8ee27ba8, 0x24430001, 0x210c0, 0x571021, -0xaee37ba8, 0x8fa30018, 0x8fa4001c, 0xac437bac, -0xac447bb0, 0x8002ea0, 0xaee0725c, 0x10400072, -0x0, 0x8ee27ba8, 0x24430001, 0x210c0, -0x571021, 0xaee37ba8, 0x8fa30018, 0x8fa4001c, -0xac437bac, 0xac447bb0, 0x8ee27ba8, 0x10400063, -0x4821, 0x5021, 0x8f8200f0, 0x24480008, -0x27621800, 0x102102b, 0x50400001, 0x27681000, -0x8f8200f4, 0x15020007, 0x0, 0x8ee201b4, -0x8021, 0x24420001, 0xaee201b4, 0x8002dfa, -0x8ee201b4, 0x8f8300f0, 0x24100001, 0x1571021, -0x8c447bac, 0x8c457bb0, 0xac640000, 0xac650004, -0xaf8800f0, 0x16000006, 0x2ea1021, 0x8ee20088, -0x24420001, 0xaee20088, 0x8002e3f, 0x8ee20088, -0x8c427bb0, 0x8ee400e0, 0x8ee500e4, 0x8ee67b9c, -0x401821, 0x1021, 0xa32821, 0xa3382b, -0x822021, 0x872021, 0x8ee204fc, 0xc93021, -0x63100, 0xaee400e0, 0xaee500e4, 0xc23021, -0x94c2000a, 0x240c0002, 0x21142, 0x30430003, -0x106c0016, 0x28620003, 0x10400005, 0x240c0001, -0x106c0008, 0x0, 0x8002e3f, 0x0, -0x240c0003, 0x106c0017, 0x0, 0x8002e3f, -0x0, 0x8ee200e8, 0x8ee300ec, 0x24630001, -0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec, -0x8ee200e8, 0x8002e3f, 0x8ee300ec, 0x8ee200f0, -0x8ee300f4, 0x24630001, 0x2c640001, 0x441021, -0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002e3f, -0x8ee300f4, 0x8ee200f8, 0x8ee300fc, 0x24630001, -0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc, -0x8ee200f8, 0x8ee300fc, 0x8ee27ba8, 0x25290001, -0x122102b, 0x1440ffa0, 0x254a0008, 0xa2e07b98, -0x8002e9f, 0xaee07ba8, 0x8f8200f0, 0x24470008, -0x27621800, 0xe2102b, 0x50400001, 0x27671000, -0x8f8200f4, 0x14e20007, 0x0, 0x8ee201b4, -0x8021, 0x24420001, 0xaee201b4, 0x8002e5d, -0x8ee201b4, 0x8f8200f0, 0x24100001, 0x8fa30018, -0x8fa4001c, 0xac430000, 0xac440004, 0xaf8700f0, -0x16000007, 0x0, 0x8ee20088, 0x24420001, -0xaee20088, 0x8ee20088, 0x8002ea0, 0xaee0725c, -0x8ee2725c, 0x8ee400e0, 0x8ee500e4, 0x240c0002, -0x401821, 0x1021, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0x161142, 0x30430003, -0xaee400e0, 0xaee500e4, 0x106c0017, 0x2c620003, -0x10400005, 0x240c0001, 0x106c0008, 0x0, -0x8002ea0, 0xaee0725c, 0x240c0003, 0x106c0019, -0x0, 0x8002ea0, 0xaee0725c, 0x8ee200e8, -0x8ee300ec, 0x24630001, 0x2c640001, 0x441021, -0xaee200e8, 0xaee300ec, 0x8ee200e8, 0x8ee300ec, -0x8002ea0, 0xaee0725c, 0x8ee200f0, 0x8ee300f4, -0x24630001, 0x2c640001, 0x441021, 0xaee200f0, -0xaee300f4, 0x8ee200f0, 0x8ee300f4, 0x8002ea0, -0xaee0725c, 0x8ee200f8, 0x8ee300fc, 0x24630001, -0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc, -0x8ee200f8, 0x8ee300fc, 0xaee0725c, 0x8e62001c, -0x96e30458, 0x8ee404f0, 0x24420001, 0x2463ffff, -0x431024, 0x24840001, 0xaee204e4, 0xaee404f0, -0x8f42023c, 0x82202b, 0x148000b0, 0x0, -0x8f830120, 0x27623800, 0x24660020, 0xc2102b, -0x50400001, 0x27663000, 0x8f820128, 0x10c20004, -0x0, 0x8f820124, 0x14c20007, 0x0, -0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4, -0x8002f07, 0x8ee201a4, 0x8ee204e4, 0xac62001c, -0x8ee404b0, 0x8ee504b4, 0x2462001c, 0xac620008, -0x24020008, 0xa462000e, 0x24020011, 0xac620018, -0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, -0xaf860120, 0x92e24e20, 0x14400037, 0x24100001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c830000, 0x24020012, 0x1462001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x240c0040, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee34e30, 0x24420001, 0x104c0007, 0x0, -0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x8002ef1, 0x0, 0x14600005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x8002f07, 0x0, 0x8ee24e30, 0x240c0040, -0x24420001, 0x504c0003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020012, 0x240c0001, -0xac820000, 0xac8c0004, 0x5600000d, 0x24100001, -0x8ee204e4, 0x3c040001, 0x24845754, 0xafa00014, -0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009, -0x34a5f006, 0xc002403, 0xafab0038, 0x8fab0038, -0x16000003, 0x240c0001, 0x8002f5c, 0xa2ec04f4, -0x8ee20170, 0x24420001, 0xaee20170, 0x8ee20170, -0x8ee204e4, 0xa2e004f4, 0xaee004f0, 0xaee07274, -0xaee204f8, 0x8f42023c, 0x10400038, 0x0, -0x8ee20184, 0x24420001, 0xaee20184, 0x8002f5c, -0x8ee20184, 0x8ee20504, 0x240c0040, 0x24420001, -0x504c0003, 0x1021, 0x8ee20504, 0x24420001, -0xaee20504, 0x8ee20504, 0x8e630018, 0x240c0003, -0x21080, 0x571021, 0x146c000f, 0x8c440508, -0x3c020001, 0x571021, 0x904283b1, 0x10400014, -0x0, 0x8ee201d0, 0x8ee35240, 0x441021, -0xaee201d0, 0x8ee201d8, 0x641821, 0x306300ff, -0x8002f4f, 0xaee35240, 0x8ee201cc, 0x8ee30e10, -0x441021, 0xaee201cc, 0x8ee201d8, 0x641821, -0x306301ff, 0xaee30e10, 0x441021, 0xaee201d8, -0x8ee20000, 0x34420040, 0x8002f5c, 0xaee20000, -0x8ee2014c, 0x3c010001, 0x370821, 0xa02083e0, -0x24420001, 0xaee2014c, 0x8ee2014c, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x8f820108, -0x27633000, 0x43102b, 0x14400002, 0x27622800, -0xaf820108, 0x8f830108, 0x8f820104, 0x1462fc1e, -0x0, 0x8fbf0060, 0x8fbe005c, 0x8fb60058, -0x8fb50054, 0x8fb40050, 0x8fb3004c, 0x8fb20048, -0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0068, -0x52843, 0x10a0000d, 0x3021, 0x3c030001, -0x34633800, 0x3c07ffff, 0x3631021, 0x82102b, -0x50400001, 0x872021, 0x94820000, 0x24840002, -0x24a5ffff, 0x14a0fff8, 0xc23021, 0x61c02, -0x30c2ffff, 0x623021, 0x61c02, 0x30c2ffff, -0x623021, 0x3e00008, 0x30c2ffff, 0x27bdff88, -0x240f0001, 0xafbf0070, 0xafbe006c, 0xafb60068, -0xafb50064, 0xafb40060, 0xafb3005c, 0xafb20058, -0xafb10054, 0xafb00050, 0xa3a00027, 0xafaf002c, -0x8ee204d4, 0x8021, 0x30420001, 0x1440002a, -0xa3a00037, 0x8f8700e0, 0x8f8800c4, 0x8f8200e8, -0xe22023, 0x2c821000, 0x50400001, 0x24841000, -0x420c2, 0x801821, 0x8ee400c8, 0x8ee500cc, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaee400c8, 0xaee500cc, 0x8f8300c8, -0x3c02000a, 0x3442efff, 0x1032023, 0x44102b, -0x10400003, 0x3c02000a, 0x3442f000, 0x822021, -0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, -0xa32821, 0xa3302b, 0x822021, 0x862021, -0xaee400c0, 0xaee500c4, 0xaf8800c8, 0xaf8700e4, -0x80034cc, 0xaf8700e8, 0x3c020001, 0x571021, -0x904283c0, 0x1040000b, 0x0, 0x3c140001, -0x297a021, 0x8e9483c4, 0x3c130001, 0x2779821, -0x8e7383c8, 0x3c120001, 0x2579021, 0x8003193, -0x8e5283cc, 0x8f8300e0, 0x8f8200e4, 0x10430007, -0x8821, 0x8f8200e4, 0x24110001, 0x8c430000, -0x8c440004, 0xafa30018, 0xafa4001c, 0x1620000e, -0x3c02ffff, 0x8f8200c4, 0xafa20010, 0x8f8200c8, -0x3c040001, 0x24845870, 0xafa20014, 0x8f8600e0, -0x8f8700e4, 0x3c050006, 0xc002403, 0x34a5f000, -0x80034cc, 0x0, 0x8fa3001c, 0x8fb20018, -0x3074ffff, 0x2694fffc, 0x621024, 0x10400058, -0x2409821, 0x3c020080, 0x621024, 0x1040000a, -0x3c040040, 0x8ee2007c, 0x24420001, 0xaee2007c, -0x8ee2007c, 0x8ee201fc, 0x24420001, 0xaee201fc, -0x80034c6, 0x8ee201fc, 0x3c060004, 0x3c0b0001, -0x3c0a0002, 0x3c050010, 0x3c090008, 0x8ee20080, -0x3c080020, 0x34078000, 0x24420001, 0xaee20080, -0x8ee20080, 0x8fa2001c, 0x441824, 0x10660021, -0xc3102b, 0x14400007, 0x0, 0x106b0011, -0x0, 0x106a0015, 0x0, 0x8003049, -0x42042, 0x10650023, 0xa3102b, 0x14400005, -0x0, 0x10690019, 0x0, 0x8003049, -0x42042, 0x10680021, 0x0, 0x8003049, -0x42042, 0x8ee20034, 0x24420001, 0xaee20034, -0x8ee20034, 0x8003049, 0x42042, 0x8ee201ec, -0x24420001, 0xaee201ec, 0x8ee201ec, 0x8003049, -0x42042, 0x8ee201f0, 0x24420001, 0xaee201f0, -0x8ee201f0, 0x8003049, 0x42042, 0x8ee201f4, -0x24420001, 0xaee201f4, 0x8ee201f4, 0x8003049, -0x42042, 0x8ee20030, 0x24420001, 0xaee20030, -0x8ee20030, 0x8003049, 0x42042, 0x8ee201f8, -0x24420001, 0xaee201f8, 0x8ee201f8, 0x42042, -0x1087047c, 0x0, 0x800300e, 0x0, -0x3c020001, 0x571021, 0x904283b2, 0x14400084, -0x24020001, 0x3c030001, 0x771821, 0x906383b3, -0x1462007f, 0x3c020100, 0x8e430000, 0x621024, -0x1040006f, 0x2402ffff, 0x14620005, 0x24100001, -0x96430004, 0x3402ffff, 0x10620075, 0x0, -0x92e204d8, 0x14400072, 0x0, 0x3c020001, -0x571021, 0x8c4283b4, 0x28420005, 0x10400020, -0x3821, 0x3c020001, 0x571021, 0x8c4283b4, -0x18400016, 0x2821, 0x96660000, 0x520c0, -0x971021, 0x9442777e, 0x14460009, 0x971021, -0x94437780, 0x96620002, 0x14620005, 0x971021, -0x94437782, 0x96620004, 0x50620008, 0x24070001, -0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001, -0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff, -0x10400440, 0x0, 0x80030d5, 0x0, -0x2402021, 0xc0022fe, 0x24050006, 0x3044001f, -0x428c0, 0x2e51021, 0x9442727c, 0x30424000, -0x14400434, 0xb71021, 0x9443727e, 0x96620000, -0x1462000b, 0x418c0, 0xb71021, 0x94437280, -0x96620002, 0x14620006, 0x418c0, 0xb71021, -0x94437282, 0x96620004, 0x10620035, 0x418c0, -0x2e31021, 0x9442727c, 0x30428000, 0x14400421, -0x2e31021, 0x944b727c, 0x96670000, 0xb28c0, -0xb71021, 0x9442737e, 0x80030b7, 0x3021, -0x420c0, 0x2e41021, 0x9443737c, 0x2e41021, -0x944b737c, 0x30638000, 0x14600010, 0xb28c0, -0xb71021, 0x9442737e, 0x1447fff5, 0x1602021, -0xb71021, 0x94437380, 0x96620002, 0x5462fff1, -0x420c0, 0xb71021, 0x94437382, 0x96620004, -0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff, -0x10400400, 0x0, 0x80030d5, 0x0, -0x97430202, 0x96420000, 0x146203fa, 0x0, -0x97430204, 0x96420002, 0x146203f6, 0x0, -0x97430206, 0x96420004, 0x146203f2, 0x0, -0x92420000, 0x3a030001, 0x30420001, 0x431024, -0x10400074, 0x2402ffff, 0x8e630000, 0x14620004, -0x3402ffff, 0x96630004, 0x1062006f, 0x240f0002, -0x3c020001, 0x571021, 0x904283b2, 0x1440006a, -0x240f0003, 0x92e204d8, 0x54400068, 0xafaf002c, -0x3c020001, 0x571021, 0x8c4283b4, 0x28420005, -0x10400020, 0x3821, 0x3c020001, 0x571021, -0x8c4283b4, 0x18400016, 0x2821, 0x96660000, -0x520c0, 0x971021, 0x9442777e, 0x14460009, -0x971021, 0x94437780, 0x96620002, 0x14620005, -0x971021, 0x94437782, 0x96620004, 0x50620008, -0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, -0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, -0x30e200ff, 0x14400044, 0x240f0003, 0x80034c6, -0x0, 0x2402021, 0xc0022fe, 0x24050006, -0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, -0x30424000, 0x144003af, 0xb71021, 0x9443727e, -0x96620000, 0x1462000b, 0x418c0, 0xb71021, -0x94437280, 0x96620002, 0x14620006, 0x418c0, -0xb71021, 0x94437282, 0x96620004, 0x10620027, -0x418c0, 0x2e31021, 0x9442727c, 0x30428000, -0x1440039c, 0x2e31021, 0x944b727c, 0x96670000, -0xb28c0, 0xb71021, 0x9442737e, 0x800313c, -0x3021, 0x420c0, 0x2e41021, 0x9443737c, -0x2e41021, 0x944b737c, 0x30638000, 0x14600010, -0xb28c0, 0xb71021, 0x9442737e, 0x1447fff5, -0x1602021, 0xb71021, 0x94437380, 0x96620002, -0x5462fff1, 0x420c0, 0xb71021, 0x94437382, -0x96620004, 0x5462ffec, 0x420c0, 0x24060001, -0x30c200ff, 0x1040037b, 0x0, 0x800314f, -0x240f0003, 0x240f0001, 0xafaf002c, 0x8f420260, -0x54102b, 0x1040003a, 0x0, 0x8f8300e4, -0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4, -0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2801821, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058, -0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, -0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0, -0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845878, -0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, -0xc002403, 0x34a5f003, 0x80034cc, 0x0, -0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001, -0x24845884, 0xafa20014, 0x8ee60e10, 0x8ee70e18, -0x3c050006, 0xc002403, 0x34a5f002, 0x8ee201c0, -0x24420001, 0xaee201c0, 0x8ee20000, 0x8ee301c0, -0x2403ffbf, 0x431024, 0x8003470, 0xaee20000, -0x96e20468, 0x54102b, 0x10400003, 0x0, -0x240f0001, 0xa3af0027, 0x12800301, 0x24160007, -0x24150040, 0x241e0001, 0x240e0012, 0x8ee2724c, -0x8f430280, 0x24420001, 0x304207ff, 0x106202d3, -0x0, 0x93a20027, 0x10400014, 0x0, -0x8ee35240, 0x8ee25244, 0x10620009, 0x26ed5244, -0x8ee65244, 0x8ee35244, 0x21140, 0x24425248, -0x2e28021, 0x24630001, 0x80031bf, 0x306b00ff, -0x92e27248, 0x1440ffca, 0x0, 0x8ee201e0, -0x24420001, 0xaee201e0, 0x8ee201e0, 0x8ee30e10, -0x8ee20e18, 0x1062ffc2, 0x26ed0e18, 0x8ee60e18, -0x8ee30e18, 0x21140, 0x24420e20, 0x2e28021, -0x24630001, 0x306b01ff, 0x96e2046a, 0x30420010, -0x10400019, 0x0, 0x9642000c, 0x340f8100, -0x144f0015, 0x0, 0x3c020001, 0x571021, -0x904283c0, 0x14400010, 0x0, 0x9642000e, -0xa6020016, 0x8e420008, 0x8e430004, 0x8e440000, -0x2694fffc, 0xae42000c, 0xae430008, 0xae440004, -0x9602000e, 0x26730004, 0x240f0001, 0xa3af0037, -0x34420200, 0xa602000e, 0x8e020000, 0x8e030004, -0x3c040001, 0x34843800, 0x306a0007, 0x26a9823, -0x3641021, 0x262102b, 0x10400005, 0x28aa021, -0x2641023, 0x3621823, 0x3c020020, 0x439823, -0x26820007, 0x2404fff8, 0x9603000a, 0x446024, -0x6a1821, 0x6c102b, 0x10400002, 0x1803821, -0x603821, 0xae130018, 0x8f880120, 0x24e20007, -0x443824, 0x27623800, 0x25090020, 0x122102b, -0x50400001, 0x27693000, 0x8f820128, 0x11220004, -0x0, 0x8f820124, 0x15220007, 0x1401821, -0x8ee201a4, 0x8821, 0x24420001, 0xaee201a4, -0x800324c, 0x8ee201a4, 0x8e040000, 0x8e050004, -0x1021, 0xad130008, 0xa507000e, 0xad160018, -0xad06001c, 0xa3302b, 0xa32823, 0x822023, -0x862023, 0xad040000, 0xad050004, 0x8ee204c0, -0xad020010, 0xaf890120, 0x92e24e20, 0x14400033, -0x24110001, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c820000, 0x1456001f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee34e30, 0x24420001, 0x10550007, 0x0, -0x8ee24e34, 0x24420001, 0x10620005, 0x0, -0x8003239, 0x0, 0x14600005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400010, 0xac800000, -0x800324c, 0x0, 0x8ee24e30, 0x24420001, -0x50550003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0xac960000, 0xac9e0004, 0x16200018, -0x3c050006, 0x8e020018, 0x3c040001, 0x24845890, -0xafa20010, 0x8e020000, 0x8e030004, 0x34a5f009, -0x2003021, 0xc002403, 0xafa30014, 0x93a20037, -0x10400216, 0x340f8100, 0x8e420004, 0x8e430008, -0x8e44000c, 0xa64f000c, 0xae420000, 0xae430004, -0xae440008, 0x96020016, 0x8003470, 0xa642000e, -0x14ec0168, 0x28a1823, 0x960c000a, 0x9603000e, -0x28a1023, 0xa602000a, 0x34620004, 0xa602000e, -0x8f880120, 0x27623800, 0x25090020, 0x122102b, -0x14400002, 0x306affff, 0x27693000, 0x8f820128, -0x11220004, 0x0, 0x8f820124, 0x15220007, -0x24040020, 0x8ee201a4, 0x8821, 0x24420001, -0xaee201a4, 0x80032ca, 0x8ee201a4, 0x8ee5724c, -0x8ee60490, 0x8ee70494, 0xa504000e, 0x24040004, -0xad100008, 0xad040018, 0x52940, 0xa01821, -0x1021, 0xe33821, 0xe3202b, 0xc23021, -0xc43021, 0xad060000, 0xad070004, 0x8ee2724c, -0xad02001c, 0x8ee204c4, 0xad020010, 0xaf890120, -0x92e24e20, 0x14400033, 0x24110001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c820000, -0x1456001f, 0x0, 0x8ee34e30, 0x8ee24e34, -0x1062001b, 0x0, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, -0x10550007, 0x0, 0x8ee24e34, 0x24420001, -0x10620005, 0x0, 0x80032b7, 0x0, -0x14600005, 0x0, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400010, 0xac800000, 0x80032ca, 0x0, -0x8ee24e30, 0x24420001, 0x50550003, 0x1021, -0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0xac960000, -0xac9e0004, 0x1620000d, 0x0, 0xa60c000a, -0xa60a000e, 0x8f820100, 0xafa20010, 0x8f820104, -0x3c040001, 0x2484589c, 0x3c050006, 0xafa20014, -0x8ee6724c, 0x800343b, 0x34a5f00b, 0x3c010001, -0x370821, 0xa02083c0, 0xadab0000, 0x8ee201d8, -0x8ee3724c, 0x2442ffff, 0xaee201d8, 0x8ee201d8, -0x24630001, 0x306307ff, 0x26e25244, 0x15a20006, -0xaee3724c, 0x8ee201d0, 0x2442ffff, 0xaee201d0, -0x80032ef, 0x8ee201d0, 0x8ee201cc, 0x2442ffff, -0xaee201cc, 0x8ee201cc, 0x8f420240, 0x10400073, -0x0, 0x8ee20e1c, 0x24420001, 0xaee20e1c, -0x8f430240, 0x43102b, 0x14400176, 0xa021, -0x8f830120, 0x27623800, 0x24660020, 0xc2102b, -0x50400001, 0x27663000, 0x8f820128, 0x10c20004, -0x0, 0x8f820124, 0x14c20007, 0x0, -0x8ee201a4, 0x8821, 0x24420001, 0xaee201a4, -0x800334f, 0x8ee201a4, 0x8ee2724c, 0xac62001c, -0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008, -0x24020008, 0xa462000e, 0x24020011, 0xac620018, -0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, -0xaf860120, 0x92e24e20, 0x14400033, 0x24110001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c820000, 0x144e001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x10550007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x800333c, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x800334f, -0x0, 0x8ee24e30, 0x24420001, 0x50550003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0xac8e0000, 0xac9e0004, 0x5620000d, 0x24110001, -0x8ee2724c, 0x3c040001, 0x248458a8, 0xafa00014, -0xafa20010, 0x8ee6724c, 0x8f470280, 0x3c050009, -0x34a5f008, 0xc002403, 0xafae0048, 0x8fae0048, -0x56200001, 0xaee00e1c, 0x8ee20188, 0x24420001, -0xaee20188, 0x80033c8, 0x8ee20188, 0x8f830120, -0x27623800, 0x24660020, 0xc2102b, 0x50400001, -0x27663000, 0x8f820128, 0x10c20004, 0x0, -0x8f820124, 0x14c20007, 0x0, 0x8ee201a4, -0x8821, 0x24420001, 0xaee201a4, 0x80033ba, -0x8ee201a4, 0x8ee2724c, 0xac62001c, 0x8ee404a8, -0x8ee504ac, 0x2462001c, 0xac620008, 0x24020008, -0xa462000e, 0x24020011, 0xac620018, 0xac640000, -0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120, -0x92e24e20, 0x14400033, 0x24110001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c820000, -0x144e001f, 0x0, 0x8ee34e30, 0x8ee24e34, -0x1062001b, 0x0, 0x8c820004, 0x24420001, -0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001, -0x10550007, 0x0, 0x8ee24e34, 0x24420001, -0x10620005, 0x0, 0x80033a7, 0x0, -0x14600005, 0x0, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, -0x50400010, 0xac800000, 0x80033ba, 0x0, -0x8ee24e30, 0x24420001, 0x50550003, 0x1021, -0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0xac8e0000, -0xac9e0004, 0x1620000d, 0x0, 0x8ee2724c, -0x3c040001, 0x248458a8, 0xafa00014, 0xafa20010, -0x8ee6724c, 0x8f470280, 0x3c050009, 0x34a5f008, -0xc002403, 0xafae0048, 0x8fae0048, 0x8ee20174, -0x24420001, 0xaee20174, 0x8ee20174, 0x800346e, -0xa021, 0x960c000a, 0x183102b, 0x54400001, -0x1801821, 0xa603000a, 0x8f880120, 0x27623800, -0x25090020, 0x122102b, 0x50400001, 0x27693000, -0x8f820128, 0x11220004, 0x0, 0x8f820124, -0x15220007, 0x24040020, 0x8ee201a4, 0x8821, -0x24420001, 0xaee201a4, 0x800342f, 0x8ee201a4, -0x8ee5724c, 0x8ee60490, 0x8ee70494, 0xa504000e, -0x24040004, 0xad100008, 0xad040018, 0x52940, -0xa01821, 0x1021, 0xe33821, 0xe3202b, -0xc23021, 0xc43021, 0xad060000, 0xad070004, -0x8ee2724c, 0xad02001c, 0x8ee204c4, 0xad020010, -0xaf890120, 0x92e24e20, 0x14400033, 0x24110001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c820000, 0x1456001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x10550007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x800341c, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400010, 0xac800000, 0x800342f, -0x0, 0x8ee24e30, 0x24420001, 0x50550003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0xac960000, 0xac9e0004, 0x1620001d, 0x0, -0xa60c000a, 0x8f820100, 0xafa20010, 0x8f820104, -0x3c040001, 0x2484589c, 0x3c050006, 0xafa20014, -0x8ee6724c, 0x34a5f00d, 0xc002403, 0x2003821, -0x93a20037, 0x10400031, 0x340f8100, 0x8e420004, -0x8e430008, 0x8e44000c, 0xa64f000c, 0xae420000, -0xae430004, 0xae440008, 0x96020016, 0xa642000e, -0x9602000e, 0x3042fdff, 0x8003470, 0xa602000e, -0x8ee201d8, 0x2442ffff, 0xaee201d8, 0x8ee201d8, -0x8ee201cc, 0x3c04001f, 0x3c010001, 0x370821, -0xa03e83c0, 0x2442ffff, 0xaee201cc, 0x9603000a, -0x3484ffff, 0x8ee201cc, 0x6a1821, 0x2639821, -0x93202b, 0x10800003, 0x3c02fff5, 0x34421000, -0x2629821, 0xadab0000, 0x8ee2724c, 0x24420001, -0x304207ff, 0xaee2724c, 0x8f420240, 0x10400004, -0x283a023, 0x8ee20e1c, 0x24420001, 0xaee20e1c, -0xa3a00027, 0x1680fd29, 0x0, 0x12800024, -0x0, 0x3c010001, 0x370821, 0xac3483c4, -0x3c010001, 0x370821, 0xac3383c8, 0x3c010001, -0x370821, 0xac3283cc, 0x93a20037, 0x10400008, -0x0, 0x3c020001, 0x571021, 0x8c4283cc, -0x24420004, 0x3c010001, 0x370821, 0xac2283cc, -0x8ee2724c, 0x8f430280, 0x24420001, 0x304207ff, -0x14620006, 0x0, 0x8ee201c4, 0x24420001, -0xaee201c4, 0x80034cc, 0x8ee201c4, 0x8ee201bc, -0x24420001, 0xaee201bc, 0x80034cc, 0x8ee201bc, -0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0, -0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0xaee400c0, 0xaee500c4, -0x8faf002c, 0x24020002, 0x11e2000f, 0x29e20003, -0x14400017, 0x24020003, 0x15e20015, 0x0, -0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001, -0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0, -0x80034c6, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, -0x24630001, 0x2c640001, 0x441021, 0xaee200d8, -0xaee300dc, 0x8ee200d8, 0x80034c6, 0x8ee300dc, -0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001, -0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8, -0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003, -0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8fbf0070, -0x8fbe006c, 0x8fb60068, 0x8fb50064, 0x8fb40060, -0x8fb3005c, 0x8fb20058, 0x8fb10054, 0x8fb00050, -0x3e00008, 0x27bd0078, 0x27bdffb0, 0xafb50044, -0xa821, 0xafb00030, 0x8021, 0xafbf004c, -0xafb60048, 0xafb40040, 0xafb3003c, 0xafb20038, -0xafb10034, 0x8ee204d4, 0x24140001, 0x30420001, -0x1440002a, 0xb021, 0x8f8700e0, 0x8f8800c4, -0x8f8200e8, 0xe22023, 0x2c821000, 0x50400001, -0x24841000, 0x420c2, 0x801821, 0x8ee400c8, -0x8ee500cc, 0x1021, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0xaee400c8, 0xaee500cc, -0x8f8300c8, 0x3c02000a, 0x3442efff, 0x1032023, -0x44102b, 0x10400003, 0x3c02000a, 0x3442f000, -0x822021, 0x801821, 0x8ee400c0, 0x8ee500c4, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8, -0xaf8700e4, 0x8003850, 0xaf8700e8, 0x3c020001, -0x571021, 0x904283c0, 0x1040000b, 0x0, -0x3c130001, 0x2779821, 0x8e7383c4, 0x3c110001, -0x2378821, 0x8e3183c8, 0x3c120001, 0x2579021, -0x80036e8, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4, -0x10430007, 0x4821, 0x8f8200e4, 0x24090001, -0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c, -0x1520000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010, -0x8f8200c8, 0x3c040001, 0x24845870, 0xafa20014, -0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403, -0x34a5f000, 0x8003850, 0x0, 0x8fa3001c, -0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024, -0x10400058, 0x2408821, 0x3c020080, 0x621024, -0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001, -0xaee2007c, 0x8ee2007c, 0x8ee201fc, 0x24420001, -0xaee201fc, 0x800384a, 0x8ee201fc, 0x3c060004, -0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008, -0x8ee20080, 0x3c080020, 0x34078000, 0x24420001, -0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824, -0x10660021, 0xc3102b, 0x14400007, 0x0, -0x106b0011, 0x0, 0x106a0015, 0x0, -0x8003592, 0x42042, 0x10650023, 0xa3102b, -0x14400005, 0x0, 0x10690019, 0x0, -0x8003592, 0x42042, 0x10680021, 0x0, -0x8003592, 0x42042, 0x8ee20034, 0x24420001, -0xaee20034, 0x8ee20034, 0x8003592, 0x42042, -0x8ee201ec, 0x24420001, 0xaee201ec, 0x8ee201ec, -0x8003592, 0x42042, 0x8ee201f0, 0x24420001, -0xaee201f0, 0x8ee201f0, 0x8003592, 0x42042, -0x8ee201f4, 0x24420001, 0xaee201f4, 0x8ee201f4, -0x8003592, 0x42042, 0x8ee20030, 0x24420001, -0xaee20030, 0x8ee20030, 0x8003592, 0x42042, -0x8ee201f8, 0x24420001, 0xaee201f8, 0x8ee201f8, -0x42042, 0x108702b7, 0x0, 0x8003557, -0x0, 0x3c020001, 0x571021, 0x904283b2, -0x14400084, 0x24020001, 0x3c030001, 0x771821, -0x906383b3, 0x1462007f, 0x3c020100, 0x8e430000, -0x621024, 0x1040006f, 0x2402ffff, 0x14620005, -0x24100001, 0x96430004, 0x3402ffff, 0x10620075, -0x0, 0x92e204d8, 0x14400072, 0x0, -0x3c020001, 0x571021, 0x8c4283b4, 0x28420005, -0x10400020, 0x3821, 0x3c020001, 0x571021, -0x8c4283b4, 0x18400016, 0x2821, 0x96260000, -0x520c0, 0x971021, 0x9442777e, 0x14460009, -0x971021, 0x94437780, 0x96220002, 0x14620005, -0x971021, 0x94437782, 0x96220004, 0x50620008, -0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, -0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, -0x30e200ff, 0x1040027b, 0x0, 0x800361e, -0x0, 0x2402021, 0xc0022fe, 0x24050006, -0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, -0x30424000, 0x1440026f, 0xb71021, 0x9443727e, -0x96220000, 0x1462000b, 0x418c0, 0xb71021, -0x94437280, 0x96220002, 0x14620006, 0x418c0, -0xb71021, 0x94437282, 0x96220004, 0x10620035, -0x418c0, 0x2e31021, 0x9442727c, 0x30428000, -0x1440025c, 0x2e31021, 0x9448727c, 0x96270000, -0x828c0, 0xb71021, 0x9442737e, 0x8003600, -0x3021, 0x420c0, 0x2e41021, 0x9443737c, -0x2e41021, 0x9448737c, 0x30638000, 0x14600010, -0x828c0, 0xb71021, 0x9442737e, 0x1447fff5, -0x1002021, 0xb71021, 0x94437380, 0x96220002, -0x5462fff1, 0x420c0, 0xb71021, 0x94437382, -0x96220004, 0x5462ffec, 0x420c0, 0x24060001, -0x30c200ff, 0x1040023b, 0x0, 0x800361e, -0x0, 0x97430202, 0x96420000, 0x14620235, -0x0, 0x97430204, 0x96420002, 0x14620231, -0x0, 0x97430206, 0x96420004, 0x1462022d, -0x0, 0x92420000, 0x3a030001, 0x30420001, -0x431024, 0x10400074, 0x2402ffff, 0x8e230000, -0x14620004, 0x3402ffff, 0x96230004, 0x1062006f, -0x24140002, 0x3c020001, 0x571021, 0x904283b2, -0x1440006a, 0x24140003, 0x92e204d8, 0x14400067, -0x0, 0x3c020001, 0x571021, 0x8c4283b4, -0x28420005, 0x10400020, 0x3821, 0x3c020001, -0x571021, 0x8c4283b4, 0x18400016, 0x2821, -0x96260000, 0x520c0, 0x971021, 0x9442777e, -0x14460009, 0x971021, 0x94437780, 0x96220002, -0x14620005, 0x971021, 0x94437782, 0x96220004, -0x50620008, 0x24070001, 0x3c020001, 0x571021, -0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, -0x520c0, 0x30e200ff, 0x14400044, 0x24140003, -0x800384a, 0x0, 0x2402021, 0xc0022fe, -0x24050006, 0x3044001f, 0x428c0, 0x2e51021, -0x9442727c, 0x30424000, 0x144001ea, 0xb71021, -0x9443727e, 0x96220000, 0x1462000b, 0x418c0, -0xb71021, 0x94437280, 0x96220002, 0x14620006, -0x418c0, 0xb71021, 0x94437282, 0x96220004, -0x10620027, 0x418c0, 0x2e31021, 0x9442727c, -0x30428000, 0x144001d7, 0x2e31021, 0x9448727c, -0x96270000, 0x828c0, 0xb71021, 0x9442737e, -0x8003685, 0x3021, 0x420c0, 0x2e41021, -0x9443737c, 0x2e41021, 0x9448737c, 0x30638000, -0x14600010, 0x828c0, 0xb71021, 0x9442737e, -0x1447fff5, 0x1002021, 0xb71021, 0x94437380, -0x96220002, 0x5462fff1, 0x420c0, 0xb71021, -0x94437382, 0x96220004, 0x5462ffec, 0x420c0, -0x24060001, 0x30c200ff, 0x104001b6, 0x0, -0x8003698, 0x24140003, 0x24140001, 0x8f420260, -0x53102b, 0x10400049, 0x0, 0x8f8300e4, -0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4, -0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2601821, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058, -0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, -0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0, -0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845878, -0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, -0xc002403, 0x34a5f003, 0x8003850, 0x0, -0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001, -0x24845884, 0xafa20014, 0x8ee60e10, 0x8ee70e18, -0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001, -0xaee201c0, 0x8ee20000, 0x8ee301c0, 0x2403ffbf, -0x431024, 0x80037f8, 0xaee20000, 0x8ee25240, -0xafa20010, 0x8ee25244, 0x3c040001, 0x24845884, -0xafa20014, 0x8ee60e10, 0x8ee70e18, 0x3c050006, -0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001, -0xaee201c0, 0x80037f8, 0x8ee201c0, 0x96e20468, -0x53102b, 0x54400001, 0x3c158000, 0x12600131, -0x3c0c001f, 0x358cffff, 0x8ee2724c, 0x8f430280, -0x24420001, 0x304207ff, 0x10620108, 0x0, -0x12a00014, 0x0, 0x8ee35240, 0x8ee25244, -0x10620009, 0x26ee5244, 0x8eeb5244, 0x8ee35244, -0x21140, 0x24425248, 0x2e28021, 0x24630001, -0x8003712, 0x306800ff, 0x92e27248, 0x1440ffc0, -0x3c050006, 0x8ee201e0, 0x24420001, 0xaee201e0, -0x8ee201e0, 0x8ee30e10, 0x8ee20e18, 0x1062ffcb, -0x26ee0e18, 0x8eeb0e18, 0xa821, 0x8ee30e18, -0x21140, 0x24420e20, 0x2e28021, 0x24630001, -0x306801ff, 0x96e2046a, 0x30420010, 0x10400017, -0x34028100, 0x9643000c, 0x14620014, 0x0, -0x3c020001, 0x571021, 0x904283c0, 0x1440000f, -0x0, 0x9642000e, 0xa6020016, 0x8e420008, -0x8e430004, 0x8e440000, 0x2673fffc, 0xae42000c, -0xae430008, 0xae440004, 0x9602000e, 0x26310004, -0x24160001, 0x34420200, 0xa602000e, 0x9603000a, -0x2605021, 0x73102b, 0x10400002, 0x2606821, -0x605021, 0x2d42003d, 0x1040002a, 0x3821, -0x9623000c, 0x24020800, 0x54620027, 0xae110018, -0x3c020001, 0x571021, 0x904283c0, 0x54400022, -0xae110018, 0x26220017, 0x182102b, 0x10400013, -0x0, 0x3c02fff5, 0x511021, 0x90421017, -0x38430006, 0x2c630001, 0x38420011, 0x2c420001, -0x621825, 0x10600013, 0x26220010, 0x182102b, -0x1040000e, 0x0, 0x3c07fff5, 0xf13821, -0x94e71010, 0x800375e, 0x24e7000e, 0x92220017, -0x38430006, 0x2c630001, 0x38420011, 0x2c420001, -0x621825, 0x50600004, 0xae110018, 0x96270010, -0x24e7000e, 0xae110018, 0x3c020001, 0x571021, -0x904283c0, 0x2102b, 0x14e00002, 0x24ec0, -0x1403821, 0x8f830120, 0x27623800, 0x24660020, -0xc2102b, 0x50400001, 0x27663000, 0x8f820128, -0x10c20004, 0x0, 0x8f820124, 0x14c20007, -0x2402000b, 0x8ee201a4, 0x4821, 0x24420001, -0xaee201a4, 0x80037bf, 0x8ee201a4, 0x8e040000, -0x8e050004, 0xac620018, 0x1751025, 0x491025, -0xac710008, 0xa467000e, 0xac62001c, 0xac640000, -0xac650004, 0x8ee204c0, 0xac620010, 0xaf860120, -0x92e24e20, 0x14400038, 0x24090001, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c830000, -0x24020007, 0x14620020, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001c, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee34e34, 0x8ee54e30, -0x24020040, 0x24630001, 0x10620007, 0x0, -0x8ee24e34, 0x24420001, 0x10a20005, 0x0, -0x80037a9, 0x0, 0x14a00005, 0x0, -0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, -0x8c820004, 0x2c420011, 0x50400013, 0xac800000, -0x80037bf, 0x0, 0x8ee24e30, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020007, 0xac820000, -0x24020001, 0xac820004, 0x15200018, 0x3c050006, -0x8e020018, 0x3c040001, 0x24845890, 0xafa20010, -0x8e020000, 0x8e030004, 0x34a5f009, 0x2003021, -0xc002403, 0xafa30014, 0x32c200ff, 0x1040002b, -0x34028100, 0x8e430004, 0x8e440008, 0x8e45000c, -0xa642000c, 0xae430000, 0xae440004, 0xae450008, -0x96020016, 0x80037f8, 0xa642000e, 0x154d000a, -0x0, 0x9602000e, 0xa613000a, 0x34420004, -0xa602000e, 0x3c010001, 0x370821, 0xa02083c0, -0x80037f6, 0x9821, 0x9604000a, 0x93102b, -0x10400002, 0x2601821, 0x801821, 0x24020001, -0xa603000a, 0x3c010001, 0x370821, 0xa02283c0, -0x9604000a, 0x2248821, 0x191102b, 0x10400003, -0x3c02fff5, 0x34421000, 0x2228821, 0x2649823, -0xa821, 0x1660fef4, 0xadc80000, 0x12600021, -0x32c200ff, 0x3c010001, 0x370821, 0xac3383c4, -0x3c010001, 0x370821, 0xac3183c8, 0x3c010001, -0x370821, 0x10400008, 0xac3283cc, 0x3c020001, -0x571021, 0x8c4283cc, 0x24420004, 0x3c010001, -0x370821, 0xac2283cc, 0x8ee2724c, 0x8f430280, -0x24420001, 0x14620006, 0x0, 0x8ee201c4, -0x24420001, 0xaee201c4, 0x8003850, 0x8ee201c4, -0x8ee201bc, 0x24420001, 0xaee201bc, 0x8003850, -0x8ee201bc, 0x97a4001e, 0x2484fffc, 0x801821, -0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, -0xa3302b, 0x822021, 0x862021, 0x24020002, -0xaee400c0, 0xaee500c4, 0x1282000f, 0x2a820003, -0x14400017, 0x24020003, 0x16820015, 0x0, -0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001, -0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0, -0x800384a, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, -0x24630001, 0x2c640001, 0x441021, 0xaee200d8, -0xaee300dc, 0x8ee200d8, 0x800384a, 0x8ee300dc, -0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001, -0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8, -0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003, -0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8fbf004c, -0x8fb60048, 0x8fb50044, 0x8fb40040, 0x8fb3003c, -0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008, -0x27bd0050, 0x27bdff90, 0xafb60060, 0xb021, -0xafbf0068, 0xafbe0064, 0xafb5005c, 0xafb40058, -0xafb30054, 0xafb20050, 0xafb1004c, 0xafb00048, -0x8ee204d4, 0x8821, 0x24150001, 0x30420001, -0x1440002a, 0xa3a0002f, 0x8f8700e0, 0x8f8800c4, -0x8f8200e8, 0xe22023, 0x2c821000, 0x50400001, -0x24841000, 0x420c2, 0x801821, 0x8ee400c8, -0x8ee500cc, 0x1021, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0xaee400c8, 0xaee500cc, -0x8f8300c8, 0x3c02000a, 0x3442efff, 0x1032023, -0x44102b, 0x10400003, 0x3c02000a, 0x3442f000, -0x822021, 0x801821, 0x8ee400c0, 0x8ee500c4, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8, -0xaf8700e4, 0x8003c5b, 0xaf8700e8, 0x3c020001, -0x571021, 0x904283c0, 0x1040000b, 0x0, -0x3c130001, 0x2779821, 0x8e7383c4, 0x3c100001, -0x2178021, 0x8e1083c8, 0x3c120001, 0x2579021, -0x8003a59, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4, -0x10430007, 0x3821, 0x8f8200e4, 0x24070001, -0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c, -0x14e0000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010, -0x8f8200c8, 0x3c040001, 0x248458b4, 0xafa20014, -0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403, -0x34a5f200, 0x8003c5b, 0x0, 0x8fa3001c, -0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024, -0x10400058, 0x2408021, 0x3c020080, 0x621024, -0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001, -0xaee2007c, 0x8ee2007c, 0x8ee201fc, 0x24420001, -0xaee201fc, 0x8003c55, 0x8ee201fc, 0x3c060004, -0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008, -0x8ee20080, 0x3c080020, 0x34078000, 0x24420001, -0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824, -0x10660021, 0xc3102b, 0x14400007, 0x0, -0x106b0011, 0x0, 0x106a0015, 0x0, -0x8003916, 0x42042, 0x10650023, 0xa3102b, -0x14400005, 0x0, 0x10690019, 0x0, -0x8003916, 0x42042, 0x10680021, 0x0, -0x8003916, 0x42042, 0x8ee20034, 0x24420001, -0xaee20034, 0x8ee20034, 0x8003916, 0x42042, -0x8ee201ec, 0x24420001, 0xaee201ec, 0x8ee201ec, -0x8003916, 0x42042, 0x8ee201f0, 0x24420001, -0xaee201f0, 0x8ee201f0, 0x8003916, 0x42042, -0x8ee201f4, 0x24420001, 0xaee201f4, 0x8ee201f4, -0x8003916, 0x42042, 0x8ee20030, 0x24420001, -0xaee20030, 0x8ee20030, 0x8003916, 0x42042, -0x8ee201f8, 0x24420001, 0xaee201f8, 0x8ee201f8, -0x42042, 0x1087033e, 0x0, 0x80038db, -0x0, 0x3c020001, 0x571021, 0x904283b2, -0x14400084, 0x24020001, 0x3c030001, 0x771821, -0x906383b3, 0x1462007f, 0x3c020100, 0x8e430000, -0x621024, 0x1040006f, 0x2402ffff, 0x14620005, -0x24110001, 0x96430004, 0x3402ffff, 0x10620075, -0x0, 0x92e204d8, 0x14400072, 0x0, -0x3c020001, 0x571021, 0x8c4283b4, 0x28420005, -0x10400020, 0x3821, 0x3c020001, 0x571021, -0x8c4283b4, 0x18400016, 0x2821, 0x96060000, -0x520c0, 0x971021, 0x9442777e, 0x14460009, -0x971021, 0x94437780, 0x96020002, 0x14620005, -0x971021, 0x94437782, 0x96020004, 0x50620008, -0x24070001, 0x3c020001, 0x571021, 0x8c4283b4, -0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, -0x30e200ff, 0x10400302, 0x0, 0x80039a2, -0x0, 0x2402021, 0xc0022fe, 0x24050006, -0x3044001f, 0x428c0, 0x2e51021, 0x9442727c, -0x30424000, 0x144002f6, 0xb71021, 0x9443727e, -0x96020000, 0x1462000b, 0x418c0, 0xb71021, -0x94437280, 0x96020002, 0x14620006, 0x418c0, -0xb71021, 0x94437282, 0x96020004, 0x10620035, -0x418c0, 0x2e31021, 0x9442727c, 0x30428000, -0x144002e3, 0x2e31021, 0x944d727c, 0x96070000, -0xd28c0, 0xb71021, 0x9442737e, 0x8003984, -0x3021, 0x420c0, 0x2e41021, 0x9443737c, -0x2e41021, 0x944d737c, 0x30638000, 0x14600010, -0xd28c0, 0xb71021, 0x9442737e, 0x1447fff5, -0x1a02021, 0xb71021, 0x94437380, 0x96020002, -0x5462fff1, 0x420c0, 0xb71021, 0x94437382, -0x96020004, 0x5462ffec, 0x420c0, 0x24060001, -0x30c200ff, 0x104002c2, 0x0, 0x80039a2, -0x0, 0x97430202, 0x96420000, 0x146202bc, -0x0, 0x97430204, 0x96420002, 0x146202b8, -0x0, 0x97430206, 0x96420004, 0x146202b4, -0x0, 0x92420000, 0x3a230001, 0x30420001, -0x431024, 0x10400074, 0x2402ffff, 0x8e030000, -0x14620004, 0x3402ffff, 0x96030004, 0x1062006f, -0x24150002, 0x3c020001, 0x571021, 0x904283b2, -0x1440006a, 0x24150003, 0x92e204d8, 0x14400067, -0x0, 0x3c020001, 0x571021, 0x8c4283b4, -0x28420005, 0x10400020, 0x3821, 0x3c020001, -0x571021, 0x8c4283b4, 0x18400016, 0x2821, -0x96060000, 0x520c0, 0x971021, 0x9442777e, -0x14460009, 0x971021, 0x94437780, 0x96020002, -0x14620005, 0x971021, 0x94437782, 0x96020004, -0x50620008, 0x24070001, 0x3c020001, 0x571021, -0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee, -0x520c0, 0x30e200ff, 0x14400044, 0x24150003, -0x8003c55, 0x0, 0x2402021, 0xc0022fe, -0x24050006, 0x3044001f, 0x428c0, 0x2e51021, -0x9442727c, 0x30424000, 0x14400271, 0xb71021, -0x9443727e, 0x96020000, 0x1462000b, 0x418c0, -0xb71021, 0x94437280, 0x96020002, 0x14620006, -0x418c0, 0xb71021, 0x94437282, 0x96020004, -0x10620027, 0x418c0, 0x2e31021, 0x9442727c, -0x30428000, 0x1440025e, 0x2e31021, 0x944d727c, -0x96070000, 0xd28c0, 0xb71021, 0x9442737e, -0x8003a09, 0x3021, 0x420c0, 0x2e41021, -0x9443737c, 0x2e41021, 0x944d737c, 0x30638000, -0x14600010, 0xd28c0, 0xb71021, 0x9442737e, -0x1447fff5, 0x1a02021, 0xb71021, 0x94437380, -0x96020002, 0x5462fff1, 0x420c0, 0xb71021, -0x94437382, 0x96020004, 0x5462ffec, 0x420c0, -0x24060001, 0x30c200ff, 0x1040023d, 0x0, -0x8003a1c, 0x24150003, 0x24150001, 0x8f420260, -0x53102b, 0x10400036, 0x0, 0x8f8300e4, -0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4, -0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2601821, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058, -0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, -0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0, -0xafa20010, 0x8f8200e4, 0x3c040001, 0x248458c0, -0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, -0xc002403, 0x34a5f203, 0x8003c5b, 0x0, -0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001, -0x248458cc, 0xafa20014, 0x8ee60e10, 0x8ee70e18, -0x3c050006, 0xc002403, 0x34a5f202, 0x8ee201c0, -0x24420001, 0xaee201c0, 0x8003c02, 0x8ee201c0, -0x96e20468, 0x53102b, 0x54400001, 0x3c168000, -0x126001cb, 0x3c0e001f, 0x35ceffff, 0x3c0ffff5, -0x35ef1000, 0x241e0040, 0x8ee2724c, 0x8f430280, -0x24420001, 0x304207ff, 0x1062019e, 0x0, -0x12c00012, 0x0, 0x8ee35240, 0x8ee25244, -0x1062000a, 0x26f85244, 0x8ef45244, 0xafb80024, -0x8ee35244, 0x21140, 0x24425248, 0x2e28821, -0x24630001, 0x8003a85, 0x306d00ff, 0x8ee201e0, -0x24420001, 0xaee201e0, 0x8ee201e0, 0x8ee30e10, -0x8ee20e18, 0x1062ffca, 0x26f80e18, 0x8ef40e18, -0xb021, 0xafb80024, 0x8ee30e18, 0x21140, -0x24420e20, 0x2e28821, 0x24630001, 0x306d01ff, -0x96e2046a, 0x30420010, 0x10400018, 0x34028100, -0x9643000c, 0x14620015, 0x0, 0x3c020001, -0x571021, 0x904283c0, 0x14400010, 0x0, -0x9642000e, 0xa6220016, 0x8e420008, 0x8e430004, -0x8e440000, 0x2673fffc, 0xae42000c, 0xae430008, -0xae440004, 0x9622000e, 0x26100004, 0x24180001, -0xa3b8002f, 0x34420200, 0xa622000e, 0x8e220000, -0x8e230004, 0x3c040001, 0x34843800, 0x2003021, -0x306a0007, 0x20a8023, 0x3641021, 0x202102b, -0x10400005, 0x26a9821, 0x2041023, 0x3621823, -0x3c020020, 0x438023, 0x26620007, 0x9623000a, -0x2418fff8, 0x58c824, 0x6a1821, 0x79102b, -0x10400002, 0x3206021, 0x606021, 0x1801821, -0x24620007, 0x2418fff8, 0x586024, 0x26c102b, -0x14400004, 0x1932823, 0x1832823, 0x8003ac3, -0xc31021, 0xd31021, 0x4a2023, 0x1c4102b, -0x54400001, 0x8f2021, 0x25420040, 0x4c102b, -0x14400035, 0x5821, 0x94c3000c, 0x24020800, -0x54620032, 0xae260018, 0x3c020001, 0x571021, -0x904283c0, 0x5440002d, 0xae260018, 0x24c20017, -0x1c2102b, 0x10400013, 0x0, 0x3c02fff5, -0x461021, 0x90421017, 0x38430006, 0x2c630001, -0x38420011, 0x2c420001, 0x621825, 0x10600014, -0x24c20010, 0x1c2102b, 0x1040000e, 0x0, -0x3c0bfff5, 0x1665821, 0x956b1010, 0x8003af4, -0x2562000e, 0x90c20017, 0x38430006, 0x2c630001, -0x38420011, 0x2c420001, 0x621825, 0x10600005, -0x1601821, 0x94cb0010, 0x2562000e, 0x4a5821, -0x1601821, 0x24620007, 0x2418fff8, 0x585824, -0xc31021, 0x4a2023, 0x1c4102b, 0x10400002, -0x1632823, 0x8f2021, 0xae260018, 0x3c020001, -0x571021, 0x904283c0, 0x2102b, 0x216c0, -0x15600002, 0xafa20044, 0x1805821, 0x30820001, -0x10400007, 0x4021, 0x90880000, 0x24840001, -0x1c4102b, 0x10400002, 0x24a5ffff, 0x8f2021, -0x50a00012, 0x81c02, 0x2ca20002, 0x54400009, -0x24a5ffff, 0x94820000, 0x24840002, 0x1024021, -0x1c4102b, 0x10400006, 0x24a5fffe, 0x8003b21, -0x8f2021, 0x90820000, 0x21200, 0x1024021, -0x14a0fff2, 0x2ca20002, 0x81c02, 0x3102ffff, -0x624021, 0x3108ffff, 0x1402821, 0x11400011, -0x2002021, 0x2ca20002, 0x54400009, 0x24a5ffff, -0x94820000, 0x24840002, 0x1024021, 0x1c4102b, -0x10400006, 0x24a5fffe, 0x8003b38, 0x8f2021, -0x90820000, 0x21200, 0x1024021, 0x14a0fff2, -0x2ca20002, 0x81c02, 0x3102ffff, 0x624021, -0x81c02, 0x3102ffff, 0x8f890120, 0x624021, -0x27623800, 0x25230020, 0x62102b, 0x14400002, -0x3108ffff, 0x27633000, 0x8f820128, 0x10620004, -0x0, 0x8f820124, 0x14620007, 0x1402821, -0x8ee201a4, 0x3821, 0x24420001, 0xaee201a4, -0x8003bc9, 0x8ee201a4, 0x8e260000, 0x8e270004, -0x81400, 0x3448000b, 0xad300008, 0xa52b000e, -0xad280018, 0x8fb80044, 0x2021, 0x2961025, -0x581025, 0xad22001c, 0xe5102b, 0xe53823, -0xc43023, 0xc23023, 0xad260000, 0xad270004, -0x8ee204c0, 0xad220010, 0xaf830120, 0x92e24e20, -0x1440005f, 0x24070001, 0x2502ffee, 0x2c420002, -0x14400003, 0x24020011, 0x15020024, 0x0, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c830000, 0x24020012, 0x1462000f, 0x0, -0x8ee34e30, 0x8ee24e34, 0x1062000b, 0x0, -0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34, -0x8ee34e30, 0x24420001, 0x105e002a, 0x0, -0x8003ba8, 0x0, 0x8ee24e30, 0x24420001, -0x505e0003, 0x1021, 0x8ee24e30, 0x24420001, -0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8003bc6, 0x24020012, 0x8ee24e30, -0x210c0, 0x24425038, 0x2e22021, 0x8c830000, -0x24020007, 0x1462001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x105e0007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8003bb4, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400012, 0xac800000, 0x8003bc9, -0x0, 0x8ee24e30, 0x24420001, 0x505e0003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x24020007, 0xac820000, 0x24020001, 0xac820004, -0x14e00019, 0x3c050006, 0x3c040001, 0x24845890, -0x8e220018, 0x34a5f209, 0xafa20010, 0x8e220000, -0x8e230004, 0x2203021, 0x1603821, 0xc002403, -0xafa30014, 0x93a2002f, 0x1040002a, 0x34028100, -0x8e430004, 0x8e440008, 0x8e45000c, 0xa642000c, -0xae430000, 0xae440004, 0xae450008, 0x96220016, -0x8003c02, 0xa642000e, 0x1599000a, 0x26a1823, -0x9622000e, 0xa623000a, 0x34420004, 0xa622000e, -0x3c010001, 0x370821, 0xa02083c0, 0x8003bff, -0x9821, 0x9624000a, 0x83102b, 0x54400001, -0x801821, 0x24020001, 0xa623000a, 0x3c010001, -0x370821, 0xa02283c0, 0x9622000a, 0x4a1821, -0x2038021, 0x1d0102b, 0x54400001, 0x20f8021, -0x2639823, 0xb021, 0x8fb80024, 0x1660fe5e, -0xaf0d0000, 0x12600022, 0x0, 0x3c010001, -0x370821, 0xac3383c4, 0x3c010001, 0x370821, -0xac3083c8, 0x3c010001, 0x370821, 0xac3283cc, -0x93a2002f, 0x10400008, 0x0, 0x3c020001, -0x571021, 0x8c4283cc, 0x24420004, 0x3c010001, -0x370821, 0xac2283cc, 0x8f430280, 0x8ee2724c, -0x14620006, 0x0, 0x8ee201c4, 0x24420001, -0xaee201c4, 0x8003c5b, 0x8ee201c4, 0x8ee201bc, -0x24420001, 0xaee201bc, 0x8003c5b, 0x8ee201bc, -0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0, -0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0x24020002, 0xaee400c0, -0xaee500c4, 0x12a2000f, 0x2aa20003, 0x14400017, -0x24020003, 0x16a20015, 0x0, 0x8ee200d0, -0x8ee300d4, 0x24630001, 0x2c640001, 0x441021, -0xaee200d0, 0xaee300d4, 0x8ee200d0, 0x8003c55, -0x8ee300d4, 0x8ee200d8, 0x8ee300dc, 0x24630001, -0x2c640001, 0x441021, 0xaee200d8, 0xaee300dc, -0x8ee200d8, 0x8003c55, 0x8ee300dc, 0x8ee200c8, -0x8ee300cc, 0x24630001, 0x2c640001, 0x441021, -0xaee200c8, 0xaee300cc, 0x8ee200c8, 0x8ee300cc, -0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008, -0xaf8300e4, 0xaf8300e8, 0x8fbf0068, 0x8fbe0064, -0x8fb60060, 0x8fb5005c, 0x8fb40058, 0x8fb30054, -0x8fb20050, 0x8fb1004c, 0x8fb00048, 0x3e00008, -0x27bd0070, 0x27bdffe0, 0xafbf0018, 0x8ee30e14, -0x8ee20e0c, 0x10620074, 0x0, 0x8ee30e0c, -0x8ee20e14, 0x622023, 0x4820001, 0x24840200, -0x8ee30e18, 0x8ee20e14, 0x43102b, 0x14400004, -0x24020200, 0x8ee30e14, 0x8003c7d, 0x431823, -0x8ee20e18, 0x8ee30e14, 0x431023, 0x2443ffff, -0x804821, 0x69102a, 0x54400001, 0x604821, -0x8f870100, 0x27623000, 0x24e80020, 0x102102b, -0x50400001, 0x27682800, 0x8f820108, 0x11020004, -0x0, 0x8f820104, 0x15020007, 0x1021, -0x8ee201a8, 0x2021, 0x24420001, 0xaee201a8, -0x8003cbf, 0x8ee201a8, 0x8ee40e14, 0x42140, -0x801821, 0x8ee40460, 0x8ee50464, 0xa32821, -0xa3302b, 0x822021, 0x862021, 0xace40000, -0xace50004, 0x8ee30e14, 0x91140, 0xa4e2000e, -0x24020002, 0xace20018, 0x31940, 0x24630e20, -0x2e31021, 0xace20008, 0x8ee20e14, 0xace2001c, -0x8ee204cc, 0xace20010, 0xaf880100, 0x92e204ec, -0x14400011, 0x24040001, 0x8ee24e28, 0x24030040, -0x24420001, 0x50430003, 0x1021, 0x8ee24e28, -0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0, -0x24424e38, 0x2e21821, 0x24020002, 0xac620000, -0x24020001, 0xac620004, 0x1480000e, 0x24030040, -0x8ee20e14, 0xafa20010, 0x8ee20e18, 0x3c050007, -0xafa20014, 0x8ee60e0c, 0x8ee70e10, 0x3c040001, -0x248458d4, 0xc002403, 0x34a5f001, 0x8003cdd, -0x0, 0x8ee20500, 0x24420001, 0x50430003, -0x1021, 0x8ee20500, 0x24420001, 0xaee20500, -0x8ee20500, 0x21080, 0x571021, 0xac490508, -0x8ee20e14, 0x491021, 0x304201ff, 0xaee20e14, -0x8ee30e14, 0x8ee20e0c, 0x14620005, 0x0, -0x8f820060, 0x2403fdff, 0x431024, 0xaf820060, -0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0, -0xafbf0018, 0x8ee3523c, 0x8ee25238, 0x10620074, -0x0, 0x8ee35238, 0x8ee2523c, 0x622023, -0x4820001, 0x24840100, 0x8ee35244, 0x8ee2523c, -0x43102b, 0x14400004, 0x24020100, 0x8ee3523c, -0x8003cff, 0x431823, 0x8ee25244, 0x8ee3523c, -0x431023, 0x2443ffff, 0x804821, 0x69102a, -0x54400001, 0x604821, 0x8f870100, 0x27623000, -0x24e80020, 0x102102b, 0x50400001, 0x27682800, -0x8f820108, 0x11020004, 0x0, 0x8f820104, -0x15020007, 0x1021, 0x8ee201a8, 0x2021, -0x24420001, 0xaee201a8, 0x8003d41, 0x8ee201a8, -0x8ee4523c, 0x42140, 0x801821, 0x8ee40470, -0x8ee50474, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xace40000, 0xace50004, 0x8ee3523c, -0x91140, 0xa4e2000e, 0x24020003, 0xace20018, -0x31940, 0x24635248, 0x2e31021, 0xace20008, -0x8ee2523c, 0xace2001c, 0x8ee204cc, 0xace20010, -0xaf880100, 0x92e204ec, 0x14400011, 0x24040001, -0x8ee24e28, 0x24030040, 0x24420001, 0x50430003, -0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28, -0x8ee24e28, 0x210c0, 0x24424e38, 0x2e21821, -0x24020003, 0xac620000, 0x24020001, 0xac620004, -0x1480000e, 0x24030040, 0x8ee2523c, 0xafa20010, -0x8ee25244, 0x3c050007, 0xafa20014, 0x8ee65238, -0x8ee75240, 0x3c040001, 0x248458e0, 0xc002403, -0x34a5f010, 0x8003d5f, 0x0, 0x8ee20500, -0x24420001, 0x50430003, 0x1021, 0x8ee20500, -0x24420001, 0xaee20500, 0x8ee20500, 0x21080, -0x571021, 0xac490508, 0x8ee2523c, 0x491021, -0x304200ff, 0xaee2523c, 0x8ee3523c, 0x8ee25238, -0x14620005, 0x0, 0x8f820060, 0x2403feff, -0x431024, 0xaf820060, 0x8fbf0018, 0x3e00008, -0x27bd0020, 0x8f820120, 0x8ee34e34, 0x8f820124, -0x8f860128, 0x24020040, 0x24630001, 0x50620003, -0x1021, 0x8ee24e34, 0x24420001, 0xaee24e34, -0x8ee24e34, 0x8ee44e34, 0x8ee34e30, 0x210c0, -0x24425038, 0x14830007, 0x2e22821, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8003d92, -0xaca00000, 0x8ee24e34, 0x24030040, 0x24420001, -0x50430003, 0x1021, 0x8ee24e34, 0x24420001, -0x210c0, 0x24425038, 0x2e22821, 0x8ca20004, -0x8f830128, 0x21140, 0x621821, 0xaf830128, -0xaca00000, 0x8cc20018, 0x2443fffe, 0x2c620012, -0x10400008, 0x31080, 0x3c010001, 0x220821, -0x8c2258f0, 0x400008, 0x0, 0x24020001, -0xaee24e24, 0x3e00008, 0x0, 0x27bdffc8, -0xafbf0030, 0xafb5002c, 0xafb40028, 0xafb30024, -0xafb20020, 0xafb1001c, 0xafb00018, 0x8f830128, -0x8f820124, 0x106202b0, 0x9821, 0x3c11001f, -0x3631ffff, 0x3c12fff5, 0x36521000, 0x24150012, -0x24140040, 0x8f8c0128, 0x8f820128, 0x24420020, -0xaf820128, 0x9182001b, 0x8f830128, 0x2443fffe, -0x2c620012, 0x1040029c, 0x31080, 0x3c010001, -0x220821, 0x8c225948, 0x400008, 0x0, -0x8f420218, 0x30420100, 0x10400007, 0x0, -0x95830016, 0x95820018, 0x621823, 0x31402, -0x431021, 0xa5820016, 0x8d82001c, 0x3c038000, -0x3044ffff, 0x436824, 0x3c030800, 0x431824, -0x11a00004, 0xad84001c, 0x41140, 0x8003dd8, -0x24425248, 0x41140, 0x24420e20, 0x2e25821, -0x9562000e, 0x3042fffc, 0x10600004, 0xa562000e, -0x95840016, 0x8003ec0, 0x0, 0x8d690018, -0x4021, 0x952a0000, 0x25290002, 0x95270000, -0x25290002, 0x95260000, 0x25290002, 0x95250000, -0x25290002, 0x95240000, 0x25290002, 0x95230000, -0x25290002, 0x95220000, 0x25290002, 0x1475021, -0x1465021, 0x1455021, 0x1445021, 0x1435021, -0x1425021, 0xa1c02, 0x3142ffff, 0x625021, -0xa1c02, 0x3142ffff, 0x625021, 0x96e2046a, -0x314effff, 0x30420002, 0x10400044, 0x5021, -0x25220014, 0x222102b, 0x10400014, 0x1201821, -0x2405000a, 0x2021, 0x223102b, 0x54400001, -0x721821, 0x94620000, 0x24630002, 0x24a5ffff, -0x14a0fff9, 0x822021, 0x41c02, 0x3082ffff, -0x622021, 0x41402, 0x3083ffff, 0x431021, -0x3042ffff, 0x8003e33, 0x1425021, 0x952a0000, -0x25290002, 0x95280000, 0x25290002, 0x95270000, -0x25290002, 0x95260000, 0x25290002, 0x95250000, -0x25290002, 0x95230000, 0x25290002, 0x95220000, -0x25290002, 0x95240000, 0x25290002, 0x1485021, -0x1475021, 0x1465021, 0x1455021, 0x1435021, -0x1425021, 0x95220000, 0x95230002, 0x1445021, -0x1425021, 0x1435021, 0xa1c02, 0x3142ffff, -0x625021, 0xa1c02, 0x3142ffff, 0x625021, -0x3148ffff, 0x51000001, 0x3408ffff, 0x8d620018, -0x9443000c, 0x24020800, 0x54620005, 0xa5680010, -0x9562000e, 0x34420002, 0xa562000e, 0xa5680010, -0x96e2046a, 0x2821, 0x30420008, 0x14400056, -0x3021, 0x8d630018, 0x24620024, 0x222102b, -0x10400034, 0x24690010, 0x229102b, 0x54400001, -0x1324821, 0x95250000, 0x24690014, 0x229102b, -0x10400002, 0x24a5ffec, 0x1324821, 0x95220000, -0x30420fff, 0x14400003, 0x25290002, 0x8003e60, -0x24130001, 0x9821, 0xa03021, 0x229102b, -0x54400001, 0x1324821, 0x91220001, 0x25290002, -0xa22821, 0x229102b, 0x54400001, 0x1324821, -0x25290002, 0x229102b, 0x54400001, 0x1324821, -0x95220000, 0x25290002, 0xa22821, 0x229102b, -0x54400001, 0x1324821, 0x95220000, 0x25290002, -0xa22821, 0x229102b, 0x54400001, 0x1324821, -0x95220000, 0x25290002, 0xa22821, 0x229102b, -0x54400001, 0x1324821, 0x95220000, 0x8003e99, -0xa22821, 0x94650010, 0x94620014, 0x24690016, -0x30420fff, 0x14400003, 0x24a5ffec, 0x8003e8c, -0x24130001, 0x9821, 0xa03021, 0x91230001, -0x25290004, 0x95220000, 0x25290002, 0x95240000, -0x25290002, 0xa32821, 0xa22821, 0x95220000, -0x95230002, 0xa42821, 0xa22821, 0xa32821, -0x51c02, 0x30a2ffff, 0x622821, 0x51c02, -0x30a2ffff, 0x622821, 0x96e2046a, 0x30420001, -0x1040001e, 0x2021, 0x95820016, 0x4e2023, -0x41402, 0x822021, 0x326200ff, 0x50400002, -0x862021, 0x852021, 0x41402, 0x822021, -0x3084ffff, 0x50800001, 0x3404ffff, 0x8d620018, -0x24430017, 0x223102b, 0x54400001, 0x721821, -0x90620000, 0x38430011, 0x2c630001, 0x38420006, -0x2c420001, 0x621825, 0x10600004, 0x0, -0x9562000e, 0x34420001, 0xa562000e, 0x9562000e, -0x240a0002, 0x30420004, 0x10400002, 0xa5640012, -0x240a0004, 0x8f880120, 0x27623800, 0x25090020, -0x122102b, 0x50400001, 0x27693000, 0x8f820128, -0x11220004, 0x0, 0x8f820124, 0x15220007, -0x24040020, 0x8ee201a4, 0x8021, 0x24420001, -0xaee201a4, 0x8003f4f, 0x8ee201a4, 0x8ee5724c, -0x8ee60490, 0x8ee70494, 0xad0b0008, 0xa504000e, -0xad0a0018, 0x52940, 0xa01821, 0x1021, -0xe33821, 0xe3202b, 0xc23021, 0xc43021, -0xad060000, 0xad070004, 0x8ee2724c, 0x4d1025, -0xad02001c, 0x8ee204c4, 0xad020010, 0xaf890120, -0x92e24e20, 0x14400060, 0x24100001, 0x2543ffee, -0x2c630002, 0x39420011, 0x2c420001, 0x621825, -0x10600024, 0x0, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c820000, 0x1455000f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062000b, -0x0, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee34e30, 0x24420001, 0x1054002b, -0x0, 0x8003f2e, 0x0, 0x8ee24e30, -0x24420001, 0x50540003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020001, 0x8003f4e, -0xac950000, 0x8ee24e30, 0x210c0, 0x24425038, -0x2e22021, 0x8c830000, 0x24020007, 0x1462001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x0, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10540007, -0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x8003f3a, 0x0, 0x14600005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400012, -0xac800000, 0x8003f4f, 0x0, 0x8ee24e30, -0x24420001, 0x50540003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020007, 0xac820000, -0x24020001, 0xac820004, 0x1600000d, 0x0, -0x8f820120, 0x3c040001, 0x24845938, 0xafa00014, -0xafa20010, 0x8d86001c, 0x8f870124, 0x3c050008, -0xc002403, 0x34a50001, 0x8004057, 0x0, -0x8ee2724c, 0x24420001, 0x304207ff, 0x11a00006, -0xaee2724c, 0x8ee201d0, 0x2442ffff, 0xaee201d0, -0x8003f6b, 0x8ee201d0, 0x8ee201cc, 0x2442ffff, -0xaee201cc, 0x8ee201cc, 0x8ee201d8, 0x2442ffff, -0xaee201d8, 0x8004057, 0x8ee201d8, 0x8f420240, -0x104000e5, 0x0, 0x8ee20e1c, 0x24420001, -0x8004057, 0xaee20e1c, 0x9582001e, 0xad82001c, -0x8f420240, 0x10400072, 0x0, 0x8ee20e1c, -0x24420001, 0xaee20e1c, 0x8f430240, 0x43102b, -0x144000d5, 0x0, 0x8f830120, 0x27623800, -0x24660020, 0xc2102b, 0x50400001, 0x27663000, -0x8f820128, 0x10c20004, 0x0, 0x8f820124, -0x14c20007, 0x0, 0x8ee201a4, 0x8021, -0x24420001, 0xaee201a4, 0x8003fda, 0x8ee201a4, -0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac, -0x2462001c, 0xac620008, 0x24020008, 0xa462000e, -0x24020011, 0xac620018, 0xac640000, 0xac650004, -0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, -0x14400034, 0x24100001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c820000, 0x1455001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x0, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10540007, -0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x8003fc6, 0x0, 0x14600005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400011, -0xac800000, 0x8003fda, 0x0, 0x8ee24e30, -0x24420001, 0x50540003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x24020001, 0xac950000, -0xac820004, 0x5600000b, 0x24100001, 0x8ee2724c, -0x3c040001, 0x248458a8, 0xafa00014, 0xafa20010, -0x8ee6724c, 0x8f470280, 0x3c050009, 0xc002403, -0x34a5f008, 0x56000001, 0xaee00e1c, 0x8ee20188, -0x24420001, 0xaee20188, 0x8004050, 0x8ee20188, -0x8f830120, 0x27623800, 0x24660020, 0xc2102b, -0x50400001, 0x27663000, 0x8f820128, 0x10c20004, -0x0, 0x8f820124, 0x14c20007, 0x0, -0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4, -0x8004044, 0x8ee201a4, 0x8ee2724c, 0xac62001c, -0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008, -0x24020008, 0xa462000e, 0x24020011, 0xac620018, -0xac640000, 0xac650004, 0x8ee204c4, 0xac620010, -0xaf860120, 0x92e24e20, 0x14400034, 0x24100001, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x8c820000, 0x1455001f, 0x0, 0x8ee34e30, -0x8ee24e34, 0x1062001b, 0x0, 0x8c820004, -0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30, -0x24420001, 0x10540007, 0x0, 0x8ee24e34, -0x24420001, 0x10620005, 0x0, 0x8004030, -0x0, 0x14600005, 0x0, 0x8f820128, -0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, -0x2c420011, 0x50400011, 0xac800000, 0x8004044, -0x0, 0x8ee24e30, 0x24420001, 0x50540003, -0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30, -0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021, -0x24020001, 0xac950000, 0xac820004, 0x1600000b, -0x0, 0x8ee2724c, 0x3c040001, 0x248458a8, -0xafa00014, 0xafa20010, 0x8ee6724c, 0x8f470280, -0x3c050009, 0xc002403, 0x34a5f008, 0x8ee20174, -0x24420001, 0xaee20174, 0x8004057, 0x8ee20174, -0x24020001, 0xaee24e24, 0x8f830128, 0x8f820124, -0x1462fd58, 0x0, 0x8fbf0030, 0x8fb5002c, -0x8fb40028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, -0x8fb00018, 0x3e00008, 0x27bd0038, 0x27bdffe8, -0x27840208, 0x27450200, 0x24060008, 0xafbf0014, -0xc00249a, 0xafb00010, 0x2021, 0x24100001, -0x2402241f, 0xaf900210, 0xaf900200, 0xaf800204, -0xaf820214, 0x8f460248, 0x24030004, 0x3c020040, -0x3c010001, 0xac235cc4, 0x3c010001, 0xac235cc8, -0x3c010001, 0xac205d9c, 0x3c010001, 0xac225cc0, -0x3c010001, 0xac235cc8, 0xc005108, 0x24050004, -0xc004822, 0x0, 0x8ee20000, 0x3c03feff, -0x3463fffd, 0x431024, 0xaee20000, 0x3c023c00, -0xaf82021c, 0x3c010001, 0x370821, 0xac3083ac, -0x8fbf0014, 0x8fb00010, 0x3e00008, 0x27bd0018, -0x27bdffe0, 0x3c050008, 0x34a50400, 0xafbf0018, -0xafa00010, 0xafa00014, 0x8f860200, 0x3c040001, -0x248459f0, 0xc002403, 0x3821, 0x8ee20280, -0x24420001, 0xaee20280, 0x8ee20280, 0x8f830200, -0x3c023f00, 0x621824, 0x8fbf0018, 0x3c020400, -0x3e00008, 0x27bd0020, 0x27bdffd8, 0xafbf0020, -0xafb1001c, 0xafb00018, 0x8f900220, 0x8ee20214, -0x3821, 0x24420001, 0xaee20214, 0x8ee20214, -0x3c020300, 0x2021024, 0x10400027, 0x3c110400, -0xc00429b, 0x0, 0x3c020100, 0x2021024, -0x10400007, 0x0, 0x8ee20218, 0x24420001, -0xaee20218, 0x8ee20218, 0x80040c6, 0x3c03fdff, -0x8ee2021c, 0x24420001, 0xaee2021c, 0x8ee2021c, -0x3c03fdff, 0x3463ffff, 0x3c0808ff, 0x3508ffff, -0x8ee20000, 0x3c040001, 0x248459fc, 0x3c050008, -0x2003021, 0x431024, 0xaee20000, 0x8f820220, -0x3821, 0x3c030300, 0x481024, 0x431025, -0xaf820220, 0xafa00010, 0xc002403, 0xafa00014, -0x8004296, 0x0, 0x2111024, 0x1040001f, -0x3c024000, 0x8f830224, 0x24021402, 0x1462000b, -0x3c03fdff, 0x3c040001, 0x24845a08, 0x3c050008, -0xafa00010, 0xafa00014, 0x8f860224, 0x34a5ffff, -0xc002403, 0x3821, 0x3c03fdff, 0x8ee20000, -0x3463ffff, 0x2002021, 0x431024, 0xc004e54, -0xaee20000, 0x8ee20220, 0x24420001, 0xaee20220, -0x8ee20220, 0x8f820220, 0x3c0308ff, 0x3463ffff, -0x431024, 0x8004295, 0x511025, 0x2021024, -0x10400142, 0x0, 0x8ee2022c, 0x24420001, -0xaee2022c, 0x8ee2022c, 0x8f820220, 0x3c0308ff, -0x3463ffff, 0x431024, 0x34420004, 0xaf820220, -0x8f830054, 0x8f820054, 0x800410e, 0x24630002, -0x8f820054, 0x621023, 0x2c420003, 0x1440fffc, -0x0, 0x8f8600e0, 0x8f8400e4, 0x30c20007, -0x10400012, 0x0, 0x8f8300e4, 0x2402fff8, -0xc21024, 0x1043000d, 0x0, 0x8f820054, -0x8f8300e0, 0x14c30009, 0x24440050, 0x8f820054, -0x821023, 0x2c420051, 0x10400004, 0x0, -0x8f8200e0, 0x10c2fff9, 0x0, 0x8f820220, -0x3c0308ff, 0x3463fffd, 0x431024, 0xaf820220, -0x8f8600e0, 0x30c20007, 0x10400003, 0x2402fff8, -0xc23024, 0xaf8600e0, 0x8f8300c4, 0x3c02001f, -0x3442ffff, 0x24680008, 0x48102b, 0x10400003, -0x3c02fff5, 0x34421000, 0x1024021, 0x8f8b00c8, -0x8f850120, 0x8f840124, 0x8004145, 0x6021, -0x27623800, 0x82102b, 0x50400001, 0x27643000, -0x10a40010, 0x318200ff, 0x8c820018, 0x38430007, -0x2c630001, 0x3842000b, 0x2c420001, 0x621825, -0x5060fff3, 0x24840020, 0x8ee20240, 0x240c0001, -0x24420001, 0xaee20240, 0x8ee20240, 0x8c8b0008, -0x318200ff, 0x14400065, 0x0, 0x3c020001, -0x571021, 0x904283c0, 0x14400060, 0x0, -0x8f8400e4, 0xc41023, 0x218c3, 0x4620001, -0x24630200, 0x8f8900c4, 0x10600005, 0x24020001, -0x10620009, 0x0, 0x8004187, 0x0, -0x8ee20230, 0x1205821, 0x24420001, 0xaee20230, -0x80041bc, 0x8ee20230, 0x8ee20234, 0x3c05000a, -0x24420001, 0xaee20234, 0x8c8b0000, 0x34a5f000, -0x8ee20234, 0x12b1823, 0xa3102b, 0x54400001, -0x651821, 0x2c62233f, 0x14400040, 0x0, -0x8f8200e8, 0x24420008, 0xaf8200e8, 0x8f8200e8, -0x8f8200e4, 0x1205821, 0x24420008, 0xaf8200e4, -0x80041bc, 0x8f8200e4, 0x8ee20238, 0x3c03000a, -0x24420001, 0xaee20238, 0x8c840000, 0x3463f000, -0x8ee20238, 0x883823, 0x67102b, 0x54400001, -0xe33821, 0x3c020003, 0x34420d40, 0x47102b, -0x10400003, 0x0, 0x80041bc, 0x805821, -0x8f8200e4, 0x24440008, 0xaf8400e4, 0x8f8400e4, -0x10860018, 0x3c05000a, 0x34a5f000, 0x3c0a0003, -0x354a0d40, 0x8ee2007c, 0x24420001, 0xaee2007c, -0x8c830000, 0x8ee2007c, 0x683823, 0xa7102b, -0x54400001, 0xe53821, 0x147102b, 0x54400007, -0x605821, 0x8f8200e4, 0x24440008, 0xaf8400e4, -0x8f8400e4, 0x1486ffef, 0x0, 0x14860005, -0x0, 0x1205821, 0xaf8600e4, 0x80041bc, -0xaf8600e8, 0xaf8400e4, 0xaf8400e8, 0x8f8200c8, -0x3c03000a, 0x3463f000, 0x483823, 0x67102b, -0x54400001, 0xe33821, 0x3c020003, 0x34420d3f, -0x47102b, 0x54400007, 0x6021, 0x1683823, -0x67102b, 0x54400003, 0xe33821, 0x80041cf, -0x3c020003, 0x3c020003, 0x34420d3f, 0x47102b, -0x14400016, 0x318200ff, 0x14400006, 0x0, -0x3c020001, 0x571021, 0x904283c0, 0x1040000f, -0x0, 0x8ee2023c, 0x3c04fdff, 0x8ee30000, -0x3484ffff, 0x24420001, 0xaee2023c, 0x8ee2023c, -0x24020001, 0x641824, 0x3c010001, 0x370821, -0xa02283b8, 0x800422c, 0xaee30000, 0xaf8b00c8, -0x8f8300c8, 0x8f8200c4, 0x3c04000a, 0x3484f000, -0x623823, 0x87102b, 0x54400001, 0xe43821, -0x3c020003, 0x34420d40, 0x47102b, 0x2ce30001, -0x431025, 0x10400008, 0x0, 0x8f820220, -0x3c0308ff, 0x3463ffff, 0x431024, 0x3c034000, -0x431025, 0xaf820220, 0x8f8600e0, 0x8f8400e4, -0x10c4002a, 0x0, 0x8ee2007c, 0x24420001, -0xaee2007c, 0x8ee2007c, 0x24c2fff8, 0xaf8200e0, -0x3c020001, 0x8c427e30, 0x3c030008, 0x8f8600e0, -0x431024, 0x1040001d, 0x0, 0x10c4001b, -0x240dfff8, 0x3c0a000a, 0x354af000, 0x3c0c0080, -0x24850008, 0x27622800, 0x50a20001, 0x27651800, -0x8c880004, 0x8c820000, 0x8ca90000, 0x3103ffff, -0x431021, 0x4d1024, 0x24430010, 0x6b102b, -0x54400001, 0x6a1821, 0x12b102b, 0x54400001, -0x12a4821, 0x10690002, 0x10c1025, 0xac820004, -0xa02021, 0x14c4ffeb, 0x24850008, 0x8f820220, -0x3c0308ff, 0x3463ffff, 0x431024, 0x34420002, -0xaf820220, 0x8f830054, 0x8f820054, 0x8004237, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x8f820220, 0x3c0308ff, -0x3463fffb, 0x431024, 0xaf820220, 0x6010055, -0x0, 0x8ee20228, 0x24420001, 0xaee20228, -0x8ee20228, 0x8f820220, 0x3c0308ff, 0x3463ffff, -0x431024, 0x34420004, 0xaf820220, 0x8f830054, -0x8f820054, 0x8004251, 0x24630002, 0x8f820054, -0x621023, 0x2c420003, 0x1440fffc, 0x0, -0x8f8600e0, 0x30c20007, 0x10400012, 0x0, -0x8f8300e4, 0x2402fff8, 0xc21024, 0x1043000d, -0x0, 0x8f820054, 0x8f8300e0, 0x14c30009, -0x24440032, 0x8f820054, 0x821023, 0x2c420033, -0x10400004, 0x0, 0x8f8200e0, 0x10c2fff9, -0x0, 0x8f820220, 0x3c0308ff, 0x3463fffd, -0x431024, 0xaf820220, 0x8f8600e0, 0x30c20007, -0x10400003, 0x2402fff8, 0xc23024, 0xaf8600e0, -0x240301f5, 0x8f8200e8, 0x673823, 0x718c0, -0x431021, 0xaf8200e8, 0x8f8200e8, 0xaf8200e4, -0x8ee2007c, 0x3c0408ff, 0x3484ffff, 0x471021, -0xaee2007c, 0x8f820220, 0x3c038000, 0x34630002, -0x441024, 0x431025, 0xaf820220, 0x8f830054, -0x8f820054, 0x800428d, 0x24630001, 0x8f820054, -0x621023, 0x2c420002, 0x1440fffc, 0x0, -0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024, -0xaf820220, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, -0x3e00008, 0x27bd0028, 0x3c020001, 0x8c425cd8, -0x27bdffd8, 0x10400012, 0xafbf0020, 0x3c040001, -0x24845a14, 0x3c050008, 0x24020001, 0x3c010001, -0x370821, 0xac2283ac, 0xafa00010, 0xafa00014, -0x8f860220, 0x34a50498, 0x3c010001, 0xac205cd8, -0x3c010001, 0xac225ccc, 0xc002403, 0x3821, -0x8f420268, 0x3c037fff, 0x3463ffff, 0x431024, -0xaf420268, 0x8ee204d0, 0x8ee404d4, 0x2403fffe, -0x431024, 0x30840002, 0x1080011e, 0xaee204d0, -0x8ee204d4, 0x2403fffd, 0x431024, 0xaee204d4, -0x8f820044, 0x3c030600, 0x34632000, 0x34420020, -0xaf820044, 0xafa30018, 0x8ee20608, 0x8f430228, -0x24420001, 0x304a00ff, 0x514300fe, 0xafa00010, -0x8ee20608, 0x210c0, 0x571021, 0x8fa30018, -0x8fa4001c, 0xac43060c, 0xac440610, 0x8f830054, -0x8f820054, 0x24690032, 0x1221023, 0x2c420033, -0x1040006a, 0x5821, 0x24180008, 0x240f000d, -0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120, -0x27623800, 0x24e80020, 0x102102b, 0x50400001, -0x27683000, 0x8f820128, 0x11020004, 0x0, -0x8f820124, 0x15020007, 0x1021, 0x8ee201a4, -0x2821, 0x24420001, 0xaee201a4, 0x800433d, -0x8ee201a4, 0x8ee40608, 0x420c0, 0x801821, -0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b, -0x822021, 0x862021, 0xace40000, 0xace50004, -0x8ee20608, 0xa4f8000e, 0xacef0018, 0xacea001c, -0x210c0, 0x2442060c, 0x2e21021, 0xace20008, -0x8ee204c4, 0xace20010, 0xaf880120, 0x92e24e20, -0x14400033, 0x24050001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c820000, 0x144d001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x0, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee34e30, 0x24420001, 0x104c0007, -0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x800432a, 0x0, 0x14600005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, -0xac800000, 0x800433d, 0x0, 0x8ee24e30, -0x24420001, 0x504c0003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0xac8d0000, 0xac8e0004, -0x54a00006, 0x240b0001, 0x8f820054, 0x1221023, -0x2c420033, 0x1440ff9d, 0x0, 0x316300ff, -0x24020001, 0x54620079, 0xafa00010, 0xaeea0608, -0x8f830054, 0x8f820054, 0x24690032, 0x1221023, -0x2c420033, 0x10400061, 0x5821, 0x240d0008, -0x240c0011, 0x24080012, 0x24070040, 0x240a0001, -0x8f830120, 0x27623800, 0x24660020, 0xc2102b, -0x50400001, 0x27663000, 0x8f820128, 0x10c20004, -0x0, 0x8f820124, 0x14c20007, 0x0, -0x8ee201a4, 0x2821, 0x24420001, 0xaee201a4, -0x80043a9, 0x8ee201a4, 0x8ee20608, 0xac62001c, -0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008, -0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004, -0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20, -0x14400033, 0x24050001, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0x8c820000, 0x1448001f, -0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b, -0x0, 0x8c820004, 0x24420001, 0xac820004, -0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10470007, -0x0, 0x8ee24e34, 0x24420001, 0x10620005, -0x0, 0x8004396, 0x0, 0x14600005, -0x0, 0x8f820128, 0x24420020, 0xaf820128, -0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, -0xac800000, 0x80043a9, 0x0, 0x8ee24e30, -0x24420001, 0x50470003, 0x1021, 0x8ee24e30, -0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0, -0x24425038, 0x2e22021, 0xac880000, 0xac8a0004, -0x54a00006, 0x240b0001, 0x8f820054, 0x1221023, -0x2c420033, 0x1440ffa6, 0x0, 0x316300ff, -0x24020001, 0x54620003, 0xafa00010, 0x80043d6, -0x0, 0x3c040001, 0x24845a20, 0xafa00014, -0x8f860120, 0x8f870124, 0x3c050009, 0xc002403, -0x34a5f011, 0x80043d6, 0x0, 0x3c040001, -0x24845a2c, 0xafa00014, 0x8f860120, 0x8f870124, -0x3c050009, 0xc002403, 0x34a5f010, 0x80043d6, -0x0, 0x3c040001, 0x24845a38, 0xafa00014, -0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403, -0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac, -0x8ee201ac, 0x8ee2015c, 0x24420001, 0xaee2015c, -0x8ee2015c, 0x8fbf0020, 0x3e00008, 0x27bd0028, -0x3c020001, 0x8c425cd8, 0x27bdffe0, 0x1440000d, -0xafbf0018, 0x3c040001, 0x24845a44, 0x3c050008, -0xafa00010, 0xafa00014, 0x8f860220, 0x34a50499, -0x24020001, 0x3c010001, 0xac225cd8, 0xc002403, -0x3821, 0x8ee204d0, 0x3c030001, 0x771821, -0x946383b2, 0x34420001, 0x10600007, 0xaee204d0, -0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, -0x34420008, 0xaf820220, 0x2021, 0xc0052a2, -0x24050004, 0xaf420268, 0x8fbf0018, 0x3e00008, -0x27bd0020, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x3c120001, -0x26521200, 0x3c140001, 0x8e945c50, 0x3c100001, -0x26101120, 0x3c15c000, 0x36b50060, 0x8e8a0000, -0x8eb30000, 0x26a400b, 0x248000a, 0x200f821, -0x0, 0xd, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x80014d6, -0x0, 0x80014d8, 0x3c0a0001, 0x80014d8, -0x3c0a0002, 0x80014d8, 0x0, 0x80024a6, -0x0, 0x80014d8, 0x3c0a0003, 0x80014d8, -0x3c0a0004, 0x8002f8c, 0x0, 0x80014d8, -0x3c0a0005, 0x8003ce8, 0x0, 0x8003c66, -0x0, 0x80014d8, 0x3c0a0006, 0x80014d8, -0x3c0a0007, 0x80014d8, 0x0, 0x80014d8, -0x0, 0x80014d8, 0x0, 0x8002a75, -0x0, 0x80014d8, 0x3c0a000b, 0x80014d8, -0x3c0a000c, 0x80014d8, 0x3c0a000d, 0x800237a, -0x0, 0x8002339, 0x0, 0x80014d8, -0x3c0a000e, 0x8001b3c, 0x0, 0x80024a4, -0x0, 0x80014d8, 0x3c0a000f, 0x80040a7, -0x0, 0x8004091, 0x0, 0x80014d8, -0x3c0a0010, 0x80014ee, 0x0, 0x80014d8, -0x3c0a0011, 0x80014d8, 0x3c0a0012, 0x80014d8, -0x3c0a0013, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x3c030001, -0x34633800, 0x24050080, 0x2404001f, 0x2406ffff, -0x24020001, 0xaf80021c, 0xaf820200, 0xaf820220, -0x3631021, 0xaf8200c0, 0x3631021, 0xaf8200c4, -0x3631021, 0xaf8200c8, 0x27623800, 0xaf8200d0, -0x27623800, 0xaf8200d4, 0x27623800, 0xaf8200d8, -0x27621800, 0xaf8200e0, 0x27621800, 0xaf8200e4, -0x27621800, 0xaf8200e8, 0x27621000, 0xaf8200f0, -0x27621000, 0xaf8200f4, 0x27621000, 0xaf8200f8, -0xaca00000, 0x2484ffff, 0x1486fffd, 0x24a50004, -0x8f830040, 0x3c02f000, 0x621824, 0x3c025000, -0x1062000c, 0x43102b, 0x14400006, 0x3c026000, -0x3c024000, 0x10620008, 0x24020800, 0x8004539, -0x0, 0x10620004, 0x24020800, 0x8004539, -0x0, 0x24020700, 0x3c010001, 0xac225cdc, -0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024, -0xafb00020, 0x8f830054, 0x8f820054, 0x3c010001, -0xac205cc4, 0x8004545, 0x24630064, 0x8f820054, -0x621023, 0x2c420065, 0x1440fffc, 0x0, -0xc004d71, 0x0, 0x24040001, 0x2821, -0x27a60018, 0x34028000, 0xc00498e, 0xa7a20018, -0x8f830054, 0x8f820054, 0x8004556, 0x24630064, -0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, -0x24040001, 0x24050001, 0xc00494c, 0x27a60018, -0x8f830054, 0x8f820054, 0x8004562, 0x24630064, -0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, -0x24040001, 0x24050001, 0xc00494c, 0x27a60018, -0x8f830054, 0x8f820054, 0x800456e, 0x24630064, -0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, -0x24040001, 0x3c060001, 0x24c65da0, 0xc00494c, -0x24050002, 0x8f830054, 0x8f820054, 0x800457b, -0x24630064, 0x8f820054, 0x621023, 0x2c420065, -0x1440fffc, 0x24040001, 0x24050003, 0x3c100001, -0x26105da2, 0xc00494c, 0x2003021, 0x97a60018, -0x3c070001, 0x94e75da0, 0x3c040001, 0x24845ab0, -0xafa00014, 0x96020000, 0x3c05000d, 0x34a50100, -0xc002403, 0xafa20010, 0x97a20018, 0x1040004c, -0x24036040, 0x96020000, 0x3042fff0, 0x1443000a, -0x24020020, 0x3c030001, 0x94635da0, 0x54620009, -0x24027830, 0x24020003, 0x3c010001, 0xac225cc4, -0x80045ac, 0x24020005, 0x3c030001, 0x94635da0, -0x24027830, 0x1462000f, 0x24030010, 0x3c020001, -0x94425da2, 0x3042fff0, 0x1443000a, 0x24020003, -0x3c010001, 0xac225cc4, 0x24020006, 0x3c010001, -0xac225db0, 0x3c010001, 0xac225dbc, 0x80045e6, -0x3c09fff0, 0x3c020001, 0x8c425cc4, 0x3c030001, -0x94635da0, 0x34420001, 0x3c010001, 0xac225cc4, -0x24020015, 0x1462000f, 0x0, 0x3c020001, -0x94425da2, 0x3042fff0, 0x3843f420, 0x2c630001, -0x3842f430, 0x2c420001, 0x621825, 0x10600005, -0x24020003, 0x3c010001, 0xac225dbc, 0x80045e6, -0x3c09fff0, 0x3c030001, 0x94635da0, 0x24027810, -0x1462000b, 0x24020002, 0x3c020001, 0x94425da2, -0x3042fff0, 0x14400006, 0x24020002, 0x24020004, -0x3c010001, 0xac225dbc, 0x80045e6, 0x3c09fff0, -0x3c010001, 0xac225dbc, 0x80045e6, 0x3c09fff0, -0x3c020001, 0x8c425cc4, 0x24030001, 0x3c010001, -0xac235dbc, 0x34420004, 0x3c010001, 0xac225cc4, -0x3c09fff0, 0x3529bdc0, 0x3c060001, 0x8cc65cc4, -0x3c040001, 0x24845ab0, 0x24020001, 0x3c010001, -0xac225ccc, 0x8f820054, 0x3c070001, 0x8ce75dbc, -0x3c030001, 0x94635da0, 0x3c080001, 0x95085da2, -0x3c05000d, 0x34a50100, 0x3c010001, 0xac205cc8, -0x491021, 0x3c010001, 0xac225dac, 0xafa30010, -0xc002403, 0xafa80014, 0x8fbf0024, 0x8fb00020, -0x3e00008, 0x27bd0028, 0x27bdffe8, 0x3c050001, -0x8ca55cc8, 0x24060004, 0x24020001, 0x14a20014, -0xafbf0010, 0x3c020001, 0x8c427e3c, 0x30428000, -0x10400005, 0x3c04000f, 0x3c030001, 0x8c635dbc, -0x8004617, 0x34844240, 0x3c040004, 0x3c030001, -0x8c635dbc, 0x348493e0, 0x24020005, 0x14620016, -0x0, 0x3c04003d, 0x800462f, 0x34840900, -0x3c020001, 0x8c427e38, 0x30428000, 0x10400005, -0x3c04001e, 0x3c030001, 0x8c635dbc, 0x800462a, -0x34848480, 0x3c04000f, 0x3c030001, 0x8c635dbc, -0x34844240, 0x24020005, 0x14620003, 0x0, -0x3c04007a, 0x34841200, 0x3c020001, 0x8c425dac, -0x8f830054, 0x441021, 0x431023, 0x44102b, -0x14400037, 0x0, 0x3c020001, 0x8c425cd0, -0x14400033, 0x0, 0x3c010001, 0x10c00025, -0xac205ce0, 0x3c090001, 0x8d295cc4, 0x24070001, -0x3c044000, 0x3c080001, 0x25087e3c, 0x250afffc, -0x52842, 0x14a00002, 0x24c6ffff, 0x24050008, -0xa91024, 0x10400010, 0x0, 0x14a70008, -0x0, 0x8d020000, 0x441024, 0x1040000a, -0x0, 0x3c010001, 0x800465b, 0xac255ce0, -0x8d420000, 0x441024, 0x10400003, 0x0, -0x3c010001, 0xac275ce0, 0x3c020001, 0x8c425ce0, -0x6182b, 0x2c420001, 0x431024, 0x5440ffe5, -0x52842, 0x8f820054, 0x3c030001, 0x8c635ce0, -0x3c010001, 0xac225dac, 0x1060002a, 0x24020001, -0x3c010001, 0xac255cc8, 0x3c010001, 0xac225ccc, -0x3c020001, 0x8c425ce0, 0x10400022, 0x0, -0x3c020001, 0x8c425ccc, 0x1040000a, 0x24020001, -0x3c010001, 0xac205ccc, 0x3c010001, 0x370821, -0xac2283ac, 0x3c010001, 0xac205d4c, 0x3c010001, -0xac225d04, 0x3c030001, 0x771821, 0x8c6383ac, -0x24020008, 0x10620005, 0x24020001, 0xc004695, -0x0, 0x8004692, 0x0, 0x3c030001, -0x8c635cc8, 0x10620007, 0x2402000e, 0x3c030001, -0x8c637dd0, 0x10620003, 0x0, 0xc004e54, -0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018, -0x27bdffe0, 0x3c02fdff, 0xafbf0018, 0x8ee30000, -0x3c050001, 0x8ca55cc8, 0x3c040001, 0x8c845cf0, -0x3442ffff, 0x621824, 0x14a40008, 0xaee30000, -0x3c030001, 0x771821, 0x8c6383ac, 0x3c020001, -0x8c425cf4, 0x10620008, 0x0, 0x3c020001, -0x571021, 0x8c4283ac, 0x3c010001, 0xac255cf0, -0x3c010001, 0xac225cf4, 0x3c030001, 0x8c635cc8, -0x24020002, 0x10620169, 0x2c620003, 0x10400005, -0x24020001, 0x10620008, 0x0, 0x800481c, -0x0, 0x24020004, 0x106200b1, 0x24020001, -0x800481d, 0x0, 0x3c020001, 0x571021, -0x8c4283ac, 0x2443ffff, 0x2c620008, 0x1040015a, -0x31080, 0x3c010001, 0x220821, 0x8c225ac8, -0x400008, 0x0, 0x3c030001, 0x8c635dbc, -0x24020005, 0x14620014, 0x0, 0x3c020001, -0x8c425cd4, 0x1040000a, 0x24020003, 0xc004822, -0x0, 0x24020002, 0x3c010001, 0x370821, -0xac2283ac, 0x3c010001, 0x80046e0, 0xac205cd4, -0x3c010001, 0x370821, 0xac2283ac, 0x3c010001, -0x800481f, 0xac205c60, 0xc004822, 0x0, -0x3c020001, 0x8c425cd4, 0x3c010001, 0xac205c60, -0x104000dd, 0x24020002, 0x3c010001, 0x370821, -0xac2283ac, 0x3c010001, 0x800481f, 0xac205cd4, -0x3c030001, 0x8c635dbc, 0x24020005, 0x14620003, -0x24020001, 0x3c010001, 0xac225d00, 0xc0049cf, -0x0, 0x3c030001, 0x8c635d00, 0x800478e, -0x24020011, 0x3c050001, 0x8ca55cc8, 0x3c060001, -0x8cc67e3c, 0xc005108, 0x2021, 0x24020005, -0x3c010001, 0xac205cd4, 0x3c010001, 0x370821, -0x800481f, 0xac2283ac, 0x3c040001, 0x24845abc, -0x3c05000f, 0x34a50100, 0x3021, 0x3821, -0xafa00010, 0xc002403, 0xafa00014, 0x800481f, -0x0, 0x8f820220, 0x3c03f700, 0x431025, -0x80047b7, 0xaf820220, 0x8f820220, 0x3c030004, -0x431024, 0x144000a9, 0x24020007, 0x8f830054, -0x3c020001, 0x8c425da4, 0x2463d8f0, 0x431023, -0x2c422710, 0x144000f8, 0x24020001, 0x800481d, -0x0, 0x3c050001, 0x8ca55cc8, 0xc0052a2, -0x2021, 0xc005386, 0x2021, 0x3c030001, -0x8c637e34, 0x46100ea, 0x24020001, 0x3c020008, -0x621024, 0x10400006, 0x0, 0x8f820214, -0x3c03ffff, 0x431024, 0x8004741, 0x3442251f, -0x8f820214, 0x3c03ffff, 0x431024, 0x3442241f, -0xaf820214, 0x8ee20000, 0x3c030200, 0x431025, -0xaee20000, 0x8f820220, 0x2403fffb, 0x431024, -0xaf820220, 0x8f820220, 0x34420002, 0xaf820220, -0x24020008, 0x3c010001, 0x370821, 0xac2283ac, -0x8f820220, 0x3c030004, 0x431024, 0x14400005, -0x0, 0x8f820220, 0x3c03f700, 0x431025, -0xaf820220, 0x3c030001, 0x8c635dbc, 0x24020005, -0x1462000a, 0x0, 0x3c020001, 0x94425da2, -0x24429fbc, 0x2c420004, 0x10400004, 0x24040018, -0x24050002, 0xc004d93, 0x24060020, 0xc0043dd, -0x0, 0x3c010001, 0x800481f, 0xac205d50, -0x3c020001, 0x571021, 0x8c4283ac, 0x2443ffff, -0x2c620008, 0x104000ac, 0x31080, 0x3c010001, -0x220821, 0x8c225ae8, 0x400008, 0x0, -0xc00429b, 0x0, 0x3c010001, 0xac205ccc, -0xaf800204, 0x3c010001, 0xc004822, 0xac207e20, -0x24020001, 0x3c010001, 0xac225ce4, 0x24020002, -0x3c010001, 0x370821, 0x800481f, 0xac2283ac, -0xc00489f, 0x0, 0x3c030001, 0x8c635ce4, -0x24020009, 0x14620090, 0x24020003, 0x3c010001, -0x370821, 0x800481f, 0xac2283ac, 0x3c020001, -0x8c427e38, 0x30424000, 0x10400005, 0x0, -0x8f820044, 0x3c03ffff, 0x800479f, 0x34637fff, -0x8f820044, 0x2403ff7f, 0x431024, 0xaf820044, -0x8f830054, 0x80047b9, 0x24020004, 0x8f830054, -0x3c020001, 0x8c425da4, 0x2463d8f0, 0x431023, -0x2c422710, 0x14400074, 0x24020005, 0x3c010001, -0x370821, 0x800481f, 0xac2283ac, 0x8f820220, -0x3c03f700, 0x431025, 0xaf820220, 0xaf800204, -0x3c010001, 0xac207e20, 0x8f830054, 0x24020006, -0x3c010001, 0x370821, 0xac2283ac, 0x3c010001, -0x800481f, 0xac235da4, 0x8f830054, 0x3c020001, -0x8c425da4, 0x2463fff6, 0x431023, 0x2c42000a, -0x14400059, 0x0, 0x24020007, 0x3c010001, -0x370821, 0x800481f, 0xac2283ac, 0x8f820220, -0x3c04f700, 0x441025, 0xaf820220, 0x8f820220, -0x3c030300, 0x431024, 0x14400005, 0x1821, -0x8f820220, 0x24030001, 0x441025, 0xaf820220, -0x10600043, 0x24020001, 0x8f820214, 0x3c03ffff, -0x3c040001, 0x8c845d98, 0x431024, 0x3442251f, -0xaf820214, 0x24020008, 0x3c010001, 0x370821, -0x1080000b, 0xac2283ac, 0x3c020001, 0x8c425d74, -0x14400007, 0x24020001, 0x3c010001, 0xac227dd0, -0xc004e54, 0x8f840220, 0x800480c, 0x0, -0x8f820220, 0x3c030008, 0x431024, 0x14400017, -0x2402000e, 0x3c010001, 0xac227dd0, 0x8ee20000, -0x2021, 0x3c030200, 0x431025, 0xc005386, -0xaee20000, 0x8f820220, 0x2403fffb, 0x431024, -0xaf820220, 0x8f820220, 0x34420002, 0xc0043dd, -0xaf820220, 0x3c050001, 0x8ca55cc8, 0xc0052a2, -0x2021, 0x800481f, 0x0, 0x3c020001, -0x8c425d74, 0x10400010, 0x0, 0x3c020001, -0x8c425d70, 0x2442ffff, 0x3c010001, 0xac225d70, -0x14400009, 0x24020002, 0x3c010001, 0xac205d74, -0x3c010001, 0x800481f, 0xac225d70, 0x24020001, -0x3c010001, 0xac225ccc, 0x8fbf0018, 0x3e00008, -0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220, -0x34420004, 0xaf820220, 0x8f820200, 0x3c060001, -0x8cc65cc8, 0x34420004, 0xaf820200, 0x24020002, -0x10c2003a, 0x2cc20003, 0x10400005, 0x24020001, -0x10c20008, 0x0, 0x8004868, 0x0, -0x24020004, 0x10c20013, 0x24020001, 0x8004868, -0x0, 0x3c030001, 0x8c635cb8, 0x3c020001, -0x8c425cc0, 0x3c040001, 0x8c845cdc, 0x3c050001, -0x8ca55cbc, 0xaf860200, 0xaf860220, 0x34630022, -0x441025, 0x451025, 0x34420002, 0x8004867, -0xaf830200, 0x3c030001, 0x8c635d98, 0xaf820200, -0x10600009, 0xaf820220, 0x3c020001, 0x8c425d74, -0x14400005, 0x3c033f00, 0x3c020001, 0x8c425cb0, -0x800485b, 0x346300e0, 0x3c020001, 0x8c425cb0, -0x3c033f00, 0x346300e2, 0x431025, 0xaf820200, -0x3c030001, 0x8c635cb4, 0x3c04f700, 0x3c020001, -0x8c425cc0, 0x3c050001, 0x8ca55cdc, 0x641825, -0x431025, 0x451025, 0xaf820220, 0x3e00008, -0x0, 0x8f820220, 0x3c030001, 0x8c635cc8, -0x34420004, 0xaf820220, 0x24020001, 0x1062000f, -0x0, 0x8f830054, 0x8f820054, 0x24630002, -0x621023, 0x2c420003, 0x10400011, 0x0, -0x8f820054, 0x621023, 0x2c420003, 0x1040000c, -0x0, 0x8004879, 0x0, 0x8f830054, -0x8f820054, 0x8004885, 0x24630007, 0x8f820054, -0x621023, 0x2c420008, 0x1440fffc, 0x0, -0x8f8400e0, 0x30820007, 0x1040000d, 0x0, -0x8f820054, 0x8f8300e0, 0x14830009, 0x24450032, -0x8f820054, 0xa21023, 0x2c420033, 0x10400004, -0x0, 0x8f8200e0, 0x1082fff9, 0x0, -0x8f820220, 0x2403fffd, 0x431024, 0xaf820220, -0x3e00008, 0x0, 0x3c030001, 0x8c635ce4, -0x3c020001, 0x8c425ce8, 0x50620004, 0x2463ffff, -0x3c010001, 0xac235ce8, 0x2463ffff, 0x2c620009, -0x1040009d, 0x31080, 0x3c010001, 0x220821, -0x8c225b08, 0x400008, 0x0, 0x8f820044, -0x34428080, 0xaf820044, 0x8f830054, 0x8004938, -0x24020002, 0x8f830054, 0x3c020001, 0x8c425da8, -0x2463d8f0, 0x431023, 0x2c422710, 0x1440008a, -0x24020003, 0x8004945, 0x0, 0x8f820044, -0x3c03ffff, 0x34637fff, 0x431024, 0xaf820044, -0x8f830054, 0x8004938, 0x24020004, 0x8f830054, -0x3c020001, 0x8c425da8, 0x2463fff6, 0x431023, -0x2c42000a, 0x14400078, 0x24020005, 0x8004945, -0x0, 0x8f820220, 0x3c03f700, 0x431025, -0xaf820220, 0x8f820220, 0x2403fffb, 0x431024, -0xaf820220, 0x8f820220, 0x34420002, 0xaf820220, -0x3c023f00, 0x344200e0, 0xaf820200, 0x8f820200, -0x2403fffd, 0x431024, 0xaf820200, 0x24040001, -0x3405ffff, 0xaf840204, 0x8f830054, 0x8f820054, -0x80048ec, 0x24630001, 0x8f820054, 0x621023, -0x2c420002, 0x1440fffc, 0x0, 0x8f820224, -0x42040, 0xa4102b, 0x1040fff2, 0x0, -0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, -0x8f820214, 0x3c03ffff, 0x431024, 0x3442251f, -0xaf820214, 0x8f820220, 0x2403fffb, 0x431024, -0xaf820220, 0x8f820220, 0x3c04f700, 0x34840008, -0x34420002, 0xaf820220, 0x8f820220, 0x3c033f00, -0x346300e2, 0x441025, 0xaf820220, 0xaf830200, -0x8f8400f0, 0x276217f8, 0x14820002, 0x24850008, -0x27651000, 0x8f8200f4, 0x10a20007, 0x3c038000, -0x34630040, 0x3c020001, 0x24425c70, 0xac820000, -0xac830004, 0xaf8500f0, 0x8f830054, 0x8004938, -0x24020006, 0x8f830054, 0x3c020001, 0x8c425da8, -0x2463fff6, 0x431023, 0x2c42000a, 0x14400022, -0x24020007, 0x8004945, 0x0, 0x8f8200e0, -0xaf8200e4, 0x8f8200e0, 0xaf8200e8, 0x8f820220, -0x34420004, 0xaf820220, 0x8f820220, 0x2403fff7, -0x431024, 0xaf820220, 0x8f820044, 0x34428080, -0xaf820044, 0x8f830054, 0x24020008, 0x3c010001, -0xac225ce4, 0x3c010001, 0x8004947, 0xac235da8, -0x8f830054, 0x3c020001, 0x8c425da8, 0x2463d8f0, -0x431023, 0x2c422710, 0x14400003, 0x24020009, -0x3c010001, 0xac225ce4, 0x3e00008, 0x0, -0x0, 0x0, 0x0, 0x27bdffd8, -0xafb20018, 0x809021, 0xafb3001c, 0xa09821, -0xafb10014, 0xc08821, 0xafb00010, 0x8021, -0xafbf0020, 0xa6200000, 0xc004d4b, 0x24040001, -0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004d4b, 0x2021, 0xc004d4b, 0x24040001, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0x24100010, 0x2501024, 0x10400002, 0x2021, -0x24040001, 0xc004d4b, 0x108042, 0x1600fffa, -0x2501024, 0x24100010, 0x2701024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x2701024, 0xc004d71, 0x34108000, -0xc004d71, 0x0, 0xc004d2b, 0x0, -0x50400005, 0x108042, 0x96220000, 0x501025, -0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc004d71, 0x0, 0x8fbf0020, 0x8fb3001c, -0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, -0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821, -0xafb20018, 0xa09021, 0xafb3001c, 0xc09821, -0xafb00010, 0x8021, 0xafbf0020, 0xc004d4b, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0x24100010, 0x2301024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x2301024, 0x24100010, 0x2501024, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x2501024, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0x34108000, -0x96620000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d4b, 0x108042, 0x1600fff8, -0x0, 0xc004d71, 0x0, 0x8fbf0020, -0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, -0x3e00008, 0x27bd0028, 0x3c030001, 0x8c635d00, -0x3c020001, 0x8c425d48, 0x27bdffd8, 0xafbf0020, -0xafb1001c, 0x10620003, 0xafb00018, 0x3c010001, -0xac235d48, 0x2463ffff, 0x2c620013, 0x10400349, -0x31080, 0x3c010001, 0x220821, 0x8c225b30, -0x400008, 0x0, 0xc004d71, 0x8021, -0x34028000, 0xa7a20010, 0x27b10010, 0xc004d4b, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0xc004d4b, -0x2021, 0x108042, 0x1600fffc, 0x0, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fff8, 0x0, 0xc004d71, 0x0, -0x8004d24, 0x24020002, 0x27b10010, 0xa7a00010, -0x8021, 0xc004d4b, 0x24040001, 0x26100001, -0x2e020020, 0x1440fffb, 0x0, 0xc004d4b, -0x2021, 0xc004d4b, 0x24040001, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0x24100010, -0x32020001, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020001, -0x24100010, 0xc004d4b, 0x2021, 0x108042, -0x1600fffc, 0x0, 0xc004d71, 0x34108000, -0xc004d71, 0x0, 0xc004d2b, 0x0, -0x50400005, 0x108042, 0x96220000, 0x501025, -0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc004d71, 0x0, 0x97a20010, 0x30428000, -0x144002dc, 0x24020003, 0x8004d24, 0x0, -0x24021200, 0xa7a20010, 0x27b10010, 0x8021, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0xc004d4b, 0x2021, 0x108042, 0x1600fffc, -0x0, 0xc004d4b, 0x24040001, 0xc004d4b, -0x2021, 0x34108000, 0x96220000, 0x501024, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fff8, 0x0, 0xc004d71, -0x0, 0x8f830054, 0x8004d16, 0x24020004, -0x8f830054, 0x3c020001, 0x8c425db8, 0x2463ff9c, -0x431023, 0x2c420064, 0x1440029e, 0x24020002, -0x3c030001, 0x8c635dbc, 0x10620297, 0x2c620003, -0x14400296, 0x24020011, 0x24020003, 0x10620005, -0x24020004, 0x10620291, 0x2402000f, 0x8004d24, -0x24020011, 0x8004d24, 0x24020005, 0x24020014, -0xa7a20010, 0x27b10010, 0x8021, 0xc004d4b, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x32020012, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020012, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0x34108000, -0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d4b, 0x108042, 0x1600fff8, -0x0, 0xc004d71, 0x0, 0x8f830054, -0x8004d16, 0x24020006, 0x8f830054, 0x3c020001, -0x8c425db8, 0x2463ff9c, 0x431023, 0x2c420064, -0x14400250, 0x24020007, 0x8004d24, 0x0, -0x24020006, 0xa7a20010, 0x27b10010, 0x8021, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020013, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020013, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fff8, 0x0, 0xc004d71, 0x0, -0x8f830054, 0x8004d16, 0x24020008, 0x8f830054, -0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023, -0x2c420064, 0x1440020f, 0x24020009, 0x8004d24, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001, -0xc004d4b, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020018, -0xc004d71, 0x34108000, 0xc004d71, 0x0, -0xc004d2b, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004d71, 0x8021, -0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020018, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fff8, 0x0, 0xc004d71, 0x0, -0x8f830054, 0x8004d16, 0x2402000a, 0x8f830054, -0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023, -0x2c420064, 0x1440019b, 0x2402000b, 0x8004d24, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001, -0xc004d4b, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020017, -0xc004d71, 0x34108000, 0xc004d71, 0x0, -0xc004d2b, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004d71, 0x8021, -0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020017, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fff8, 0x0, 0xc004d71, 0x0, -0x8f830054, 0x8004d16, 0x2402000c, 0x8f830054, -0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023, -0x2c420064, 0x14400127, 0x24020012, 0x8004d24, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001, -0xc004d4b, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020014, -0xc004d71, 0x34108000, 0xc004d71, 0x0, -0xc004d2b, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004d71, 0x8021, -0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020014, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fff8, 0x0, 0xc004d71, 0x0, -0x8f830054, 0x8004d16, 0x24020013, 0x8f830054, -0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023, -0x2c420064, 0x144000b3, 0x2402000d, 0x8004d24, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001, -0xc004d4b, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020018, -0xc004d71, 0x34108000, 0xc004d71, 0x0, -0xc004d2b, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004d71, 0x8021, -0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010, -0xc004d4b, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0xc004d4b, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d4b, 0x108042, 0x1600fffa, 0x32020018, -0xc004d4b, 0x24040001, 0xc004d4b, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fff8, 0x0, 0xc004d71, 0x0, -0x8f830054, 0x8004d16, 0x2402000e, 0x24020840, -0xa7a20010, 0x27b10010, 0x8021, 0xc004d4b, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x32020013, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x32020013, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0x34108000, -0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d4b, 0x108042, 0x1600fff8, -0x0, 0xc004d71, 0x0, 0x8f830054, -0x24020010, 0x3c010001, 0xac225d00, 0x3c010001, -0x8004d26, 0xac235db8, 0x8f830054, 0x3c020001, -0x8c425db8, 0x2463ff9c, 0x431023, 0x2c420064, -0x14400004, 0x0, 0x24020011, 0x3c010001, -0xac225d00, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, -0x3e00008, 0x27bd0028, 0x8f850044, 0x8f820044, -0x3c030001, 0x431025, 0x3c030008, 0xaf820044, -0x8f840054, 0x8f820054, 0xa32824, 0x8004d37, -0x24840001, 0x8f820054, 0x821023, 0x2c420002, -0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe, -0x3463ffff, 0x431024, 0xaf820044, 0x8f830054, -0x8f820054, 0x8004d45, 0x24630001, 0x8f820054, -0x621023, 0x2c420002, 0x1440fffc, 0x0, -0x3e00008, 0xa01021, 0x8f830044, 0x3c02fff0, -0x3442ffff, 0x42480, 0x621824, 0x3c020002, -0x822025, 0x641825, 0xaf830044, 0x8f820044, -0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044, -0x8f830054, 0x8f820054, 0x8004d5e, 0x24630001, -0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, -0x0, 0x8f820044, 0x3c030001, 0x431025, -0xaf820044, 0x8f830054, 0x8f820054, 0x8004d6b, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x3e00008, 0x0, -0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024, -0xaf820044, 0x8f820044, 0x3c030001, 0x431025, -0xaf820044, 0x8f830054, 0x8f820054, 0x8004d7f, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe, -0x3463ffff, 0x431024, 0xaf820044, 0x8f830054, -0x8f820054, 0x8004d8d, 0x24630001, 0x8f820054, -0x621023, 0x2c420002, 0x1440fffc, 0x0, -0x3e00008, 0x0, 0x27bdffc8, 0xafb30024, -0x809821, 0xafb5002c, 0xa0a821, 0xafb20020, -0xc09021, 0x32a2ffff, 0xafbf0030, 0xafb40028, -0xafb1001c, 0xafb00018, 0x14400034, 0xa7b20010, -0x3271ffff, 0x27b20010, 0x8021, 0xc004d4b, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x2301024, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x2301024, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0x34108000, -0x96420000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d4b, 0x108042, 0x12000075, -0x0, 0x8004dc9, 0x0, 0x3274ffff, -0x27b10010, 0xa7a00010, 0x8021, 0xc004d4b, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0xc004d4b, 0x24040001, 0xc004d4b, -0x2021, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x2901024, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x2901024, 0xc004d71, -0x34108000, 0xc004d71, 0x0, 0xc004d2b, -0x0, 0x50400005, 0x108042, 0x96220000, -0x501025, 0xa6220000, 0x108042, 0x1600fff7, -0x0, 0xc004d71, 0x0, 0x32a5ffff, -0x24020001, 0x54a20004, 0x24020002, 0x97a20010, -0x8004e14, 0x521025, 0x14a20006, 0x3271ffff, -0x97a20010, 0x121827, 0x431024, 0xa7a20010, -0x3271ffff, 0x27b20010, 0x8021, 0xc004d4b, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0xc004d4b, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d4b, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x2301024, -0x10400002, 0x2021, 0x24040001, 0xc004d4b, -0x108042, 0x1600fffa, 0x2301024, 0xc004d4b, -0x24040001, 0xc004d4b, 0x2021, 0x34108000, -0x96420000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d4b, 0x108042, 0x1600fff8, -0x0, 0xc004d71, 0x0, 0x8fbf0030, -0x8fb5002c, 0x8fb40028, 0x8fb30024, 0x8fb20020, -0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038, -0x0, 0x0, 0x0, 0x27bdffe8, -0xafbf0010, 0x3c030001, 0x771821, 0x8c6383ac, -0x24020008, 0x1462022c, 0x803021, 0x3c020001, -0x8c425d98, 0x14400033, 0x0, 0x8f850224, -0x38a30020, 0x2c630001, 0x38a20010, 0x2c420001, -0x621825, 0x1460000d, 0x38a30030, 0x2c630001, -0x38a20400, 0x2c420001, 0x621825, 0x14600007, -0x38a30402, 0x2c630001, 0x38a20404, 0x2c420001, -0x621825, 0x10600005, 0x0, 0xc00429b, -0x0, 0x8004e8d, 0x2402000e, 0xc0043dd, -0x0, 0x3c050001, 0x8ca55cc8, 0xc0052a2, -0x2021, 0x3c030001, 0x8c635cc8, 0x24020004, -0x14620005, 0x2403fffb, 0x3c020001, 0x8c425cc4, -0x8004e89, 0x2403fff7, 0x3c020001, 0x8c425cc4, -0x431024, 0x3c010001, 0xac225cc4, 0x2402000e, -0x3c010001, 0xc00429b, 0xac227dd0, 0x8005087, -0x0, 0x8f820220, 0x3c030400, 0x431024, -0x10400027, 0x2403ffbf, 0x8f850224, 0x3c020001, -0x8c427ddc, 0xa32024, 0x431024, 0x1482000c, -0x0, 0x3c020001, 0x8c427de0, 0x24420001, -0x3c010001, 0xac227de0, 0x2c420002, 0x14400008, -0x24020001, 0x3c010001, 0x8004ead, 0xac227e00, -0x3c010001, 0xac207de0, 0x3c010001, 0xac207e00, -0x3c020001, 0x8c427e00, 0x10400006, 0x30a20040, -0x10400004, 0x24020001, 0x3c010001, 0x8004eb8, -0xac227e04, 0x3c010001, 0xac207e04, 0x3c010001, -0xac257ddc, 0x3c010001, 0x8004ec8, 0xac207e10, -0x24020001, 0x3c010001, 0xac227e10, 0x3c010001, -0xac207e00, 0x3c010001, 0xac207de0, 0x3c010001, -0xac207e04, 0x3c010001, 0xac207ddc, 0x3c030001, -0x8c637dd0, 0x3c020001, 0x8c427dd4, 0x10620003, -0x3c020200, 0x3c010001, 0xac237dd4, 0xc21024, -0x10400007, 0x2463ffff, 0x8f820220, 0x24030001, -0x3c010001, 0xac235ccc, 0x8005085, 0x3c03f700, -0x2c62000e, 0x104001a8, 0x31080, 0x3c010001, -0x220821, 0x8c225b80, 0x400008, 0x0, -0x3c010001, 0xac207e00, 0x3c010001, 0xac207de0, -0x3c010001, 0xac207ddc, 0x3c010001, 0xac207e04, -0x3c010001, 0xac207df8, 0x3c010001, 0xac207df0, -0xc00486a, 0xaf800224, 0x24020002, 0x3c010001, -0xac227dd0, 0x3c020001, 0x8c427e10, 0x14400056, -0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024, -0xc00429b, 0xaee20000, 0xaf800204, 0x8f820200, -0x2403fffd, 0x431024, 0xaf820200, 0x3c010001, -0xac207e20, 0x8f830054, 0x3c020001, 0x8c427df8, -0x24040001, 0x3c010001, 0xac247e0c, 0x24420001, -0x3c010001, 0xac227df8, 0x2c420004, 0x3c010001, -0xac237df4, 0x14400006, 0x24020003, 0x3c010001, -0xac245ccc, 0x3c010001, 0x8005083, 0xac207df8, -0x3c010001, 0x8005083, 0xac227dd0, 0x8f830054, -0x3c020001, 0x8c427df4, 0x2463d8f0, 0x431023, -0x2c422710, 0x14400003, 0x24020004, 0x3c010001, -0xac227dd0, 0x3c020001, 0x8c427e10, 0x14400026, -0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024, -0x8005083, 0xaee20000, 0x3c040001, 0x8c845d9c, -0x3c010001, 0xc00508a, 0xac207de8, 0x3c020001, -0x8c427e1c, 0xaf820204, 0x3c020001, 0x8c427e10, -0x14400015, 0x3c03fdff, 0x8ee20000, 0x3463ffff, -0x431024, 0xaee20000, 0x8f820204, 0x30420030, -0x1440013c, 0x24020002, 0x3c030001, 0x8c637e1c, -0x24020005, 0x3c010001, 0xac227dd0, 0x3c010001, -0x8005083, 0xac237e20, 0x3c020001, 0x8c427e10, -0x10400010, 0x3c03fdff, 0x3c020001, 0x8c425d6c, -0x24420001, 0x3c010001, 0xac225d6c, 0x2c420002, -0x14400131, 0x24020001, 0x3c010001, 0xac225d74, -0x3c010001, 0xac205d6c, 0x3c010001, 0x8005083, -0xac225ccc, 0x8ee20000, 0x3463ffff, 0x431024, -0xaee20000, 0x3c020001, 0x8c427e00, 0x10400122, -0x0, 0x3c020001, 0x8c427ddc, 0x1040011e, -0x0, 0x3c010001, 0xac227e08, 0x24020003, -0x3c010001, 0xac227de0, 0x8005024, 0x24020006, -0x3c010001, 0xac207de8, 0x8f820204, 0x34420040, -0xaf820204, 0x3c020001, 0x8c427e20, 0x24030007, -0x3c010001, 0xac237dd0, 0x34420040, 0x3c010001, -0xac227e20, 0x3c020001, 0x8c427e00, 0x10400005, -0x0, 0x3c020001, 0x8c427ddc, 0x104000f9, -0x24020002, 0x3c050001, 0x24a57de0, 0x8ca20000, -0x2c424e21, 0x104000f3, 0x24020002, 0x3c020001, -0x8c427e04, 0x104000f8, 0x2404ffbf, 0x3c020001, -0x8c427ddc, 0x3c030001, 0x8c637e08, 0x441024, -0x641824, 0x10430004, 0x24020001, 0x3c010001, -0x8005083, 0xac227dd0, 0x24020003, 0xaca20000, -0x24020008, 0x3c010001, 0xac227dd0, 0x3c020001, -0x8c427e0c, 0x1040000c, 0x24020001, 0x3c040001, -0xc005097, 0x8c847ddc, 0x3c020001, 0x8c427e28, -0x14400005, 0x24020001, 0x3c020001, 0x8c427e24, -0x10400006, 0x24020001, 0x3c010001, 0xac225ccc, -0x3c010001, 0x8005083, 0xac207df8, 0x3c020001, -0x8c427df0, 0x3c030001, 0x8c637ddc, 0x2c420001, -0x210c0, 0x30630008, 0x3c010001, 0xac227df0, -0x3c010001, 0xac237dec, 0x8f830054, 0x24020009, -0x3c010001, 0xac227dd0, 0x3c010001, 0x8005083, -0xac237df4, 0x8f830054, 0x3c020001, 0x8c427df4, -0x2463d8f0, 0x431023, 0x2c422710, 0x144000a8, -0x0, 0x3c020001, 0x8c427e00, 0x10400005, -0x0, 0x3c020001, 0x8c427ddc, 0x104000a9, -0x24020002, 0x3c030001, 0x24637de0, 0x8c620000, -0x2c424e21, 0x104000a3, 0x24020002, 0x3c020001, -0x8c427e0c, 0x1040000e, 0x0, 0x3c020001, -0x8c427ddc, 0x3c010001, 0xac207e0c, 0x30420080, -0x1040002f, 0x2402000c, 0x8f820204, 0x30420080, -0x1440000c, 0x24020003, 0x8005011, 0x2402000c, -0x3c020001, 0x8c427ddc, 0x30420080, 0x14400005, -0x24020003, 0x8f820204, 0x30420080, 0x1040001f, -0x24020003, 0xac620000, 0x2402000a, 0x3c010001, -0xac227dd0, 0x3c040001, 0x24847e18, 0x8c820000, -0x3c030001, 0x8c637df0, 0x431025, 0xaf820204, -0x8c830000, 0x3c040001, 0x8c847df0, 0x2402000b, -0x3c010001, 0xac227dd0, 0x641825, 0x3c010001, -0xac237e20, 0x3c050001, 0x24a57de0, 0x8ca20000, -0x2c424e21, 0x1040006f, 0x24020002, 0x3c020001, -0x8c427e10, 0x10400005, 0x0, 0x2402000c, -0x3c010001, 0x8005083, 0xac227dd0, 0x3c020001, -0x8c427e00, 0x1040006c, 0x0, 0x3c040001, -0x8c847ddc, 0x1080005e, 0x30820008, 0x3c030001, -0x8c637dec, 0x10620064, 0x24020003, 0x3c010001, -0xac247e08, 0xaca20000, 0x24020006, 0x3c010001, -0x8005083, 0xac227dd0, 0x8f820200, 0x34420002, -0xaf820200, 0x8f830054, 0x2402000d, 0x3c010001, -0xac227dd0, 0x3c010001, 0xac237df4, 0x8f830054, -0x3c020001, 0x8c427df4, 0x2463d8f0, 0x431023, -0x2c422710, 0x1440003a, 0x0, 0x3c020001, -0x8c427e10, 0x10400029, 0x2402000e, 0x3c030001, -0x8c637e24, 0x3c010001, 0x14600015, 0xac227dd0, -0xc0043dd, 0x0, 0x3c050001, 0x8ca55cc8, -0xc0052a2, 0x2021, 0x3c030001, 0x8c635cc8, -0x24020004, 0x14620005, 0x2403fffb, 0x3c020001, -0x8c425cc4, 0x8005052, 0x2403fff7, 0x3c020001, -0x8c425cc4, 0x431024, 0x3c010001, 0xac225cc4, -0x8ee20000, 0x3c030200, 0x431025, 0xaee20000, -0x8f820224, 0x3c010001, 0xac227e2c, 0x8f820220, -0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, -0x34420002, 0x8005083, 0xaf820220, 0x3c020001, -0x8c427e00, 0x10400005, 0x0, 0x3c020001, -0x8c427ddc, 0x1040000f, 0x24020002, 0x3c020001, -0x8c427de0, 0x2c424e21, 0x1040000a, 0x24020002, -0x3c020001, 0x8c427e00, 0x1040000f, 0x0, -0x3c020001, 0x8c427ddc, 0x1440000b, 0x0, -0x24020002, 0x3c010001, 0x8005083, 0xac227dd0, -0x3c020001, 0x8c427e00, 0x10400003, 0x0, -0xc00429b, 0x0, 0x8f820220, 0x3c03f700, -0x431025, 0xaf820220, 0x8fbf0010, 0x3e00008, -0x27bd0018, 0x3c030001, 0x24637e28, 0x8c620000, -0x10400005, 0x34422000, 0x3c010001, 0xac227e1c, -0x8005095, 0xac600000, 0x3c010001, 0xac247e1c, -0x3e00008, 0x0, 0x27bdffe0, 0x30820030, -0xafbf0018, 0x3c010001, 0xac227e24, 0x14400067, -0x3c02ffff, 0x34421f0e, 0x821024, 0x14400061, -0x24020030, 0x30822000, 0x1040005d, 0x30838000, -0x31a02, 0x30820001, 0x21200, 0x3c040001, -0x8c845d9c, 0x621825, 0x331c2, 0x3c030001, -0x24635d78, 0x30828000, 0x21202, 0x30840001, -0x42200, 0x441025, 0x239c2, 0x61080, -0x431021, 0x471021, 0x90430000, 0x24020001, -0x10620025, 0x0, 0x10600007, 0x24020002, -0x10620013, 0x24020003, 0x1062002c, 0x3c05000f, -0x80050f9, 0x0, 0x8f820200, 0x2403feff, -0x431024, 0xaf820200, 0x8f820220, 0x3c03fffe, -0x3463ffff, 0x431024, 0xaf820220, 0x3c010001, -0xac207e44, 0x3c010001, 0x8005104, 0xac207e4c, -0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, -0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220, -0x24020100, 0x3c010001, 0xac227e44, 0x3c010001, -0x8005104, 0xac207e4c, 0x8f820200, 0x2403feff, -0x431024, 0xaf820200, 0x8f820220, 0x3c030001, -0x431025, 0xaf820220, 0x3c010001, 0xac207e44, -0x3c010001, 0x8005104, 0xac237e4c, 0x8f820200, -0x34420100, 0xaf820200, 0x8f820220, 0x3c030001, -0x431025, 0xaf820220, 0x24020100, 0x3c010001, -0xac227e44, 0x3c010001, 0x8005104, 0xac237e4c, -0x34a5ffff, 0x3c040001, 0x24845bb8, 0xafa30010, -0xc002403, 0xafa00014, 0x8005104, 0x0, -0x24020030, 0x3c010001, 0xac227e28, 0x8fbf0018, -0x3e00008, 0x27bd0020, 0x0, 0x27bdffc8, -0xafb20028, 0x809021, 0xafb3002c, 0xa09821, -0xafb00020, 0xc08021, 0x3c040001, 0x24845bd0, -0x3c050009, 0x3c020001, 0x8c425cc8, 0x34a59001, -0x2403021, 0x2603821, 0xafbf0030, 0xafb10024, -0xa7a0001a, 0xafb00014, 0xc002403, 0xafa20010, -0x24020002, 0x12620083, 0x2e620003, 0x10400005, -0x24020001, 0x1262000a, 0x0, 0x800529b, -0x0, 0x24020004, 0x126200fa, 0x24020008, -0x126200f9, 0x3c02ffec, 0x800529b, 0x0, -0x3c020001, 0x8c425cc4, 0x30420002, 0x14400004, -0x128940, 0x3c02fffb, 0x3442ffff, 0x2028024, -0x3c010001, 0x310821, 0xac307e3c, 0x3c024000, -0x2021024, 0x1040004e, 0x1023c2, 0x30840030, -0x101382, 0x3042001c, 0x3c030001, 0x24635d08, -0x431021, 0x823821, 0x3c020020, 0x2021024, -0x10400006, 0x24020100, 0x3c010001, 0x310821, -0xac227e40, 0x8005150, 0x3c020080, 0x3c010001, -0x310821, 0xac207e40, 0x3c020080, 0x2021024, -0x10400006, 0x121940, 0x3c020001, 0x3c010001, -0x230821, 0x800515c, 0xac227e48, 0x121140, -0x3c010001, 0x220821, 0xac207e48, 0x94e40000, -0x3c030001, 0x8c635dbc, 0x24020005, 0x10620010, -0xa7a40018, 0x32024000, 0x10400002, 0x34824000, -0xa7a20018, 0x24040001, 0x94e20002, 0x24050004, -0x24e60002, 0x34420001, 0xc00498e, 0xa4e20002, -0x24040001, 0x2821, 0xc00498e, 0x27a60018, -0x3c020001, 0x8c425cc8, 0x24110001, 0x3c010001, -0xac315cd4, 0x14530004, 0x32028000, 0xc00429b, -0x0, 0x32028000, 0x1040011f, 0x0, -0xc00429b, 0x0, 0x3c030001, 0x8c635dbc, -0x24020005, 0x10620118, 0x24020002, 0x3c010001, -0xac315ccc, 0x3c010001, 0x800529b, 0xac225cc8, -0x24040001, 0x24050004, 0x27b0001a, 0xc00498e, -0x2003021, 0x24040001, 0x2821, 0xc00498e, -0x2003021, 0x3c020001, 0x511021, 0x8c427e34, -0x3c040001, 0x8c845cc8, 0x3c03bfff, 0x3463ffff, -0x3c010001, 0xac335cd4, 0x431024, 0x3c010001, -0x310821, 0x109300fa, 0xac227e34, 0x800529b, -0x0, 0x3c022000, 0x2021024, 0x10400005, -0x24020001, 0x3c010001, 0xac225d98, 0x80051ad, -0x128940, 0x3c010001, 0xac205d98, 0x128940, -0x3c010001, 0x310821, 0xac307e38, 0x3c024000, -0x2021024, 0x14400016, 0x0, 0x3c020001, -0x8c425d98, 0x10400008, 0x24040004, 0x24050001, -0xc004d93, 0x24062000, 0x24020001, 0x3c010001, -0x370821, 0xac2283ac, 0x3c020001, 0x511021, -0x8c427e30, 0x3c03bfff, 0x3463ffff, 0x431024, -0x3c010001, 0x310821, 0x8005299, 0xac227e30, -0x3c020001, 0x8c425d98, 0x10400028, 0x3c0300a0, -0x2031024, 0x5443000d, 0x3c020020, 0x3c020001, -0x8c425d9c, 0x24030100, 0x3c010001, 0x310821, -0xac237e44, 0x3c030001, 0x3c010001, 0x310821, -0xac237e4c, 0x80051f0, 0x34420400, 0x2021024, -0x10400008, 0x24030100, 0x3c020001, 0x8c425d9c, -0x3c010001, 0x310821, 0xac237e44, 0x80051f0, -0x34420800, 0x3c020080, 0x2021024, 0x1040002e, -0x3c030001, 0x3c020001, 0x8c425d9c, 0x3c010001, -0x310821, 0xac237e4c, 0x34420c00, 0x3c010001, -0xac225d9c, 0x8005218, 0x24040001, 0x3c020020, -0x2021024, 0x10400006, 0x24020100, 0x3c010001, -0x310821, 0xac227e44, 0x8005201, 0x3c020080, -0x3c010001, 0x310821, 0xac207e44, 0x3c020080, -0x2021024, 0x10400007, 0x121940, 0x3c020001, -0x3c010001, 0x230821, 0xac227e4c, 0x800520f, -0x24040001, 0x121140, 0x3c010001, 0x220821, -0xac207e4c, 0x24040001, 0x2821, 0x27b0001e, -0xc00494c, 0x2003021, 0x24040001, 0x2821, -0xc00494c, 0x2003021, 0x24040001, 0x24050001, -0x27b0001c, 0xc00494c, 0x2003021, 0x24040001, -0x24050001, 0xc00494c, 0x2003021, 0x8005299, -0x0, 0x3c02ffec, 0x3442ffff, 0x2028024, -0x3c020008, 0x2028025, 0x121140, 0x3c010001, -0x220821, 0xac307e38, 0x3c022000, 0x2021024, -0x10400009, 0x0, 0x3c020001, 0x8c425d74, -0x14400005, 0x24020001, 0x3c010001, 0xac225d98, -0x800523a, 0x3c024000, 0x3c010001, 0xac205d98, -0x3c024000, 0x2021024, 0x1440001e, 0x0, -0x3c020001, 0x8c425d98, 0x3c010001, 0xac205ce0, -0x10400007, 0x24022020, 0x3c010001, 0xac225d9c, -0x24020001, 0x3c010001, 0x370821, 0xac2283ac, -0x3c04bfff, 0x121940, 0x3c020001, 0x431021, -0x8c427e30, 0x3c050001, 0x8ca55cc8, 0x3484ffff, -0x441024, 0x3c010001, 0x230821, 0xac227e30, -0x24020001, 0x10a20044, 0x0, 0x8005299, -0x0, 0x3c020001, 0x8c425d98, 0x1040001c, -0x24022000, 0x3c010001, 0xac225d9c, 0x3c0300a0, -0x2031024, 0x14430005, 0x121140, 0x3402a000, -0x3c010001, 0x8005294, 0xac225d9c, 0x3c030001, -0x621821, 0x8c637e38, 0x3c020020, 0x621024, -0x10400004, 0x24022001, 0x3c010001, 0x8005294, -0xac225d9c, 0x3c020080, 0x621024, 0x1040001f, -0x3402a001, 0x3c010001, 0x8005294, 0xac225d9c, -0x3c020020, 0x2021024, 0x10400007, 0x121940, -0x24020100, 0x3c010001, 0x230821, 0xac227e44, -0x8005288, 0x3c020080, 0x121140, 0x3c010001, -0x220821, 0xac207e44, 0x3c020080, 0x2021024, -0x10400006, 0x121940, 0x3c020001, 0x3c010001, -0x230821, 0x8005294, 0xac227e4c, 0x121140, -0x3c010001, 0x220821, 0xac207e4c, 0x3c030001, -0x8c635cc8, 0x24020001, 0x10620003, 0x0, -0xc00429b, 0x0, 0x8fbf0030, 0x8fb3002c, -0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008, -0x27bd0038, 0x27bdffd8, 0xafb20020, 0x809021, -0xafb1001c, 0x8821, 0x24020002, 0xafbf0024, -0xafb00018, 0xa7a00012, 0x10a200d3, 0xa7a00010, -0x2ca20003, 0x10400005, 0x24020001, 0x10a2000a, -0x128140, 0x8005380, 0x2201021, 0x24020004, -0x10a2007d, 0x24020008, 0x10a2007c, 0x122940, -0x8005380, 0x2201021, 0x3c030001, 0x701821, -0x8c637e3c, 0x3c024000, 0x621024, 0x14400009, -0x24040001, 0x3c027fff, 0x3442ffff, 0x628824, -0x3c010001, 0x300821, 0xac317e34, 0x8005380, -0x2201021, 0x24050001, 0xc00494c, 0x27a60010, -0x24040001, 0x24050001, 0xc00494c, 0x27a60010, -0x97a20010, 0x30420004, 0x10400034, 0x3c114000, -0x3c020001, 0x8c425dbc, 0x2443ffff, 0x2c620006, -0x10400034, 0x31080, 0x3c010001, 0x220821, -0x8c225be0, 0x400008, 0x0, 0x24040001, -0x24050011, 0x27b00012, 0xc00494c, 0x2003021, -0x24040001, 0x24050011, 0xc00494c, 0x2003021, -0x97a50012, 0x30a24000, 0x10400002, 0x3c040010, -0x3c040008, 0x3c030001, 0x8005301, 0x30a28000, -0x24040001, 0x24050014, 0x27b00012, 0xc00494c, -0x2003021, 0x24040001, 0x24050014, 0xc00494c, -0x2003021, 0x97a50012, 0x30a21000, 0x10400002, -0x3c040010, 0x3c040008, 0x3c030001, 0x30a20800, -0x54400001, 0x3c030002, 0x3c028000, 0x2221025, -0x641825, 0x800530e, 0x438825, 0x3c110001, -0x2308821, 0x8e317e3c, 0x3c027fff, 0x3442ffff, -0x2228824, 0x3c020001, 0x8c425cd8, 0x1040001d, -0x121140, 0x3c020001, 0x8c425d98, 0x10400002, -0x3c022000, 0x2228825, 0x121140, 0x3c010001, -0x220821, 0x8c227e40, 0x10400003, 0x3c020020, -0x8005322, 0x2228825, 0x3c02ffdf, 0x3442ffff, -0x2228824, 0x121140, 0x3c010001, 0x220821, -0x8c227e48, 0x10400003, 0x3c020080, 0x800532d, -0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824, -0x121140, 0x3c010001, 0x220821, 0xac317e34, -0x8005380, 0x2201021, 0x122940, 0x3c030001, -0x651821, 0x8c637e38, 0x3c024000, 0x621024, -0x14400008, 0x3c027fff, 0x3442ffff, 0x628824, -0x3c010001, 0x250821, 0xac317e30, 0x8005380, -0x2201021, 0x3c020001, 0x8c425cd8, 0x10400033, -0x3c11c00c, 0x3c020001, 0x8c425d74, 0x3c04c00c, -0x34842000, 0x3c030001, 0x8c635d98, 0x2102b, -0x21023, 0x441024, 0x10600003, 0x518825, -0x3c022000, 0x2228825, 0x3c020001, 0x451021, -0x8c427e44, 0x10400003, 0x3c020020, 0x800535d, -0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824, -0x121140, 0x3c010001, 0x220821, 0x8c227e4c, -0x10400003, 0x3c020080, 0x8005368, 0x2228825, -0x3c02ff7f, 0x3442ffff, 0x2228824, 0x3c020001, -0x8c425d60, 0x10400002, 0x3c020800, 0x2228825, -0x3c020001, 0x8c425d64, 0x10400002, 0x3c020400, -0x2228825, 0x3c020001, 0x8c425d68, 0x10400006, -0x3c020100, 0x800537b, 0x2228825, 0x3c027fff, -0x3442ffff, 0x628824, 0x121140, 0x3c010001, -0x220821, 0xac317e30, 0x2201021, 0x8fbf0024, -0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008, -0x27bd0028, 0x27bdffd8, 0xafb40020, 0x80a021, -0xafbf0024, 0xafb3001c, 0xafb20018, 0xafb10014, -0xafb00010, 0x8f900200, 0x3c030001, 0x8c635cc8, -0x8f930220, 0x24020002, 0x10620063, 0x2c620003, -0x10400005, 0x24020001, 0x1062000a, 0x141940, -0x8005448, 0x0, 0x24020004, 0x1062005a, -0x24020008, 0x10620059, 0x149140, 0x8005448, -0x0, 0x3c040001, 0x832021, 0x8c847e3c, -0x3c110001, 0x2238821, 0x8e317e34, 0x3c024000, -0x821024, 0x1040003e, 0x3c020008, 0x2221024, -0x10400020, 0x36100002, 0x3c020001, 0x431021, -0x8c427e40, 0x10400005, 0x36100020, 0x36100100, -0x3c020020, 0x80053bd, 0x2228825, 0x2402feff, -0x2028024, 0x3c02ffdf, 0x3442ffff, 0x2228824, -0x141140, 0x3c010001, 0x220821, 0x8c227e48, -0x10400005, 0x3c020001, 0x2629825, 0x3c020080, -0x80053dc, 0x2228825, 0x3c02fffe, 0x3442ffff, -0x2629824, 0x3c02ff7f, 0x3442ffff, 0x80053dc, -0x2228824, 0x2402fedf, 0x2028024, 0x3c02fffe, -0x3442ffff, 0x2629824, 0x3c02ff5f, 0x3442ffff, -0x2228824, 0x3c010001, 0x230821, 0xac207e40, -0x3c010001, 0x230821, 0xac207e48, 0xc00486a, -0x0, 0xaf900200, 0xaf930220, 0x8f820220, -0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, -0x34420002, 0xaf820220, 0x80053f3, 0x141140, -0x8f820200, 0x2403fffd, 0x431024, 0xc00486a, -0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b, -0x2228824, 0x141140, 0x3c010001, 0x220821, -0x8005448, 0xac317e34, 0x149140, 0x3c040001, -0x922021, 0x8c847e38, 0x3c110001, 0x2328821, -0x8e317e30, 0x3c024000, 0x821024, 0x14400011, -0x0, 0x3c020001, 0x8c425d98, 0x14400006, -0x3c02bfff, 0x8f820200, 0x34420002, 0xc00486a, -0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b, -0x2228824, 0x3c010001, 0x320821, 0x8005448, -0xac317e30, 0x3c020001, 0x8c425d98, 0x10400005, -0x3c020020, 0x3c020001, 0x8c425d74, 0x1040002b, -0x3c020020, 0x821024, 0x10400007, 0x36100020, -0x24020100, 0x3c010001, 0x320821, 0xac227e44, -0x8005428, 0x36100100, 0x3c010001, 0x320821, -0xac207e44, 0x2402feff, 0x2028024, 0x3c020080, -0x821024, 0x10400007, 0x141940, 0x3c020001, -0x3c010001, 0x230821, 0xac227e4c, 0x8005439, -0x2629825, 0x141140, 0x3c010001, 0x220821, -0xac207e4c, 0x3c02fffe, 0x3442ffff, 0x2629824, -0xc00486a, 0x0, 0xaf900200, 0xaf930220, -0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, -0x8f820220, 0x34420002, 0xaf820220, 0x141140, -0x3c010001, 0x220821, 0xac317e30, 0x8fbf0024, -0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, -0x8fb00010, 0x3e00008, 0x27bd0028, 0x0 }; -static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { -0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f66776d, 0x61696e2e, 0x632c7620, 0x312e312e, -0x322e3131, 0x20313939, 0x382f3034, 0x2f323720, -0x32323a31, 0x333a3432, 0x20736875, 0x616e6720, -0x45787020, 0x24000000, 0x7468655f, 0x4441574e, -0x0, 0x53544143, 0x4b5f3120, 0x0, -0x42616453, 0x6e64526e, 0x67000000, 0x3f456e71, -0x45767400, 0x3f6e6f51, 0x64457650, 0x0, -0x6576526e, 0x6746756c, 0x6c000000, 0x496c6c43, -0x6f6e6652, 0x78000000, 0x53656e64, 0x436b5375, -0x6d000000, 0x52656376, 0x566c616e, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f74696d, 0x65722e63, 0x2c762031, 0x2e312e32, -0x2e382031, 0x3939382f, 0x30372f33, 0x31203137, -0x3a35383a, 0x34352073, 0x6875616e, 0x67204578, -0x70202400, 0x542d446d, 0x61526431, 0x0, -0x542d446d, 0x61424200, 0x542d446d, 0x61320000, -0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51, -0x64527845, 0x0, 0x656e714d, 0x45765046, -0x61696c00, 0x656e714d, 0x45764661, 0x696c0000, -0x6661696c, 0x456e454d, 0x0, 0x3f456e71, -0x45767400, 0x3f6e6f51, 0x64457650, 0x0, -0x6576526e, 0x6746756c, 0x6c000000, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f636f6d, 0x6d616e64, 0x2e632c76, 0x20312e31, -0x2e322e31, 0x30203139, 0x39382f31, 0x312f3138, -0x2031373a, 0x31313a31, 0x38207368, 0x75616e67, -0x20457870, 0x20240000, 0x3f4d626f, 0x78457674, -0x0, 0x4e4f636f, 0x6d616e64, 0x0, -0x68737465, 0x5f455252, 0x0, 0x412d4572, -0x72427563, 0x0, 0x4552524f, 0x522d4164, -0x64000000, 0x656e714d, 0x45765046, 0x61696c00, -0x656e714d, 0x45764661, 0x696c0000, 0x6661696c, -0x456e454d, 0x0, 0x442d4572, 0x724c6173, -0x74000000, 0x442d4572, 0x72320000, 0x6d437374, -0x4d644552, 0x52000000, 0x70726f6d, 0x4d644552, -0x52000000, 0x46696c74, 0x4d644552, 0x52000000, -0x636d645f, 0x45525200, 0x3f456e71, 0x45767400, -0x3f6e6f51, 0x64457650, 0x0, 0x6576526e, -0x6746756c, 0x6c000000, 0x0, 0x6ea0, -0x7fbc, 0x6e38, 0x8734, 0x82b0, -0x8780, 0x8780, 0x6f54, 0x7694, -0x7f0c, 0x80a8, 0x8074, 0x8780, -0x7e70, 0x80cc, 0x6e64, 0x81cc, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f646d61, 0x2e632c76, 0x20312e31, 0x2e322e33, -0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, -0x333a3431, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x646d6172, 0x6441544e, 0x0, -0x646d6177, 0x7241544e, 0x0, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f747261, 0x63652e63, 0x2c762031, 0x2e312e32, -0x2e322031, 0x3939382f, 0x30342f32, 0x37203232, -0x3a31333a, 0x35302073, 0x6875616e, 0x67204578, -0x70202400, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f646174, 0x612e632c, 0x7620312e, 0x312e322e, -0x32203139, 0x39382f30, 0x342f3237, 0x2032323a, -0x31333a34, 0x30207368, 0x75616e67, 0x20457870, -0x20240000, 0x46575f56, 0x45525349, 0x4f4e3a20, -0x23312046, 0x72692041, 0x70722037, 0x2031373a, -0x35353a34, 0x38205044, 0x54203230, 0x30300000, -0x46575f43, 0x4f4d5049, 0x4c455f54, 0x494d453a, -0x2031373a, 0x35353a34, 0x38000000, 0x46575f43, -0x4f4d5049, 0x4c455f42, 0x593a2064, 0x65767263, -0x73000000, 0x46575f43, 0x4f4d5049, 0x4c455f48, -0x4f53543a, 0x20636f6d, 0x70757465, 0x0, -0x46575f43, 0x4f4d5049, 0x4c455f44, 0x4f4d4149, -0x4e3a2065, 0x6e672e61, 0x6374656f, 0x6e2e636f, -0x6d000000, 0x46575f43, 0x4f4d5049, 0x4c45523a, -0x20676363, 0x20766572, 0x73696f6e, 0x20322e37, -0x2e320000, 0x0, 0x0, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f6d656d, 0x2e632c76, 0x20312e31, 0x2e322e32, -0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, -0x333a3434, 0x20736875, 0x616e6720, 0x45787020, -0x24000000, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f73656e, 0x642e632c, 0x7620312e, 0x312e322e, -0x31312031, 0x3939382f, 0x31322f32, 0x32203137, -0x3a31373a, 0x35352073, 0x6875616e, 0x67204578, -0x70202400, 0x736e6464, 0x654e6f51, 0x20000000, -0x6e6f454e, 0x515f5458, 0x0, 0x736e6464, -0x744e6f51, 0x20000000, 0x3f6e6f51, 0x64547845, -0x0, 0x756e6b72, 0x64747970, 0x65000000, -0x0, 0xaccc, 0xaccc, 0xad9c, -0xaab0, 0xaab0, 0xad9c, 0xad9c, -0xad9c, 0xad9c, 0xad9c, 0xad9c, -0xad9c, 0xad9c, 0xad9c, 0xad9c, -0xad9c, 0xad9c, 0xad9c, 0xad7c, -0x0, 0xbca8, 0xbca8, 0xbd70, -0xae4c, 0xb058, 0xbd70, 0xbd70, -0xbd70, 0xbd70, 0xbd70, 0xbd70, -0xbd70, 0xbd70, 0xbd70, 0xbd70, -0xbd70, 0xbd70, 0xbd70, 0xbd54, -0xb040, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f726563, 0x762e632c, 0x7620312e, 0x312e322e, -0x31392031, 0x3939382f, 0x30372f32, 0x34203231, -0x3a33303a, 0x30352073, 0x6875616e, 0x67204578, -0x70202400, 0x706b5278, 0x45525200, 0x66726d32, -0x4c617267, 0x65000000, 0x72784e6f, 0x52784264, -0x0, 0x72785144, 0x6d614446, 0x0, -0x72785144, 0x6d614246, 0x0, 0x3f6e6f51, -0x64527845, 0x0, 0x706b5278, 0x45525273, -0x0, 0x66726d32, 0x4c726753, 0x0, -0x72784e6f, 0x42645300, 0x3f724264, 0x446d6146, -0x0, 0x3f724a42, 0x64446d46, 0x0, -0x0, 0xf678, 0xf678, 0xf678, -0xf678, 0xf678, 0xf678, 0xf678, -0xf678, 0xf678, 0xf678, 0xf678, -0xf678, 0xf678, 0xf678, 0xf678, -0xf670, 0xf670, 0xf670, 0x572d444d, -0x41456e46, 0x0, 0x0, 0xfdc0, -0x1015c, 0xfddc, 0x1015c, 0x1015c, -0x1015c, 0x1015c, 0x1015c, 0x1015c, -0xf704, 0x1015c, 0x1015c, 0x1015c, -0x1015c, 0x1015c, 0x10154, 0x10154, -0x10154, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f6d6163, 0x2e632c76, 0x20312e31, 0x2e322e31, -0x32203139, 0x39382f30, 0x342f3237, 0x2032323a, -0x31333a34, 0x32207368, 0x75616e67, 0x20457870, -0x20240000, 0x6d616374, 0x7841544e, 0x0, -0x4e745379, 0x6e264c6b, 0x0, 0x72656d61, -0x73737274, 0x0, 0x6c696e6b, 0x444f574e, -0x0, 0x656e714d, 0x45765046, 0x61696c00, -0x656e714d, 0x45764661, 0x696c0000, 0x6661696c, -0x456e454d, 0x0, 0x6c696e6b, 0x55500000, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, -0x2f636b73, 0x756d2e63, 0x2c762031, 0x2e312e32, -0x2e322031, 0x3939382f, 0x30342f32, 0x37203232, -0x3a31333a, 0x33392073, 0x6875616e, 0x67204578, -0x70202400, 0x50726f62, 0x65506879, 0x0, -0x6c6e6b41, 0x53535254, 0x0, 0x11b2c, -0x11bc4, 0x11bf8, 0x11c2c, 0x11c58, -0x11c6c, 0x11ca8, 0x1207c, 0x11de4, -0x11e24, 0x11e50, 0x11e90, 0x11ec0, -0x11efc, 0x11f30, 0x1207c, 0x122c0, -0x122d8, 0x12300, 0x12320, 0x12348, -0x12478, 0x124a0, 0x124f4, 0x1251c, -0x0, 0x1278c, 0x1285c, 0x12934, -0x12a04, 0x12a60, 0x12b3c, 0x12b64, -0x12c40, 0x12c68, 0x12e10, 0x12e38, -0x12fe0, 0x131d8, 0x1346c, 0x13380, -0x1346c, 0x13498, 0x13008, 0x131b0, -0x0, 0x13b84, 0x13bc8, 0x13c60, -0x13cac, 0x13d1c, 0x13db4, 0x13de8, -0x13e70, 0x13f08, 0x13fd8, 0x14018, -0x1409c, 0x140c0, 0x141f4, 0x646f4261, -0x73655067, 0x0, 0x0, 0x0, -0x0, 0x73746d61, 0x634c4e4b, 0x0, -0x0, 0x14c38, 0x14c38, 0x14b80, -0x14bc4, 0x14c38, 0x14c38, 0x0, -0x0, 0x0 }; -static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { -0x416c7465, -0x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465, -0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242, -0x0, 0x0, 0x0, 0x135418, -0x13e7fc, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x60cf00, -0x60, 0xcf000000, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x3, 0x0, -0x1, 0x0, 0x0, 0x0, -0x1, 0x0, 0x1, 0x0, -0x0, 0x0, 0x0, 0x1, -0x1, 0x0, 0x0, 0x0, -0x0, 0x0, 0x1000000, 0x21000000, -0x12000140, 0x0, 0x0, 0x20000000, -0x120000a0, 0x0, 0x12000060, 0x12000180, -0x120001e0, 0x0, 0x0, 0x0, -0x1, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x2, -0x0, 0x0, 0x30001, 0x1, -0x30201, 0x0, 0x0, 0x0 }; -#endif -/* Generated by genfw.c */ -#define tigon2FwReleaseMajor 0xc -#define tigon2FwReleaseMinor 0x4 -#define tigon2FwReleaseFix 0xb -#define tigon2FwStartAddr 0x00004000 -#define tigon2FwTextAddr 0x00004000 -#define tigon2FwTextLen 0x11bc0 -#define tigon2FwRodataAddr 0x00015bc0 -#define tigon2FwRodataLen 0x10d0 -#define tigon2FwDataAddr 0x00016cc0 -#define tigon2FwDataLen 0x1c0 -#define tigon2FwSbssAddr 0x00016e80 -#define tigon2FwSbssLen 0xcc -#define tigon2FwBssAddr 0x00016f50 -#define tigon2FwBssLen 0x20c0 -static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { -0x0, -0x10000003, 0x0, 0xd, 0xd, -0x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000, -0x26104000, 0xc0010c0, 0x0, 0xd, -0x3c1d0001, 0x8fbd6d24, 0x3a0f021, 0x3c100000, -0x26104000, 0xc0017e0, 0x0, 0xd, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x2000008, -0x0, 0x800172f, 0x3c0a0001, 0x800172f, -0x3c0a0002, 0x800172f, 0x0, 0x8002cac, -0x0, 0x8002c4f, 0x0, 0x800172f, -0x3c0a0004, 0x800328a, 0x0, 0x8001a52, -0x0, 0x800394d, 0x0, 0x80038f4, -0x0, 0x800172f, 0x3c0a0006, 0x80039bb, -0x3c0a0007, 0x800172f, 0x3c0a0008, 0x800172f, -0x3c0a0009, 0x8003a13, 0x0, 0x8002ea6, -0x0, 0x800172f, 0x3c0a000b, 0x800172f, -0x3c0a000c, 0x800172f, 0x3c0a000d, 0x80028fb, -0x0, 0x8002890, 0x0, 0x800172f, -0x3c0a000e, 0x800208c, 0x0, 0x8001964, -0x0, 0x8001a04, 0x0, 0x8003ca6, -0x0, 0x8003c94, 0x0, 0x800172f, -0x0, 0x800191a, 0x0, 0x800172f, -0x0, 0x800172f, 0x3c0a0013, 0x800172f, -0x3c0a0014, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x27bdffe0, -0x3c1cc000, 0xafbf001c, 0xafb00018, 0x8f820140, -0x24030003, 0xaf8300ec, 0x34420004, 0xc002b20, -0xaf820140, 0x3c0100c0, 0xc001763, 0xac203ffc, -0x401821, 0x3c020010, 0x3c010001, 0xac236e9c, -0x10620011, 0x43102b, 0x14400002, 0x3c020020, -0x3c020008, 0x1062000c, 0x24050100, 0x3c060001, -0x8cc66e9c, 0x3c040001, 0x24845c74, 0x3821, -0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020020, -0x3c010001, 0xac226e9c, 0x24020008, 0x3c010001, -0xac226eb4, 0x2402001f, 0x3c010001, 0xac226ec4, -0x24020016, 0x3c010001, 0xac226e98, 0x3c05fffe, -0x34a56f08, 0x3c020001, 0x8c426e9c, 0x3c030002, -0x24639010, 0x3c040001, 0x8c846cc4, 0x431023, -0x14800002, 0x458021, 0x2610fa38, 0x2402f000, -0x2028024, 0xc001785, 0x2002021, 0x2022823, -0x3c040020, 0x821823, 0x651823, 0x247bb000, -0x3c03fffe, 0x3463bf08, 0x363b821, 0x3c0600bf, -0x34c6f000, 0x3c070001, 0x8ce76cc0, 0x3c0300bf, -0x3463e000, 0x852023, 0x3c010001, 0xac246ea8, -0x822023, 0x3c010001, 0xac256e90, 0x52842, -0x3c010001, 0xac226e84, 0x27620ffc, 0x3c010001, -0xac226d20, 0x27621ffc, 0xdb3023, 0x7b1823, -0x3c010001, 0xac246e88, 0x3c010001, 0xac256eac, -0x3c010001, 0xac226d24, 0xaf860150, 0x10e00011, -0xaf830250, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021, -0xc001749, 0x0, 0x3c020001, 0x8c426cd0, -0x3c030001, 0x8c636cd4, 0x2442fe00, 0x24630200, -0x3c010001, 0xac226cd0, 0x3c010001, 0x10000004, -0xac236cd4, 0x3c1d0001, 0x8fbd6d20, 0x3a0f021, -0x3c020001, 0x8c426cc4, 0x1040000d, 0x26fafa38, -0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4, -0x3c1a0001, 0x8f5a6cd4, 0x2442fa38, 0x246305c8, -0x3c010001, 0xac226cd0, 0x3c010001, 0xac236cd4, -0x3c020001, 0x8c426cc8, 0x14400003, 0x0, -0x3c010001, 0xac206cd0, 0xc001151, 0x0, -0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, -0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4, -0x27bdff98, 0xafb00048, 0x3c100001, 0x8e1066b8, -0xafb20050, 0x3c120000, 0x26524100, 0xafbf0060, -0xafbe005c, 0xafb50058, 0xafb30054, 0xafb1004c, -0xafa20034, 0xafa30030, 0xafa00010, 0xafa00014, -0x8f860040, 0x3c040001, 0x24845c80, 0x24050200, -0x3c010001, 0xac326e80, 0xc002b3b, 0x2003821, -0x8f830040, 0x3c02f000, 0x621824, 0x3c026000, -0x1062000b, 0xa3a0003f, 0x240e0001, 0x3c040001, -0x24845c88, 0xa3ae003f, 0xafa00010, 0xafa00014, -0x8f860040, 0x24050300, 0xc002b3b, 0x2003821, -0x8f820240, 0x3c030001, 0x431025, 0xaf820240, -0xaf800048, 0x8f820048, 0x14400005, 0x0, -0xaf800048, 0x8f820048, 0x10400004, 0x0, -0xaf800048, 0x10000003, 0x2e02021, 0xaf80004c, -0x2e02021, 0x3c050001, 0xc002ba8, 0x34a540f8, -0x3402021, 0xc002ba8, 0x240505c8, 0x3c020001, -0x8c426ea8, 0x3c0d0001, 0x8dad6e88, 0x3c030001, -0x8c636e84, 0x3c080001, 0x8d086e90, 0x3c090001, -0x8d296eac, 0x3c0a0001, 0x8d4a6eb4, 0x3c0b0001, -0x8d6b6ec4, 0x3c0c0001, 0x8d8c6e98, 0x3c040001, -0x24845c94, 0x24050400, 0xaf42013c, 0x8f42013c, -0x24060001, 0x24070001, 0xaf400000, 0xaf4d0138, -0xaf430144, 0xaf480148, 0xaf49014c, 0xaf4a0150, -0xaf4b0154, 0xaf4c0158, 0x2442ff80, 0xaf420140, -0x24020001, 0xafa20010, 0xc002b3b, 0xafa00014, -0x8f420138, 0xafa20010, 0x8f42013c, 0xafa20014, -0x8f460144, 0x8f470148, 0x3c040001, 0x24845ca0, -0xc002b3b, 0x24050500, 0xafb70010, 0xafba0014, -0x8f46014c, 0x8f470150, 0x3c040001, 0x24845cac, -0xc002b3b, 0x24050600, 0x3c020001, 0x8c426e9c, -0x3603821, 0x3c060002, 0x24c69010, 0x2448ffff, -0x1061824, 0xe81024, 0x43102b, 0x10400006, -0x24050900, 0x3c040001, 0x24845cb8, 0xafa80010, -0xc002b3b, 0xafa00014, 0x8f82000c, 0xafa20010, -0x8f82003c, 0xafa20014, 0x8f860000, 0x8f870004, -0x3c040001, 0x24845cc4, 0xc002b3b, 0x24051000, -0x8c020220, 0x8c030224, 0x8c060218, 0x8c07021c, -0x3c040001, 0x24845ccc, 0x24051100, 0xafa20010, -0xc002b3b, 0xafa30014, 0xaf800054, 0xaf80011c, -0x8c020218, 0x30420002, 0x10400009, 0x0, -0x8c020220, 0x3c030002, 0x34630004, 0x431025, -0xaf42000c, 0x8c02021c, 0x10000008, 0x34420004, -0x8c020220, 0x3c030002, 0x34630006, 0x431025, -0xaf42000c, 0x8c02021c, 0x34420006, 0xaf420014, -0x8c020218, 0x30420010, 0x1040000a, 0x0, -0x8c02021c, 0x34420004, 0xaf420010, 0x8c020220, -0x3c03000a, 0x34630004, 0x431025, 0x10000009, -0xaf420008, 0x8c020220, 0x3c03000a, 0x34630006, -0x431025, 0xaf420008, 0x8c02021c, 0x34420006, -0xaf420010, 0x24020001, 0xaf8200a0, 0xaf8200b0, -0x8f830054, 0x8f820054, 0xaf8000d0, 0xaf8000c0, -0x10000002, 0x24630064, 0x8f820054, 0x621023, -0x2c420065, 0x1440fffc, 0x0, 0x8c040208, -0x8c05020c, 0x26e20028, 0xaee20020, 0x24020490, -0xaee20010, 0xaee40008, 0xaee5000c, 0x26e40008, -0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094, -0x8c820018, 0xaf8200b4, 0x9482000a, 0xaf82009c, -0x8f420014, 0xaf8200b0, 0x8f8200b0, 0x30420004, -0x1440fffd, 0x0, 0x8f8200b0, 0x3c03ef00, -0x431024, 0x10400021, 0x0, 0x8f8200b4, -0xafa20010, 0x8f820090, 0x8f830094, 0x3c040001, -0x24845cd4, 0xafa30014, 0x8f8600b0, 0x8f87009c, -0x3c050001, 0xc002b3b, 0x34a5200d, 0x3c040001, -0x24845ce0, 0x240203c0, 0xafa20010, 0xafa00014, -0x8f860144, 0x3c070001, 0x24e75ce8, 0xc002b3b, -0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c, -0x8f820220, 0x34420004, 0xaf820220, 0x8f820140, -0x3c030001, 0x431025, 0xaf820140, 0x96e20472, -0x96e60452, 0x96e70462, 0xafa20010, 0x96e20482, -0x3c040001, 0x24845d14, 0x24051200, 0xc002b3b, -0xafa20014, 0x96f00452, 0x32020001, 0x10400002, -0xb021, 0x24160001, 0x32020002, 0x54400001, -0x36d60002, 0x32020008, 0x54400001, 0x36d60004, -0x32020010, 0x54400001, 0x36d60008, 0x32020020, -0x54400001, 0x36d60010, 0x32020040, 0x54400001, -0x36d60020, 0x32020080, 0x54400001, 0x36d60040, -0x96e60482, 0x30c20200, 0x54400001, 0x36d64000, -0x96e30472, 0x30620200, 0x10400003, 0x30620100, -0x10000003, 0x36d62000, 0x54400001, 0x36d61000, -0x96f00462, 0x32c24000, 0x14400004, 0x3207009b, -0x30c2009b, 0x14e20007, 0x240e0001, 0x32c22000, -0x1440000d, 0x32020001, 0x3062009b, 0x10e20009, -0x240e0001, 0x3c040001, 0x24845d20, 0x24051300, -0x2003821, 0xa3ae003f, 0xafa30010, 0xc002b3b, -0xafa00014, 0x32020001, 0x54400001, 0x36d60080, -0x32020002, 0x54400001, 0x36d60100, 0x32020008, -0x54400001, 0x36d60200, 0x32020010, 0x54400001, -0x36d60400, 0x32020080, 0x54400001, 0x36d60800, -0x8c020218, 0x30420200, 0x10400002, 0x3c020008, -0x2c2b025, 0x8c020218, 0x30420800, 0x10400002, -0x3c020080, 0x2c2b025, 0x8c020218, 0x30420400, -0x10400002, 0x3c020100, 0x2c2b025, 0x8c020218, -0x30420100, 0x10400002, 0x3c020200, 0x2c2b025, -0x8c020218, 0x30420080, 0x10400002, 0x3c020400, -0x2c2b025, 0x8c020218, 0x30422000, 0x10400002, -0x3c020010, 0x2c2b025, 0x8c020218, 0x30424000, -0x10400002, 0x3c020020, 0x2c2b025, 0x8c020218, -0x30421000, 0x10400002, 0x3c020040, 0x2c2b025, -0x8ee20498, 0x8ee3049c, 0xaf420160, 0xaf430164, -0x8ee204a0, 0x8ee304a4, 0xaf420168, 0xaf43016c, -0x8ee204a8, 0x8ee304ac, 0xaf420170, 0xaf430174, -0x8ee20428, 0x8ee3042c, 0xaf420178, 0xaf43017c, -0x8ee20448, 0x8ee3044c, 0xaf420180, 0xaf430184, -0x8ee20458, 0x8ee3045c, 0xaf420188, 0xaf43018c, -0x8ee20468, 0x8ee3046c, 0xaf420190, 0xaf430194, -0x8ee20478, 0x8ee3047c, 0xaf420198, 0xaf43019c, -0x8ee20488, 0x8ee3048c, 0xaf4201a0, 0xaf4301a4, -0x8ee204b0, 0x8ee304b4, 0x24040080, 0xaf4201a8, -0xaf4301ac, 0xc002ba8, 0x24050080, 0x8c02025c, -0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200, -0x24060008, 0xc002bbf, 0xaf4201f8, 0x3c043b9a, -0x3484ca00, 0x3821, 0x24020006, 0x24030002, -0xaf4201f4, 0x240203e8, 0xaf430204, 0xaf430200, -0xaf4401fc, 0xaf420294, 0x24020001, 0xaf430290, -0xaf42029c, 0x3c030001, 0x671821, 0x90636cd8, -0x3471021, 0x24e70001, 0xa043022c, 0x2ce2000f, -0x1440fff8, 0x3471821, 0x24e70001, 0x3c080001, -0x350840f8, 0x8f820040, 0x3c040001, 0x24845d2c, -0x24051400, 0x21702, 0x24420030, 0xa062022c, -0x3471021, 0xa040022c, 0x8c070218, 0x2c03021, -0x240205c8, 0xafa20010, 0xc002b3b, 0xafa80014, -0x3c040001, 0x24845d38, 0x3c050000, 0x24a55c80, -0x24060010, 0x27b10030, 0x2203821, 0x27b30034, -0xc0017a3, 0xafb30010, 0x3c030001, 0x8c636cc8, -0x1060000a, 0x408021, 0x8fa30030, 0x2405ff00, -0x8fa20034, 0x246400ff, 0x852024, 0x831823, -0x431023, 0xafa20034, 0xafa40030, 0x3c040001, -0x24845d44, 0x3c050000, 0x24a54100, 0x24060108, -0x2203821, 0xc0017a3, 0xafb30010, 0x409021, -0x32c20003, 0x3c010001, 0xac326e80, 0x10400045, -0x2203821, 0x8f820050, 0x3c030010, 0x431024, -0x10400016, 0x0, 0x8c020218, 0x30420040, -0x1040000f, 0x24020001, 0x8f820050, 0x8c030218, -0x240e0001, 0x3c040001, 0x24845d50, 0xa3ae003f, -0xafa20010, 0xafa30014, 0x8f870040, 0x24051500, -0xc002b3b, 0x2c03021, 0x10000004, 0x0, -0x3c010001, 0x370821, 0xa02240f4, 0x3c040001, -0x24845d5c, 0x3c050001, 0x24a55b40, 0x3c060001, -0x24c65bac, 0xc53023, 0x8f420010, 0x27b30030, -0x2603821, 0x27b10034, 0x34420a00, 0xaf420010, -0xc0017a3, 0xafb10010, 0x3c040001, 0x24845d70, -0x3c050001, 0x24a5b714, 0x3c060001, 0x24c6ba90, -0xc53023, 0x2603821, 0xaf420108, 0xc0017a3, -0xafb10010, 0x3c040001, 0x24845d8c, 0x3c050001, -0x24a5be58, 0x3c060001, 0x24c6c900, 0xc53023, -0x2603821, 0x3c010001, 0xac226ef4, 0xc0017a3, -0xafb10010, 0x3c040001, 0x24845da4, 0x10000024, -0x24051600, 0x3c040001, 0x24845dac, 0x3c050001, -0x24a5a10c, 0x3c060001, 0x24c6a238, 0xc53023, -0xc0017a3, 0xafb30010, 0x3c040001, 0x24845dbc, -0x3c050001, 0x24a5b2b0, 0x3c060001, 0x24c6b70c, -0xc53023, 0x2203821, 0xaf420108, 0xc0017a3, -0xafb30010, 0x3c040001, 0x24845dd0, 0x3c050001, -0x24a5ba98, 0x3c060001, 0x24c6be50, 0xc53023, -0x2203821, 0x3c010001, 0xac226ef4, 0xc0017a3, -0xafb30010, 0x3c040001, 0x24845de4, 0x24051650, -0x2c03021, 0x3821, 0x3c010001, 0xac226ef8, -0xafa00010, 0xc002b3b, 0xafa00014, 0x32c20020, -0x10400021, 0x27a70030, 0x3c040001, 0x24845df0, -0x3c050001, 0x24a5b13c, 0x3c060001, 0x24c6b2a8, -0xc53023, 0x24022000, 0xaf42001c, 0x27a20034, -0xc0017a3, 0xafa20010, 0x21900, 0x31982, -0x3c040800, 0x641825, 0xae430028, 0x24030010, -0xaf43003c, 0x96e30450, 0xaf430040, 0x8f430040, -0x3c040001, 0x24845e04, 0xafa00014, 0xafa30010, -0x8f47001c, 0x24051660, 0x3c010001, 0xac226ef0, -0x10000025, 0x32c60020, 0x8ee20448, 0x8ee3044c, -0xaf43001c, 0x8f42001c, 0x2442e000, 0x2c422001, -0x1440000a, 0x240e0001, 0x3c040001, 0x24845e10, -0xa3ae003f, 0xafa00010, 0xafa00014, 0x8f46001c, -0x24051700, 0xc002b3b, 0x3821, 0x3c020000, -0x24425cbc, 0x21100, 0x21182, 0x3c030800, -0x431025, 0xae420028, 0x24020008, 0xaf42003c, -0x96e20450, 0xaf420040, 0x8f420040, 0x3c040001, -0x24845e1c, 0xafa00014, 0xafa20010, 0x8f47001c, -0x24051800, 0x32c60020, 0xc002b3b, 0x0, -0x3c050fff, 0x3c030001, 0x8c636ef4, 0x34a5ffff, -0x2403021, 0x3c020001, 0x8c426ef8, 0x3c040800, -0x651824, 0x31882, 0x641825, 0x451024, -0x21082, 0x441025, 0xacc20080, 0x32c20180, -0x10400056, 0xacc30020, 0x8f82005c, 0x3c030080, -0x431024, 0x1040000d, 0x0, 0x8f820050, -0xafa20010, 0x8f82005c, 0x240e0001, 0x3c040001, -0x24845e28, 0xa3ae003f, 0xafa20014, 0x8f870040, -0x24051900, 0xc002b3b, 0x2c03021, 0x8f820050, -0x3c030010, 0x431024, 0x10400016, 0x0, -0x8c020218, 0x30420040, 0x1040000f, 0x24020001, -0x8f820050, 0x8c030218, 0x240e0001, 0x3c040001, -0x24845d50, 0xa3ae003f, 0xafa20010, 0xafa30014, -0x8f870040, 0x24052000, 0xc002b3b, 0x2c03021, -0x10000004, 0x0, 0x3c010001, 0x370821, -0xa02240f4, 0x3c040001, 0x24845e34, 0x3c050001, -0x24a55ac0, 0x3c060001, 0x24c65b38, 0xc53023, -0x8f420008, 0x27b30030, 0x2603821, 0x27b10034, -0x34420e00, 0xaf420008, 0xc0017a3, 0xafb10010, -0x3c040001, 0x24845e4c, 0x3c050001, 0x24a5d8b4, -0x3c060001, 0x24c6e3c8, 0xc53023, 0x2603821, -0xaf42010c, 0xc0017a3, 0xafb10010, 0x3c040001, -0x24845e64, 0x3c050001, 0x24a5e9ac, 0x3c060001, -0x24c6f0f0, 0xc53023, 0x2603821, 0x3c010001, -0xac226f04, 0xc0017a3, 0xafb10010, 0x3c040001, -0x24845e7c, 0x10000027, 0x24052100, 0x3c040001, -0x24845e84, 0x3c050001, 0x24a59fc8, 0x3c060001, -0x24c6a104, 0xc53023, 0x27b10030, 0x2203821, -0x27b30034, 0xc0017a3, 0xafb30010, 0x3c040001, -0x24845e94, 0x3c050001, 0x24a5cad4, 0x3c060001, -0x24c6d8ac, 0xc53023, 0x2203821, 0xaf42010c, -0xc0017a3, 0xafb30010, 0x3c040001, 0x24845ea4, -0x3c050001, 0x24a5e84c, 0x3c060001, 0x24c6e9a4, -0xc53023, 0x2203821, 0x3c010001, 0xac226f04, -0xc0017a3, 0xafb30010, 0x3c040001, 0x24845eb8, -0x24052150, 0x2c03021, 0x3821, 0x3c010001, -0xac226f10, 0xafa00010, 0xc002b3b, 0xafa00014, -0x3c110fff, 0x3c030001, 0x8c636f04, 0x3631ffff, -0x2409821, 0x3c020001, 0x8c426f10, 0x3c0e0800, -0x711824, 0x31882, 0x6e1825, 0x511024, -0x21082, 0x4e1025, 0xae630038, 0xae620078, -0x8c020218, 0x30420040, 0x14400004, 0x24020001, -0x3c010001, 0x370821, 0xa02240f4, 0x3c040001, -0x24845ec4, 0x3c050001, 0x24a5e3d0, 0x3c060001, -0x24c6e52c, 0xc53023, 0x27be0030, 0x3c03821, -0x27b50034, 0xc0017a3, 0xafb50010, 0x3c010001, -0xac226efc, 0x511024, 0x21082, 0x3c0e0800, -0x4e1025, 0xae620050, 0x32c22000, 0x10400006, -0x3c03821, 0x3c020000, 0x24425cbc, 0x2221024, -0x1000000f, 0x21082, 0x3c040001, 0x24845ed8, -0x3c050001, 0x24a5e534, 0x3c060001, 0x24c6e6e4, -0xc53023, 0xc0017a3, 0xafb50010, 0x3c010001, -0xac226f14, 0x511024, 0x21082, 0x3c0e0800, -0x4e1025, 0xae620048, 0x32c24000, 0x10400005, -0x27a70030, 0x3c020000, 0x24425cbc, 0x1000000e, -0x21100, 0x3c040001, 0x24845ef0, 0x3c050001, -0x24a5e6ec, 0x3c060001, 0x24c6e844, 0xc53023, -0x27a20034, 0xc0017a3, 0xafa20010, 0x3c010001, -0xac226f08, 0x21100, 0x21182, 0x3c030800, -0x431025, 0xae420060, 0x3c040001, 0x24845f08, -0x3c050001, 0x24a58230, 0x3c060001, 0x24c68650, -0xc53023, 0x27b10030, 0x2203821, 0x27b30034, -0xc0017a3, 0xafb30010, 0x3c0e0fff, 0x35ceffff, -0x3c040001, 0x24845f14, 0x3c050000, 0x24a56468, -0x3c060000, 0x24c66588, 0xc53023, 0x2203821, -0x240f021, 0x3c010001, 0xac226edc, 0x4e1024, -0x21082, 0x3c150800, 0x551025, 0xafae0044, -0xafc200b8, 0xc0017a3, 0xafb30010, 0x3c040001, -0x24845f20, 0x3c050000, 0x24a56590, 0x3c060000, -0x24c66808, 0x8fae0044, 0xc53023, 0x2203821, -0x3c010001, 0xac226ed0, 0x4e1024, 0x21082, -0x551025, 0xafc200e8, 0xc0017a3, 0xafb30010, -0x3c040001, 0x24845f38, 0x3c050000, 0x24a56810, -0x3c060000, 0x24c66940, 0x8fae0044, 0xc53023, -0x2203821, 0x3c010001, 0xac226ec8, 0x4e1024, -0x21082, 0x551025, 0xafc200c0, 0xc0017a3, -0xafb30010, 0x3c040001, 0x24845f50, 0x3c050001, -0x24a5fad0, 0x3c060001, 0x24c6fba8, 0x8fae0044, -0xc53023, 0x2203821, 0x3c010001, 0xac226ed4, -0x4e1024, 0x21082, 0x551025, 0xafc200c8, -0xc0017a3, 0xafb30010, 0x3c040001, 0x24845f5c, -0x3c050001, 0x24a5c93c, 0x3c060001, 0x24c6ca20, -0xc53023, 0x2203821, 0xaf420110, 0xc0017a3, -0xafb30010, 0x3c040001, 0x24845f6c, 0x3c050001, -0x24a5c910, 0x3c060001, 0x24c6c934, 0xc53023, -0x2203821, 0xaf420124, 0xc0017a3, 0xafb30010, -0x3c040001, 0x24845f7c, 0x3c050001, 0x24a55a80, -0x3c060001, 0x24c65aac, 0xc53023, 0x2203821, -0xaf420120, 0xaf420114, 0xc0017a3, 0xafb30010, -0x3c040001, 0x24845f88, 0x3c050001, 0x24a5f298, -0x3c060001, 0x24c6f6b4, 0xc53023, 0x2203821, -0xaf420118, 0xc0017a3, 0xafb30010, 0x8fae0044, -0x3c010001, 0xac226f18, 0x4e1024, 0x21082, -0x551025, 0xc003fc3, 0xafc200d0, 0xc003c40, -0x0, 0xc0027a8, 0x0, 0xac000228, -0xac00022c, 0x96e20450, 0x2442ffff, 0xaf420038, -0x96e20460, 0xaf420080, 0x32c24000, 0x14400003, -0x0, 0x96e20480, 0xaf420084, 0x96e70490, -0x50e00001, 0x24070800, 0x24e2ffff, 0xaf420088, -0xaf42007c, 0x24020800, 0x10e2000f, 0x32c24000, -0x10400003, 0x24020400, 0x10e2000b, 0x0, -0x240e0001, 0x3c040001, 0x24845f98, 0xa3ae003f, -0x96e60490, 0x24052170, 0x2c03821, 0xafa00010, -0xc002b3b, 0xafa00014, 0x8f430138, 0x8f440138, -0x24020001, 0xa34205c2, 0xaf430094, 0xaf440098, -0xafa00010, 0xafa00014, 0x8f460080, 0x8f470084, -0x3c040001, 0x24845fa4, 0xc002b3b, 0x24052200, -0xc0024a4, 0x3c110800, 0x3c1433d8, 0x3694cb58, -0x3c020800, 0x34420080, 0x3c040001, 0x24845fb0, -0x3c050000, 0x24a55d00, 0x3c060000, 0x24c65d1c, -0xc53023, 0x27a70030, 0xaf820060, 0x2402ffff, -0xaf820064, 0x27a20034, 0xc0017a3, 0xafa20010, -0x3c010001, 0xac226eb8, 0x21100, 0x21182, -0x511025, 0xc0018fc, 0xae420000, 0x8f820240, -0x3c030001, 0x431025, 0xaf820240, 0x3c020000, -0x24424034, 0xaf820244, 0xaf800240, 0x8f820060, -0x511024, 0x14400005, 0x3c030800, 0x8f820060, -0x431024, 0x1040fffd, 0x0, 0xc003c4d, -0x8821, 0x3c020100, 0xafa20020, 0x8f530018, -0x240200ff, 0x56620001, 0x26710001, 0x8c020228, -0x1622000e, 0x1330c0, 0x8f42033c, 0x24420001, -0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001, -0x24845c24, 0x3c050009, 0xafa00014, 0xafa20010, -0x8fa60020, 0x1000003f, 0x34a50100, 0xd71021, -0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, -0xc01821, 0x8f440178, 0x8f45017c, 0x1021, -0x24070004, 0xafa70010, 0xafb10014, 0x8f48000c, -0x24c604c0, 0x2e63021, 0xafa80018, 0x8f48010c, -0x24070008, 0xa32821, 0xa3482b, 0x822021, -0x100f809, 0x892021, 0x1440000b, 0x24070008, -0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001, -0x24845c2c, 0x3c050009, 0xafa20014, 0x8fa60020, -0x1000001c, 0x34a50200, 0x8f440160, 0x8f450164, -0x8f43000c, 0xaf510018, 0x8f860120, 0x24020010, -0xafa20010, 0xafb10014, 0xafa30018, 0x8f42010c, -0x40f809, 0x24c6001c, 0x14400010, 0x0, -0x8f420340, 0x24420001, 0xaf420340, 0x8f420340, -0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001, -0x24845c34, 0x3c050009, 0xafa20014, 0x8fa60020, -0x34a50300, 0xc002b3b, 0x2603821, 0x8f4202e4, -0x24420001, 0xaf4202e4, 0x8f4202e4, 0x93a2003f, -0x10400069, 0x3c020700, 0x34423000, 0xafa20028, -0x8f530018, 0x240200ff, 0x12620002, 0x8821, -0x26710001, 0x8c020228, 0x1622000e, 0x1330c0, -0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c, -0x8c020228, 0x3c040001, 0x24845c24, 0x3c050009, -0xafa00014, 0xafa20010, 0x8fa60028, 0x1000003f, -0x34a50100, 0xd71021, 0x8fa30028, 0x8fa4002c, -0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178, -0x8f45017c, 0x1021, 0x24070004, 0xafa70010, -0xafb10014, 0x8f48000c, 0x24c604c0, 0x2e63021, -0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, -0xa3482b, 0x822021, 0x100f809, 0x892021, -0x1440000b, 0x24070008, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x24845c2c, 0x3c050009, -0xafa20014, 0x8fa60028, 0x1000001c, 0x34a50200, -0x8f440160, 0x8f450164, 0x8f43000c, 0xaf510018, -0x8f860120, 0x24020010, 0xafa20010, 0xafb10014, -0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x14400010, 0x0, 0x8f420340, 0x24420001, -0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x24845c34, 0x3c050009, -0xafa20014, 0x8fa60028, 0x34a50300, 0xc002b3b, -0x2603821, 0x8f4202f0, 0x24420001, 0xaf4202f0, -0x8f4202f0, 0x3c040001, 0x24845fc0, 0xafa00010, -0xafa00014, 0x8fa60028, 0x24052300, 0xc002b3b, -0x3821, 0x10000004, 0x0, 0x8c020264, -0x10400005, 0x0, 0x8f8200a0, 0x30420004, -0x1440fffa, 0x0, 0x8f820044, 0x34420004, -0xaf820044, 0x8f420308, 0x24420001, 0xaf420308, -0x8f420308, 0x8f8200d8, 0x8f8300d4, 0x431023, -0x2442ff80, 0xaf420090, 0x8f420090, 0x2842ff81, -0x10400006, 0x24020001, 0x8f420090, 0x8f430144, -0x431021, 0xaf420090, 0x24020001, 0xaf42008c, -0x32c20008, 0x10400006, 0x0, 0x8f820214, -0x3c038100, 0x3042ffff, 0x431025, 0xaf820214, -0x3c030001, 0x8c636d94, 0x30620002, 0x10400009, -0x30620001, 0x3c040001, 0x24845fcc, 0x3c050000, -0x24a56d50, 0x3c060000, 0x24c671c8, 0x10000012, -0xc53023, 0x10400009, 0x0, 0x3c040001, -0x24845fdc, 0x3c050000, 0x24a571d0, 0x3c060000, -0x24c67678, 0x10000008, 0xc53023, 0x3c040001, -0x24845fec, 0x3c050000, 0x24a56948, 0x3c060000, -0x24c66d48, 0xc53023, 0x27a70030, 0x27a20034, -0xc0017a3, 0xafa20010, 0x3c010001, 0xac226ecc, -0x3c020001, 0x8c426ecc, 0x3c030800, 0x21100, -0x21182, 0x431025, 0xae420040, 0x8f8200a0, -0xafa20010, 0x8f8200b0, 0xafa20014, 0x8f86005c, -0x8f87011c, 0x3c040001, 0x24845ffc, 0x3c010001, -0xac366ea4, 0x3c010001, 0xac206e94, 0x3c010001, -0xac3c6e8c, 0x3c010001, 0xac3b6ebc, 0x3c010001, -0xac376ec0, 0x3c010001, 0xac3a6ea0, 0xc002b3b, -0x24052400, 0x8f820200, 0xafa20010, 0x8f820220, -0xafa20014, 0x8f860044, 0x8f870050, 0x3c040001, -0x24846008, 0xc002b3b, 0x24052500, 0x8f830060, -0x74100b, 0x242000a, 0x200f821, 0x0, -0xd, 0x8fbf0060, 0x8fbe005c, 0x8fb50058, -0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048, -0x3e00008, 0x27bd0068, 0x27bdffe0, 0x3c040001, -0x24846014, 0x24052600, 0x3021, 0x3821, -0xafbf0018, 0xafa00010, 0xc002b3b, 0xafa00014, -0x8fbf0018, 0x3e00008, 0x27bd0020, 0x3e00008, -0x0, 0x3e00008, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x3e00008, 0x0, 0x3e00008, 0x0, -0x27bdfde0, 0x27a50018, 0x3c04dead, 0x3484beef, -0xafbf0218, 0x8f820150, 0x3c03001f, 0x3463ffff, -0xafa40018, 0xa22823, 0xa32824, 0x8ca20000, -0x1044000a, 0x0, 0xafa50010, 0x8ca20000, -0xafa20014, 0x8f860150, 0x8f870250, 0x3c040001, -0x2484601c, 0xc002b3b, 0x24052700, 0x8fbf0218, -0x3e00008, 0x27bd0220, 0x27bdffe0, 0x3c06abba, -0x34c6babe, 0xafb00018, 0x3c100004, 0x3c07007f, -0x34e7ffff, 0xafbf001c, 0x102840, 0x8e040000, -0x8ca30000, 0xaca00000, 0xae060000, 0x8ca20000, -0xaca30000, 0x10460005, 0xae040000, 0xa08021, -0xf0102b, 0x1040fff5, 0x102840, 0x3c040001, -0x24846028, 0x24052800, 0x2003021, 0x3821, -0xafa00010, 0xc002b3b, 0xafa00014, 0x2001021, -0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, -0x8c020224, 0x3047003f, 0x10e00010, 0x803021, -0x2821, 0x24030020, 0xe31024, 0x10400002, -0x63042, 0xa62821, 0x31842, 0x1460fffb, -0xe31024, 0x2402f000, 0xa22824, 0x3402ffff, -0x45102b, 0x14400003, 0x3c020001, 0x10000008, -0x3c020001, 0x3442ffff, 0x851823, 0x43102b, -0x14400003, 0xa01021, 0x3c02fffe, 0x821021, -0x3e00008, 0x0, 0x27bdffd0, 0xafb50028, -0x8fb50040, 0xafb20020, 0xa09021, 0xafb1001c, -0x24c60003, 0xafbf002c, 0xafb30024, 0xafb00018, -0x8ea20000, 0x2403fffc, 0xc38024, 0x50102b, -0x1440001b, 0xe08821, 0x8e330000, 0xafb00010, -0x8ea20000, 0xafa20014, 0x8e270000, 0x24053000, -0xc002b3b, 0x2403021, 0x8e230000, 0x702021, -0x64102b, 0x10400007, 0x2402821, 0x8ca20000, -0xac620000, 0x24630004, 0x64102b, 0x1440fffb, -0x24a50004, 0x8ea20000, 0x501023, 0xaea20000, -0x8e220000, 0x501021, 0x1000000b, 0xae220000, -0x2402002d, 0xa0820000, 0xafb00010, 0x8ea20000, -0x2409821, 0xafa20014, 0x8e270000, 0x24053100, -0xc002b3b, 0x2603021, 0x2601021, 0x8fbf002c, -0x8fb50028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, -0x8fb00018, 0x3e00008, 0x27bd0030, 0x27bdffe8, -0x3c1cc000, 0x3c05fffe, 0x3c030001, 0x8c636e84, -0x3c040001, 0x8c846e90, 0x34a5bf08, 0x24021ffc, -0x3c010001, 0xac226cd0, 0x3c0200c0, 0x3c010001, -0xac226cd4, 0x3c020020, 0xafbf0010, 0x3c0100c0, -0xac201ffc, 0x431023, 0x441023, 0x245bb000, -0x365b821, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021, -0x3c0400c0, 0x34840200, 0x3c1a00c0, 0x3c0300c0, -0x346307c8, 0x24021dfc, 0x3c010001, 0xac226cd0, -0x24021834, 0x3c010001, 0xac246cd4, 0x3c010001, -0xac226cd0, 0x3c010001, 0xac236cd4, 0xc00180d, -0x375a0200, 0x8fbf0010, 0x3e00008, 0x27bd0018, -0x27bdffc8, 0x3c040001, 0x24846034, 0x24053200, -0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4, -0x3021, 0x3603821, 0xafbf0030, 0xafb3002c, -0xafb20028, 0xafb10024, 0xafb00020, 0xafa2001c, -0xafa30018, 0xafb70010, 0xc002b3b, 0xafba0014, -0xc001916, 0x0, 0x8f820240, 0x34420004, -0xaf820240, 0x24020001, 0xaf420000, 0x3c020001, -0x571021, 0x904240f4, 0x10400092, 0x2403fffc, -0x3c100001, 0x2610ac73, 0x3c120001, 0x2652a84c, -0x2121023, 0x438024, 0x8fa3001c, 0x3c040001, -0x24846040, 0x70102b, 0x1440001a, 0x27b30018, -0x8fb10018, 0x24053000, 0x2403021, 0xafb00010, -0xafa30014, 0xc002b3b, 0x2203821, 0x8fa30018, -0x702021, 0x64102b, 0x10400007, 0x2403021, -0x8cc20000, 0xac620000, 0x24630004, 0x64102b, -0x1440fffb, 0x24c60004, 0x8fa2001c, 0x501023, -0xafa2001c, 0x8e620000, 0x501021, 0x1000000a, -0xae620000, 0x2408821, 0x24053100, 0xafb00010, -0xafa30014, 0x8fa70018, 0x2203021, 0x2402002d, -0xc002b3b, 0xa0820000, 0x24070020, 0x8fa3001c, -0x3c040001, 0x2484605c, 0x24120020, 0x3c010001, -0xac316eb0, 0x2c620020, 0x1440001d, 0x27b10018, -0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f50, -0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821, -0x8fa30018, 0x3c040001, 0x24846f50, 0x24650020, -0x65102b, 0x10400007, 0x0, 0x8c820000, -0xac620000, 0x24630004, 0x65102b, 0x1440fffb, -0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c, -0x8e220000, 0x521021, 0x1000000b, 0xae220000, -0x3c100001, 0x26106f50, 0x24053100, 0xafa70010, -0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d, -0xc002b3b, 0xa0820000, 0x24070020, 0x3c040001, -0x24846070, 0x8fa3001c, 0x24120020, 0x3c010001, -0xac306ee4, 0x2c620020, 0x1440001d, 0x27b10018, -0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f70, -0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821, -0x8fa30018, 0x3c040001, 0x24846f70, 0x24650020, -0x65102b, 0x10400007, 0x0, 0x8c820000, -0xac620000, 0x24630004, 0x65102b, 0x1440fffb, -0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c, -0x8e220000, 0x521021, 0x1000000b, 0xae220000, -0x3c100001, 0x26106f70, 0x24053100, 0xafa70010, -0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d, -0xc002b3b, 0xa0820000, 0x3c010001, 0x10000031, -0xac306ee0, 0x3c100001, 0x2610821f, 0x3c120001, -0x2652809c, 0x2121023, 0x438024, 0x8fa3001c, -0x3c040001, 0x24846084, 0x70102b, 0x1440001a, -0x27b30018, 0x8fb10018, 0x24053000, 0x2403021, -0xafb00010, 0xafa30014, 0xc002b3b, 0x2203821, -0x8fa30018, 0x702021, 0x64102b, 0x10400007, -0x2403021, 0x8cc20000, 0xac620000, 0x24630004, -0x64102b, 0x1440fffb, 0x24c60004, 0x8fa2001c, -0x501023, 0xafa2001c, 0x8e620000, 0x501021, -0x1000000a, 0xae620000, 0x2408821, 0x24053100, -0xafb00010, 0xafa30014, 0x8fa70018, 0x2203021, -0x2402002d, 0xc002b3b, 0xa0820000, 0x3c010001, -0xac316eb0, 0x3c030001, 0x8c636eb0, 0x24020400, -0x60f809, 0xaf820070, 0x8fbf0030, 0x8fb3002c, -0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008, -0x27bd0038, 0x0, 0x0, 0x8f820040, -0x3c03f000, 0x431024, 0x3c036000, 0x14430006, -0x0, 0x8f820050, 0x2403ff80, 0x431024, -0x34420055, 0xaf820050, 0x8f820054, 0x244203e8, -0xaf820058, 0x240201f4, 0xaf4200e0, 0x24020004, -0xaf4200e8, 0x24020002, 0xaf4001b0, 0xaf4000e4, -0xaf4200dc, 0xaf4000d8, 0xaf4000d4, 0x3e00008, -0xaf4000d0, 0x8f820054, 0x24420005, 0x3e00008, -0xaf820078, 0x27bdffe8, 0xafbf0010, 0x8f820054, -0x244203e8, 0xaf820058, 0x3c020800, 0x2c21024, -0x10400004, 0x3c02f7ff, 0x3442ffff, 0x2c2b024, -0x36940040, 0x3c020001, 0x8c426da8, 0x10400017, -0x3c020200, 0x3c030001, 0x8c636f1c, 0x10600016, -0x282a025, 0x3c020001, 0x8c426e44, 0x14400012, -0x3c020200, 0x3c020001, 0x8c426d94, 0x30420003, -0x1440000d, 0x3c020200, 0x8f830224, 0x3c020002, -0x8c428fec, 0x10620008, 0x3c020200, 0xc003daf, -0x0, 0x10000004, 0x3c020200, 0xc004196, -0x0, 0x3c020200, 0x2c21024, 0x10400003, -0x0, 0xc001f4b, 0x0, 0x8f4200d8, -0x8f4300dc, 0x24420001, 0xaf4200d8, 0x43102b, -0x14400003, 0x0, 0xaf4000d8, 0x36940080, -0x8c030238, 0x1060000c, 0x0, 0x8f4201b0, -0x244203e8, 0xaf4201b0, 0x43102b, 0x14400006, -0x0, 0x934205c5, 0x14400003, 0x0, -0xc001da0, 0x0, 0x8fbf0010, 0x3e00008, -0x27bd0018, 0x3e00008, 0x0, 0x27bdffd8, -0xafbf0020, 0x8f43002c, 0x8f420038, 0x10620059, -0x0, 0x3c020001, 0x571021, 0x904240f0, -0x10400026, 0x24070008, 0x8f440170, 0x8f450174, -0x8f48000c, 0x8f860120, 0x24020020, 0xafa20010, -0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, -0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, -0x370821, 0xa02240f0, 0x8f820124, 0xafa20010, -0x8f820128, 0x3c040001, 0x24846128, 0xafa20014, -0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b, -0x34a50900, 0x1000005c, 0x0, 0x8f420300, -0x24420001, 0xaf420300, 0x8f420300, 0x8f42002c, -0xa34005c1, 0x10000027, 0xaf420038, 0x8f440170, -0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120, -0x24020080, 0xafa20010, 0xafa30014, 0xafa80018, -0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, -0x24020001, 0x3c010001, 0x370821, 0xa02240f1, -0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001, -0x24846134, 0xafa20014, 0x8f46002c, 0x8f870120, -0x3c050009, 0xc002b3b, 0x34a51100, 0x10000036, -0x0, 0x8f420300, 0x8f43002c, 0x24420001, -0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1, -0xaf430038, 0x3c010001, 0x370821, 0xa02040f1, -0x3c010001, 0x370821, 0xa02040f0, 0x10000026, -0xaf400034, 0x934205c1, 0x1040001d, 0x0, -0xa34005c1, 0x8f820040, 0x30420001, 0x14400008, -0x2021, 0x8c030104, 0x24020001, 0x50620005, -0x24040001, 0x8c020264, 0x10400003, 0x801021, -0x24040001, 0x801021, 0x10400006, 0x0, -0x8f42030c, 0x24420001, 0xaf42030c, 0x10000008, -0x8f42030c, 0x8f820044, 0x34420004, 0xaf820044, -0x8f420308, 0x24420001, 0xaf420308, 0x8f420308, -0x3c010001, 0x370821, 0xa02040f0, 0x3c010001, -0x370821, 0xa02040f1, 0x8f420000, 0x10400007, -0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd, -0x0, 0x10000005, 0x0, 0xaf800048, -0x8f820048, 0x1040fffd, 0x0, 0x8f820060, -0x3c03ff7f, 0x3463ffff, 0x431024, 0xaf820060, -0x8f420000, 0x10400003, 0x0, 0x10000002, -0xaf80004c, 0xaf800048, 0x8fbf0020, 0x3e00008, -0x27bd0028, 0x3e00008, 0x0, 0x27bdffd8, -0xafbf0020, 0x8f430044, 0x8f42007c, 0x10620029, -0x24070008, 0x8f440168, 0x8f45016c, 0x8f48000c, -0x8f860120, 0x24020040, 0xafa20010, 0xafa30014, -0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x14400011, 0x24020001, 0x3c010001, 0x370821, -0xa02240f2, 0x8f820124, 0xafa20010, 0x8f820128, -0x3c040001, 0x2484613c, 0xafa20014, 0x8f460044, -0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51300, -0x1000000f, 0x0, 0x8f420304, 0x24420001, -0xaf420304, 0x8f420304, 0x8f420044, 0xaf42007c, -0x3c010001, 0x370821, 0xa02040f2, 0x10000004, -0xaf400078, 0x3c010001, 0x370821, 0xa02040f2, -0x8f420000, 0x10400007, 0x0, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x3c03feff, 0x3463ffff, -0x431024, 0xaf820060, 0x8f420000, 0x10400003, -0x0, 0x10000002, 0xaf80004c, 0xaf800048, -0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008, -0x0, 0x3c020001, 0x8c426da8, 0x27bdffa8, -0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044, -0xafb20040, 0xafb1003c, 0xafb00038, 0x104000d5, -0x8f900044, 0x8f4200d0, 0x24430001, 0x2842000b, -0x144000e4, 0xaf4300d0, 0x8f420004, 0x30420002, -0x1440009c, 0xaf4000d0, 0x8f420004, 0x3c030001, -0x8c636d98, 0x34420002, 0xaf420004, 0x24020001, -0x14620003, 0x3c020600, 0x10000002, 0x34423000, -0x34421000, 0xafa20020, 0x8f4a0018, 0xafaa0034, -0x27aa0020, 0xafaa002c, 0x8faa0034, 0x240200ff, -0x11420002, 0x1821, 0x25430001, 0x8c020228, -0x609821, 0x1662000e, 0x3c050009, 0x8f42033c, -0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228, -0x8fa70034, 0x3c040001, 0x2484610c, 0xafa00014, -0xafa20010, 0x8fa60020, 0x10000070, 0x34a50500, -0x8faa0034, 0xa38c0, 0xf71021, 0x8fa30020, -0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054, -0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9, -0x1040001b, 0xa821, 0xe09021, 0x265e04c0, -0x8f440178, 0x8f45017c, 0x2401821, 0x240a0004, -0xafaa0010, 0xafb30014, 0x8f48000c, 0x1021, -0x2fe3021, 0xafa80018, 0x8f48010c, 0x24070008, -0xa32821, 0xa3482b, 0x822021, 0x100f809, -0x892021, 0x54400006, 0x24150001, 0x8f820054, -0x2221023, 0x2c4203e9, 0x1440ffe9, 0x0, -0x32a200ff, 0x54400018, 0xaf530018, 0x8f420378, -0x24420001, 0xaf420378, 0x8f420378, 0x8f820120, -0x8faa002c, 0x8fa70034, 0xafa20010, 0x8f820124, -0x3c040001, 0x24846118, 0xafa20014, 0x8d460000, -0x3c050009, 0x10000035, 0x34a50600, 0x8f420308, -0x24150001, 0x24420001, 0xaf420308, 0x8f420308, -0x1000001e, 0x32a200ff, 0x8f830054, 0x8f820054, -0x247103e8, 0x2221023, 0x2c4203e9, 0x10400016, -0xa821, 0x3c1e0020, 0x24120010, 0x8f42000c, -0x8f440160, 0x8f450164, 0x8f860120, 0xafb20010, -0xafb30014, 0x5e1025, 0xafa20018, 0x8f42010c, -0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3, -0x0, 0x8f820054, 0x2221023, 0x2c4203e9, -0x1440ffee, 0x0, 0x32a200ff, 0x14400011, -0x3c050009, 0x8f420378, 0x24420001, 0xaf420378, -0x8f420378, 0x8f820120, 0x8faa002c, 0x8fa70034, -0xafa20010, 0x8f820124, 0x3c040001, 0x24846120, -0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b, -0x0, 0x8f4202ec, 0x24420001, 0xaf4202ec, -0x8f4202ec, 0x8f420004, 0x30420001, 0x50400029, -0x36100040, 0x3c020400, 0x2c21024, 0x10400013, -0x2404ffdf, 0x8f420250, 0x8f430254, 0x8f4401b4, -0x14640006, 0x36100040, 0x8f420270, 0x8f430274, -0x8f4401b8, 0x10640007, 0x2402ffdf, 0x8f420250, -0x8f430254, 0x8f440270, 0x8f450274, 0x10000012, -0x3a100020, 0x1000002b, 0x2028024, 0x8f420250, -0x8f430254, 0x8f4501b4, 0x14650006, 0x2048024, -0x8f420270, 0x8f430274, 0x8f4401b8, 0x50640021, -0x36100040, 0x8f420250, 0x8f430254, 0x8f440270, -0x8f450274, 0x3a100040, 0xaf4301b4, 0x10000019, -0xaf4501b8, 0x8f4200d4, 0x24430001, 0x10000011, -0x28420033, 0x8f420004, 0x30420001, 0x10400009, -0x3c020400, 0x2c21024, 0x10400004, 0x2402ffdf, -0x2028024, 0x1000000b, 0x36100040, 0x10000009, -0x36100060, 0x8f4200d4, 0x36100040, 0x24430001, -0x284201f5, 0x14400003, 0xaf4300d4, 0xaf4000d4, -0x3a100020, 0xaf900044, 0x2402ff7f, 0x282a024, -0x8fbf0050, 0x8fbe004c, 0x8fb50048, 0x8fb30044, -0x8fb20040, 0x8fb1003c, 0x8fb00038, 0x3e00008, -0x27bd0058, 0x3e00008, 0x0, 0x3c020001, -0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044, -0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034, -0x104000c7, 0xafb00030, 0x8f4200d0, 0x24430001, -0x2842000b, 0x144000da, 0xaf4300d0, 0x8f420004, -0x30420002, 0x14400097, 0xaf4000d0, 0x8f420004, -0x3c030001, 0x8c636d98, 0x34420002, 0xaf420004, -0x24020001, 0x14620003, 0x3c020600, 0x10000002, -0x34423000, 0x34421000, 0xafa20020, 0x1821, -0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002, -0xafaa002c, 0x27c30001, 0x8c020228, 0x609021, -0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001, -0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001, -0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010, -0x8fa60020, 0x1000006d, 0x34a50500, 0xf71021, -0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, -0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x1040001b, 0x9821, 0xe08821, -0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821, -0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c, -0x1021, 0x2f53021, 0xafa80018, 0x8f48010c, -0x24070008, 0xa32821, 0xa3482b, 0x822021, -0x100f809, 0x892021, 0x54400006, 0x24130001, -0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9, -0x0, 0x326200ff, 0x54400017, 0xaf520018, -0x8f420378, 0x24420001, 0xaf420378, 0x8f420378, -0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124, -0x3c040001, 0x24846118, 0x3c050009, 0xafa20014, -0x8d460000, 0x10000035, 0x34a50600, 0x8f420308, -0x24130001, 0x24420001, 0xaf420308, 0x8f420308, -0x1000001e, 0x326200ff, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x10400016, -0x9821, 0x3c150020, 0x24110010, 0x8f42000c, -0x8f440160, 0x8f450164, 0x8f860120, 0xafb10010, -0xafb20014, 0x551025, 0xafa20018, 0x8f42010c, -0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3, -0x0, 0x8f820054, 0x2021023, 0x2c4203e9, -0x1440ffee, 0x0, 0x326200ff, 0x14400011, -0x0, 0x8f420378, 0x24420001, 0xaf420378, -0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010, -0x8f820124, 0x3c040001, 0x24846120, 0x3c050009, -0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b, -0x3c03821, 0x8f4202ec, 0x24420001, 0xaf4202ec, -0x8f4202ec, 0x8f420004, 0x30420001, 0x10400018, -0x24040001, 0x8f420250, 0x8f430254, 0x8f4501b4, -0x3c010001, 0x14650006, 0xa0246cf1, 0x8f420270, -0x8f430274, 0x8f4401b8, 0x10640021, 0x0, -0x8f420250, 0x8f430254, 0x3c040001, 0x90846cf0, -0x8f460270, 0x8f470274, 0x38840001, 0xaf4301b4, -0xaf4701b8, 0x3c010001, 0x10000025, 0xa0246cf0, -0x8f4200d4, 0x3c010001, 0xa0206cf0, 0x24430001, -0x28420033, 0x1440001e, 0xaf4300d4, 0x3c020001, -0x90426cf1, 0xaf4000d4, 0x10000017, 0x38420001, -0x8f420004, 0x30420001, 0x10400008, 0x0, -0xc00565a, 0x2021, 0x3c010001, 0xa0206cf1, -0x3c010001, 0x1000000e, 0xa0206cf0, 0x8f4200d4, -0x3c010001, 0xa0206cf0, 0x24430001, 0x284201f5, -0x14400007, 0xaf4300d4, 0x3c020001, 0x90426cf1, -0xaf4000d4, 0x421026, 0x3c010001, 0xa0226cf1, -0x3c030001, 0x8c636d98, 0x24020002, 0x1462000c, -0x3c030002, 0x3c030001, 0x90636cf1, 0x24020001, -0x5462001f, 0x2021, 0x3c020001, 0x90426cf0, -0x1443001b, 0x24040005, 0x10000019, 0x24040006, -0x3c020002, 0x8c428ff4, 0x431024, 0x1040000b, -0x24020001, 0x3c030001, 0x90636cf1, 0x54620010, -0x2021, 0x3c020001, 0x90426cf0, 0x1443000c, -0x24040003, 0x1000000a, 0x24040004, 0x3c030001, -0x90636cf1, 0x14620006, 0x2021, 0x3c020001, -0x90426cf0, 0x24040001, 0x50440001, 0x24040002, -0xc00565a, 0x0, 0x2402ff7f, 0x282a024, -0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c, -0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008, -0x27bd0050, 0x3e00008, 0x0, 0x3c020001, -0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044, -0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034, -0x104000de, 0xafb00030, 0x8f4200d0, 0x3c040001, -0x8c846d98, 0x24430001, 0x2842000b, 0xaf4400e8, -0x144000fe, 0xaf4300d0, 0x8f420004, 0x30420002, -0x14400095, 0xaf4000d0, 0x8f420004, 0x34420002, -0xaf420004, 0x24020001, 0x14820003, 0x3c020600, -0x10000002, 0x34423000, 0x34421000, 0xafa20020, -0x1821, 0x8f5e0018, 0x27aa0020, 0x240200ff, -0x13c20002, 0xafaa002c, 0x27c30001, 0x8c020228, -0x609021, 0x1642000e, 0x1e38c0, 0x8f42033c, -0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228, -0x3c040001, 0x2484610c, 0x3c050009, 0xafa00014, -0xafa20010, 0x8fa60020, 0x1000006d, 0x34a50500, -0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0, -0xac4404c4, 0x8f830054, 0x8f820054, 0x247003e8, -0x2021023, 0x2c4203e9, 0x1040001b, 0x9821, -0xe08821, 0x263504c0, 0x8f440178, 0x8f45017c, -0x2201821, 0x240a0004, 0xafaa0010, 0xafb20014, -0x8f48000c, 0x1021, 0x2f53021, 0xafa80018, -0x8f48010c, 0x24070008, 0xa32821, 0xa3482b, -0x822021, 0x100f809, 0x892021, 0x54400006, -0x24130001, 0x8f820054, 0x2021023, 0x2c4203e9, -0x1440ffe9, 0x0, 0x326200ff, 0x54400017, -0xaf520018, 0x8f420378, 0x24420001, 0xaf420378, -0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010, -0x8f820124, 0x3c040001, 0x24846118, 0x3c050009, -0xafa20014, 0x8d460000, 0x10000035, 0x34a50600, -0x8f420308, 0x24130001, 0x24420001, 0xaf420308, -0x8f420308, 0x1000001e, 0x326200ff, 0x8f830054, -0x8f820054, 0x247003e8, 0x2021023, 0x2c4203e9, -0x10400016, 0x9821, 0x3c150020, 0x24110010, -0x8f42000c, 0x8f440160, 0x8f450164, 0x8f860120, -0xafb10010, 0xafb20014, 0x551025, 0xafa20018, -0x8f42010c, 0x24070008, 0x40f809, 0x24c6001c, -0x1440ffe3, 0x0, 0x8f820054, 0x2021023, -0x2c4203e9, 0x1440ffee, 0x0, 0x326200ff, -0x14400011, 0x0, 0x8f420378, 0x24420001, -0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c, -0xafa20010, 0x8f820124, 0x3c040001, 0x24846120, -0x3c050009, 0xafa20014, 0x8d460000, 0x34a50700, -0xc002b3b, 0x3c03821, 0x8f4202ec, 0x24420001, -0xaf4202ec, 0x8f4202ec, 0x8f420004, 0x30420001, -0x10400033, 0x3c020400, 0x2c21024, 0x10400017, -0x0, 0x934205c0, 0x8f440250, 0x8f450254, -0x8f4301b4, 0x34420020, 0x14a30006, 0xa34205c0, -0x8f420270, 0x8f430274, 0x8f4401b8, 0x10640008, -0x0, 0x8f420250, 0x8f430254, 0x934405c0, -0x8f460270, 0x8f470274, 0x10000016, 0x38840040, -0x934205c0, 0x10000048, 0x304200bf, 0x934205c0, -0x8f440250, 0x8f450254, 0x8f4301b4, 0x304200bf, -0x14a30006, 0xa34205c0, 0x8f420270, 0x8f430274, -0x8f4401b8, 0x1064000b, 0x0, 0x8f420250, -0x8f430254, 0x934405c0, 0x8f460270, 0x8f470274, -0x38840020, 0xaf4301b4, 0xaf4701b8, 0x10000033, -0xa34405c0, 0x934205c0, 0x1000002f, 0x34420020, -0x934205c0, 0x8f4300d4, 0x34420020, 0xa34205c0, -0x24620001, 0x10000023, 0x28630033, 0x8f4200e4, -0x8f4300e0, 0x24420001, 0xaf4200e4, 0x43102a, -0x14400006, 0x24030001, 0x8f4200e8, 0x14430002, -0xaf4000e4, 0x24030004, 0xaf4300e8, 0x8f420004, -0x30420001, 0x1040000d, 0x3c020400, 0x2c21024, -0x10400007, 0x0, 0x934205c0, 0x34420040, -0xa34205c0, 0x934205c0, 0x1000000f, 0x304200df, -0x934205c0, 0x1000000c, 0x34420060, 0x934205c0, -0x8f4300d4, 0x34420020, 0xa34205c0, 0x24620001, -0x286300fb, 0x14600005, 0xaf4200d4, 0x934205c0, -0xaf4000d4, 0x38420040, 0xa34205c0, 0x934205c0, -0x8f4300e8, 0x3042007f, 0xa34205c0, 0x24020001, -0x14620005, 0x0, 0x934405c0, 0x42102, -0x10000003, 0x348400f0, 0x934405c0, 0x3484000f, -0xc005640, 0x0, 0x2402ff7f, 0x282a024, -0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c, -0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008, -0x27bd0050, 0x3e00008, 0x0, 0x27bdffb0, -0x274401c0, 0x26e30028, 0x24650400, 0x65102b, -0xafbf0048, 0xafbe0044, 0xafb50040, 0xafb3003c, -0xafb20038, 0xafb10034, 0x10400007, 0xafb00030, -0x8c820000, 0xac620000, 0x24630004, 0x65102b, -0x1440fffb, 0x24840004, 0x8c020080, 0xaee20044, -0x8c0200c0, 0xaee20040, 0x8c020084, 0xaee20030, -0x8c020084, 0xaee2023c, 0x8c020088, 0xaee20240, -0x8c02008c, 0xaee20244, 0x8c020090, 0xaee20248, -0x8c020094, 0xaee2024c, 0x8c020098, 0xaee20250, -0x8c02009c, 0xaee20254, 0x8c0200a0, 0xaee20258, -0x8c0200a4, 0xaee2025c, 0x8c0200a8, 0xaee20260, -0x8c0200ac, 0xaee20264, 0x8c0200b0, 0xaee20268, -0x8c0200b4, 0xaee2026c, 0x8c0200b8, 0xaee20270, -0x8c0200bc, 0x24040001, 0xaee20274, 0xaee00034, -0x41080, 0x571021, 0x8ee30034, 0x8c42023c, -0x24840001, 0x621821, 0x2c82000f, 0xaee30034, -0x1440fff8, 0x41080, 0x8c0200cc, 0xaee20048, -0x8c0200d0, 0xaee2004c, 0x8c0200e0, 0xaee201f8, -0x8c0200e4, 0xaee201fc, 0x8c0200e8, 0xaee20200, -0x8c0200ec, 0xaee20204, 0x8c0200f0, 0xaee20208, -0x8ee400c0, 0x8ee500c4, 0x8c0200fc, 0x45102b, -0x1040000b, 0x0, 0x8ee200c0, 0x8ee300c4, -0x24040001, 0x24050000, 0x651821, 0x65302b, -0x441021, 0x461021, 0xaee200c0, 0xaee300c4, -0x8c0200fc, 0x8ee400c0, 0x8ee500c4, 0x2408ffff, -0x24090000, 0x401821, 0x1021, 0x882024, -0xa92824, 0x822025, 0xa32825, 0xaee400c0, -0xaee500c4, 0x8ee400d0, 0x8ee500d4, 0x8c0200f4, -0x45102b, 0x1040000b, 0x0, 0x8ee200d0, -0x8ee300d4, 0x24040001, 0x24050000, 0x651821, -0x65302b, 0x441021, 0x461021, 0xaee200d0, -0xaee300d4, 0x8c0200f4, 0x8ee400d0, 0x8ee500d4, -0x401821, 0x1021, 0x882024, 0xa92824, -0x822025, 0xa32825, 0xaee400d0, 0xaee500d4, -0x8ee400c8, 0x8ee500cc, 0x8c0200f8, 0x45102b, -0x1040000b, 0x0, 0x8ee200c8, 0x8ee300cc, -0x24040001, 0x24050000, 0x651821, 0x65302b, -0x441021, 0x461021, 0xaee200c8, 0xaee300cc, -0x8c0200f8, 0x8ee400c8, 0x8ee500cc, 0x401821, -0x1021, 0x882024, 0xa92824, 0x822025, -0xa32825, 0x24020008, 0xaee400c8, 0xaee500cc, -0xafa20010, 0xafa00014, 0x8f42000c, 0x8c040208, -0x8c05020c, 0xafa20018, 0x8f42010c, 0x26e60028, -0x40f809, 0x24070400, 0x104000f0, 0x3c020400, -0xafa20020, 0x934205c6, 0x10400089, 0x1821, -0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002, -0xafaa002c, 0x27c30001, 0x8c020228, 0x609021, -0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001, -0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001, -0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010, -0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, -0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, -0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x1040001b, 0x9821, 0xe08821, -0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821, -0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c, -0x1021, 0x2f53021, 0xafa80018, 0x8f48010c, -0x24070008, 0xa32821, 0xa3482b, 0x822021, -0x100f809, 0x892021, 0x54400006, 0x24130001, -0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9, -0x0, 0x326200ff, 0x54400017, 0xaf520018, -0x8f420378, 0x24420001, 0xaf420378, 0x8f420378, -0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124, -0x3c040001, 0x24846118, 0x3c050009, 0xafa20014, -0x8d460000, 0x10000033, 0x34a50600, 0x8f420308, -0x24130001, 0x24420001, 0xaf420308, 0x8f420308, -0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014, -0x9821, 0x24110010, 0x8f42000c, 0x8f440160, -0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014, -0xafa20018, 0x8f42010c, 0x24070008, 0x40f809, -0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054, -0x2021023, 0x2c4203e9, 0x1440ffef, 0x0, -0x326200ff, 0x54400012, 0x24020001, 0x8f420378, -0x24420001, 0xaf420378, 0x8f420378, 0x8f820120, -0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001, -0x24846120, 0x3c050009, 0xafa20014, 0x8d460000, -0x34a50700, 0xc002b3b, 0x3c03821, 0x1021, -0x1440005b, 0x24020001, 0x10000065, 0x0, -0x8f510018, 0x240200ff, 0x12220002, 0x8021, -0x26300001, 0x8c020228, 0x1602000e, 0x1130c0, -0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c, -0x8c020228, 0x3c040001, 0x248460f4, 0x3c050009, -0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f, -0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024, -0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178, -0x8f45017c, 0x1021, 0x24070004, 0xafa70010, -0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021, -0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, -0xa3482b, 0x822021, 0x100f809, 0x892021, -0x1440000b, 0x24070008, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x248460fc, 0x3c050009, -0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200, -0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018, -0x8f860120, 0x24020010, 0xafa20010, 0xafb00014, -0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x54400011, 0x24020001, 0x8f420340, 0x24420001, -0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x24846104, 0x3c050009, -0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b, -0x2203821, 0x1021, 0x1040000d, 0x24020001, -0x8f4202e8, 0xa34005c6, 0xaf4001b0, 0x24420001, -0xaf4202e8, 0x8f4202e8, 0x8ee20150, 0x24420001, -0xaee20150, 0x10000003, 0x8ee20150, 0x24020001, -0xa34205c6, 0x8fbf0048, 0x8fbe0044, 0x8fb50040, -0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, -0x3e00008, 0x27bd0050, 0x27bdffd8, 0xafbf0020, -0x8f8200b0, 0x30420004, 0x10400068, 0x0, -0x8f430128, 0x8f820104, 0x14620005, 0x0, -0x8f430130, 0x8f8200b4, 0x10620006, 0x0, -0x8f820104, 0xaf420128, 0x8f8200b4, 0x1000005b, -0xaf420130, 0x8f8200b0, 0x3c030080, 0x431024, -0x1040000d, 0x0, 0x8f82011c, 0x34420002, -0xaf82011c, 0x8f8200b0, 0x2403fffb, 0x431024, -0xaf8200b0, 0x8f82011c, 0x2403fffd, 0x431024, -0x1000004a, 0xaf82011c, 0x8f430128, 0x8f820104, -0x14620005, 0x0, 0x8f430130, 0x8f8200b4, -0x10620010, 0x0, 0x8f820104, 0xaf420128, -0x8f8200b4, 0x8f430128, 0xaf420130, 0xafa30010, -0x8f420130, 0x3c040001, 0x24846144, 0xafa20014, -0x8f86011c, 0x8f8700b0, 0x3c050005, 0x10000031, -0x34a50900, 0x8f420128, 0xafa20010, 0x8f420130, -0x3c040001, 0x24846150, 0xafa20014, 0x8f86011c, -0x8f8700b0, 0x3c050005, 0xc002b3b, 0x34a51000, -0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104, -0x8f8200b0, 0x34420001, 0xaf8200b0, 0x24020008, -0xaf830104, 0xafa20010, 0xafa00014, 0x8f42000c, -0x8c040208, 0x8c05020c, 0xafa20018, 0x8f42010c, -0x26e60028, 0x40f809, 0x24070400, 0x8f82011c, -0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc, -0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f420128, -0xafa20010, 0x8f420130, 0x3c040001, 0x2484615c, -0xafa20014, 0x8f86011c, 0x8f8700b0, 0x3c050005, -0x34a51100, 0xc002b3b, 0x0, 0x8f8200a0, -0x30420004, 0x10400069, 0x0, 0x8f43012c, -0x8f820124, 0x14620005, 0x0, 0x8f430134, -0x8f8200a4, 0x10620006, 0x0, 0x8f820124, -0xaf42012c, 0x8f8200a4, 0x1000005c, 0xaf420134, -0x8f8200a0, 0x3c030080, 0x431024, 0x1040000d, -0x0, 0x8f82011c, 0x34420002, 0xaf82011c, -0x8f8200a0, 0x2403fffb, 0x431024, 0xaf8200a0, -0x8f82011c, 0x2403fffd, 0x431024, 0x1000004b, -0xaf82011c, 0x8f43012c, 0x8f820124, 0x14620005, -0x0, 0x8f430134, 0x8f8200a4, 0x10620010, -0x0, 0x8f820124, 0xaf42012c, 0x8f8200a4, -0x8f43012c, 0xaf420134, 0xafa30010, 0x8f420134, -0x3c040001, 0x24846168, 0xafa20014, 0x8f86011c, -0x8f8700a0, 0x3c050005, 0x10000032, 0x34a51200, -0x8f42012c, 0xafa20010, 0x8f420134, 0x3c040001, -0x24846174, 0xafa20014, 0x8f86011c, 0x8f8700a0, -0x3c050005, 0xc002b3b, 0x34a51300, 0x8f82011c, -0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0, -0x34420001, 0xaf8200a0, 0x24020080, 0xaf830124, -0xafa20010, 0xafa00014, 0x8f420014, 0x8c040208, -0x8c05020c, 0xafa20018, 0x8f420108, 0x3c060001, -0x24c66ed8, 0x40f809, 0x24070004, 0x8f82011c, -0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc, -0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f42012c, -0xafa20010, 0x8f420134, 0x3c040001, 0x24846180, -0xafa20014, 0x8f86011c, 0x8f8700a0, 0x3c050005, -0x34a51400, 0xc002b3b, 0x0, 0x8fbf0020, -0x3e00008, 0x27bd0028, 0x3c081000, 0x24070001, -0x3c060080, 0x3c050100, 0x8f820070, 0x481024, -0x1040fffd, 0x0, 0x8f820054, 0x24420005, -0xaf820078, 0x8c040234, 0x10800016, 0x1821, -0x3c020001, 0x571021, 0x8c4240e8, 0x24420005, -0x3c010001, 0x370821, 0xac2240e8, 0x3c020001, -0x571021, 0x8c4240e8, 0x44102b, 0x14400009, -0x0, 0x3c030080, 0x3c010001, 0x370821, -0xac2040e8, 0x3c010001, 0x370821, 0x1000000b, -0xa02740f0, 0x3c020001, 0x571021, 0x904240f0, -0x54400006, 0x661825, 0x3c020001, 0x571021, -0x904240f1, 0x54400001, 0x661825, 0x8c040230, -0x10800013, 0x0, 0x3c020001, 0x571021, -0x8c4240ec, 0x24420005, 0x3c010001, 0x370821, -0xac2240ec, 0x3c020001, 0x571021, 0x8c4240ec, -0x44102b, 0x14400006, 0x0, 0x3c010001, -0x370821, 0xac2040ec, 0x10000006, 0x651825, -0x3c020001, 0x571021, 0x904240f2, 0x54400001, -0x651825, 0x1060ffbc, 0x0, 0x8f420000, -0x10400007, 0x0, 0xaf80004c, 0x8f82004c, -0x1040fffd, 0x0, 0x10000005, 0x0, -0xaf800048, 0x8f820048, 0x1040fffd, 0x0, -0x8f820060, 0x431025, 0xaf820060, 0x8f420000, -0x10400003, 0x0, 0x1000ffa7, 0xaf80004c, -0x1000ffa5, 0xaf800048, 0x3e00008, 0x0, -0x0, 0x0, 0x0, 0x27bdffe0, -0xafbf0018, 0x8f860064, 0x30c20004, 0x10400025, -0x24040004, 0x8c020114, 0xaf420020, 0xaf840064, -0x8f4202fc, 0x24420001, 0xaf4202fc, 0x8f4202fc, -0x8f820064, 0x30420004, 0x14400005, 0x0, -0x8c030114, 0x8f420020, 0x1462fff2, 0x0, -0x8f420000, 0x10400007, 0x8f43003c, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x431025, 0xaf820060, -0x8f420000, 0x10400073, 0x0, 0x1000006f, -0x0, 0x30c20008, 0x10400020, 0x24040008, -0x8c02011c, 0xaf420048, 0xaf840064, 0x8f4202a8, -0x24420001, 0xaf4202a8, 0x8f4202a8, 0x8f820064, -0x30420008, 0x14400005, 0x0, 0x8c03011c, -0x8f420048, 0x1462fff2, 0x0, 0x8f420000, -0x10400007, 0x0, 0xaf80004c, 0x8f82004c, -0x1040fffd, 0x0, 0x10000005, 0x0, -0xaf800048, 0x8f820048, 0x1040fffd, 0x0, -0x8f820060, 0x1000ffd9, 0x34420200, 0x30c20020, -0x10400023, 0x24040020, 0x8c02012c, 0xaf420068, -0xaf840064, 0x8f4202d8, 0x24420001, 0xaf4202d8, -0x8f4202d8, 0x8f820064, 0x30420020, 0x14400005, -0x32c24000, 0x8c03012c, 0x8f420068, 0x1462fff2, -0x32c24000, 0x14400002, 0x3c020001, 0x2c2b025, -0x8f420000, 0x10400007, 0x0, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x1000ffb4, 0x34420800, -0x30c20010, 0x10400029, 0x24040010, 0x8c020124, -0xaf420058, 0xaf840064, 0x8f4202d4, 0x24420001, -0xaf4202d4, 0x8f4202d4, 0x8f820064, 0x30420010, -0x14400005, 0x32c22000, 0x8c030124, 0x8f420058, -0x1462fff2, 0x32c22000, 0x50400001, 0x36d68000, -0x8f420000, 0x10400007, 0x0, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x34420100, 0xaf820060, -0x8f420000, 0x10400003, 0x0, 0x1000006c, -0xaf80004c, 0x1000006a, 0xaf800048, 0x30c20001, -0x10400004, 0x24020001, 0xaf820064, 0x10000064, -0x0, 0x30c20002, 0x1440000b, 0x3c050003, -0x3c040001, 0x24846244, 0x34a50500, 0x3821, -0xafa00010, 0xc002b3b, 0xafa00014, 0x2402ffc0, -0x10000057, 0xaf820064, 0x8c05022c, 0x8c02010c, -0x10a20048, 0x51080, 0x8c460300, 0x24a20001, -0x3045003f, 0x24020003, 0xac05022c, 0x61e02, -0x10620005, 0x24020010, 0x1062001d, 0x30c20fff, -0x10000039, 0x0, 0x8f4302a8, 0x8f440000, -0x30c20fff, 0xaf420048, 0x24630001, 0xaf4302a8, -0x10800007, 0x8f4202a8, 0xaf80004c, 0x8f82004c, -0x1040fffd, 0x0, 0x10000005, 0x0, -0xaf800048, 0x8f820048, 0x1040fffd, 0x0, -0x8f820060, 0x34420200, 0xaf820060, 0x8f420000, -0x1040001f, 0x0, 0x1000001b, 0x0, -0xaf420058, 0x32c22000, 0x50400001, 0x36d68000, -0x8f4202d4, 0x8f430000, 0x24420001, 0xaf4202d4, -0x10600007, 0x8f4202d4, 0xaf80004c, 0x8f82004c, -0x1040fffd, 0x0, 0x10000005, 0x0, -0xaf800048, 0x8f820048, 0x1040fffd, 0x0, -0x8f820060, 0x34420100, 0xaf820060, 0x8f420000, -0x10400003, 0x0, 0x10000006, 0xaf80004c, -0x10000004, 0xaf800048, 0xc002196, 0xc02021, -0x402821, 0x8c02010c, 0x14a20002, 0x24020002, -0xaf820064, 0x8f820064, 0x30420002, 0x14400004, -0x0, 0x8c02010c, 0x14a2ffac, 0x0, -0x8fbf0018, 0x3e00008, 0x27bd0020, 0x3e00008, -0x0, 0x27bdffa0, 0xafb00040, 0x808021, -0x101602, 0x2442ffff, 0x304300ff, 0x2c620013, -0xafbf0058, 0xafbe0054, 0xafb50050, 0xafb3004c, -0xafb20048, 0xafb10044, 0x104001f3, 0xafa50034, -0x31080, 0x3c010001, 0x220821, 0x8c226288, -0x400008, 0x0, 0x101302, 0x30440fff, -0x24020001, 0x10820005, 0x24020002, 0x1082000c, -0x2402fffe, 0x10000024, 0x3c050003, 0x8f430004, -0x3c020001, 0x8c426f04, 0xaf440200, 0xaf440204, -0x3c040001, 0x8c846e80, 0x10000009, 0x34630001, -0x8f430004, 0xaf440200, 0xaf440204, 0x3c040001, -0x8c846e80, 0x621824, 0x3c020001, 0x2442ca28, -0x21100, 0x21182, 0xaf430004, 0x3c030800, -0x431025, 0xac820038, 0x8f840054, 0x41442, -0x41c82, 0x431021, 0x41cc2, 0x431023, -0x41d02, 0x431021, 0x41d42, 0x431023, -0x10000009, 0xaf420208, 0x3c040001, 0x24846250, -0x34a51000, 0x2003021, 0x3821, 0xafa00010, -0xc002b3b, 0xafa00014, 0x8f4202a0, 0x24420001, -0xaf4202a0, 0x1000021f, 0x8f4202a0, 0x27b00028, -0x2002021, 0x24050210, 0xc002bbf, 0x24060008, -0xc002518, 0x2002021, 0x10000216, 0x0, -0x8faa0034, 0x27a40028, 0xa1880, 0x25420001, -0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034, -0x21080, 0x8c430300, 0x25420001, 0x3042003f, -0xafa20034, 0xac02022c, 0xafa50028, 0xc002518, -0xafa3002c, 0x10000203, 0x0, 0x27b00028, -0x2002021, 0x24050210, 0xc002bbf, 0x24060008, -0xc002657, 0x2002021, 0x100001fa, 0x0, -0x8faa0034, 0x27a40028, 0xa1880, 0x25420001, -0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034, -0x21080, 0x8c430300, 0x25420001, 0x3042003f, -0xafa20034, 0xac02022c, 0xafa50028, 0xc002657, -0xafa3002c, 0x100001e7, 0x0, 0x101302, -0x30430fff, 0x24020001, 0x10620005, 0x24020002, -0x1062001e, 0x3c020002, 0x10000033, 0x3c050003, -0x3c030002, 0x2c31024, 0x54400037, 0x2c3b025, -0x8f820228, 0x3c010001, 0x370821, 0xac2238d8, -0x8f82022c, 0x3c010001, 0x370821, 0xac2238dc, -0x8f820230, 0x3c010001, 0x370821, 0xac2238e0, -0x8f820234, 0x3c010001, 0x370821, 0xac2238e4, -0x2402ffff, 0xaf820228, 0xaf82022c, 0xaf820230, -0xaf820234, 0x10000020, 0x2c3b025, 0x2c21024, -0x10400012, 0x3c02fffd, 0x3c020001, 0x571021, -0x8c4238d8, 0xaf820228, 0x3c020001, 0x571021, -0x8c4238dc, 0xaf82022c, 0x3c020001, 0x571021, -0x8c4238e0, 0xaf820230, 0x3c020001, 0x571021, -0x8c4238e4, 0xaf820234, 0x3c02fffd, 0x3442ffff, -0x10000009, 0x2c2b024, 0x3c040001, 0x2484625c, -0x34a51100, 0x2003021, 0x3821, 0xafa00010, -0xc002b3b, 0xafa00014, 0x8f4202cc, 0x24420001, -0xaf4202cc, 0x1000019f, 0x8f4202cc, 0x101302, -0x30450fff, 0x24020001, 0x10a20005, 0x24020002, -0x10a2000d, 0x3c0408ff, 0x10000014, 0x3c050003, -0x3c0208ff, 0x3442ffff, 0x8f830220, 0x3c040004, -0x2c4b025, 0x621824, 0x34630008, 0xaf830220, -0x10000012, 0xaf450298, 0x3484fff7, 0x3c03fffb, -0x8f820220, 0x3463ffff, 0x2c3b024, 0x441024, -0xaf820220, 0x10000009, 0xaf450298, 0x3c040001, -0x24846268, 0x34a51200, 0x2003021, 0x3821, -0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202bc, -0x24420001, 0xaf4202bc, 0x10000176, 0x8f4202bc, -0x27840208, 0x24050200, 0xc002bbf, 0x24060008, -0x27440224, 0x24050200, 0xc002bbf, 0x24060008, -0x8f4202c4, 0x24420001, 0xaf4202c4, 0x10000169, -0x8f4202c4, 0x101302, 0x30430fff, 0x24020001, -0x10620011, 0x28620002, 0x50400005, 0x24020002, -0x10600007, 0x0, 0x10000017, 0x0, -0x1062000f, 0x0, 0x10000013, 0x0, -0x8c060248, 0x2021, 0xc005104, 0x24050004, -0x10000007, 0x0, 0x8c060248, 0x2021, -0xc005104, 0x24050004, 0x10000010, 0x0, -0x8c06024c, 0x2021, 0xc005104, 0x24050001, -0x1000000a, 0x0, 0x3c040001, 0x24846274, -0x3c050003, 0x34a51300, 0x2003021, 0x3821, -0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202c0, -0x24420001, 0xaf4202c0, 0x1000013a, 0x8f4202c0, -0xc002426, 0x0, 0x10000136, 0x0, -0x24020001, 0xa34205c5, 0x24100100, 0x8f4401a8, -0x8f4501ac, 0xafb00010, 0xafa00014, 0x8f420014, -0xafa20018, 0x8f420108, 0x26e60028, 0x40f809, -0x24070400, 0x1040fff5, 0x0, 0x10000125, -0x0, 0x3c03ffff, 0x34637fff, 0x8f420368, -0x8f440360, 0x2c3b024, 0x1821, 0xaf400058, -0xaf40005c, 0xaf400060, 0xaf400064, 0x441023, -0xaf420368, 0x3c020900, 0xaf400360, 0xafa20020, -0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002, -0xafaa003c, 0x27c30001, 0x8c020228, 0x609021, -0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001, -0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001, -0x2484620c, 0x3c050009, 0xafa00014, 0xafa20010, -0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, -0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, -0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x1040001b, 0x9821, 0xe08821, -0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821, -0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c, -0x1021, 0x2f53021, 0xafa80018, 0x8f48010c, -0x24070008, 0xa32821, 0xa3482b, 0x822021, -0x100f809, 0x892021, 0x54400006, 0x24130001, -0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9, -0x0, 0x326200ff, 0x54400017, 0xaf520018, -0x8f420378, 0x24420001, 0xaf420378, 0x8f420378, -0x8f820120, 0x8faa003c, 0xafa20010, 0x8f820124, -0x3c040001, 0x24846218, 0x3c050009, 0xafa20014, -0x8d460000, 0x10000033, 0x34a50600, 0x8f420308, -0x24130001, 0x24420001, 0xaf420308, 0x8f420308, -0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014, -0x9821, 0x24110010, 0x8f42000c, 0x8f440160, -0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014, -0xafa20018, 0x8f42010c, 0x24070008, 0x40f809, -0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054, -0x2021023, 0x2c4203e9, 0x1440ffef, 0x0, -0x326200ff, 0x14400011, 0x0, 0x8f420378, -0x24420001, 0xaf420378, 0x8f420378, 0x8f820120, -0x8faa003c, 0xafa20010, 0x8f820124, 0x3c040001, -0x24846220, 0x3c050009, 0xafa20014, 0x8d460000, -0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b0, -0x24420001, 0xaf4202b0, 0x8f4202b0, 0x8f4202f8, -0x24420001, 0xaf4202f8, 0x1000008a, 0x8f4202f8, -0x8c02025c, 0x27440224, 0xaf4201f0, 0x8c020260, -0x24050200, 0x24060008, 0xc002bbf, 0xaf4201f8, -0x8f820220, 0x30420008, 0x14400002, 0x24020001, -0x24020002, 0xaf420298, 0x8f4202ac, 0x24420001, -0xaf4202ac, 0x10000077, 0x8f4202ac, 0x3c0200ff, -0x3442ffff, 0x2021824, 0x32c20180, 0x14400006, -0x3402fffb, 0x43102b, 0x14400003, 0x0, -0x1000006c, 0xaf4300bc, 0x3c040001, 0x24846280, -0x3c050003, 0x34a51500, 0x2003021, 0x3821, -0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020700, -0x34421000, 0x101e02, 0x621825, 0xafa30020, -0x8f510018, 0x240200ff, 0x12220002, 0x8021, -0x26300001, 0x8c020228, 0x1602000e, 0x1130c0, -0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c, -0x8c020228, 0x3c040001, 0x248461f4, 0x3c050009, -0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f, -0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024, -0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178, -0x8f45017c, 0x1021, 0x24070004, 0xafa70010, -0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021, -0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, -0xa3482b, 0x822021, 0x100f809, 0x892021, -0x1440000b, 0x24070008, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x248461fc, 0x3c050009, -0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200, -0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018, -0x8f860120, 0x24020010, 0xafa20010, 0xafb00014, -0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x14400010, 0x0, 0x8f420340, 0x24420001, -0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010, -0x8f820124, 0x3c040001, 0x24846204, 0x3c050009, -0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b, -0x2203821, 0x8f4202e0, 0x24420001, 0xaf4202e0, -0x8f4202e0, 0x8f4202f0, 0x24420001, 0xaf4202f0, -0x8f4202f0, 0x8fa20034, 0x8fbf0058, 0x8fbe0054, -0x8fb50050, 0x8fb3004c, 0x8fb20048, 0x8fb10044, -0x8fb00040, 0x3e00008, 0x27bd0060, 0x27bdfff8, -0x2408ffff, 0x10a00014, 0x4821, 0x3c0aedb8, -0x354a8320, 0x90870000, 0x24840001, 0x3021, -0x1071026, 0x30420001, 0x10400002, 0x81842, -0x6a1826, 0x604021, 0x24c60001, 0x2cc20008, -0x1440fff7, 0x73842, 0x25290001, 0x125102b, -0x1440fff0, 0x0, 0x1001021, 0x3e00008, -0x27bd0008, 0x27bdffb0, 0xafbf0048, 0xafbe0044, -0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034, -0xafb00030, 0x8f870220, 0xafa70024, 0x8f870200, -0xafa7002c, 0x8f820220, 0x3c0308ff, 0x3463ffff, -0x431024, 0x34420004, 0xaf820220, 0x8f820200, -0x3c03c0ff, 0x3463ffff, 0x431024, 0x34420004, -0xaf820200, 0x8f530358, 0x8f55035c, 0x8f5e0360, -0x8f470364, 0xafa70014, 0x8f470368, 0xafa7001c, -0x8f4202d0, 0x274401c0, 0x24420001, 0xaf4202d0, -0x8f5002d0, 0x8f510204, 0x8f520200, 0xc002ba8, -0x24050400, 0xaf530358, 0xaf55035c, 0xaf5e0360, -0x8fa70014, 0xaf470364, 0x8fa7001c, 0xaf470368, -0xaf5002d0, 0xaf510204, 0xaf520200, 0x8c02025c, -0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200, -0x24060008, 0xaf4201f8, 0x24020006, 0xc002bbf, -0xaf4201f4, 0x3c023b9a, 0x3442ca00, 0xaf4201fc, -0x240203e8, 0x24040002, 0x24030001, 0xaf420294, -0xaf440290, 0xaf43029c, 0x8f820220, 0x30420008, -0x10400004, 0x0, 0xaf430298, 0x10000003, -0x3021, 0xaf440298, 0x3021, 0x3c030001, -0x661821, 0x90636d00, 0x3461021, 0x24c60001, -0xa043022c, 0x2cc2000f, 0x1440fff8, 0x3461821, -0x24c60001, 0x8f820040, 0x24040080, 0x24050080, -0x21702, 0x24420030, 0xa062022c, 0x3461021, -0xc002ba8, 0xa040022c, 0x8fa70024, 0x30e20004, -0x14400006, 0x0, 0x8f820220, 0x3c0308ff, -0x3463fffb, 0x431024, 0xaf820220, 0x8fa7002c, -0x30e20004, 0x14400006, 0x0, 0x8f820200, -0x3c03c0ff, 0x3463fffb, 0x431024, 0xaf820200, -0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c, -0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008, -0x27bd0050, 0x0, 0x0, 0xaf400104, -0x24040001, 0x410c0, 0x2e21821, 0x24820001, -0x3c010001, 0x230821, 0xa42234d0, 0x402021, -0x2c820080, 0x1440fff8, 0x410c0, 0x24020001, -0x3c010001, 0x370821, 0xa42038d0, 0xaf420100, -0xaf800228, 0xaf80022c, 0xaf800230, 0xaf800234, -0x3e00008, 0x0, 0x27bdffe8, 0xafbf0014, -0xafb00010, 0x8f420104, 0x28420005, 0x10400026, -0x808021, 0x3c020001, 0x8f430104, 0x344230d0, -0x2e22021, 0x318c0, 0x621821, 0x2e31821, -0x83102b, 0x10400015, 0x1021, 0x96070000, -0x24840006, 0x24660006, 0x9482fffc, 0x14470009, -0x2821, 0x9483fffe, 0x96020002, 0x14620006, -0xa01021, 0x94820000, 0x96030004, 0x431026, -0x2c450001, 0xa01021, 0x14400009, 0x24840008, -0x86102b, 0x1440fff0, 0x1021, 0x304200ff, -0x14400030, 0x24020001, 0x1000002e, 0x1021, -0x1000fffa, 0x24020001, 0x2002021, 0xc00240c, -0x24050006, 0x3042007f, 0x218c0, 0x2e31021, -0x3c010001, 0x220821, 0x942230d0, 0x1040fff2, -0x2e31021, 0x3c060001, 0xc23021, 0x94c630d0, -0x10c0ffed, 0x3c080001, 0x350834d2, 0x96070000, -0x610c0, 0x572021, 0x882021, 0x94820000, -0x14470009, 0x2821, 0x94830002, 0x96020002, -0x14620006, 0xa01021, 0x94820004, 0x96030004, -0x431026, 0x2c450001, 0xa01021, 0x14400007, -0x610c0, 0x2e21021, 0x3c060001, 0xc23021, -0x94c634d0, 0x14c0ffeb, 0x610c0, 0x10c0ffd2, -0x24020001, 0x8fbf0014, 0x8fb00010, 0x3e00008, -0x27bd0018, 0x3e00008, 0x0, 0x27bdffb0, -0x801021, 0xafb00030, 0x24500002, 0x2002021, -0x24050006, 0xafb10034, 0x408821, 0xafbf0048, -0xafbe0044, 0xafb50040, 0xafb3003c, 0xc00240c, -0xafb20038, 0x3047007f, 0x710c0, 0x2e21021, -0x3c050001, 0xa22821, 0x94a530d0, 0x50a0001c, -0xa03021, 0x3c090001, 0x352934d2, 0x96280002, -0x510c0, 0x572021, 0x892021, 0x94820000, -0x14480009, 0x3021, 0x94830002, 0x96020002, -0x14620006, 0xc01021, 0x94820004, 0x96030004, -0x431026, 0x2c460001, 0xc01021, 0x14400007, -0x510c0, 0x2e21021, 0x3c050001, 0xa22821, -0x94a534d0, 0x14a0ffeb, 0x510c0, 0xa03021, -0x10c00014, 0x610c0, 0x571821, 0x3c010001, -0x230821, 0x8c2334d0, 0x571021, 0xafa30010, -0x3c010001, 0x220821, 0x8c2234d4, 0x3c040001, -0x24846394, 0xafa20014, 0x8e260000, 0x8e270004, -0x3c050004, 0xc002b3b, 0x34a50400, 0x10000063, -0x3c020800, 0x8f450100, 0x10a00006, 0x510c0, -0x2e21021, 0x3c010001, 0x220821, 0x942234d0, -0xaf420100, 0xa03021, 0x14c00011, 0x628c0, -0x710c0, 0x2e21021, 0xafa70010, 0x3c010001, -0x220821, 0x942230d0, 0x3c040001, 0x248463a0, -0xafa20014, 0x8e260000, 0x8e270004, 0x3c050004, -0xc002b3b, 0x34a50500, 0x10000048, 0x3c020800, -0xb71821, 0x3c020001, 0x96040000, 0x344234d2, -0x621821, 0xa4640000, 0x8e020002, 0x720c0, -0xac620002, 0x2e41021, 0x3c030001, 0x621821, -0x946330d0, 0x2e51021, 0x3c010001, 0x220821, -0xa42334d0, 0x2e41021, 0x3c010001, 0x220821, -0xa42630d0, 0x8f420104, 0x24420001, 0x28420080, -0x1040000f, 0x3c020002, 0x8f420104, 0x3c040001, -0x348430d2, 0x96030000, 0x210c0, 0x571021, -0x441021, 0xa4430000, 0x8e030002, 0xac430002, -0x8f420104, 0x24420001, 0xaf420104, 0x3c020002, -0x2c21024, 0x10400011, 0x72142, 0x3c030001, -0x346338d8, 0x24020003, 0x441023, 0x21080, -0x572021, 0x832021, 0x571021, 0x431021, -0x30e5001f, 0x8c430000, 0x24020001, 0xa21004, -0x621825, 0x1000000c, 0xac830000, 0x24020003, -0x441023, 0x21080, 0x5c2821, 0x5c1021, -0x30e4001f, 0x8c430228, 0x24020001, 0x821004, -0x621825, 0xaca30228, 0x3c020800, 0x34421000, -0x1821, 0xafa20020, 0x8f5e0018, 0x27aa0020, -0x240200ff, 0x13c20002, 0xafaa002c, 0x27c30001, -0x8c020228, 0x609021, 0x1642000e, 0x1e38c0, -0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c, -0x8c020228, 0x3c040001, 0x2484635c, 0x3c050009, -0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006b, -0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, -0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b, -0x9821, 0xe08821, 0x263504c0, 0x8f440178, -0x8f45017c, 0x2201821, 0x240a0004, 0xafaa0010, -0xafb20014, 0x8f48000c, 0x1021, 0x2f53021, -0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, -0xa3482b, 0x822021, 0x100f809, 0x892021, -0x54400006, 0x24130001, 0x8f820054, 0x2021023, -0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff, -0x54400017, 0xaf520018, 0x8f420378, 0x24420001, -0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c, -0xafa20010, 0x8f820124, 0x3c040001, 0x24846368, -0x3c050009, 0xafa20014, 0x8d460000, 0x10000033, -0x34a50600, 0x8f420308, 0x24130001, 0x24420001, -0xaf420308, 0x8f420308, 0x1000001c, 0x326200ff, -0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x10400014, 0x9821, 0x24110010, -0x8f42000c, 0x8f440160, 0x8f450164, 0x8f860120, -0xafb10010, 0xafb20014, 0xafa20018, 0x8f42010c, -0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe5, -0x0, 0x8f820054, 0x2021023, 0x2c4203e9, -0x1440ffef, 0x0, 0x326200ff, 0x14400011, -0x0, 0x8f420378, 0x24420001, 0xaf420378, -0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010, -0x8f820124, 0x3c040001, 0x24846370, 0x3c050009, -0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b, -0x3c03821, 0x8f4202b4, 0x24420001, 0xaf4202b4, -0x8f4202b4, 0x8f4202f4, 0x24420001, 0xaf4202f4, -0x8f4202f4, 0x8fbf0048, 0x8fbe0044, 0x8fb50040, -0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, -0x3e00008, 0x27bd0050, 0x27bdffa0, 0x801021, -0xafb00040, 0x24500002, 0x2002021, 0x24050006, -0xafb10044, 0x408821, 0xafbf0058, 0xafbe0054, -0xafb50050, 0xafb3004c, 0xc00240c, 0xafb20048, -0x3048007f, 0x810c0, 0x2e21021, 0x3c060001, -0xc23021, 0x94c630d0, 0x10c0001c, 0x3821, -0x3c0a0001, 0x354a34d2, 0x96290002, 0x610c0, -0x572021, 0x8a2021, 0x94820000, 0x14490009, -0x2821, 0x94830002, 0x96020002, 0x14620006, -0xa01021, 0x94820004, 0x96030004, 0x431026, -0x2c450001, 0xa01021, 0x14400008, 0x610c0, -0xc03821, 0x2e21021, 0x3c060001, 0xc23021, -0x94c634d0, 0x14c0ffea, 0x610c0, 0x14c00011, -0xafa70028, 0x810c0, 0x2e21021, 0xafa80010, -0x3c010001, 0x220821, 0x942230d0, 0x3c040001, -0x248463ac, 0xafa20014, 0x8e260000, 0x8e270004, -0x3c050004, 0xc002b3b, 0x34a50900, 0x10000075, -0x3c020800, 0x10e0000c, 0x610c0, 0x2e21021, -0x3c030001, 0x621821, 0x946334d0, 0x710c0, -0x2e21021, 0x3c010001, 0x220821, 0xa42334d0, -0x1000000b, 0x3c040001, 0x2e21021, 0x3c030001, -0x621821, 0x946334d0, 0x810c0, 0x2e21021, -0x3c010001, 0x220821, 0xa42330d0, 0x3c040001, -0x348430d0, 0x8f430100, 0x610c0, 0x2e21021, -0x3c010001, 0x220821, 0xa42334d0, 0x8f420104, -0x2e43821, 0x2821, 0x18400029, 0xaf460100, -0x24e60006, 0x94c3fffc, 0x96020000, 0x14620009, -0x2021, 0x94c3fffe, 0x96020002, 0x14620006, -0x801021, 0x94c20000, 0x96030004, 0x431026, -0x2c440001, 0x801021, 0x50400014, 0x24a50001, -0x8f420104, 0x2442ffff, 0xa2102a, 0x1040000b, -0x24e40004, 0x94820006, 0x8c830008, 0xa482fffe, -0xac830000, 0x8f420104, 0x24a50001, 0x2442ffff, -0xa2102a, 0x1440fff7, 0x24840008, 0x8f420104, -0x2442ffff, 0x10000006, 0xaf420104, 0x8f420104, -0x24c60008, 0xa2102a, 0x1440ffda, 0x24e70008, -0x810c0, 0x2e21021, 0x3c010001, 0x220821, -0x942230d0, 0x14400023, 0x3c020800, 0x3c020002, -0x2c21024, 0x10400012, 0x82142, 0x3c030001, -0x346338d8, 0x24020003, 0x441023, 0x21080, -0x572021, 0x832021, 0x571021, 0x431021, -0x3105001f, 0x24030001, 0x8c420000, 0xa31804, -0x31827, 0x431024, 0x1000000d, 0xac820000, -0x24020003, 0x441023, 0x21080, 0x5c2821, -0x5c1021, 0x3104001f, 0x24030001, 0x8c420228, -0x831804, 0x31827, 0x431024, 0xaca20228, -0x3c020800, 0x34422000, 0x1821, 0xafa20020, -0x8f5e0018, 0x27ab0020, 0x240200ff, 0x13c20002, -0xafab0034, 0x27c30001, 0x8c020228, 0x609021, -0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001, -0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001, -0x2484635c, 0x3c050009, 0xafa00014, 0xafa20010, -0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021, -0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4, -0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x1040001b, 0x9821, 0xe08821, -0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821, -0x240b0004, 0xafab0010, 0xafb20014, 0x8f48000c, -0x1021, 0x2f53021, 0xafa80018, 0x8f48010c, -0x24070008, 0xa32821, 0xa3482b, 0x822021, -0x100f809, 0x892021, 0x54400006, 0x24130001, -0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9, -0x0, 0x326200ff, 0x54400017, 0xaf520018, -0x8f420378, 0x24420001, 0xaf420378, 0x8f420378, -0x8f820120, 0x8fab0034, 0xafa20010, 0x8f820124, -0x3c040001, 0x24846368, 0x3c050009, 0xafa20014, -0x8d660000, 0x10000033, 0x34a50600, 0x8f420308, -0x24130001, 0x24420001, 0xaf420308, 0x8f420308, -0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014, -0x9821, 0x24110010, 0x8f42000c, 0x8f440160, -0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014, -0xafa20018, 0x8f42010c, 0x24070008, 0x40f809, -0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054, -0x2021023, 0x2c4203e9, 0x1440ffef, 0x0, -0x326200ff, 0x14400011, 0x0, 0x8f420378, -0x24420001, 0xaf420378, 0x8f420378, 0x8f820120, -0x8fab0034, 0xafa20010, 0x8f820124, 0x3c040001, -0x24846370, 0x3c050009, 0xafa20014, 0x8d660000, -0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b8, -0x24420001, 0xaf4202b8, 0x8f4202b8, 0x8f4202f4, -0x24420001, 0xaf4202f4, 0x8f4202f4, 0x8fbf0058, -0x8fbe0054, 0x8fb50050, 0x8fb3004c, 0x8fb20048, -0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0060, -0x0, 0x0, 0x0, 0x27bdffe0, -0x27644000, 0xafbf0018, 0xc002ba8, 0x24051000, -0x3c030001, 0x34632cc0, 0x3c040001, 0x34842ec8, -0x24020020, 0xaf82011c, 0x2e31021, 0xaf800100, -0xaf800104, 0xaf800108, 0xaf800110, 0xaf800114, -0xaf800118, 0xaf800120, 0xaf800124, 0xaf800128, -0xaf800130, 0xaf800134, 0xaf800138, 0xaf4200ec, -0x2e31021, 0xaf4200f0, 0x2e41021, 0xaf4200f4, -0x2e41021, 0xaf4200f8, 0x3c020001, 0x571021, -0x904240f4, 0x1440001c, 0x3c050001, 0x8f82011c, -0x3c040001, 0x24846470, 0x3c050001, 0x34420001, -0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c, -0x34a50100, 0xc002b3b, 0x3821, 0x8c020218, -0x30420040, 0x10400014, 0x0, 0x8f82011c, -0x3c040001, 0x2484647c, 0x3c050001, 0x34420004, -0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c, -0x10000007, 0x34a50200, 0x3c040001, 0x24846484, -0xafa00010, 0xafa00014, 0x8f86011c, 0x34a50300, -0xc002b3b, 0x3821, 0x8fbf0018, 0x3e00008, -0x27bd0020, 0x8fa90010, 0x8f83012c, 0x8faa0014, -0x8fab0018, 0x1060000a, 0x27624fe0, 0x14620002, -0x24680020, 0x27684800, 0x8f820128, 0x11020004, -0x0, 0x8f820124, 0x15020007, 0x0, -0x8f430334, 0x1021, 0x24630001, 0xaf430334, -0x10000039, 0x8f430334, 0xac640000, 0xac650004, -0xac660008, 0xa467000e, 0xac690018, 0xac6a001c, -0xac6b0010, 0xac620014, 0xaf880120, 0x8f4200fc, -0x8f4400f4, 0x2442ffff, 0xaf4200fc, 0x8c820000, -0x10490005, 0x3042ff8f, 0x10400019, 0x3122ff8f, -0x10400018, 0x3c020001, 0x8c830004, 0x2c620010, -0x10400013, 0x3c020001, 0x24630001, 0xac830004, -0x8f4300f8, 0x344230c8, 0x2e21021, 0x54620004, -0x24620008, 0x3c020001, 0x34422ec8, 0x2e21021, -0x14440015, 0x24020001, 0x8f820128, 0x24420020, -0xaf820128, 0x8f820128, 0x1000000f, 0x24020001, -0x3c020001, 0x344230c8, 0x2e21021, 0x54820004, -0x24820008, 0x3c020001, 0x34422ec8, 0x2e21021, -0x402021, 0x24020001, 0xaf4400f4, 0xac890000, -0xac820004, 0x24020001, 0x3e00008, 0x0, -0x3e00008, 0x0, 0x8fa90010, 0x8f83010c, -0x8faa0014, 0x8fab0018, 0x1060000a, 0x276247e0, -0x14620002, 0x24680020, 0x27684000, 0x8f820108, -0x11020004, 0x0, 0x8f820104, 0x15020007, -0x0, 0x8f430338, 0x1021, 0x24630001, -0xaf430338, 0x10000035, 0x8f430338, 0xac640000, -0xac650004, 0xac660008, 0xa467000e, 0xac690018, -0xac6a001c, 0xac6b0010, 0xac620014, 0xaf880100, -0x8f4400ec, 0x8c820000, 0x30420006, 0x10400019, -0x31220006, 0x10400018, 0x3c020001, 0x8c830004, -0x2c620010, 0x10400013, 0x3c020001, 0x24630001, -0xac830004, 0x8f4300f0, 0x34422ec0, 0x2e21021, -0x54620004, 0x24620008, 0x3c020001, 0x34422cc0, -0x2e21021, 0x14440015, 0x24020001, 0x8f820108, -0x24420020, 0xaf820108, 0x8f820108, 0x1000000f, -0x24020001, 0x3c020001, 0x34422ec0, 0x2e21021, -0x54820004, 0x24820008, 0x3c020001, 0x34422cc0, -0x2e21021, 0x402021, 0x24020001, 0xaf4400ec, -0xac890000, 0xac820004, 0x24020001, 0x3e00008, -0x0, 0x3e00008, 0x0, 0x27bdffd8, -0x3c040001, 0x2484648c, 0x3c050001, 0xafbf0024, -0xafb20020, 0xafb1001c, 0xafb00018, 0x8f900104, -0x8f9100b0, 0x8f92011c, 0x34a52500, 0x8f820100, -0x2403021, 0x2203821, 0xafa20010, 0xc002b3b, -0xafb00014, 0x8e020008, 0xafa20010, 0x8e02000c, -0x3c040001, 0x24846498, 0xafa20014, 0x8e060000, -0x8e070004, 0x3c050001, 0xc002b3b, 0x34a52510, -0x8e020018, 0xafa20010, 0x8e02001c, 0x3c040001, -0x248464a4, 0xafa20014, 0x8e060010, 0x8e070014, -0x3c050001, 0xc002b3b, 0x34a52520, 0x3c027f00, -0x2221024, 0x3c030800, 0x54430016, 0x3c030200, -0x8f82009c, 0x3042ffff, 0x14400012, 0x3c030200, -0x3c040001, 0x248464b0, 0x3c050002, 0x34a5f030, -0x3021, 0x3821, 0x36420002, 0xaf82011c, -0x36220001, 0xaf8200b0, 0xaf900104, 0xaf92011c, -0xafa00010, 0xc002b3b, 0xafa00014, 0x10000024, -0x0, 0x2c31024, 0x1040000d, 0x2231024, -0x1040000b, 0x36420002, 0xaf82011c, 0x36220001, -0xaf8200b0, 0xaf900104, 0xaf92011c, 0x8f420330, -0x24420001, 0xaf420330, 0x10000015, 0x8f420330, -0x3c040001, 0x248464b8, 0x240202a9, 0xafa20010, -0xafa00014, 0x8f860144, 0x3c070001, 0x24e764c0, -0xc002b3b, 0x3405dead, 0x8f82011c, 0x34420002, -0xaf82011c, 0x8f820220, 0x34420004, 0xaf820220, -0x8f820140, 0x3c030001, 0x431025, 0xaf820140, -0x8fbf0024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, -0x3e00008, 0x27bd0028, 0x27bdffd8, 0x3c040001, -0x248464e8, 0x3c050001, 0xafbf0024, 0xafb20020, -0xafb1001c, 0xafb00018, 0x8f900124, 0x8f9100a0, -0x8f92011c, 0x34a52600, 0x8f820120, 0x2403021, -0x2203821, 0xafa20010, 0xc002b3b, 0xafb00014, -0x8e020008, 0xafa20010, 0x8e02000c, 0x3c040001, -0x248464f4, 0xafa20014, 0x8e060000, 0x8e070004, -0x3c050001, 0xc002b3b, 0x34a52610, 0x8e020018, -0xafa20010, 0x8e02001c, 0x3c040001, 0x24846500, -0xafa20014, 0x8e060010, 0x8e070014, 0x3c050001, -0xc002b3b, 0x34a52620, 0x3c027f00, 0x2221024, -0x3c030800, 0x54430016, 0x3c030200, 0x8f8200ac, -0x3042ffff, 0x14400012, 0x3c030200, 0x3c040001, -0x2484650c, 0x3c050001, 0x34a5f030, 0x3021, -0x3821, 0x36420002, 0xaf82011c, 0x36220001, -0xaf8200a0, 0xaf900124, 0xaf92011c, 0xafa00010, -0xc002b3b, 0xafa00014, 0x10000024, 0x0, -0x2c31024, 0x1040000d, 0x2231024, 0x1040000b, -0x36420002, 0xaf82011c, 0x36220001, 0xaf8200a0, -0xaf900124, 0xaf92011c, 0x8f42032c, 0x24420001, -0xaf42032c, 0x10000015, 0x8f42032c, 0x3c040001, -0x248464b8, 0x240202e2, 0xafa20010, 0xafa00014, -0x8f860144, 0x3c070001, 0x24e764c0, 0xc002b3b, -0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c, -0x8f820220, 0x34420004, 0xaf820220, 0x8f820140, -0x3c030001, 0x431025, 0xaf820140, 0x8fbf0024, -0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008, -0x27bd0028, 0x6021, 0x5021, 0x3021, -0x2821, 0x6821, 0x4821, 0x7821, -0x7021, 0x8f880124, 0x8f870104, 0x1580002e, -0x8f8b011c, 0x11a00014, 0x31620800, 0x8f820120, -0x10460029, 0x0, 0x3c040001, 0x8c846ee4, -0x8cc20000, 0x8cc30004, 0xac820000, 0xac830004, -0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e, -0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014, -0x10000012, 0x24c60020, 0x10400017, 0x0, -0x3c040001, 0x8c846ee4, 0x8d020000, 0x8d030004, -0xac820000, 0xac830004, 0x8d020008, 0xac820008, -0x9502000e, 0xa482000e, 0x8d020010, 0x25060020, -0xac820010, 0x8d020014, 0x240c0001, 0xc01821, -0xac820014, 0x27624fe0, 0x43102b, 0x54400001, -0x27634800, 0x603021, 0x1540002f, 0x31620100, -0x11200014, 0x31628000, 0x8f820100, 0x1045002a, -0x31620100, 0x3c040001, 0x8c846ee0, 0x8ca20000, -0x8ca30004, 0xac820000, 0xac830004, 0x8ca20008, -0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010, -0x240a0001, 0xac820010, 0x8ca20014, 0x10000012, -0x24a50020, 0x10400018, 0x31620100, 0x3c040001, -0x8c846ee0, 0x8ce20000, 0x8ce30004, 0xac820000, -0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e, -0xa482000e, 0x8ce20010, 0x24e50020, 0xac820010, -0x8ce20014, 0x240a0001, 0xa01821, 0xac820014, -0x276247e0, 0x43102b, 0x54400001, 0x27634000, -0x602821, 0x31620100, 0x5440001d, 0x31621000, -0x11a00009, 0x31a20800, 0x10400004, 0x25020020, -0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124, -0x8f880124, 0x6821, 0x11800011, 0x31621000, -0x3c040001, 0x8c846ee4, 0x8c820000, 0x8c830004, -0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4, -0x9482000e, 0xaf8200ac, 0x8c820010, 0x6021, -0xaf8200a0, 0x8c8d0010, 0x8c8f0014, 0x31621000, -0x1440ff82, 0x0, 0x1120000f, 0x31220800, -0x10400004, 0x3c020002, 0x8f8200b8, 0xa5c20000, -0x3c020002, 0x1221024, 0x10400004, 0x24e20020, -0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104, -0x8f870104, 0x4821, 0x1140ff70, 0x0, -0x3c040001, 0x8c846ee0, 0x8c820000, 0x8c830004, -0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4, -0x9482000e, 0xaf82009c, 0x8c820010, 0x5021, -0xaf8200b0, 0x8c890010, 0x1000ff60, 0x8c8e0014, -0x3e00008, 0x0, 0x6021, 0x5821, -0x3021, 0x2821, 0x6821, 0x5021, -0x7821, 0x7021, 0x8f880124, 0x8f870104, -0x3c180100, 0x1580002e, 0x8f89011c, 0x11a00014, -0x31220800, 0x8f820120, 0x10460029, 0x0, -0x3c040001, 0x8c846ee4, 0x8cc20000, 0x8cc30004, -0xac820000, 0xac830004, 0x8cc20008, 0xac820008, -0x94c2000e, 0xa482000e, 0x8cc20010, 0x240c0001, -0xac820010, 0x8cc20014, 0x10000012, 0x24c60020, -0x10400017, 0x0, 0x3c040001, 0x8c846ee4, -0x8d020000, 0x8d030004, 0xac820000, 0xac830004, -0x8d020008, 0xac820008, 0x9502000e, 0xa482000e, -0x8d020010, 0x25060020, 0xac820010, 0x8d020014, -0x240c0001, 0xc01821, 0xac820014, 0x27624fe0, -0x43102b, 0x54400001, 0x27634800, 0x603021, -0x1560002f, 0x31220100, 0x11400014, 0x31228000, -0x8f820100, 0x1045002a, 0x31220100, 0x3c040001, -0x8c846ee0, 0x8ca20000, 0x8ca30004, 0xac820000, -0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e, -0xa482000e, 0x8ca20010, 0x240b0001, 0xac820010, -0x8ca20014, 0x10000012, 0x24a50020, 0x10400018, -0x31220100, 0x3c040001, 0x8c846ee0, 0x8ce20000, -0x8ce30004, 0xac820000, 0xac830004, 0x8ce20008, -0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010, -0x24e50020, 0xac820010, 0x8ce20014, 0x240b0001, -0xa01821, 0xac820014, 0x276247e0, 0x43102b, -0x54400001, 0x27634000, 0x602821, 0x31220100, -0x5440001d, 0x31221000, 0x11a00009, 0x31a20800, -0x10400004, 0x25020020, 0x8f8200a8, 0xa5e20000, -0x25020020, 0xaf820124, 0x8f880124, 0x6821, -0x11800011, 0x31221000, 0x3c040001, 0x8c846ee4, -0x8c820000, 0x8c830004, 0xaf820080, 0xaf830084, -0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac, -0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010, -0x8c8f0014, 0x31221000, 0x14400022, 0x0, -0x1140000f, 0x31420800, 0x10400004, 0x3c020002, -0x8f8200b8, 0xa5c20000, 0x3c020002, 0x1421024, -0x10400004, 0x24e20020, 0x8f8200b4, 0xaf8200d4, -0x24e20020, 0xaf820104, 0x8f870104, 0x5021, -0x11600010, 0x0, 0x3c040001, 0x8c846ee0, -0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094, -0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c, -0x8c820010, 0x5821, 0xaf8200b0, 0x8c8a0010, -0x8c8e0014, 0x8f820070, 0x3c031000, 0x431024, -0x1040ff5c, 0x0, 0x8f820054, 0x24420005, -0xaf820078, 0x8c040234, 0x10800016, 0x1821, -0x3c020001, 0x571021, 0x8c4240e8, 0x24420005, -0x3c010001, 0x370821, 0xac2240e8, 0x3c020001, -0x571021, 0x8c4240e8, 0x44102b, 0x14400009, -0x24020001, 0x3c030080, 0x3c010001, 0x370821, -0xac2040e8, 0x3c010001, 0x370821, 0x1000000c, -0xa02240f0, 0x3c020001, 0x571021, 0x904240f0, -0x14400006, 0x3c020080, 0x3c020001, 0x571021, -0x904240f1, 0x10400002, 0x3c020080, 0x621825, -0x8c040230, 0x10800013, 0x0, 0x3c020001, -0x571021, 0x8c4240ec, 0x24420005, 0x3c010001, -0x370821, 0xac2240ec, 0x3c020001, 0x571021, -0x8c4240ec, 0x44102b, 0x14400006, 0x0, -0x3c010001, 0x370821, 0xac2040ec, 0x10000006, -0x781825, 0x3c020001, 0x571021, 0x904240f2, -0x54400001, 0x781825, 0x1060ff1a, 0x0, -0x8f420000, 0x10400007, 0x0, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x431025, 0xaf820060, -0x8f420000, 0x10400003, 0x0, 0x1000ff05, -0xaf80004c, 0x1000ff03, 0xaf800048, 0x3e00008, -0x0, 0x0, 0x0, 0x3c020001, -0x8c426d28, 0x27bdffe8, 0xafbf0014, 0x14400012, -0xafb00010, 0x3c100001, 0x26106f90, 0x2002021, -0xc002ba8, 0x24052000, 0x26021fe0, 0x3c010001, -0xac226eec, 0x3c010001, 0xac226ee8, 0xac020250, -0x24022000, 0xac100254, 0xac020258, 0x24020001, -0x3c010001, 0xac226d28, 0x8fbf0014, 0x8fb00010, -0x3e00008, 0x27bd0018, 0x3c090001, 0x8d296eec, -0x8c820000, 0x8fa30010, 0x8fa80014, 0xad220000, -0x8c820004, 0xad250008, 0xad220004, 0x8f820054, -0xad260010, 0xad270014, 0xad230018, 0xad28001c, -0xad22000c, 0x2529ffe0, 0x3c020001, 0x24426f90, -0x122102b, 0x10400003, 0x0, 0x3c090001, -0x8d296ee8, 0x3c020001, 0x8c426d10, 0xad220000, -0x3c020001, 0x8c426d10, 0x3c010001, 0xac296eec, -0xad220004, 0xac090250, 0x3e00008, 0x0, -0x27bdffd0, 0xafb00010, 0x3c100001, 0x8e106eec, -0x3c020001, 0x8c426d10, 0xafb10014, 0x808821, -0xafbe0024, 0x8fbe0040, 0x8fa40048, 0xafb20018, -0xa09021, 0xafbf0028, 0xafb50020, 0xafb3001c, -0xae020000, 0x3c020001, 0x8c426d10, 0xc09821, -0xe0a821, 0x10800006, 0xae020004, 0x26050008, -0xc002bb3, 0x24060018, 0x10000005, 0x2610ffe0, -0x26040008, 0xc002ba8, 0x24050018, 0x2610ffe0, -0x3c030001, 0x24636f90, 0x203102b, 0x10400003, -0x0, 0x3c100001, 0x8e106ee8, 0x8e220000, -0xae020000, 0x8e220004, 0xae120008, 0xae020004, -0x8f820054, 0xae130010, 0xae150014, 0xae1e0018, -0x8fa80044, 0xae08001c, 0xae02000c, 0x2610ffe0, -0x203102b, 0x10400003, 0x0, 0x3c100001, -0x8e106ee8, 0x3c020001, 0x8c426d10, 0xae020000, -0x3c020001, 0x8c426d10, 0x3c010001, 0xac306eec, -0xae020004, 0xac100250, 0x8fbf0028, 0x8fbe0024, -0x8fb50020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, -0x8fb00010, 0x3e00008, 0x27bd0030, 0x851821, -0x83102b, 0x10400006, 0x0, 0xac800000, -0x24840004, 0x83102b, 0x5440fffd, 0xac800000, -0x3e00008, 0x0, 0xa61821, 0xa3102b, -0x10400007, 0x0, 0x8c820000, 0xaca20000, -0x24a50004, 0xa3102b, 0x1440fffb, 0x24840004, -0x3e00008, 0x0, 0x861821, 0x83102b, -0x10400007, 0x0, 0x8ca20000, 0xac820000, -0x24840004, 0x83102b, 0x1440fffb, 0x24a50004, -0x3e00008, 0x0, 0x63080, 0x861821, -0x83102b, 0x10400006, 0x0, 0xac850000, -0x24840004, 0x83102b, 0x5440fffd, 0xac850000, -0x3e00008, 0x0, 0x0, 0x26e50028, -0xa03021, 0x274301c0, 0x8f4d0358, 0x8f47035c, -0x8f480360, 0x8f490364, 0x8f4a0368, 0x8f4b0204, -0x8f4c0200, 0x24640400, 0x64102b, 0x10400008, -0x3c0208ff, 0x8cc20000, 0xac620000, 0x24630004, -0x64102b, 0x1440fffb, 0x24c60004, 0x3c0208ff, -0x3442ffff, 0x3c03c0ff, 0xaf4d0358, 0xaf47035c, -0xaf480360, 0xaf490364, 0xaf4a0368, 0xaf4b0204, -0xaf4c0200, 0x8f840220, 0x3463ffff, 0x8f860200, -0x821024, 0x34420004, 0xc31824, 0x34630004, -0xaf820220, 0xaf830200, 0x8ca20214, 0xac020084, -0x8ca20218, 0xac020088, 0x8ca2021c, 0xac02008c, -0x8ca20220, 0xac020090, 0x8ca20224, 0xac020094, -0x8ca20228, 0xac020098, 0x8ca2022c, 0xac02009c, -0x8ca20230, 0xac0200a0, 0x8ca20234, 0xac0200a4, -0x8ca20238, 0xac0200a8, 0x8ca2023c, 0xac0200ac, -0x8ca20240, 0xac0200b0, 0x8ca20244, 0xac0200b4, -0x8ca20248, 0xac0200b8, 0x8ca2024c, 0xac0200bc, -0x8ca2001c, 0xac020080, 0x8ca20018, 0xac0200c0, -0x8ca20020, 0xac0200cc, 0x8ca20024, 0xac0200d0, -0x8ca201d0, 0xac0200e0, 0x8ca201d4, 0xac0200e4, -0x8ca201d8, 0xac0200e8, 0x8ca201dc, 0xac0200ec, -0x8ca201e0, 0xac0200f0, 0x8ca20098, 0x8ca3009c, -0xac0300fc, 0x8ca200a8, 0x8ca300ac, 0xac0300f4, -0x8ca200a0, 0x8ca300a4, 0x30840004, 0xac0300f8, -0x14800007, 0x30c20004, 0x8f820220, 0x3c0308ff, -0x3463fffb, 0x431024, 0xaf820220, 0x30c20004, -0x14400006, 0x0, 0x8f820200, 0x3c03c0ff, -0x3463fffb, 0x431024, 0xaf820200, 0x8f4202dc, -0xa34005c5, 0x24420001, 0xaf4202dc, 0x8f4202dc, -0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024, -0xafb00020, 0x8f430024, 0x8f420020, 0x10620038, -0x0, 0x8f430020, 0x8f420024, 0x622023, -0x4810003, 0x0, 0x8f420040, 0x822021, -0x8f430030, 0x8f420024, 0x43102b, 0x14400005, -0x0, 0x8f430040, 0x8f420024, 0x10000005, -0x621023, 0x8f420030, 0x8f430024, 0x431023, -0x2442ffff, 0x406021, 0x8c102a, 0x54400001, -0x806021, 0x8f4a0024, 0x8f490040, 0x8f480024, -0x8f440180, 0x8f450184, 0x8f460024, 0x8f4b001c, -0x24070001, 0xafa70010, 0x84100, 0x1001821, -0x14c5021, 0x2529ffff, 0x1498024, 0xafb00014, -0x8f470014, 0x1021, 0x63100, 0xafa70018, -0xa32821, 0xa3382b, 0x822021, 0x872021, -0x8f420108, 0x1663021, 0x40f809, 0xc3900, -0x54400001, 0xaf500024, 0x8f430024, 0x8f420020, -0x14620018, 0x0, 0x8f420000, 0x10400007, -0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd, -0x0, 0x10000005, 0x0, 0xaf800048, -0x8f820048, 0x1040fffd, 0x0, 0x8f820060, -0x2403ffef, 0x431024, 0xaf820060, 0x8f420000, -0x10400003, 0x0, 0x10000002, 0xaf80004c, -0xaf800048, 0x8fbf0024, 0x8fb00020, 0x3e00008, -0x27bd0028, 0x3e00008, 0x0, 0x27bdffc0, -0x32c20020, 0xafbf0038, 0xafb30034, 0xafb20030, -0xafb1002c, 0x10400004, 0xafb00028, 0x8f530028, -0x10000002, 0x0, 0x8f530020, 0x8f420030, -0x105300eb, 0x21100, 0x8f43001c, 0x628021, -0x8e040000, 0x8e050004, 0x96120008, 0x8f420090, -0x9611000a, 0x3246ffff, 0x46102a, 0x10400017, -0x0, 0x8f8200d8, 0x8f430098, 0x431023, -0x2442dcbe, 0xaf420090, 0x8f420090, 0x2842dcbf, -0x10400005, 0x0, 0x8f420090, 0x8f430144, -0x431021, 0xaf420090, 0x8f420090, 0x46102a, -0x10400006, 0x0, 0x8f420348, 0x24420001, -0xaf420348, 0x100000e1, 0x8f420348, 0x8f8200fc, -0x14400006, 0x0, 0x8f420344, 0x24420001, -0xaf420344, 0x100000d9, 0x8f420344, 0x934205c2, -0x1040000b, 0x32c20008, 0x10400008, 0x32220200, -0x10400006, 0x3c034000, 0x9602000e, 0xaf4300ac, -0x21400, 0x10000002, 0xaf4200b0, 0xaf4000ac, -0x32220004, 0x1040007f, 0x32220800, 0x10400003, -0x3247ffff, 0x10000002, 0x24020020, 0x24020004, -0xafa20010, 0x8f420030, 0xafa20014, 0x8f420010, -0x3c030002, 0x431025, 0xafa20018, 0x8f460098, -0x8f420108, 0x40f809, 0x0, 0x104000b7, -0x0, 0x8f42009c, 0x8f430094, 0x2421021, -0xaf42009c, 0xae03000c, 0x8f4200ac, 0x10400008, -0x3c034000, 0x8f420094, 0x431025, 0xafa20020, -0x8f42009c, 0x8f4300b0, 0x10000004, 0x431025, -0x8f420094, 0xafa20020, 0x8f42009c, 0xafa20024, -0x8f8200fc, 0x8fa30020, 0x8fa40024, 0xac430000, -0xac440004, 0x24420008, 0xaf8200f0, 0x8f42009c, -0x8f440270, 0x8f450274, 0x401821, 0x1021, -0xa32821, 0xa3302b, 0x822021, 0x862021, -0x32230060, 0x24020040, 0xaf440270, 0xaf450274, -0x10620017, 0x2c620041, 0x10400005, 0x24020020, -0x10620008, 0x24020001, 0x10000026, 0x0, -0x24020060, 0x10620019, 0x24020001, 0x10000021, -0x0, 0x8f420278, 0x8f43027c, 0x24630001, -0x2c640001, 0x441021, 0xaf420278, 0xaf43027c, -0x8f420278, 0x8f43027c, 0x10000016, 0x24020001, -0x8f420280, 0x8f430284, 0x24630001, 0x2c640001, -0x441021, 0xaf420280, 0xaf430284, 0x8f420280, -0x8f430284, 0x1000000b, 0x24020001, 0x8f420288, -0x8f43028c, 0x24630001, 0x2c640001, 0x441021, -0xaf420288, 0xaf43028c, 0x8f420288, 0x8f43028c, -0x24020001, 0xa34205c2, 0x8f420098, 0x3244ffff, -0x2406fff8, 0x8f45013c, 0x441021, 0x24420007, -0x461024, 0x24840007, 0xaf420094, 0x8f420090, -0x8f430094, 0x862024, 0x441023, 0x65182b, -0x14600005, 0xaf420090, 0x8f420094, 0x8f430144, -0x431023, 0xaf420094, 0x8f420094, 0x10000023, -0xaf40009c, 0x3247ffff, 0x50e00022, 0x32c20020, -0x14400002, 0x24020010, 0x24020002, 0xafa20010, -0x8f420030, 0xafa20014, 0x8f420010, 0xafa20018, -0x8f460098, 0x8f420108, 0x40f809, 0x0, -0x1040003a, 0x3245ffff, 0x8f420098, 0x8f430090, -0x8f46013c, 0x451021, 0xaf420098, 0x8f42009c, -0x8f440098, 0xa34005c2, 0x651823, 0xaf430090, -0x451021, 0x86202b, 0x14800005, 0xaf42009c, -0x8f420098, 0x8f430144, 0x431023, 0xaf420098, -0x32c20020, 0x10400005, 0x0, 0x8f420358, -0x2442ffff, 0xaf420358, 0x8f420358, 0x8f420030, -0x8f430040, 0x24420001, 0x2463ffff, 0x431024, -0xaf420030, 0x8f420030, 0x14530018, 0x0, -0x8f420000, 0x10400007, 0x0, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x2403fff7, 0x431024, -0xaf820060, 0x8f420000, 0x10400003, 0x0, -0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf0038, -0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, -0x3e00008, 0x27bd0040, 0x3e00008, 0x0, -0x27bdffd0, 0x32c20020, 0xafbf002c, 0xafb20028, -0xafb10024, 0x10400004, 0xafb00020, 0x8f520028, -0x10000002, 0x0, 0x8f520020, 0x8f420030, -0x105200b5, 0x21100, 0x8f43001c, 0x628021, -0x8e040000, 0x8e050004, 0x96110008, 0x8f420090, -0x9607000a, 0x3226ffff, 0x46102a, 0x10400017, -0x0, 0x8f8200d8, 0x8f430098, 0x431023, -0x2442dc46, 0xaf420090, 0x8f420090, 0x2842dc47, -0x10400005, 0x0, 0x8f420090, 0x8f430144, -0x431021, 0xaf420090, 0x8f420090, 0x46102a, -0x10400006, 0x0, 0x8f420348, 0x24420001, -0xaf420348, 0x100000ab, 0x8f420348, 0x8f8600fc, -0x10c0000c, 0x0, 0x8f8200f4, 0x2403fff8, -0x431024, 0x461023, 0x218c3, 0x58600001, -0x24630100, 0x8f42008c, 0x43102b, 0x14400006, -0x712c2, 0x8f420344, 0x24420001, 0xaf420344, -0x10000098, 0x8f420344, 0x934305c2, 0x1060000f, -0x30460001, 0x8f420010, 0x34480400, 0x32c20008, -0x10400008, 0x30e20200, 0x10400006, 0x3c034000, -0x9602000e, 0xaf4300ac, 0x21400, 0x10000004, -0xaf4200b0, 0x10000002, 0xaf4000ac, 0x8f480010, -0x30e20004, 0x10400045, 0x3227ffff, 0x8f4900ac, -0x11200005, 0x30c200ff, 0x14400006, 0x24020040, -0x10000004, 0x24020008, 0x14400002, 0x24020020, -0x24020004, 0xafa20010, 0x8f430030, 0x11200004, -0xafa30014, 0x8f4200b0, 0x621025, 0xafa20014, -0x3c020002, 0x1021025, 0xafa20018, 0x8f460098, -0x8f420108, 0x40f809, 0x0, 0x10400069, -0x3224ffff, 0x8f42008c, 0x8f430094, 0x24420001, -0xaf42008c, 0x24020001, 0xae03000c, 0xa34205c2, -0x8f420098, 0x2406fff8, 0x8f45013c, 0x441021, -0x24420007, 0x461024, 0x24840007, 0xaf420094, -0x8f420090, 0x8f430094, 0x862024, 0x441023, -0x65182b, 0x14600005, 0xaf420090, 0x8f420094, -0x8f430144, 0x431023, 0xaf420094, 0x8f430094, -0x8f420140, 0x43102b, 0x10400009, 0x0, -0x8f43013c, 0x8f440094, 0x8f420090, 0x8f450138, -0x641823, 0x431023, 0xaf420090, 0xaf450094, -0x8f420094, 0x1000001f, 0xaf420098, 0x10e0001d, -0x30c200ff, 0x14400002, 0x24020010, 0x24020002, -0xafa20010, 0x8f420030, 0xafa80018, 0xafa20014, -0x8f460098, 0x8f420108, 0x40f809, 0x0, -0x10400030, 0x3225ffff, 0x8f420098, 0x8f44013c, -0x451021, 0xaf420098, 0x8f420090, 0x8f430098, -0xa34005c2, 0x451023, 0x64182b, 0x14600005, -0xaf420090, 0x8f420098, 0x8f430144, 0x431023, -0xaf420098, 0x8f420030, 0x8f430040, 0x24420001, -0x2463ffff, 0x431024, 0xaf420030, 0x8f420030, -0x14520018, 0x0, 0x8f420000, 0x10400007, -0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd, -0x0, 0x10000005, 0x0, 0xaf800048, -0x8f820048, 0x1040fffd, 0x0, 0x8f820060, -0x2403fff7, 0x431024, 0xaf820060, 0x8f420000, -0x10400003, 0x0, 0x10000002, 0xaf80004c, -0xaf800048, 0x8fbf002c, 0x8fb20028, 0x8fb10024, -0x8fb00020, 0x3e00008, 0x27bd0030, 0x3e00008, -0x0, 0x27bdffd8, 0x3c020001, 0x34422ec0, -0xafbf0020, 0x8f4300f0, 0x8f840108, 0x2e21021, -0x54620004, 0x24620008, 0x3c020001, 0x34422cc0, -0x2e21021, 0x401821, 0xaf4300f0, 0xac600000, -0x8f4200ec, 0x8c660004, 0x14620004, 0x3c020001, -0x24820020, 0x1000000f, 0xaf820108, 0x8f4300f0, -0x34422ec0, 0x2e21021, 0x54620004, 0x24620008, -0x3c020001, 0x34422cc0, 0x2e21021, 0x401821, -0x8c620004, 0x21140, 0x821021, 0xaf820108, -0xac600000, 0x8c850018, 0x30a20036, 0x1040006c, -0x30a20001, 0x8c82001c, 0x8f430040, 0x8f440034, -0x24420001, 0x2463ffff, 0x431024, 0x862021, -0xaf42002c, 0x30a20030, 0x14400006, 0xaf440034, -0x8f420034, 0x8c03023c, 0x43102b, 0x144000b4, -0x0, 0x32c20010, 0x10400028, 0x24070008, -0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c, -0x8f860120, 0x24020080, 0xafa20010, 0xafa30014, -0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x14400011, 0x24020001, 0x3c010001, 0x370821, -0xa02240f1, 0x8f820124, 0xafa20010, 0x8f820128, -0x3c040001, 0x248467c4, 0xafa20014, 0x8f46002c, -0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51100, -0x10000036, 0x0, 0x8f420300, 0x8f43002c, -0x24420001, 0xaf420300, 0x8f420300, 0x24020001, -0xa34205c1, 0x10000026, 0xaf430038, 0x8f440170, -0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120, -0x24020020, 0xafa20010, 0xafa30014, 0xafa80018, -0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, -0x24020001, 0x3c010001, 0x370821, 0xa02240f0, -0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001, -0x248467b8, 0xafa20014, 0x8f46002c, 0x8f870120, -0x3c050009, 0xc002b3b, 0x34a50900, 0x1000000f, -0x0, 0x8f420300, 0x24420001, 0xaf420300, -0x8f420300, 0x8f42002c, 0xa34005c1, 0xaf420038, -0x3c010001, 0x370821, 0xa02040f1, 0x3c010001, -0x370821, 0xa02040f0, 0xaf400034, 0x8f420314, -0x24420001, 0xaf420314, 0x10000059, 0x8f420314, -0x10400022, 0x30a27000, 0x8c85001c, 0x8f420028, -0xa22023, 0x4810003, 0x0, 0x8f420040, -0x822021, 0x8f420358, 0x8f430000, 0xaf450028, -0x441021, 0x10600007, 0xaf420358, 0xaf80004c, -0x8f82004c, 0x1040fffd, 0x0, 0x10000005, -0x0, 0xaf800048, 0x8f820048, 0x1040fffd, -0x0, 0x8f820060, 0x34420008, 0xaf820060, -0x8f420000, 0x10400003, 0x0, 0x10000038, -0xaf80004c, 0x10000036, 0xaf800048, 0x1040002f, -0x30a21000, 0x1040000c, 0x30a24000, 0x8c83001c, -0x8f420050, 0x622023, 0x4820001, 0x24840200, -0x8f42035c, 0x441021, 0xaf42035c, 0x8f420368, -0x1000001a, 0xaf430050, 0x1040000c, 0x32c28000, -0x8c83001c, 0x8f420070, 0x622023, 0x4820001, -0x24840400, 0x8f420364, 0x441021, 0xaf420364, -0x8f420368, 0x1000000d, 0xaf430070, 0x1040000e, -0x3c020800, 0x8c83001c, 0x8f420060, 0x622023, -0x4820001, 0x24840100, 0x8f420360, 0x441021, -0xaf420360, 0x8f420368, 0xaf430060, 0x441021, -0xaf420368, 0x3c020800, 0x2c21024, 0x50400008, -0x36940040, 0x10000006, 0x0, 0x30a20100, -0x10400003, 0x0, 0xc002bd8, 0x0, -0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008, -0x0, 0x27bdffa8, 0xafbf0050, 0xafbe004c, -0xafb50048, 0xafb30044, 0xafb20040, 0xafb1003c, -0xafb00038, 0x8f910108, 0x26220020, 0xaf820108, -0x8e320018, 0xa821, 0x32420024, 0x104001ba, -0xf021, 0x8e26001c, 0x8f43001c, 0x61100, -0x621821, 0x8c70000c, 0x9604000c, 0x962d0016, -0x9473000a, 0x2c8305dd, 0x38828870, 0x2c420001, -0x621825, 0x10600015, 0x2821, 0x32c20040, -0x10400015, 0x24020800, 0x96030014, 0x14620012, -0x3402aaaa, 0x9603000e, 0x14620007, 0x2021, -0x96030010, 0x24020300, 0x14620004, 0x801021, -0x96020012, 0x2c440001, 0x801021, 0x54400006, -0x24050016, 0x10000004, 0x0, 0x24020800, -0x50820001, 0x2405000e, 0x934205c3, 0x14400008, -0x5821, 0x240b0001, 0x32620180, 0xaf4500a8, -0xaf5000a0, 0x10400002, 0xaf4600a4, 0xa34b05c3, -0x10a00085, 0x2054021, 0x91020000, 0x3821, -0x3042000f, 0x25080, 0x32c20002, 0x10400012, -0x10a1821, 0x32620002, 0x10400010, 0x32c20001, -0x1002021, 0x94820000, 0x24840002, 0xe23821, -0x83102b, 0x1440fffb, 0x30e2ffff, 0x71c02, -0x623821, 0x71c02, 0x30e2ffff, 0x623821, -0x71027, 0xa502000a, 0x32c20001, 0x1040006a, -0x32620001, 0x10400068, 0x0, 0x8f4200a8, -0x10400065, 0x0, 0x8f4200a0, 0x8f4300a8, -0x431021, 0x904c0009, 0x318900ff, 0x39230006, -0x3182b, 0x39220011, 0x2102b, 0x621824, -0x1060000c, 0x3c050006, 0x8f4200a4, 0x3c040001, -0x248467d4, 0xafa20010, 0x8f4200a0, 0x34a54600, -0x1203821, 0xc002b3b, 0xafa20014, 0x1000004e, -0x0, 0x32c20004, 0x14400013, 0x2821, -0x316200ff, 0x14400004, 0x0, 0x95020002, -0x1000000d, 0x4a2823, 0x9505000c, 0x9502000e, -0x95030010, 0xa22821, 0xa32821, 0x95030012, -0x91040009, 0x95020002, 0xa32821, 0xa42821, -0x4a1023, 0xa22821, 0x2002021, 0x94820000, -0x24840002, 0xe23821, 0x88102b, 0x1440fffb, -0x71c02, 0x30e2ffff, 0x623821, 0x71c02, -0x30e2ffff, 0x623821, 0x1a52821, 0x51c02, -0x30a2ffff, 0x622821, 0x51c02, 0x30a2ffff, -0x622821, 0xa72823, 0x51402, 0xa22821, -0x30a5ffff, 0x50a00001, 0x3405ffff, 0x316200ff, -0x14400008, 0x318300ff, 0x8f4300a0, 0x8f4200a8, -0x624021, 0x91020000, 0x3042000f, 0x25080, -0x318300ff, 0x24020006, 0x14620003, 0x10a1021, -0x10000002, 0x24440010, 0x24440006, 0x316200ff, -0x14400006, 0x0, 0x94820000, 0xa22821, -0x51c02, 0x30a2ffff, 0x622821, 0x934205c3, -0x10400003, 0x32620100, 0x50400003, 0xa4850000, -0x52827, 0xa4850000, 0x9622000e, 0x8f43009c, -0x621821, 0x32a200ff, 0x10400007, 0xaf43009c, -0x3c024000, 0x2021025, 0xafa20020, 0x8f42009c, -0x10000003, 0x5e1025, 0xafb00020, 0x8f42009c, -0xafa20024, 0x32620080, 0x10400010, 0x32620100, -0x8f4200b4, 0x24430001, 0x210c0, 0x571021, -0xaf4300b4, 0x8fa30020, 0x8fa40024, 0x3c010001, -0x220821, 0xac2338e8, 0x3c010001, 0x220821, -0xac2438ec, 0x100000a5, 0x32c20020, 0x10400064, -0x0, 0x8f4200b4, 0x24430001, 0x210c0, -0x571021, 0xaf4300b4, 0x8fa30020, 0x8fa40024, -0x3c010001, 0x220821, 0xac2338e8, 0x3c010001, -0x220821, 0xac2438ec, 0x8f4200b4, 0x10400051, -0x3821, 0x3c090001, 0x352938e8, 0x3c08001f, -0x3508ffff, 0x240bffff, 0x340affff, 0x710c0, -0x571021, 0x491021, 0x8c430000, 0x8c440004, -0xafa30028, 0xafa4002c, 0x8f8200fc, 0x8fa30028, -0x8fa4002c, 0xac430000, 0xac440004, 0x24420008, -0xaf8200f0, 0x8f42008c, 0x2442ffff, 0xaf42008c, -0x97a2002e, 0x8f440270, 0x8f450274, 0x401821, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaf440270, 0xaf450274, 0x8fa20028, -0x481024, 0x90430000, 0x30630001, 0x1460000b, -0x402021, 0x8f420278, 0x8f43027c, 0x24630001, -0x2c640001, 0x441021, 0xaf420278, 0xaf43027c, -0x8f420278, 0x1000001a, 0x8f43027c, 0x8c820000, -0x144b000e, 0x0, 0x94820004, 0x144a000b, -0x0, 0x8f420288, 0x8f43028c, 0x24630001, -0x2c640001, 0x441021, 0xaf420288, 0xaf43028c, -0x8f420288, 0x1000000a, 0x8f43028c, 0x8f420280, -0x8f430284, 0x24630001, 0x2c640001, 0x441021, -0xaf420280, 0xaf430284, 0x8f420280, 0x8f430284, -0x8f4200b4, 0x24e70001, 0xe2102b, 0x1440ffb8, -0x710c0, 0xa34005c3, 0x1000003f, 0xaf4000b4, -0x8f8200fc, 0x8fa30020, 0x8fa40024, 0xac430000, -0xac440004, 0x24420008, 0xaf8200f0, 0x8f42009c, -0x8f46008c, 0x8f440270, 0x8f450274, 0x401821, -0x1021, 0x24c6ffff, 0xaf46008c, 0xa32821, -0xa3302b, 0x822021, 0x862021, 0xaf440270, -0xaf450274, 0x92020000, 0x30420001, 0x1440000c, -0x2402ffff, 0x8f420278, 0x8f43027c, 0x24630001, -0x2c640001, 0x441021, 0xaf420278, 0xaf43027c, -0x8f420278, 0x8f43027c, 0x1000001c, 0x32c20020, -0x8e030000, 0x1462000f, 0x3402ffff, 0x96030004, -0x1462000c, 0x0, 0x8f420288, 0x8f43028c, -0x24630001, 0x2c640001, 0x441021, 0xaf420288, -0xaf43028c, 0x8f420288, 0x8f43028c, 0x1000000b, -0x32c20020, 0x8f420280, 0x8f430284, 0x24630001, -0x2c640001, 0x441021, 0xaf420280, 0xaf430284, -0x8f420280, 0x8f430284, 0x32c20020, 0x10400005, -0xaf40009c, 0x8f420358, 0x2442ffff, 0xaf420358, -0x8f420358, 0x8e22001c, 0x8f430040, 0x24420001, -0x2463ffff, 0x431024, 0xaf42002c, 0x32420060, -0x14400008, 0x32c20010, 0x8f420034, 0x24420001, -0xaf420034, 0x8c03023c, 0x43102b, 0x14400102, -0x32c20010, 0x10400018, 0x24070008, 0x8f440170, -0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120, -0x24020080, 0xafa20010, 0xafa30014, 0xafa80018, -0x8f42010c, 0x40f809, 0x24c6001c, 0x10400047, -0x24020001, 0x8f420300, 0x8f43002c, 0x24420001, -0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1, -0x1000007c, 0xaf430038, 0x8f440170, 0x8f450174, -0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020020, -0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, -0x40f809, 0x24c6001c, 0x10400057, 0x24020001, -0x10000065, 0x0, 0x32420012, 0x10400075, -0x32420001, 0x9622000e, 0x8f43009c, 0x621821, -0x32c20020, 0x10400005, 0xaf43009c, 0x8f420358, -0x2442ffff, 0xaf420358, 0x8f420358, 0x8e22001c, -0x8f430040, 0x24420001, 0x2463ffff, 0x431024, -0xaf42002c, 0x32420010, 0x14400008, 0x32c20010, -0x8f420034, 0x24420001, 0xaf420034, 0x8c03023c, -0x43102b, 0x144000bc, 0x32c20010, 0x10400028, -0x24070008, 0x8f440170, 0x8f450174, 0x8f43002c, -0x8f48000c, 0x8f860120, 0x24020080, 0xafa20010, -0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809, -0x24c6001c, 0x14400011, 0x24020001, 0x3c010001, -0x370821, 0xa02240f1, 0x8f820124, 0xafa20010, -0x8f820128, 0x3c040001, 0x248467c4, 0xafa20014, -0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b, -0x34a51100, 0x10000036, 0x0, 0x8f420300, -0x8f43002c, 0x24420001, 0xaf420300, 0x8f420300, -0x24020001, 0xa34205c1, 0x10000026, 0xaf430038, -0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c, -0x8f860120, 0x24020020, 0xafa20010, 0xafa30014, -0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c, -0x14400011, 0x24020001, 0x3c010001, 0x370821, -0xa02240f0, 0x8f820124, 0xafa20010, 0x8f820128, -0x3c040001, 0x248467b8, 0xafa20014, 0x8f46002c, -0x8f870120, 0x3c050009, 0xc002b3b, 0x34a50900, -0x1000000f, 0x0, 0x8f420300, 0x24420001, -0xaf420300, 0x8f420300, 0x8f42002c, 0xa34005c1, -0xaf420038, 0x3c010001, 0x370821, 0xa02040f1, -0x3c010001, 0x370821, 0xa02040f0, 0xaf400034, -0x8f420314, 0x24420001, 0xaf420314, 0x10000062, -0x8f420314, 0x10400022, 0x32427000, 0x8e25001c, -0x8f420028, 0xa22023, 0x4810003, 0x0, -0x8f420040, 0x822021, 0x8f420358, 0x8f430000, -0xaf450028, 0x441021, 0x10600007, 0xaf420358, -0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, -0x10000005, 0x0, 0xaf800048, 0x8f820048, -0x1040fffd, 0x0, 0x8f820060, 0x34420008, -0xaf820060, 0x8f420000, 0x10400003, 0x0, -0x10000041, 0xaf80004c, 0x1000003f, 0xaf800048, -0x1040002f, 0x32421000, 0x1040000c, 0x32424000, -0x8e23001c, 0x8f420050, 0x622023, 0x4820001, -0x24840200, 0x8f42035c, 0x441021, 0xaf42035c, -0x8f420368, 0x1000001a, 0xaf430050, 0x1040000c, -0x32c28000, 0x8e23001c, 0x8f420070, 0x622023, -0x4820001, 0x24840400, 0x8f420364, 0x441021, -0xaf420364, 0x8f420368, 0x1000000d, 0xaf430070, -0x1040000e, 0x3c020800, 0x8e23001c, 0x8f420060, -0x622023, 0x4820001, 0x24840100, 0x8f420360, -0x441021, 0xaf420360, 0x8f420368, 0xaf430060, -0x441021, 0xaf420368, 0x3c020800, 0x2c21024, -0x50400011, 0x36940040, 0x1000000f, 0x0, -0x32420048, 0x10400007, 0x24150001, 0x8e22001c, -0x3c03ffff, 0x43f024, 0x3042ffff, 0x1000fd75, -0xae22001c, 0x32420100, 0x10400003, 0x0, -0xc002bd8, 0x0, 0x8fbf0050, 0x8fbe004c, -0x8fb50048, 0x8fb30044, 0x8fb20040, 0x8fb1003c, -0x8fb00038, 0x3e00008, 0x27bd0058, 0x3e00008, -0x0, 0x0, 0x0, 0x8f8300e4, -0x8f8200e0, 0x2404fff8, 0x441024, 0x621026, -0x2102b, 0x21023, 0x3e00008, 0x621024, -0x3e00008, 0x0, 0x27bdffe0, 0xafbf001c, -0xafb00018, 0x8f8600c4, 0x8f8400e0, 0x8f8500e4, -0x2402fff8, 0x821824, 0x10a30009, 0x27623ff8, -0x14a20002, 0x24a20008, 0x27623000, 0x408021, -0x16030005, 0x30820004, 0x10400004, 0xc02021, -0x10000022, 0x1021, 0x8e040000, 0x8f42011c, -0x14a20003, 0x0, 0x8f420120, 0xaf420114, -0x8ca30000, 0x8f420148, 0x831823, 0x43102b, -0x10400003, 0x0, 0x8f420148, 0x621821, -0x94a20006, 0x24420050, 0x62102b, 0x1440000f, -0xa01021, 0xafa40010, 0xafa30014, 0x8ca60000, -0x8ca70004, 0x3c040001, 0xc002b3b, 0x24846894, -0x8f42020c, 0x24420001, 0xaf42020c, 0x8f42020c, -0x1021, 0xaf9000e8, 0xaf9000e4, 0x8fbf001c, -0x8fb00018, 0x3e00008, 0x27bd0020, 0x3e00008, -0x0, 0x8f8400e0, 0x8f8800c4, 0x8f8300e8, -0x2402fff8, 0x823824, 0xe32023, 0x2c821000, -0x50400001, 0x24841000, 0x420c2, 0x801821, -0x8f440258, 0x8f45025c, 0x1021, 0xa32821, -0xa3302b, 0x822021, 0x862021, 0xaf440258, -0xaf45025c, 0x8f8300c8, 0x8f420148, 0x1032023, -0x82102b, 0x14400004, 0x801821, 0x8f420148, -0x822021, 0x801821, 0x8f440250, 0x8f450254, -0x1021, 0xa32821, 0xa3302b, 0x822021, -0x862021, 0xaf440250, 0xaf450254, 0xaf8800c8, -0xaf8700e4, 0xaf8700e8, 0x3e00008, 0x0, -0x27bdff30, 0x240a0001, 0xafbf00c8, 0xafbe00c4, -0xafb500c0, 0xafb300bc, 0xafb200b8, 0xafb100b4, -0xafb000b0, 0xa3a00097, 0xafa00044, 0xafaa005c, -0x934205c4, 0xa7a0008e, 0x1040000a, 0xa7a00086, -0x8f4b00c4, 0xafab0064, 0x8f4a00c0, 0xafaa006c, -0x8f4b00cc, 0xafab0074, 0x8f4a00c8, 0x10000129, -0xafaa007c, 0x8f420114, 0x40f809, 0x0, -0x403021, 0x10c0034f, 0x0, 0x8cc20000, -0x8cc30004, 0xafa20020, 0xafa30024, 0x8fab0024, -0x8faa0020, 0x3162ffff, 0x2442fffc, 0xafa2006c, -0x3c020006, 0x2c21024, 0xafab007c, 0x14400015, -0xafaa0064, 0x91420000, 0x30420001, 0x10400011, -0x2402ffff, 0x8d430000, 0x14620004, 0x3402ffff, -0x95430004, 0x1062000b, 0x0, 0xc0024bb, -0x8fa40064, 0x304200ff, 0x14400006, 0x0, -0x8f420118, 0x40f809, 0x0, 0x1000032d, -0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff, -0x431024, 0x3c03ffff, 0x431824, 0x14600003, -0xafa20024, 0x10000040, 0x1821, 0x3c020080, -0x621024, 0x10400007, 0x0, 0x8f42038c, -0x24420001, 0xaf42038c, 0x8f42038c, 0x10000036, -0x24030001, 0x8f420210, 0x24420001, 0xaf420210, -0x8f420210, 0x3c020001, 0x621024, 0x10400006, -0x3c020002, 0x8f4201c4, 0x24420001, 0xaf4201c4, -0x8f4201c4, 0x3c020002, 0x621024, 0x10400006, -0x3c020004, 0x8f42037c, 0x24420001, 0xaf42037c, -0x8f42037c, 0x3c020004, 0x621024, 0x10400006, -0x3c020008, 0x8f420380, 0x24420001, 0xaf420380, -0x8f420380, 0x3c020008, 0x621024, 0x10400006, -0x3c020010, 0x8f420384, 0x24420001, 0xaf420384, -0x8f420384, 0x3c020010, 0x621024, 0x10400006, -0x3c020020, 0x8f4201c0, 0x24420001, 0xaf4201c0, -0x8f4201c0, 0x3c020020, 0x621024, 0x10400006, -0x24030001, 0x8f420388, 0x24420001, 0xaf420388, -0x8f420388, 0x24030001, 0x8c020260, 0x8fab006c, -0x4b102b, 0x10400014, 0x307000ff, 0x8f4201e8, -0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8faa007c, -0x8f8200e0, 0x354a0100, 0xafaa007c, 0xafa20010, -0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0, -0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007, -0xc002b3b, 0x34a50800, 0x12000010, 0x3c020080, -0x2c21024, 0x1440000e, 0x32c20400, 0x8fab007c, -0x3c020080, 0x34420100, 0x1621024, 0x10400005, -0x0, 0x8f42020c, 0x24420001, 0xaf42020c, -0x8f42020c, 0x100002b0, 0x8fa3006c, 0x32c20400, -0x10400015, 0x34028100, 0x8faa0064, 0x9543000c, -0x14620012, 0x3c020100, 0x240b0200, 0xa7ab008e, -0x9542000e, 0x8d430008, 0x8d440004, 0x8d450000, -0x8faa006c, 0x8fab0064, 0x254afffc, 0xafaa006c, -0xa7a20086, 0xad63000c, 0xad640008, 0xad650004, -0x256b0004, 0xafab0064, 0x3c020100, 0x2c21024, -0x10400004, 0x0, 0x8faa006c, 0x254a0004, -0xafaa006c, 0x8f4200bc, 0x5040000a, 0xafa00074, -0x8fab006c, 0x4b102b, 0x50400006, 0xafa00074, -0x8f4200bc, 0x1621023, 0xafa20074, 0x8f4a00bc, -0xafaa006c, 0x8f420080, 0x8fab006c, 0x4b102b, -0x10400056, 0x32c28000, 0x1040005e, 0x240a0003, -0x32c21000, 0x1040005b, 0xafaa005c, 0x10000058, -0x240b0004, 0x8f420350, 0x2403ffbf, 0x283a024, -0x24420001, 0xaf420350, 0x1000024f, 0x8f420350, -0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128, -0x3c040001, 0x248468d0, 0x26620001, 0xafa20014, -0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007, -0xc002b3b, 0x34a52250, 0x1000023f, 0x0, -0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128, -0x3c040001, 0x248468d0, 0x24020002, 0xafa20014, -0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007, -0xc002b3b, 0x34a52450, 0x1000022f, 0x0, -0x8ea20000, 0x8ea30004, 0x3c040001, 0x248468e8, -0xafb00010, 0xafbe0014, 0x8ea70018, 0x34a52800, -0xc002b3b, 0x603021, 0x10000223, 0x0, -0xa6b1000a, 0x8f820124, 0x3c040001, 0x248468f0, -0xafbe0014, 0xafa20010, 0x8f460044, 0x8f870120, -0x3c050007, 0xc002b3b, 0x34a53000, 0x10000216, -0x0, 0xa6b1000a, 0xa6b2000e, 0x8f820124, -0x3c040001, 0x248468fc, 0xafbe0014, 0xafa20010, -0x8f460044, 0x8f870120, 0x3c050007, 0xc002b3b, -0x34a53200, 0x10000208, 0x0, 0x8f420084, -0x8faa006c, 0x4a102b, 0x14400007, 0x3c020001, -0x2c21024, 0x10400004, 0x0, 0x240b0002, -0xafab005c, 0x8faa006c, 0x1140021b, 0x27ab0020, -0xafab00a4, 0x3c0a001f, 0x354affff, 0xafaa009c, -0x8fab005c, 0x240a0001, 0x556a0021, 0x240a0002, -0x8f430054, 0x8f420050, 0x1062000b, 0x274b0054, -0x8f5e0054, 0x3403ecc0, 0xafab004c, 0x27c20001, -0x304201ff, 0xafa20054, 0x1e1140, 0x431021, -0x1000006b, 0x2e2a821, 0x8f420044, 0x8faa006c, -0x3c040001, 0x248468ac, 0xafaa0014, 0xafa20010, -0x8f460054, 0x8f470050, 0x3c050007, 0xc002b3b, -0x34a51300, 0x8f430350, 0x2402ffbf, 0x282a024, -0x24630001, 0xaf430350, 0x100001d3, 0x8f420350, -0x156a001d, 0x0, 0x8f430074, 0x8f420070, -0x1062000a, 0x274b0074, 0x8f5e0074, 0xafab004c, -0x27c20001, 0x304203ff, 0xafa20054, 0x1e1140, -0x24426cc0, 0x1000004a, 0x2e2a821, 0x8f420044, -0x8faa006c, 0x3c040001, 0x248468b8, 0x3c050007, -0xafaa0014, 0xafa20010, 0x8f460074, 0x8f470070, -0x34a51500, 0x240b0001, 0xc002b3b, 0xafab005c, -0x1000ffc3, 0x0, 0x8f430064, 0x8f420060, -0x1062001a, 0x274a0064, 0x8f5e0064, 0x8fab005c, -0xafaa004c, 0x27c20001, 0x304200ff, 0xafa20054, -0x24020004, 0x1562000e, 0x1e1140, 0x1e1180, -0x24420cc0, 0x2e21021, 0xafa20044, 0x9442002a, -0x8faa0044, 0x8fab006c, 0x4b102b, 0x10400024, -0x25550020, 0x240a0001, 0x10000021, 0xa3aa0097, -0x24424cc0, 0x1000001e, 0x2e2a821, 0x8f420044, -0x8fab006c, 0x3c040001, 0x248468c4, 0xafab0014, -0xafa20010, 0x8f460064, 0x8f470060, 0x3c050007, -0xc002b3b, 0x34a51800, 0x3c020008, 0x2c21024, -0x1440ff34, 0x0, 0x8f420370, 0x240a0001, -0xafaa005c, 0x24420001, 0xaf420370, 0x1000ff90, -0x8f420370, 0x27a30036, 0x131040, 0x621821, -0x94620000, 0x441021, 0x10000020, 0xa4620000, -0x8fab0064, 0xaeab0018, 0x93a20097, 0x10400072, -0x9821, 0x8faa0044, 0x8fa4006c, 0x8fa300a4, -0x25420020, 0xafa20028, 0x25420008, 0xafa20030, -0x25420010, 0xafaa002c, 0xafa20034, 0x9542002a, -0xa7a20038, 0x95420018, 0xa7a2003a, 0x9542001a, -0xa7a2003c, 0x9542001c, 0xa7a2003e, 0x94620018, -0x24630002, 0x822023, 0x1880ffde, 0x26730001, -0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc, -0x26650001, 0xa2102a, 0x1440002b, 0x24030001, -0x8f83012c, 0x10600023, 0x0, 0x8f820124, -0x431023, 0x22143, 0x58800001, 0x24840040, -0x8f820128, 0x431023, 0x21943, 0x58600001, -0x24630040, 0x64102a, 0x54400001, 0x602021, -0xaf4400fc, 0x8f4200fc, 0xa2102a, 0x10400011, -0x24030001, 0x10000015, 0x306200ff, 0x8fab0064, -0x96070018, 0xafab0010, 0x8e220008, 0x3c040001, -0x248468dc, 0x8c430004, 0x8c420000, 0x34a52400, -0x2403021, 0xc002b3b, 0xafa30014, 0x1000002b, -0x0, 0x8f420334, 0x1821, 0x24420001, -0xaf420334, 0x8f420334, 0x306200ff, 0x5040fedc, -0x3c020800, 0x12600021, 0x9021, 0x8fb100a4, -0x2208021, 0x8e220008, 0x96070018, 0x8fa60064, -0x8c440000, 0x8c450004, 0x240a0001, 0xafaa0010, -0xafbe0014, 0x8f420008, 0xafa20018, 0x8f42010c, -0x40f809, 0x0, 0x1040ffd8, 0x3c050007, -0x96020018, 0x8fab0064, 0x8faa009c, 0x1625821, -0x14b102b, 0x10400004, 0xafab0064, 0x8f420148, -0x1625823, 0xafab0064, 0x26100002, 0x26520001, -0x253102b, 0x1440ffe3, 0x26310004, 0x8fb0006c, -0x10000036, 0x97b10038, 0x8f4200fc, 0x24050002, -0xa2102a, 0x1440001b, 0x24030001, 0x8f83012c, -0x10600013, 0x0, 0x8f820124, 0x431023, -0x22143, 0x58800001, 0x24840040, 0x8f820128, -0x431023, 0x21943, 0x58600001, 0x24630040, -0x64102a, 0x54400001, 0x602021, 0xaf4400fc, -0x8f4200fc, 0xa2102a, 0x14400006, 0x24030001, -0x8f420334, 0x1821, 0x24420001, 0xaf420334, -0x8f420334, 0x306200ff, 0x1040fea5, 0x3c020800, -0x96b1000a, 0x8fb0006c, 0x3223ffff, 0x70102b, -0x54400001, 0x608021, 0x8ea40000, 0x8ea50004, -0x240b0001, 0xafab0010, 0xafbe0014, 0x8f420008, -0x8fa60064, 0xafa20018, 0x8f42010c, 0x40f809, -0x2003821, 0x1040fea2, 0x3c050007, 0x96a3000e, -0x97aa008e, 0x11400007, 0x609021, 0x934205c4, -0x14400004, 0x0, 0x97ab0086, 0x6a1825, -0xa6ab0016, 0x8faa007c, 0x3c02ffff, 0x1421024, -0x10400003, 0xa1402, 0x34630400, 0xa6a20014, -0x8fab006c, 0x560b0072, 0xa6a3000e, 0x34620004, -0xa6a2000e, 0x8faa0074, 0x16a1021, 0xa6a2000a, -0x8f430044, 0x8f4401a0, 0x8f4501a4, 0x34028000, -0xafa20010, 0x8f420044, 0x2a03021, 0x24070020, -0xafa20014, 0x8f42000c, 0x31940, 0x604821, -0xafa20018, 0x8f42010c, 0x4021, 0xa92821, -0xa9182b, 0x882021, 0x40f809, 0x832021, -0x5040fe7f, 0xa6b2000e, 0x8f420368, 0xafa0006c, -0xa34005c4, 0x2442ffff, 0xaf420368, 0x8fab005c, -0x240a0001, 0x8f420368, 0x156a0006, 0x240a0002, -0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c, -0x8f42035c, 0x156a0006, 0x0, 0x8f420364, -0x2442ffff, 0xaf420364, 0x10000005, 0x8f420364, -0x8f420360, 0x2442ffff, 0xaf420360, 0x8f420360, -0x8faa0054, 0x8fab004c, 0xad6a0000, 0x8f420044, -0x8f440088, 0x8f430078, 0x24420001, 0x441024, -0x24630001, 0xaf420044, 0xaf430078, 0x8c020240, -0x62182b, 0x14600075, 0x24070008, 0x8f440168, -0x8f45016c, 0x8f430044, 0x8f48000c, 0x8f860120, -0x24020040, 0xafa20010, 0xafa30014, 0xafa80018, -0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011, -0x240b0001, 0x3c010001, 0x370821, 0xa02b40f2, -0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001, -0x2484688c, 0xafa20014, 0x8f460044, 0x8f870120, -0x3c050009, 0xc002b3b, 0x34a51300, 0x1000000b, -0x0, 0x8f420304, 0x24420001, 0xaf420304, -0x8f420304, 0x8f420044, 0xaf42007c, 0x3c010001, -0x370821, 0xa02040f2, 0xaf400078, 0x8f420318, -0x24420001, 0xaf420318, 0x10000048, 0x8f420318, -0xa6b0000a, 0x8f430044, 0x8f4401a0, 0x8f4501a4, -0x34028000, 0xafa20010, 0x8f420044, 0x2a03021, -0x24070020, 0xafa20014, 0x8f42000c, 0x31940, -0x604821, 0xafa20018, 0x8f42010c, 0x4021, -0xa92821, 0xa9182b, 0x882021, 0x40f809, -0x832021, 0x1040fe1f, 0x240a0001, 0xa34a05c4, -0x8fab006c, 0x8faa0064, 0x1705823, 0xafab006c, -0x8fab009c, 0x1505021, 0x16a102b, 0x10400004, -0xafaa0064, 0x8f420148, 0x1425023, 0xafaa0064, -0x8f420368, 0x2442ffff, 0xaf420368, 0x8faa005c, -0x240b0001, 0x8f420368, 0x154b0006, 0x240b0002, -0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c, -0x8f42035c, 0x114b0006, 0x0, 0x8f420360, -0x2442ffff, 0xaf420360, 0x10000005, 0x8f420360, -0x8f420364, 0x2442ffff, 0xaf420364, 0x8f420364, -0x8fab0054, 0x8faa004c, 0xad4b0000, 0x8f420044, -0x8f440088, 0x8f430078, 0x24420001, 0x441024, -0x24630001, 0xaf420044, 0xaf430078, 0x8faa006c, -0x1540fe0b, 0x0, 0x8fab006c, 0x1160001e, -0x0, 0x934205c4, 0x10400009, 0x0, -0x8faa0064, 0xaf4a00c4, 0xaf4b00c0, 0x8fab007c, -0xaf4b00c8, 0x8faa0074, 0x1000000e, 0xaf4a00cc, -0x97ab008e, 0x1160000b, 0x34038100, 0x8fa20020, -0x8c46000c, 0xa443000c, 0x97aa0086, 0x8c440004, -0x8c450008, 0xa44a000e, 0xac440000, 0xac450004, -0xac460008, 0x8f42034c, 0x24420001, 0xaf42034c, -0x10000010, 0x8f42034c, 0x8fab007c, 0x3164ffff, -0x2484fffc, 0x801821, 0x8f440250, 0x8f450254, -0x8f460118, 0x1021, 0xa32821, 0xa3382b, -0x822021, 0x872021, 0xaf440250, 0xc0f809, -0xaf450254, 0x8fbf00c8, 0x8fbe00c4, 0x8fb500c0, -0x8fb300bc, 0x8fb200b8, 0x8fb100b4, 0x8fb000b0, -0x3e00008, 0x27bd00d0, 0x3e00008, 0x0, -0x27bdff38, 0x240b0001, 0xafbf00c0, 0xafbe00bc, -0xafb500b8, 0xafb300b4, 0xafb200b0, 0xafb100ac, -0xafb000a8, 0xa3a00087, 0xafa00044, 0xafab005c, -0x934205c4, 0xa7a00076, 0x10400007, 0xa7a0007e, -0x8f4c00c0, 0xafac0064, 0x8f4b00c8, 0x8f5e00c4, -0x10000130, 0xafab006c, 0x8f420114, 0x40f809, -0x0, 0x403021, 0x10c002a1, 0x0, -0x8cc20000, 0x8cc30004, 0xafa20020, 0xafa30024, -0x8fac0024, 0x8fbe0020, 0x3182ffff, 0x2442fffc, -0xafa20064, 0x3c020006, 0x2c21024, 0x14400015, -0xafac006c, 0x93c20000, 0x30420001, 0x10400011, -0x2402ffff, 0x8fc30000, 0x14620004, 0x3402ffff, -0x97c30004, 0x1062000b, 0x0, 0xc0024bb, -0x3c02021, 0x304200ff, 0x14400006, 0x0, -0x8f420118, 0x40f809, 0x0, 0x10000280, -0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff, -0x431024, 0x3c03ffff, 0x431824, 0x14600003, -0xafa20024, 0x10000040, 0x8021, 0x3c020080, -0x621024, 0x10400007, 0x0, 0x8f42038c, -0x24420001, 0xaf42038c, 0x8f42038c, 0x10000036, -0x24100001, 0x8f420210, 0x24420001, 0xaf420210, -0x8f420210, 0x3c020001, 0x621024, 0x10400006, -0x3c020002, 0x8f4201c4, 0x24420001, 0xaf4201c4, -0x8f4201c4, 0x3c020002, 0x621024, 0x10400006, -0x3c020004, 0x8f42037c, 0x24420001, 0xaf42037c, -0x8f42037c, 0x3c020004, 0x621024, 0x10400006, -0x3c020008, 0x8f420380, 0x24420001, 0xaf420380, -0x8f420380, 0x3c020008, 0x621024, 0x10400006, -0x3c020010, 0x8f420384, 0x24420001, 0xaf420384, -0x8f420384, 0x3c020010, 0x621024, 0x10400006, -0x3c020020, 0x8f4201c0, 0x24420001, 0xaf4201c0, -0x8f4201c0, 0x3c020020, 0x621024, 0x10400006, -0x24100001, 0x8f420388, 0x24420001, 0xaf420388, -0x8f420388, 0x24100001, 0x8c020260, 0x8fab0064, -0x4b102b, 0x10400015, 0x320200ff, 0x8f4201e8, -0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8fac006c, -0x8f8200e0, 0x358c0100, 0xafac006c, 0xafa20010, -0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0, -0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007, -0xc002b3b, 0x34a53600, 0x320200ff, 0x10400010, -0x3c020080, 0x2c21024, 0x1440000e, 0x32c20400, -0x8fab006c, 0x3c020080, 0x34420100, 0x1621024, -0x10400005, 0x0, 0x8f42020c, 0x24420001, -0xaf42020c, 0x8f42020c, 0x10000202, 0x8fa30064, -0x32c20400, 0x10400012, 0x34028100, 0x97c3000c, -0x1462000f, 0x0, 0x240c0200, 0xa7ac0076, -0x97c2000e, 0x8fc30008, 0x8fc40004, 0x8fab0064, -0x8fc50000, 0x256bfffc, 0xafab0064, 0xa7a2007e, -0xafc3000c, 0xafc40008, 0xafc50004, 0x27de0004, -0x8fa70064, 0x320200ff, 0x14400034, 0x3c020100, -0x97c4000c, 0x2c8305dd, 0x38828870, 0x2c420001, -0x621825, 0x10600015, 0x2821, 0x32c20800, -0x10400015, 0x24020800, 0x97c30014, 0x14620012, -0x3402aaaa, 0x97c3000e, 0x14620007, 0x2021, -0x97c30010, 0x24020300, 0x14620004, 0x801021, -0x97c20012, 0x2c440001, 0x801021, 0x54400006, -0x24050016, 0x10000004, 0x0, 0x24020800, -0x50820001, 0x2405000e, 0x10a00013, 0x3c52021, -0x24830009, 0x3c02001f, 0x3442ffff, 0x43102b, -0x10400003, 0x0, 0x8f420148, 0x621823, -0x90620000, 0x38430006, 0x2c630001, 0x38420011, -0x2c420001, 0x621825, 0x10600004, 0x3c020100, -0x94820002, 0x453821, 0x3c020100, 0x2c21024, -0x5040000e, 0xafa70064, 0x8fac0064, 0x10ec0008, -0x3c050007, 0x3c040001, 0x24846908, 0x8fa60064, -0x34a54000, 0xafa00010, 0xc002b3b, 0xafa00014, -0x8fab0064, 0x256b0004, 0xafab0064, 0x8f420080, -0x8fac0064, 0x4c102b, 0x1040002c, 0x32c28000, -0x10400034, 0x240b0003, 0x32c21000, 0x10400031, -0xafab005c, 0x1000002e, 0x240c0004, 0x8f420350, -0x2403ffbf, 0x283a024, 0x24420001, 0xaf420350, -0x10000173, 0x8f420350, 0x3c020800, 0x2c2b025, -0x2402ffbf, 0x282a024, 0x8f830128, 0x3c040001, -0x248468d0, 0x26620001, 0xafa20014, 0xafa30010, -0x8f860120, 0x8f870124, 0x3c050007, 0xc002b3b, -0x34a55300, 0x10000162, 0x0, 0x8ea20000, -0x8ea30004, 0x3c040001, 0x248468e8, 0xafb00010, -0xafb10014, 0x8ea70018, 0x34a55900, 0xc002b3b, -0x603021, 0x10000156, 0x0, 0x8f420084, -0x8fab0064, 0x4b102b, 0x14400007, 0x3c020001, -0x2c21024, 0x10400004, 0x0, 0x240c0002, -0xafac005c, 0x8fab0064, 0x11600166, 0x27ac0020, -0xafac008c, 0x8fab005c, 0x240c0001, 0x556c0021, -0x240c0002, 0x8f430054, 0x8f420050, 0x1062000b, -0x274b0054, 0x8f510054, 0x3403ecc0, 0xafab004c, -0x26220001, 0x304201ff, 0xafa20054, 0x111140, -0x431021, 0x1000006b, 0x2e2a821, 0x8f420044, -0x8fac0064, 0x3c040001, 0x248468ac, 0xafac0014, -0xafa20010, 0x8f460054, 0x8f470050, 0x3c050007, -0xc002b3b, 0x34a54300, 0x8f430350, 0x2402ffbf, -0x282a024, 0x24630001, 0xaf430350, 0x10000124, -0x8f420350, 0x156c001d, 0x0, 0x8f430074, -0x8f420070, 0x1062000a, 0x274b0074, 0x8f510074, -0xafab004c, 0x26220001, 0x304203ff, 0xafa20054, -0x111140, 0x24426cc0, 0x1000004a, 0x2e2a821, -0x8f420044, 0x8fac0064, 0x3c040001, 0x248468b8, -0x3c050007, 0xafac0014, 0xafa20010, 0x8f460074, -0x8f470070, 0x34a54500, 0x240b0001, 0xc002b3b, -0xafab005c, 0x1000ffc3, 0x0, 0x8f430064, -0x8f420060, 0x1062001a, 0x274c0064, 0x8f510064, -0x8fab005c, 0xafac004c, 0x26220001, 0x304200ff, -0xafa20054, 0x24020004, 0x1562000e, 0x111140, -0x111180, 0x24420cc0, 0x2e21021, 0xafa20044, -0x9442002a, 0x8fac0044, 0x8fab0064, 0x4b102b, -0x10400024, 0x25950020, 0x240c0001, 0x10000021, -0xa3ac0087, 0x24424cc0, 0x1000001e, 0x2e2a821, -0x8f420044, 0x8fab0064, 0x3c040001, 0x248468c4, -0xafab0014, 0xafa20010, 0x8f460064, 0x8f470060, -0x3c050007, 0xc002b3b, 0x34a54800, 0x3c020008, -0x2c21024, 0x1440ff61, 0x0, 0x8f420370, -0x240c0001, 0xafac005c, 0x24420001, 0xaf420370, -0x1000ff90, 0x8f420370, 0x27a30036, 0x131040, -0x621821, 0x94620000, 0x441021, 0x1000001f, -0xa4620000, 0xaebe0018, 0x93a20087, 0x10400084, -0x9821, 0x8fab0044, 0x8fa40064, 0x8fa3008c, -0x25620020, 0xafa20028, 0x25620008, 0xafa20030, -0x25620010, 0xafab002c, 0xafa20034, 0x9562002a, -0xa7a20038, 0x95620018, 0xa7a2003a, 0x9562001a, -0xa7a2003c, 0x9562001c, 0xa7a2003e, 0x94620018, -0x24630002, 0x822023, 0x1880ffdf, 0x26730001, -0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc, -0x262102a, 0x14400030, 0x24030001, 0x8f83012c, -0x10600028, 0x0, 0x8f820124, 0x431023, -0x22143, 0x58800001, 0x24840040, 0x8f820128, -0x431023, 0x21943, 0x58600001, 0x24630040, -0x64102a, 0x54400001, 0x602021, 0xaf4400fc, -0x8f4200fc, 0x262102a, 0x10400016, 0x24030001, -0x1000001a, 0x306200ff, 0x8fac008c, 0x101040, -0x4c1021, 0x94470018, 0x101080, 0x4c1021, -0xafbe0010, 0x8c420008, 0x3c040001, 0x248468dc, -0x3c050007, 0x8c430004, 0x8c420000, 0x34a55500, -0x2003021, 0xc002b3b, 0xafa30014, 0x10000039, -0x0, 0x8f420334, 0x1821, 0x24420001, -0xaf420334, 0x8f420334, 0x306200ff, 0x1040ff06, -0x8021, 0x8f430008, 0x2402fbff, 0x1260002d, -0x625024, 0x3c0b4000, 0x22b4025, 0x8fb1008c, -0x2669ffff, 0x2209021, 0x8e420008, 0x96270018, -0x8c440000, 0x8c450004, 0x56090004, 0x240b0001, -0x240c0002, 0x10000002, 0xafac0010, 0xafab0010, -0x16000004, 0xafa80014, 0x8f420008, 0x10000002, -0xafa20018, 0xafaa0018, 0x8f42010c, 0x3c03021, -0xafa80098, 0xafa9009c, 0x40f809, 0xafaa00a0, -0x8fa80098, 0x8fa9009c, 0x8faa00a0, 0x1040ffc2, -0x3c02001f, 0x96230018, 0x3442ffff, 0x3c3f021, -0x5e102b, 0x10400003, 0x26310002, 0x8f420148, -0x3c2f023, 0x26100001, 0x213102b, 0x1440ffda, -0x26520004, 0x8fb00064, 0x1000001a, 0x0, -0x96a3000a, 0x8fb00064, 0x70102b, 0x54400001, -0x608021, 0x8ea40000, 0x8ea50004, 0x8fab005c, -0x240c0002, 0xafac0010, 0x934305c4, 0xb1700, -0x10600003, 0x2223025, 0x3c020800, 0xc23025, -0xafa60014, 0x8f420008, 0xafa20018, 0x8f42010c, -0x3c03021, 0x40f809, 0x2003821, 0x1040fecb, -0x3c050007, 0x97ac0076, 0x11800007, 0x96a3000e, -0x934205c4, 0x14400004, 0x0, 0x97ab007e, -0x6c1825, 0xa6ab0016, 0x8fac006c, 0x3c02ffff, -0x1821024, 0x10400003, 0xc1402, 0x34630400, -0xa6a20014, 0xa6b0000a, 0x8fab0064, 0x560b0006, -0x3d0f021, 0x34620004, 0xafa00064, 0xa6a2000e, -0x1000000d, 0xa34005c4, 0x8fac0064, 0x3c02001f, -0x3442ffff, 0x5e102b, 0x1906023, 0xafac0064, -0xa6a3000e, 0x240b0001, 0x10400003, 0xa34b05c4, -0x8f420148, 0x3c2f023, 0x8fab0054, 0x8fac004c, -0xad8b0000, 0x8fac0064, 0x1580feba, 0x0, -0x8fab0064, 0x1160001b, 0x0, 0x934205c4, -0x10400006, 0x0, 0xaf5e00c4, 0xaf4b00c0, -0x8fac006c, 0x1000000e, 0xaf4c00c8, 0x97ab0076, -0x1160000b, 0x34038100, 0x8fa20020, 0x8c46000c, -0xa443000c, 0x97ac007e, 0x8c440004, 0x8c450008, -0xa44c000e, 0xac440000, 0xac450004, 0xac460008, -0x8f42034c, 0x24420001, 0xaf42034c, 0x10000010, -0x8f42034c, 0x8fab006c, 0x3164ffff, 0x2484fffc, -0x801821, 0x8f440250, 0x8f450254, 0x8f460118, -0x1021, 0xa32821, 0xa3382b, 0x822021, -0x872021, 0xaf440250, 0xc0f809, 0xaf450254, -0x8fbf00c0, 0x8fbe00bc, 0x8fb500b8, 0x8fb300b4, -0x8fb200b0, 0x8fb100ac, 0x8fb000a8, 0x3e00008, -0x27bd00c8, 0x3e00008, 0x0, 0x27bdffd8, -0xafbf0024, 0xafb00020, 0x8f43004c, 0x8f420048, -0x10620034, 0x0, 0x8f430048, 0x8f42004c, -0x622023, 0x4820001, 0x24840200, 0x8f430054, -0x8f42004c, 0x43102b, 0x14400004, 0x24020200, -0x8f43004c, 0x10000005, 0x431023, 0x8f420054, -0x8f43004c, 0x431023, 0x2442ffff, 0x405021, -0x8a102a, 0x54400001, 0x805021, 0x8f49004c, -0x8f48004c, 0x8f440188, 0x8f45018c, 0x8f46004c, -0x24071000, 0xafa70010, 0x84140, 0x1001821, -0x12a4821, 0x313001ff, 0xafb00014, 0x8f470014, -0x1021, 0x63140, 0xafa70018, 0xa32821, -0xa3382b, 0x822021, 0x872021, 0x3402ecc0, -0xc23021, 0x8f420108, 0x2e63021, 0x40f809, -0xa3940, 0x54400001, 0xaf50004c, 0x8f43004c, -0x8f420048, 0x14620018, 0x0, 0x8f420000, -0x10400007, 0x0, 0xaf80004c, 0x8f82004c, -0x1040fffd, 0x0, 0x10000005, 0x0, -0xaf800048, 0x8f820048, 0x1040fffd, 0x0, -0x8f820060, 0x2403fdff, 0x431024, 0xaf820060, -0x8f420000, 0x10400003, 0x0, 0x10000002, -0xaf80004c, 0xaf800048, 0x8fbf0024, 0x8fb00020, -0x3e00008, 0x27bd0028, 0x3e00008, 0x0, -0x27bdffd8, 0xafbf0024, 0xafb00020, 0x8f43005c, -0x8f420058, 0x10620049, 0x0, 0x8f430058, -0x8f42005c, 0x622023, 0x4820001, 0x24840100, -0x8f430064, 0x8f42005c, 0x43102b, 0x14400004, -0x24020100, 0x8f43005c, 0x10000005, 0x431023, -0x8f420064, 0x8f43005c, 0x431023, 0x2442ffff, -0x403821, 0x87102a, 0x54400001, 0x803821, -0x8f42005c, 0x471021, 0x305000ff, 0x32c21000, -0x10400015, 0x24082000, 0x8f49005c, 0x8f440190, -0x8f450194, 0x8f46005c, 0x73980, 0xafa80010, -0xafb00014, 0x8f480014, 0x94980, 0x1201821, -0x1021, 0xa32821, 0xa3482b, 0x822021, -0x892021, 0x63180, 0xafa80018, 0x8f420108, -0x10000014, 0x24c60cc0, 0x8f49005c, 0x8f440190, -0x8f450194, 0x8f46005c, 0x73940, 0xafa80010, -0xafb00014, 0x8f480014, 0x94940, 0x1201821, -0x1021, 0xa32821, 0xa3482b, 0x822021, -0x892021, 0x63140, 0xafa80018, 0x8f420108, -0x24c64cc0, 0x40f809, 0x2e63021, 0x54400001, -0xaf50005c, 0x8f43005c, 0x8f420058, 0x14620018, -0x0, 0x8f420000, 0x10400007, 0x0, -0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, -0x10000005, 0x0, 0xaf800048, 0x8f820048, -0x1040fffd, 0x0, 0x8f820060, 0x2403feff, -0x431024, 0xaf820060, 0x8f420000, 0x10400003, -0x0, 0x10000002, 0xaf80004c, 0xaf800048, -0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028, -0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024, -0xafb00020, 0x8f43006c, 0x8f420068, 0x10620033, -0x0, 0x8f430068, 0x8f42006c, 0x622023, -0x4820001, 0x24840400, 0x8f430074, 0x8f42006c, -0x43102b, 0x14400004, 0x24020400, 0x8f43006c, -0x10000005, 0x431023, 0x8f420074, 0x8f43006c, -0x431023, 0x2442ffff, 0x405021, 0x8a102a, -0x54400001, 0x805021, 0x8f49006c, 0x8f48006c, -0x8f440198, 0x8f45019c, 0x8f46006c, 0x24074000, -0xafa70010, 0x84140, 0x1001821, 0x12a4821, -0x313003ff, 0xafb00014, 0x8f470014, 0x1021, -0x63140, 0x24c66cc0, 0xafa70018, 0xa32821, -0xa3382b, 0x822021, 0x872021, 0x8f420108, -0x2e63021, 0x40f809, 0xa3940, 0x54400001, -0xaf50006c, 0x8f43006c, 0x8f420068, 0x14620018, -0x0, 0x8f420000, 0x10400007, 0x0, -0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, -0x10000005, 0x0, 0xaf800048, 0x8f820048, -0x1040fffd, 0x0, 0x8f820060, 0x2403f7ff, -0x431024, 0xaf820060, 0x8f420000, 0x10400003, -0x0, 0x10000002, 0xaf80004c, 0xaf800048, -0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028, -0x3e00008, 0x0, 0x8f4200fc, 0x3c030001, -0x8f4400f8, 0x346330c8, 0x24420001, 0xaf4200fc, -0x8f850128, 0x2e31021, 0x54820004, 0x24820008, -0x3c020001, 0x34422ec8, 0x2e21021, 0x401821, -0xaf4300f8, 0xac600000, 0x8f4200f4, 0x14620004, -0x3c020001, 0x24a20020, 0x1000000f, 0xaf820128, -0x8f4300f8, 0x344230c8, 0x2e21021, 0x54620004, -0x24620008, 0x3c020001, 0x34422ec8, 0x2e21021, -0x401821, 0x8c620004, 0x21140, 0xa21021, -0xaf820128, 0xac600000, 0x8ca30018, 0x30620070, -0x1040002d, 0x30620020, 0x10400004, 0x3c020010, -0x2c21024, 0x1040000d, 0x0, 0x30620040, -0x10400004, 0x3c020020, 0x2c21024, 0x10400007, -0x0, 0x30620010, 0x1040001f, 0x3c020040, -0x2c21024, 0x1440001c, 0x0, 0x8f820040, -0x30420001, 0x14400008, 0x2021, 0x8c030104, -0x24020001, 0x50620005, 0x24040001, 0x8c020264, -0x10400003, 0x801021, 0x24040001, 0x801021, -0x10400006, 0x0, 0x8f42030c, 0x24420001, -0xaf42030c, 0x10000008, 0x8f42030c, 0x8f820044, -0x34420004, 0xaf820044, 0x8f420308, 0x24420001, -0xaf420308, 0x8f420308, 0x3e00008, 0x0, -0x3e00008, 0x0, 0x27bdff98, 0xafbf0060, -0xafbe005c, 0xafb50058, 0xafb30054, 0xafb20050, -0xafb1004c, 0xafb00048, 0x8f4200fc, 0x24420001, -0xaf4200fc, 0x8f880128, 0x25020020, 0xaf820128, -0x8d030018, 0x30620070, 0x1040002e, 0x30620020, -0x10400004, 0x3c020010, 0x2c21024, 0x1040000d, -0x0, 0x30620040, 0x10400004, 0x3c020020, -0x2c21024, 0x10400007, 0x0, 0x30620010, -0x104001a9, 0x3c020040, 0x2c21024, 0x144001a6, -0x0, 0x8f820040, 0x30420001, 0x14400008, -0x2021, 0x8c030104, 0x24020001, 0x50620005, -0x24040001, 0x8c020264, 0x10400003, 0x801021, -0x24040001, 0x801021, 0x10400006, 0x0, -0x8f42030c, 0x24420001, 0xaf42030c, 0x10000192, -0x8f42030c, 0x8f820044, 0x34420004, 0xaf820044, -0x8f420308, 0x24420001, 0xaf420308, 0x1000018a, -0x8f420308, 0x30620002, 0x1040014b, 0x3c020800, -0x8d1e001c, 0x1e5702, 0xafaa0034, 0x950a0016, -0x3c22024, 0xafaa0024, 0x8faa0034, 0x24020001, -0x15420006, 0x33deffff, 0x1e1140, 0x3403ecc0, -0x431021, 0x10000010, 0x2e2a821, 0x24020002, -0x15420005, 0x24020003, 0x1e1140, 0x24426cc0, -0x10000009, 0x2e2a821, 0x15420005, 0x1e1180, -0x1e1140, 0x24424cc0, 0x10000003, 0x2e2a821, -0x571021, 0x24550ce0, 0x96a2000e, 0x304afffc, -0x30420400, 0x10400003, 0xafaa002c, 0x100000e1, -0x8821, 0x10800004, 0x8821, 0x97b10026, -0x100000dd, 0xa6b10012, 0x8eb30018, 0x966a000c, -0xa7aa003e, 0x97a5003e, 0x2ca305dd, 0x38a28870, -0x2c420001, 0x621825, 0x10600015, 0x2021, -0x32c20800, 0x10400015, 0x24020800, 0x96630014, -0x14620012, 0x3402aaaa, 0x9663000e, 0x14620007, -0x2821, 0x96630010, 0x24020300, 0x14620004, -0xa01021, 0x96620012, 0x2c450001, 0xa01021, -0x54400006, 0x24040016, 0x10000004, 0x0, -0x24020800, 0x50a20001, 0x2404000e, 0x108000b9, -0x2649021, 0x92420000, 0x3042000f, 0x28080, -0x32c20100, 0x10400020, 0x2501821, 0x3c020020, -0x43102b, 0x1440000e, 0x2402021, 0x2821, -0x94820000, 0x24840002, 0xa22821, 0x83102b, -0x1440fffb, 0x30a2ffff, 0x51c02, 0x622821, -0x51c02, 0x30a2ffff, 0x10000009, 0x622821, -0x8f470148, 0x8f420110, 0x102842, 0x3c060020, -0x40f809, 0xafa80040, 0x3045ffff, 0x8fa80040, -0x50a00001, 0x3405ffff, 0x8faa002c, 0x354a0002, -0x10000002, 0xafaa002c, 0x2821, 0x32c20080, -0x10400090, 0xa6a50010, 0x26430009, 0x3c02001f, -0x3442ffff, 0x43102b, 0x10400003, 0x0, -0x8f420148, 0x621823, 0x90660000, 0x30c200ff, -0x38430006, 0x2c630001, 0x38420011, 0x2c420001, -0x621825, 0x1060007f, 0x24020800, 0x8821, -0x97a3003e, 0x1462000f, 0x2602021, 0x96710000, -0x96620002, 0x96630004, 0x96640006, 0x2228821, -0x2238821, 0x2248821, 0x96620008, 0x9663000a, -0x9664000c, 0x2228821, 0x2238821, 0x10000007, -0x2248821, 0x94820000, 0x24840002, 0x2228821, -0x92102b, 0x1440fffb, 0x0, 0x111c02, -0x3222ffff, 0x628821, 0x111c02, 0x3222ffff, -0x628821, 0x32c20200, 0x10400003, 0x26440006, -0x1000003e, 0x8021, 0x3c05001f, 0x34a5ffff, -0xa4102b, 0x10400003, 0x0, 0x8f420148, -0x822023, 0x94820000, 0x30421fff, 0x10400004, -0x2644000c, 0x96420002, 0x10000030, 0x508023, -0x96420002, 0x26430014, 0x508023, 0x3c020020, -0x43102b, 0x1440000a, 0xd08021, 0x9642000c, -0x2028021, 0x9642000e, 0x96430010, 0x96440012, -0x2028021, 0x2038021, 0x10000020, 0x2048021, -0xa4102b, 0x10400003, 0x0, 0x8f420148, -0x822023, 0x94820000, 0x24840002, 0x2028021, -0xa4102b, 0x10400003, 0x0, 0x8f420148, -0x822023, 0x94820000, 0x24840002, 0x2028021, -0xa4102b, 0x10400003, 0x0, 0x8f420148, -0x822023, 0x94820000, 0x24840002, 0x2028021, -0xa4102b, 0x10400003, 0x0, 0x8f420148, -0x822023, 0x94820000, 0x2028021, 0x3c020100, -0x2c21024, 0x1040000e, 0x0, 0x8faa002c, -0x31420004, 0x1040000a, 0x0, 0x9504000e, -0x2642021, 0xc003eec, 0x2484fffc, 0x3042ffff, -0x2228821, 0x111c02, 0x3222ffff, 0x628821, -0x8faa0024, 0x1518823, 0x111402, 0x2228821, -0x2308821, 0x111402, 0x2228821, 0x3231ffff, -0x52200001, 0x3411ffff, 0x8faa002c, 0x354a0001, -0xafaa002c, 0xa6b10012, 0x97aa002e, 0xa6aa000e, -0x8faa002c, 0x31420004, 0x10400002, 0x24091000, -0x34098000, 0x8f480044, 0x8f4401a0, 0x8f4501a4, -0xafa90010, 0x8f490044, 0x84140, 0x1001821, -0xafa90014, 0x8f48000c, 0x2a03021, 0x24070020, -0xafa80018, 0x8f48010c, 0x1021, 0xa32821, -0xa3482b, 0x822021, 0x100f809, 0x892021, -0x1440000b, 0x0, 0x8f820128, 0x3c040001, -0x24846914, 0xafbe0014, 0xafa20010, 0x8f860124, -0x8f870120, 0x3c050007, 0xc002b3b, 0x34a59920, -0x8f420368, 0x2442ffff, 0xaf420368, 0x8f420044, -0x8f430088, 0x24420001, 0x431024, 0xaf420044, -0x8faa0034, 0x8f440368, 0x24020001, 0x15420006, -0x24020002, 0x8f42035c, 0x2442ffff, 0xaf42035c, -0x10000049, 0x8f42035c, 0x15420006, 0x0, -0x8f420364, 0x2442ffff, 0xaf420364, 0x10000042, -0x8f420364, 0x8f420360, 0x2442ffff, 0xaf420360, -0x1000003d, 0x8f420360, 0x30621000, 0x10400005, -0x30628000, 0x8f420078, 0x24420001, 0x10000036, -0xaf420078, 0x10400034, 0x0, 0x8f420078, -0x24420001, 0xaf420078, 0x8c030240, 0x43102b, -0x1440002d, 0x24070008, 0x8f440168, 0x8f45016c, -0x8f430044, 0x8f48000c, 0x8f860120, 0x24020040, -0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c, -0x40f809, 0x24c6001c, 0x14400011, 0x24020001, -0x3c010001, 0x370821, 0xa02240f2, 0x8f820124, -0xafa20010, 0x8f820128, 0x3c040001, 0x2484688c, -0xafa20014, 0x8f460044, 0x8f870120, 0x3c050009, -0xc002b3b, 0x34a51300, 0x1000000b, 0x0, -0x8f420304, 0x24420001, 0xaf420304, 0x8f420304, -0x8f420044, 0xaf42007c, 0x3c010001, 0x370821, -0xa02040f2, 0xaf400078, 0x8f420318, 0x24420001, -0xaf420318, 0x8f420318, 0x8fbf0060, 0x8fbe005c, -0x8fb50058, 0x8fb30054, 0x8fb20050, 0x8fb1004c, -0x8fb00048, 0x3e00008, 0x27bd0068, 0x3e00008, -0x0, 0x0, 0x0, 0x8f42013c, -0xaf8200c0, 0x8f42013c, 0xaf8200c4, 0x8f42013c, -0xaf8200c8, 0x8f420138, 0xaf8200d0, 0x8f420138, -0xaf8200d4, 0x8f420138, 0x3e00008, 0xaf8200d8, -0x27bdffe0, 0x27840208, 0x24050200, 0xafbf0018, -0xc002bbf, 0x24060008, 0x8c020204, 0xc004012, -0xaf820210, 0x3c020001, 0x8c426d94, 0x30420002, -0x1040000e, 0x2021, 0x8c060248, 0x24020002, -0x3c010001, 0xac226d98, 0xc005104, 0x24050002, -0x2021, 0x8c060248, 0x24020001, 0x3c010001, -0xac226d98, 0x10000011, 0x24050001, 0x8c060248, -0x24020004, 0x3c010001, 0xac226d98, 0xc005104, -0x24050004, 0x3c020001, 0x8c426d94, 0x30420001, -0x10400008, 0x24020001, 0x3c010001, 0xac226d98, -0x2021, 0x24050001, 0x3c06601b, 0xc005104, -0x0, 0x3c040001, 0x248469d0, 0x8f420150, -0x8f430154, 0x3c050008, 0x8f460158, 0x21640, -0x31940, 0x34630403, 0x431025, 0x633c0, -0x461025, 0xaf82021c, 0xafa00010, 0xafa00014, -0x8f86021c, 0x34a50200, 0xc002b3b, 0x3821, -0x3c010001, 0xac206d90, 0x3c010001, 0xac206da8, -0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0, -0x3c050008, 0x34a50300, 0xafbf0018, 0xafa00010, -0xafa00014, 0x8f860200, 0x3c040001, 0x248469dc, -0xc002b3b, 0x3821, 0x8f420410, 0x24420001, -0xaf420410, 0x8f420410, 0x8fbf0018, 0x3e00008, -0x27bd0020, 0x27bdffd8, 0xafbf0020, 0xafb1001c, -0xafb00018, 0x8f4203a4, 0x24420001, 0xaf4203a4, -0x8f4203a4, 0x8f900220, 0x8f8200e0, 0xafa20010, -0x8f8200e4, 0xafa20014, 0x8f8600c4, 0x8f8700c8, -0x3c040001, 0x248469e8, 0xc002b3b, 0x2002821, -0x3c044000, 0x2041024, 0x504000b4, 0x3c040100, -0x8f4203bc, 0x24420001, 0xaf4203bc, 0x8f4203bc, -0x8f8700c4, 0x8f8300c8, 0x8f420148, 0x671823, -0x43102b, 0x10400003, 0x0, 0x8f420148, -0x621821, 0x10600005, 0x0, 0x8f42014c, -0x43102b, 0x1040000b, 0x0, 0x8f8200e0, -0x8f430124, 0xaf42011c, 0xaf430114, 0x8f820220, -0x3c0308ff, 0x3463fffb, 0x431024, 0x100000ce, -0x441025, 0x8f820220, 0x3c0308ff, 0x3463ffff, -0x431024, 0x34420004, 0xaf820220, 0x8f8200e0, -0x8f430124, 0xaf42011c, 0xaf430114, 0x8f8600c8, -0x8f840120, 0x8f830124, 0x10000005, 0x2821, -0x14620002, 0x24620020, 0x27624800, 0x401821, -0x1064000c, 0x30a200ff, 0x8c620018, 0x30420003, -0x1040fff7, 0x27624fe0, 0x8f4203d0, 0x24050001, -0x24420001, 0xaf4203d0, 0x8f4203d0, 0x8c660008, -0x30a200ff, 0x14400058, 0x0, 0x934205c4, -0x14400055, 0x0, 0x8f8700c4, 0x8f8800e0, -0x8f8400e4, 0x2402fff8, 0x1024024, 0x1041023, -0x218c3, 0x4620001, 0x24630200, 0x10600005, -0x24020001, 0x10620009, 0x0, 0x1000001f, -0x0, 0x8f4203c0, 0xe03021, 0x24420001, -0xaf4203c0, 0x10000040, 0x8f4203c0, 0x8f4203c4, -0x24420001, 0xaf4203c4, 0x8c860000, 0x8f420148, -0x8f4303c4, 0xe61823, 0x43102b, 0x10400004, -0x2c62233f, 0x8f420148, 0x621821, 0x2c62233f, -0x14400031, 0x0, 0x8f42020c, 0x24420001, -0xaf42020c, 0x8f42020c, 0xe03021, 0x24820008, -0xaf8200e4, 0x10000028, 0xaf8200e8, 0x8f4203c8, -0x24420001, 0xaf4203c8, 0x8f4203c8, 0x8c850000, -0x8f420148, 0xa71823, 0x43102b, 0x10400003, -0x0, 0x8f420148, 0x621821, 0x8f42014c, -0x43102b, 0x5440000a, 0xa03021, 0x8f42020c, -0x24420001, 0xaf42020c, 0x8f42020c, 0x24820008, -0xaf8200e4, 0x8f8400e4, 0x1488ffec, 0xaf8400e8, -0x1488000d, 0x27623000, 0x14820002, 0x2482fff8, -0x27623ff8, 0x94430006, 0x3c02001f, 0x3442ffff, -0xc33021, 0x46102b, 0x10400003, 0x0, -0x8f420148, 0xc23023, 0xaf8600c8, 0x8f8300c4, -0x8f420148, 0xc31823, 0x43102b, 0x10400003, -0x0, 0x8f420148, 0x621821, 0x10600005, -0x0, 0x8f42014c, 0x43102b, 0x50400008, -0x3c02fdff, 0x8f820220, 0x3c0308ff, 0x3463fffb, -0x431024, 0x3c034000, 0x1000003f, 0x431025, -0x8f4303cc, 0x3442ffff, 0x282a024, 0x24630001, -0xaf4303cc, 0x10000039, 0x8f4203cc, 0x2041024, -0x1040000e, 0x3c110200, 0x8f4203a8, 0x24420001, -0xaf4203a8, 0x8f4203a8, 0x8f820220, 0x3c0308ff, -0x3463ffff, 0x431024, 0x441025, 0xc003daf, -0xaf820220, 0x10000029, 0x0, 0x2111024, -0x50400008, 0x3c110400, 0x8f4203ac, 0x24420001, -0xaf4203ac, 0xc003daf, 0x8f4203ac, 0x10000019, -0x0, 0x2111024, 0x1040001c, 0x0, -0x8f830224, 0x24021402, 0x14620009, 0x3c050008, -0x3c040001, 0x248469f4, 0xafa00010, 0xafa00014, -0x8f860224, 0x34a50500, 0xc002b3b, 0x3821, -0x8f4203b0, 0x24420001, 0xaf4203b0, 0x8f4203b0, -0x8f820220, 0x2002021, 0x34420002, 0xc004e9c, -0xaf820220, 0x8f820220, 0x3c0308ff, 0x3463ffff, -0x431024, 0x511025, 0xaf820220, 0x8fbf0020, -0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0028, -0x3e00008, 0x0, 0x3c020001, 0x8c426da8, -0x27bdffb0, 0xafbf0048, 0xafbe0044, 0xafb50040, -0xafb3003c, 0xafb20038, 0xafb10034, 0x1040000f, -0xafb00030, 0x3c040001, 0x24846a00, 0x3c050008, -0xafa00010, 0xafa00014, 0x8f860220, 0x34a50600, -0x24020001, 0x3c010001, 0xac206da8, 0x3c010001, -0xac226d9c, 0xc002b3b, 0x3821, 0x3c037fff, -0x8c020268, 0x3463ffff, 0x3c04fdff, 0x431024, -0xac020268, 0x8f420004, 0x3484ffff, 0x30420002, -0x10400092, 0x284a024, 0x3c040600, 0x34842000, -0x8f420004, 0x2821, 0x2403fffd, 0x431024, -0xaf420004, 0xafa40020, 0x8f5e0018, 0x27aa0020, -0x240200ff, 0x13c20002, 0xafaa002c, 0x27c50001, -0x8c020228, 0xa09021, 0x1642000e, 0x1e38c0, -0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c, -0x8c020228, 0x3c040001, 0x24846998, 0x3c050009, -0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006d, -0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024, -0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, -0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b, -0x9821, 0xe08821, 0x263504c0, 0x8f440178, -0x8f45017c, 0x2201821, 0x240a0004, 0xafaa0010, -0xafb20014, 0x8f48000c, 0x1021, 0x2f53021, -0xafa80018, 0x8f48010c, 0x24070008, 0xa32821, -0xa3482b, 0x822021, 0x100f809, 0x892021, -0x54400006, 0x24130001, 0x8f820054, 0x2021023, -0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff, -0x54400017, 0xaf520018, 0x8f420378, 0x24420001, -0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c, -0xafa20010, 0x8f820124, 0x3c040001, 0x248469a4, -0x3c050009, 0xafa20014, 0x8d460000, 0x10000035, -0x34a50600, 0x8f420308, 0x24130001, 0x24420001, -0xaf420308, 0x8f420308, 0x1000001e, 0x326200ff, -0x8f830054, 0x8f820054, 0x247003e8, 0x2021023, -0x2c4203e9, 0x10400016, 0x9821, 0x3c150020, -0x24110010, 0x8f42000c, 0x8f440160, 0x8f450164, -0x8f860120, 0xafb10010, 0xafb20014, 0x551025, -0xafa20018, 0x8f42010c, 0x24070008, 0x40f809, -0x24c6001c, 0x1440ffe3, 0x0, 0x8f820054, -0x2021023, 0x2c4203e9, 0x1440ffee, 0x0, -0x326200ff, 0x14400011, 0x0, 0x8f420378, -0x24420001, 0xaf420378, 0x8f420378, 0x8f820120, -0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001, -0x248469ac, 0x3c050009, 0xafa20014, 0x8d460000, -0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202ec, -0x24420001, 0xaf4202ec, 0x8f4202ec, 0x8fbf0048, -0x8fbe0044, 0x8fb50040, 0x8fb3003c, 0x8fb20038, -0x8fb10034, 0x8fb00030, 0x3e00008, 0x27bd0050, -0x3c020001, 0x8c426da8, 0x27bdffe0, 0x1440000d, -0xafbf0018, 0x3c040001, 0x24846a0c, 0x3c050008, -0xafa00010, 0xafa00014, 0x8f860220, 0x34a50700, -0x24020001, 0x3c010001, 0xac226da8, 0xc002b3b, -0x3821, 0x3c020004, 0x2c21024, 0x10400007, -0x0, 0x8f820220, 0x3c0308ff, 0x3463ffff, -0x431024, 0x34420008, 0xaf820220, 0x3c050001, -0x8ca56d98, 0x24020001, 0x14a20007, 0x2021, -0xc00529b, 0x24050001, 0xac02026c, 0x8c03026c, -0x10000006, 0x3c020007, 0xc00529b, 0x2021, -0xac020268, 0x8c030268, 0x3c020007, 0x621824, -0x3c020002, 0x5062000d, 0x3c0205f5, 0x43102b, -0x14400006, 0x3c020004, 0x3c020001, 0x10620009, -0x3c020098, 0x1000000b, 0x0, 0x14620009, -0x3c023b9a, 0x10000004, 0x3442ca00, 0x10000002, -0x3442e100, 0x34429680, 0xaf4201fc, 0x8f4201fc, -0xaee20064, 0x8fbf0018, 0x3e00008, 0x27bd0020, -0x0, 0x0, 0x0, 0x86102b, -0x50400001, 0x872023, 0xc41023, 0x24843, -0x125102b, 0x1040001b, 0x91040, 0x824021, -0x88102b, 0x10400007, 0x1821, 0x94820000, -0x24840002, 0x621821, 0x88102b, 0x1440fffb, -0x0, 0x602021, 0xc73023, 0xa91023, -0x21040, 0xc22821, 0xc5102b, 0x10400007, -0x1821, 0x94c20000, 0x24c60002, 0x621821, -0xc5102b, 0x1440fffb, 0x0, 0x1000000d, -0x832021, 0x51040, 0x822821, 0x85102b, -0x10400007, 0x1821, 0x94820000, 0x24840002, -0x621821, 0x85102b, 0x1440fffb, 0x0, -0x602021, 0x41c02, 0x3082ffff, 0x622021, -0x41c02, 0x3082ffff, 0x622021, 0x3e00008, -0x3082ffff, 0x3e00008, 0x0, 0x802821, -0x30a20001, 0x1040002b, 0x3c03001f, 0x3463ffff, -0x24a20004, 0x62102b, 0x54400007, 0x65102b, -0x90a20001, 0x90a40003, 0x90a30000, 0x90a50002, -0x1000002a, 0x441021, 0x10400003, 0x0, -0x8f420148, 0xa22823, 0x90a40000, 0x24a50001, -0x65102b, 0x10400003, 0x0, 0x8f420148, -0xa22823, 0x90a20000, 0x24a50001, 0x21200, -0x822021, 0x65102b, 0x10400003, 0x0, -0x8f420148, 0xa22823, 0x90a20000, 0x24a50001, -0x822021, 0x65102b, 0x10400003, 0x0, -0x8f420148, 0xa22823, 0x90a20000, 0x1000002d, -0x21200, 0x3463ffff, 0x24a20004, 0x62102b, -0x5440000a, 0x65102b, 0x90a20000, 0x90a40002, -0x90a30001, 0x90a50003, 0x441021, 0x21200, -0x651821, 0x10000020, 0x432021, 0x10400003, -0x0, 0x8f420148, 0xa22823, 0x90a20000, -0x24a50001, 0x22200, 0x65102b, 0x10400003, -0x0, 0x8f420148, 0xa22823, 0x90a20000, -0x24a50001, 0x822021, 0x65102b, 0x10400003, -0x0, 0x8f420148, 0xa22823, 0x90a20000, -0x24a50001, 0x21200, 0x822021, 0x65102b, -0x10400003, 0x0, 0x8f420148, 0xa22823, -0x90a20000, 0x822021, 0x41c02, 0x3082ffff, -0x622021, 0x41c02, 0x3082ffff, 0x622021, -0x3e00008, 0x3082ffff, 0x0, 0x8f820220, -0x34420002, 0xaf820220, 0x3c020002, 0x8c428ff8, -0x30424000, 0x10400054, 0x24040001, 0x8f820200, -0x24067fff, 0x8f830200, 0x30450002, 0x2402fffd, -0x621824, 0xaf830200, 0xaf840204, 0x8f830054, -0x8f820054, 0x10000002, 0x24630001, 0x8f820054, -0x621023, 0x2c420002, 0x1440fffc, 0x0, -0x8f820224, 0x1444004d, 0x42040, 0xc4102b, -0x1040fff1, 0x0, 0x8f820200, 0x451025, -0xaf820200, 0x8f820220, 0x34428000, 0xaf820220, -0x8f830054, 0x8f820054, 0x10000002, 0x24630001, -0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, -0x0, 0x8f820220, 0x3c030004, 0x431024, -0x1440000f, 0x0, 0x8f820220, 0x3c03ffff, -0x34637fff, 0x431024, 0xaf820220, 0x8f830054, -0x8f820054, 0x10000002, 0x24630001, 0x8f820054, -0x621023, 0x2c420002, 0x1440fffc, 0x0, -0x8f820220, 0x3c030004, 0x431024, 0x1440000d, -0x0, 0x8f820220, 0x34428000, 0xaf820220, -0x8f830054, 0x8f820054, 0x10000002, 0x24630001, -0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, -0x0, 0x8f820220, 0x3c030004, 0x431024, -0x1040001b, 0x1021, 0x8f830220, 0x24020001, -0x10000015, 0x3c04f700, 0x8f820220, 0x3c04f700, -0x441025, 0xaf820220, 0x8f820220, 0x2403fffd, -0x431024, 0xaf820220, 0x8f820220, 0x3c030300, -0x431024, 0x14400003, 0x0, 0x10000008, -0x1021, 0x8f820220, 0x34420002, 0xaf820220, -0x8f830220, 0x24020001, 0x641825, 0xaf830220, -0x3e00008, 0x0, 0x2021, 0x3c050100, -0x24020001, 0xaf80021c, 0xaf820200, 0xaf820220, -0x27625000, 0xaf8200c0, 0x27625000, 0xaf8200c4, -0x27625000, 0xaf8200c8, 0x27625000, 0xaf8200d0, -0x27625000, 0xaf8200d4, 0x27625000, 0xaf8200d8, -0x27623000, 0xaf8200e0, 0x27623000, 0xaf8200e4, -0x27623000, 0xaf8200e8, 0x27622800, 0xaf8200f0, -0x27622800, 0xaf8200f4, 0x27622800, 0xaf8200f8, -0x418c0, 0x24840001, 0x3631021, 0xac453004, -0x3631021, 0xac403000, 0x28820200, 0x1440fff9, -0x418c0, 0x2021, 0x418c0, 0x24840001, -0x3631021, 0xac402804, 0x3631021, 0xac402800, -0x28820100, 0x1440fff9, 0x418c0, 0xaf80023c, -0x24030080, 0x24040100, 0xac600000, 0x24630004, -0x64102b, 0x5440fffd, 0xac600000, 0x8f830040, -0x3c02f000, 0x621824, 0x3c025000, 0x1062000c, -0x43102b, 0x14400006, 0x3c026000, 0x3c024000, -0x10620008, 0x24020800, 0x10000008, 0x0, -0x10620004, 0x24020800, 0x10000004, 0x0, -0x24020700, 0x3c010001, 0xac226dac, 0x3e00008, -0x0, 0x3c020001, 0x8c426dbc, 0x27bdffd0, -0xafbf002c, 0xafb20028, 0xafb10024, 0xafb00020, -0x3c010001, 0x10400005, 0xac206d94, 0xc004d9e, -0x0, 0x3c010001, 0xac206dbc, 0x8f830054, -0x8f820054, 0x10000002, 0x24630064, 0x8f820054, -0x621023, 0x2c420065, 0x1440fffc, 0x0, -0xc004db9, 0x0, 0x24040001, 0x2821, -0x27a60018, 0x34028000, 0xc0045be, 0xa7a20018, -0x8f830054, 0x8f820054, 0x10000002, 0x24630064, -0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, -0x24040001, 0x24050001, 0xc00457c, 0x27a60018, -0x8f830054, 0x8f820054, 0x10000002, 0x24630064, -0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, -0x24040001, 0x24050001, 0xc00457c, 0x27a60018, -0x8f830054, 0x8f820054, 0x10000002, 0x24630064, -0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, -0x24040001, 0x3c060001, 0x24c66f24, 0xc00457c, -0x24050002, 0x8f830054, 0x8f820054, 0x10000002, -0x24630064, 0x8f820054, 0x621023, 0x2c420065, -0x1440fffc, 0x24040001, 0x24050003, 0x3c100001, -0x26106f26, 0xc00457c, 0x2003021, 0x97a60018, -0x3c070001, 0x94e76f24, 0x3c040001, 0x24846ae0, -0xafa00014, 0x96020000, 0x3c05000d, 0x34a50100, -0xc002b3b, 0xafa20010, 0x97a20018, 0x1040004d, -0x24036040, 0x96020000, 0x3042fff0, 0x1443000c, -0x24020020, 0x3c030001, 0x94636f24, 0x1462000b, -0x24027830, 0x24020003, 0x3c010001, 0xac226d94, -0x24020005, 0x3c010001, 0x1000003f, 0xac226f34, -0x3c030001, 0x94636f24, 0x24027830, 0x1462000c, -0x24030010, 0x3c020001, 0x94426f26, 0x3042fff0, -0x14430007, 0x24020003, 0x3c010001, 0xac226d94, -0x24020006, 0x3c010001, 0x1000002f, 0xac226f34, -0x3c020001, 0x8c426d94, 0x3c030001, 0x94636f24, -0x34420001, 0x3c010001, 0xac226d94, 0x24020015, -0x1462000b, 0x0, 0x3c020001, 0x94426f26, -0x3042fff0, 0x3843f420, 0x2c630001, 0x3842f430, -0x2c420001, 0x621825, 0x1460001b, 0x24020003, -0x3c030001, 0x94636f24, 0x24027810, 0x14620016, -0x24020002, 0x3c020001, 0x94426f26, 0x3042fff0, -0x14400011, 0x24020002, 0x1000000f, 0x24020004, -0x3c020001, 0x8c426d94, 0x34420008, 0x3c010001, -0xac226d94, 0x1000005e, 0x24020004, 0x3c020001, -0x8c426d94, 0x34420004, 0x3c010001, 0x100000af, -0xac226d94, 0x24020001, 0x3c010001, 0xac226f40, -0x3c020001, 0x8c426d94, 0x30420002, 0x144000b2, -0x3c09fff0, 0x24020e00, 0xaf820238, 0x8f840054, -0x8f820054, 0x24030008, 0x3c010001, 0xac236d98, -0x10000002, 0x248401f4, 0x8f820054, 0x821023, -0x2c4201f5, 0x1440fffc, 0x3c0200c8, 0x344201fb, -0xaf820238, 0x8f830054, 0x8f820054, 0x10000002, -0x246301f4, 0x8f820054, 0x621023, 0x2c4201f5, -0x1440fffc, 0x8021, 0x24120001, 0x24110009, -0xc004482, 0x0, 0x3c010001, 0xac326db4, -0xc004547, 0x0, 0x3c020001, 0x8c426db4, -0x1451fffb, 0x3c0200c8, 0x344201f6, 0xaf820238, -0x8f830054, 0x8f820054, 0x10000002, 0x2463000a, -0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc, -0x0, 0x8f820220, 0x24040001, 0x34420002, -0xaf820220, 0x8f830200, 0x24057fff, 0x2402fffd, -0x621824, 0xaf830200, 0xaf840204, 0x8f830054, -0x8f820054, 0x10000002, 0x24630001, 0x8f820054, -0x621023, 0x2c420002, 0x1440fffc, 0x0, -0x8f820224, 0x14440005, 0x34028000, 0x42040, -0xa4102b, 0x1040fff0, 0x34028000, 0x1082ffa0, -0x26100001, 0x2e020014, 0x1440ffcd, 0x24020004, -0x3c010001, 0xac226d98, 0x8021, 0x24120009, -0x3c11ffff, 0x36313f7f, 0xc004482, 0x0, -0x24020001, 0x3c010001, 0xac226db4, 0xc004547, -0x0, 0x3c020001, 0x8c426db4, 0x1452fffb, -0x0, 0x8f820044, 0x511024, 0x34425080, -0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, -0x2463000a, 0x8f820054, 0x621023, 0x2c42000b, -0x1440fffc, 0x0, 0x8f820044, 0x511024, -0x3442f080, 0xaf820044, 0x8f830054, 0x8f820054, -0x10000002, 0x2463000a, 0x8f820054, 0x621023, -0x2c42000b, 0x1440fffc, 0x0, 0x8f820220, -0x3c03f700, 0x431025, 0xaf820220, 0x8f830054, -0x8f820054, 0x10000002, 0x24630064, 0x8f820054, -0x621023, 0x2c420065, 0x1440fffc, 0x0, -0x8f820220, 0x24040001, 0x34420002, 0xaf820220, -0x8f830200, 0x24057fff, 0x2402fffd, 0x621824, -0xaf830200, 0xaf840204, 0x8f830054, 0x8f820054, -0x10000002, 0x24630001, 0x8f820054, 0x621023, -0x2c420002, 0x1440fffc, 0x0, 0x8f820224, -0x14440005, 0x34028000, 0x42040, 0xa4102b, -0x1040fff0, 0x34028000, 0x1082ff50, 0x26100001, -0x2e020064, 0x1440ffb0, 0x0, 0x3c020001, -0x8c426d94, 0x30420004, 0x14400007, 0x3c09fff0, -0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024, -0xaf820044, 0x3c09fff0, 0x3529bdc0, 0x3c060001, -0x8cc66d94, 0x3c040001, 0x24846ae0, 0x24020001, -0x3c010001, 0xac226d9c, 0x8f820054, 0x3c070001, -0x8ce76f40, 0x3c030001, 0x94636f24, 0x3c080001, -0x95086f26, 0x3c05000d, 0x34a50100, 0x3c010001, -0xac206d98, 0x491021, 0x3c010001, 0xac226f30, -0xafa30010, 0xc002b3b, 0xafa80014, 0x8fbf002c, -0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008, -0x27bd0030, 0x27bdffe8, 0x3c050001, 0x8ca56d98, -0x24060004, 0x24020001, 0x14a20014, 0xafbf0010, -0x3c020002, 0x8c428ffc, 0x30428000, 0x10400005, -0x3c04000f, 0x3c030001, 0x8c636f40, 0x10000005, -0x34844240, 0x3c040004, 0x3c030001, 0x8c636f40, -0x348493e0, 0x24020005, 0x14620016, 0x0, -0x3c04003d, 0x10000013, 0x34840900, 0x3c020002, -0x8c428ff8, 0x30428000, 0x10400005, 0x3c04001e, -0x3c030001, 0x8c636f40, 0x10000005, 0x34848480, -0x3c04000f, 0x3c030001, 0x8c636f40, 0x34844240, -0x24020005, 0x14620003, 0x0, 0x3c04007a, -0x34841200, 0x3c020001, 0x8c426f30, 0x8f830054, -0x441021, 0x431023, 0x44102b, 0x1440004c, -0x0, 0x3c020001, 0x8c426da0, 0x14400048, -0x0, 0x3c010001, 0x10c00025, 0xac206db0, -0x3c090001, 0x8d296d94, 0x24070001, 0x3c044000, -0x3c080002, 0x25088ffc, 0x250afffc, 0x52842, -0x14a00002, 0x24c6ffff, 0x24050008, 0xa91024, -0x10400010, 0x0, 0x14a70008, 0x0, -0x8d020000, 0x441024, 0x1040000a, 0x0, -0x3c010001, 0x10000007, 0xac256db0, 0x8d420000, -0x441024, 0x10400003, 0x0, 0x3c010001, -0xac276db0, 0x3c020001, 0x8c426db0, 0x6182b, -0x2c420001, 0x431024, 0x5440ffe5, 0x52842, -0x8f820054, 0x3c030001, 0x8c636db0, 0x3c010001, -0xac226f30, 0x1060003b, 0x24020005, 0x3c030001, -0x8c636f40, 0x3c010001, 0xac256d98, 0x14620012, -0x24020001, 0x3c020002, 0x8c428ff8, 0x3c032000, -0x34635000, 0x431024, 0x14400006, 0x24020001, -0x3c010001, 0xac206f1c, 0x3c010001, 0xac226d98, -0x24020001, 0x3c010001, 0xac226e24, 0x3c010001, -0xac226da4, 0x24020001, 0x3c010001, 0xac226d9c, -0x3c020001, 0x8c426db0, 0x1040001e, 0x0, -0x3c020001, 0x8c426d9c, 0x10400008, 0x24020001, -0x3c010001, 0xac206d9c, 0xaee204b8, 0x3c010001, -0xac206e1c, 0x3c010001, 0xac226dd4, 0x8ee304b8, -0x24020008, 0x10620005, 0x24020001, 0xc004239, -0x0, 0x1000000b, 0x0, 0x3c030001, -0x8c636d98, 0x10620007, 0x2402000e, 0x3c030002, -0x8c638f90, 0x10620003, 0x0, 0xc004e9c, -0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018, -0x27bdffe0, 0x3c03fdff, 0x3c040001, 0x8c846d98, -0x3c020001, 0x8c426dc0, 0x3463ffff, 0x283a024, -0x14820006, 0xafbf0018, 0x8ee304b8, 0x3c020001, -0x8c426dc4, 0x10620006, 0x0, 0x8ee204b8, -0x3c010001, 0xac246dc0, 0x3c010001, 0xac226dc4, -0x3c030001, 0x8c636d98, 0x24020002, 0x1062019c, -0x2c620003, 0x10400005, 0x24020001, 0x1062000a, -0x0, 0x10000226, 0x0, 0x24020004, -0x106200b6, 0x24020008, 0x1062010a, 0x24020001, -0x1000021f, 0x0, 0x8ee204b8, 0x2443ffff, -0x2c620008, 0x1040021c, 0x31080, 0x3c010001, -0x220821, 0x8c226af8, 0x400008, 0x0, -0x3c030001, 0x8c636f40, 0x24020005, 0x14620010, -0x0, 0x3c020001, 0x8c426da4, 0x10400008, -0x24020003, 0xc004482, 0x0, 0x24020002, -0xaee204b8, 0x3c010001, 0x10000002, 0xac206da4, -0xaee204b8, 0x3c010001, 0x10000203, 0xac206d30, -0xc004482, 0x0, 0x3c020001, 0x8c426da4, -0x3c010001, 0xac206d30, 0x1440017a, 0x24020002, -0x1000019d, 0x24020007, 0x3c030001, 0x8c636f40, -0x24020005, 0x14620003, 0x24020001, 0x3c010001, -0xac226dd0, 0xc0045ff, 0x0, 0x3c030001, -0x8c636dd0, 0x10000174, 0x24020011, 0x3c050001, -0x8ca56d98, 0x3c060002, 0x8cc68ffc, 0xc005104, -0x2021, 0x24020005, 0x3c010001, 0xac206da4, -0x100001e1, 0xaee204b8, 0x3c040001, 0x24846aec, -0x3c05000f, 0x34a50100, 0x3021, 0x3821, -0xafa00010, 0xc002b3b, 0xafa00014, 0x100001d6, -0x0, 0x8f820220, 0x3c030004, 0x431024, -0x14400175, 0x24020007, 0x8f830054, 0x3c020001, -0x8c426f28, 0x2463d8f0, 0x431023, 0x2c422710, -0x14400003, 0x24020001, 0x3c010001, 0xac226d9c, -0x3c020002, 0x8c428ffc, 0x30425000, 0x104001c2, -0x0, 0x8f820220, 0x30428000, 0x1040017d, -0x0, 0x10000175, 0x0, 0x3c050001, -0x8ca56d98, 0xc00529b, 0x2021, 0xc00551b, -0x2021, 0x3c030002, 0x8c638ff4, 0x46101b0, -0x24020001, 0x3c020008, 0x621024, 0x10400006, -0x0, 0x8f820214, 0x3c03ffff, 0x431024, -0x10000005, 0x3442251f, 0x8f820214, 0x3c03ffff, -0x431024, 0x3442241f, 0xaf820214, 0x8f820220, -0x3c030200, 0x34420002, 0xaf820220, 0x24020008, -0xaee204b8, 0x8f820220, 0x283a025, 0x3c030004, -0x431024, 0x14400016, 0x0, 0x3c020002, -0x8c428ffc, 0x30425000, 0x1040000d, 0x0, -0x8f820220, 0x30428000, 0x10400006, 0x0, -0x8f820220, 0x3c03ffff, 0x34637fff, 0x10000003, -0x431024, 0x8f820220, 0x34428000, 0xaf820220, -0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, -0x3c030001, 0x8c636f40, 0x24020005, 0x1462000a, -0x0, 0x3c020001, 0x94426f26, 0x24429fbc, -0x2c420004, 0x10400004, 0x24040018, 0x24050002, -0xc004ddb, 0x24060020, 0xc003e6d, 0x0, -0x3c010001, 0x10000170, 0xac206e20, 0x8ee204b8, -0x2443ffff, 0x2c620008, 0x1040016b, 0x31080, -0x3c010001, 0x220821, 0x8c226b18, 0x400008, -0x0, 0xc004547, 0x0, 0x3c030001, -0x8c636db4, 0x100000e8, 0x24020009, 0x3c020002, -0x8c428ff8, 0x30424000, 0x10400004, 0x0, -0x8f820044, 0x10000006, 0x3442f080, 0x8f820044, -0x3c03ffff, 0x34633f7f, 0x431024, 0x3442a080, -0xaf820044, 0x8f830054, 0x100000ea, 0x24020004, -0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0, -0x431023, 0x2c422710, 0x14400147, 0x24020005, -0x100000d8, 0x0, 0x8f820220, 0x3c03f700, -0x431025, 0xaf820220, 0xaf800204, 0x3c010002, -0x100000d6, 0xac208fe0, 0x8f830054, 0x3c020001, -0x8c426f28, 0x2463fff6, 0x431023, 0x2c42000a, -0x14400135, 0x24020007, 0x100000d7, 0x0, -0xc003f50, 0x0, 0x1040012d, 0x24020001, -0x8f820214, 0x3c03ffff, 0x3c040001, 0x8c846f1c, -0x431024, 0x3442251f, 0xaf820214, 0x24020008, -0x10800005, 0xaee204b8, 0x3c020001, 0x8c426e44, -0x10400064, 0x24020001, 0x8f820220, 0x3c030008, -0x431024, 0x1040006a, 0x3c020200, 0x10000078, -0x0, 0x8ee204b8, 0x2443ffff, 0x2c620007, -0x10400115, 0x31080, 0x3c010001, 0x220821, -0x8c226b38, 0x400008, 0x0, 0xc003daf, -0x0, 0x3c010001, 0xac206d9c, 0xaf800204, -0x3c010002, 0xc004482, 0xac208fe0, 0x24020001, -0x3c010001, 0xac226db4, 0x24020002, 0x10000102, -0xaee204b8, 0xc004547, 0x0, 0x3c030001, -0x8c636db4, 0x10000084, 0x24020009, 0x3c020002, -0x8c428ff8, 0x30424000, 0x10400003, 0x3c0200c8, -0x10000002, 0x344201f6, 0x344201fe, 0xaf820238, -0x8f830054, 0x1000008b, 0x24020004, 0x8f830054, -0x3c020001, 0x8c426f28, 0x2463d8f0, 0x431023, -0x2c422710, 0x144000e8, 0x24020005, 0x10000079, -0x0, 0x8f820220, 0x3c03f700, 0x431025, -0xaf820220, 0xaf800204, 0x3c010002, 0x10000077, -0xac208fe0, 0x8f830054, 0x3c020001, 0x8c426f28, -0x2463fff6, 0x431023, 0x2c42000a, 0x144000d6, -0x24020007, 0x10000078, 0x0, 0xc003f50, -0x0, 0x104000ce, 0x24020001, 0x8f820214, -0x3c03ffff, 0x3c040001, 0x8c846f1c, 0x431024, -0x3442251f, 0xaf820214, 0x24020008, 0x1080000f, -0xaee204b8, 0x3c020001, 0x8c426e44, 0x1440000b, -0x0, 0x8f820220, 0x34420002, 0xaf820220, -0x24020001, 0x3c010002, 0xac228f90, 0xc004e9c, -0x8f840220, 0x10000016, 0x0, 0x8f820220, -0x3c030008, 0x431024, 0x14400011, 0x3c020200, -0x282a025, 0x2402000e, 0x3c010002, 0xac228f90, -0xc00551b, 0x2021, 0x8f820220, 0x34420002, -0xc003e6d, 0xaf820220, 0x3c050001, 0x8ca56d98, -0xc00529b, 0x2021, 0x100000a3, 0x0, -0x3c020001, 0x8c426e44, 0x1040009f, 0x0, -0x3c020001, 0x8c426e40, 0x2442ffff, 0x3c010001, -0xac226e40, 0x14400098, 0x24020002, 0x3c010001, -0xac206e44, 0x3c010001, 0x10000093, 0xac226e40, -0x8ee204b8, 0x2443ffff, 0x2c620007, 0x1040008e, -0x31080, 0x3c010001, 0x220821, 0x8c226b58, -0x400008, 0x0, 0x3c020001, 0x8c426da4, -0x10400018, 0x24020005, 0xc004482, 0x0, -0x24020002, 0xaee204b8, 0x3c010001, 0x1000007e, -0xac206da4, 0xc004963, 0x0, 0x3c030001, -0x8c636dd4, 0x24020006, 0x14620077, 0x24020003, -0x10000075, 0xaee204b8, 0x3c050001, 0x8ca56d98, -0x3c060002, 0x8cc68ff8, 0xc005104, 0x2021, -0x24020005, 0x1000006c, 0xaee204b8, 0x8f820220, -0x3c03f700, 0x431025, 0xaf820220, 0x8f830054, -0x24020006, 0xaee204b8, 0x3c010001, 0x10000062, -0xac236f28, 0x8f820220, 0x3c030004, 0x431024, -0x10400003, 0x24020007, 0x1000005b, 0xaee204b8, -0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0, -0x431023, 0x2c422710, 0x14400003, 0x24020001, -0x3c010001, 0xac226d9c, 0x3c020002, 0x8c428ff8, -0x30425000, 0x1040004c, 0x0, 0x8f820220, -0x30428000, 0x10400007, 0x0, 0x8f820220, -0x3c03ffff, 0x34637fff, 0x431024, 0x10000042, -0xaf820220, 0x8f820220, 0x34428000, 0x1000003e, -0xaf820220, 0x3c050001, 0x8ca56d98, 0xc00529b, -0x2021, 0xc00551b, 0x2021, 0x3c020002, -0x8c428ff0, 0x4410032, 0x24020001, 0x8f820214, -0x3c03ffff, 0x431024, 0x3442251f, 0xaf820214, -0x24020008, 0xaee204b8, 0x8f820220, 0x34420002, -0xaf820220, 0x8f820220, 0x3c030004, 0x431024, -0x14400016, 0x0, 0x3c020002, 0x8c428ff8, -0x30425000, 0x1040000d, 0x0, 0x8f820220, -0x30428000, 0x10400006, 0x0, 0x8f820220, -0x3c03ffff, 0x34637fff, 0x10000003, 0x431024, -0x8f820220, 0x34428000, 0xaf820220, 0x8f820220, -0x3c03f700, 0x431025, 0xaf820220, 0x3c020001, -0x94426f26, 0x24429fbc, 0x2c420004, 0x10400004, -0x24040018, 0x24050002, 0xc004ddb, 0x24060020, -0xc003e6d, 0x0, 0x10000003, 0x0, -0x3c010001, 0xac226d9c, 0x8fbf0018, 0x3e00008, -0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220, -0x34420004, 0xaf820220, 0x8f820200, 0x3c050001, -0x8ca56d98, 0x34420004, 0xaf820200, 0x24020002, -0x10a2004b, 0x2ca20003, 0x10400005, 0x24020001, -0x10a2000a, 0x0, 0x100000b1, 0x0, -0x24020004, 0x10a20072, 0x24020008, 0x10a20085, -0x3c02f0ff, 0x100000aa, 0x0, 0x8f830050, -0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c846f40, -0x621824, 0x3c020700, 0x621825, 0x24020e00, -0x2484fffb, 0x2c840002, 0xaf830050, 0xaf850200, -0xaf850220, 0x14800006, 0xaf820238, 0x8f820044, -0x3c03ffff, 0x34633f7f, 0x431024, 0xaf820044, -0x3c030001, 0x8c636f40, 0x24020005, 0x14620004, -0x0, 0x8f820044, 0x34425000, 0xaf820044, -0x3c020001, 0x8c426d88, 0x3c030001, 0x8c636f40, -0x34420022, 0x2463fffc, 0x2c630002, 0x1460000c, -0xaf820200, 0x3c020001, 0x8c426dac, 0x3c030001, -0x8c636d90, 0x3c040001, 0x8c846d8c, 0x34428000, -0x621825, 0x641825, 0x1000000a, 0x34620002, -0x3c020001, 0x8c426d90, 0x3c030001, 0x8c636dac, -0x3c040001, 0x8c846d8c, 0x431025, 0x441025, -0x34420002, 0xaf820220, 0x1000002f, 0x24020001, -0x24020e01, 0xaf820238, 0x8f830050, 0x3c02f0ff, -0x3442ffff, 0x3c040001, 0x8c846f1c, 0x621824, -0x3c020d00, 0x621825, 0x24020001, 0xaf830050, -0xaf820200, 0xaf820220, 0x10800005, 0x3c033f00, -0x3c020001, 0x8c426d80, 0x10000004, 0x34630070, -0x3c020001, 0x8c426d80, 0x34630072, 0x431025, -0xaf820200, 0x3c030001, 0x8c636d84, 0x3c02f700, -0x621825, 0x3c020001, 0x8c426d90, 0x3c040001, -0x8c846dac, 0x3c050001, 0x8ca56f40, 0x431025, -0x441025, 0xaf820220, 0x24020005, 0x14a20006, -0x24020001, 0x8f820044, 0x2403afff, 0x431024, -0xaf820044, 0x24020001, 0x1000003d, 0xaf820238, -0x8f830050, 0x3c02f0ff, 0x3442ffff, 0x3c040001, -0x8c846f1c, 0x621824, 0x3c020a00, 0x621825, -0x24020001, 0xaf830050, 0xaf820200, 0x1080001e, -0xaf820220, 0x3c020001, 0x8c426e44, 0x1440001a, -0x3c033f00, 0x3c020001, 0x8c426d80, 0x1000001a, -0x346300e0, 0x8f830050, 0x3c040001, 0x8c846f1c, -0x3442ffff, 0x621824, 0x1080000f, 0xaf830050, -0x3c020001, 0x8c426e44, 0x1440000b, 0x3c043f00, -0x3c030001, 0x8c636d80, 0x348400e0, 0x24020001, -0xaf820200, 0xaf820220, 0x641825, 0xaf830200, -0x10000008, 0x3c05f700, 0x3c020001, 0x8c426d80, -0x3c033f00, 0x346300e2, 0x431025, 0xaf820200, -0x3c05f700, 0x34a58000, 0x3c030001, 0x8c636d84, -0x3c020001, 0x8c426d90, 0x3c040001, 0x8c846dac, -0x651825, 0x431025, 0x441025, 0xaf820220, -0x3e00008, 0x0, 0x3c030001, 0x8c636db4, -0x3c020001, 0x8c426db8, 0x10620003, 0x24020002, -0x3c010001, 0xac236db8, 0x1062001d, 0x2c620003, -0x10400025, 0x24020001, 0x14620023, 0x24020004, -0x3c030001, 0x8c636d98, 0x10620006, 0x24020008, -0x1462000c, 0x3c0200c8, 0x344201fb, 0x10000009, -0xaf820238, 0x24020e01, 0xaf820238, 0x8f820044, -0x3c03ffff, 0x34633f7f, 0x431024, 0x34420080, -0xaf820044, 0x8f830054, 0x24020002, 0x3c010001, -0xac226db4, 0x3c010001, 0x1000000b, 0xac236f2c, -0x8f830054, 0x3c020001, 0x8c426f2c, 0x2463d8f0, -0x431023, 0x2c422710, 0x14400003, 0x24020009, -0x3c010001, 0xac226db4, 0x3e00008, 0x0, -0x0, 0x0, 0x0, 0x27bdffd8, -0xafb20018, 0x809021, 0xafb3001c, 0xa09821, -0xafb10014, 0xc08821, 0xafb00010, 0x8021, -0xafbf0020, 0xa6200000, 0xc004d78, 0x24040001, -0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004d78, 0x2021, 0xc004d78, 0x24040001, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x24100010, 0x2501024, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fffa, -0x2501024, 0x24100010, 0x2701024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x2701024, 0xc004db9, 0x34108000, -0xc004db9, 0x0, 0xc004d58, 0x0, -0x50400005, 0x108042, 0x96220000, 0x501025, -0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc004db9, 0x0, 0x8fbf0020, 0x8fb3001c, -0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, -0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821, -0xafb20018, 0xa09021, 0xafb3001c, 0xc09821, -0xafb00010, 0x8021, 0xafbf0020, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0x24100010, 0x2301024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x2301024, 0x24100010, 0x2501024, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x2501024, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x34108000, -0x96620000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fff8, -0x0, 0xc004db9, 0x0, 0x8fbf0020, -0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, -0x3e00008, 0x27bd0028, 0x3c040001, 0x8c846dd0, -0x3c020001, 0x8c426e18, 0x27bdffd8, 0xafbf0020, -0xafb1001c, 0x10820003, 0xafb00018, 0x3c010001, -0xac246e18, 0x3c030001, 0x8c636f40, 0x24020005, -0x14620005, 0x2483ffff, 0xc004963, 0x0, -0x1000034c, 0x0, 0x2c620013, 0x10400349, -0x31080, 0x3c010001, 0x220821, 0x8c226b80, -0x400008, 0x0, 0xc004db9, 0x8021, -0x34028000, 0xa7a20010, 0x27b10010, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0xc004d78, -0x2021, 0x108042, 0x1600fffc, 0x0, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fff8, 0x0, 0xc004db9, 0x0, -0x1000030e, 0x24020002, 0x27b10010, 0xa7a00010, -0x8021, 0xc004d78, 0x24040001, 0x26100001, -0x2e020020, 0x1440fffb, 0x0, 0xc004d78, -0x2021, 0xc004d78, 0x24040001, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x24100010, -0x32020001, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020001, -0x24100010, 0xc004d78, 0x2021, 0x108042, -0x1600fffc, 0x0, 0xc004db9, 0x34108000, -0xc004db9, 0x0, 0xc004d58, 0x0, -0x50400005, 0x108042, 0x96220000, 0x501025, -0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc004db9, 0x0, 0x97a20010, 0x30428000, -0x144002dc, 0x24020003, 0x100002d8, 0x0, -0x24021200, 0xa7a20010, 0x27b10010, 0x8021, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0xc004d78, 0x2021, 0x108042, 0x1600fffc, -0x0, 0xc004d78, 0x24040001, 0xc004d78, -0x2021, 0x34108000, 0x96220000, 0x501024, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fff8, 0x0, 0xc004db9, -0x0, 0x8f830054, 0x10000296, 0x24020004, -0x8f830054, 0x3c020001, 0x8c426f3c, 0x2463ff9c, -0x431023, 0x2c420064, 0x1440029e, 0x24020002, -0x3c030001, 0x8c636f40, 0x10620297, 0x2c620003, -0x14400296, 0x24020011, 0x24020003, 0x10620005, -0x24020004, 0x10620291, 0x2402000f, 0x1000028f, -0x24020011, 0x1000028d, 0x24020005, 0x24020014, -0xa7a20010, 0x27b10010, 0x8021, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x32020012, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020012, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x34108000, -0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fff8, -0x0, 0xc004db9, 0x0, 0x8f830054, -0x10000248, 0x24020006, 0x8f830054, 0x3c020001, -0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064, -0x14400250, 0x24020007, 0x1000024c, 0x0, -0x24020006, 0xa7a20010, 0x27b10010, 0x8021, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020013, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020013, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fff8, 0x0, 0xc004db9, 0x0, -0x8f830054, 0x10000207, 0x24020008, 0x8f830054, -0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023, -0x2c420064, 0x1440020f, 0x24020009, 0x1000020b, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x24040001, -0xc004d78, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020018, -0xc004db9, 0x34108000, 0xc004db9, 0x0, -0xc004d58, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004db9, 0x8021, -0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020018, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fff8, 0x0, 0xc004db9, 0x0, -0x8f830054, 0x10000193, 0x2402000a, 0x8f830054, -0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023, -0x2c420064, 0x1440019b, 0x2402000b, 0x10000197, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x24040001, -0xc004d78, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020017, -0xc004db9, 0x34108000, 0xc004db9, 0x0, -0xc004d58, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004db9, 0x8021, -0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020017, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020017, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fff8, 0x0, 0xc004db9, 0x0, -0x8f830054, 0x1000011f, 0x2402000c, 0x8f830054, -0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023, -0x2c420064, 0x14400127, 0x24020012, 0x10000123, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x24040001, -0xc004d78, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020014, -0xc004db9, 0x34108000, 0xc004db9, 0x0, -0xc004d58, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004db9, 0x8021, -0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020014, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020014, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fff8, 0x0, 0xc004db9, 0x0, -0x8f830054, 0x100000ab, 0x24020013, 0x8f830054, -0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023, -0x2c420064, 0x144000b3, 0x2402000d, 0x100000af, -0x0, 0x27b10010, 0xa7a00010, 0x8021, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x24040001, -0xc004d78, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020018, -0xc004db9, 0x34108000, 0xc004db9, 0x0, -0xc004d58, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004db9, 0x8021, -0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020018, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x34108000, 0x96220000, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fff8, 0x0, 0xc004db9, 0x0, -0x8f830054, 0x10000037, 0x2402000e, 0x24020840, -0xa7a20010, 0x27b10010, 0x8021, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x32020013, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020013, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x34108000, -0x96220000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fff8, -0x0, 0xc004db9, 0x0, 0x8f830054, -0x24020010, 0x3c010001, 0xac226dd0, 0x3c010001, -0x1000000c, 0xac236f3c, 0x8f830054, 0x3c020001, -0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064, -0x14400004, 0x0, 0x24020011, 0x3c010001, -0xac226dd0, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, -0x3e00008, 0x27bd0028, 0x3c030001, 0x8c636d98, -0x27bdffc8, 0x24020002, 0xafbf0034, 0xafb20030, -0xafb1002c, 0x14620004, 0xafb00028, 0x3c120002, -0x10000003, 0x8e528ff8, 0x3c120002, 0x8e528ffc, -0x3c030001, 0x8c636dd4, 0x3c020001, 0x8c426e1c, -0x50620004, 0x2463ffff, 0x3c010001, 0xac236e1c, -0x2463ffff, 0x2c620006, 0x10400377, 0x31080, -0x3c010001, 0x220821, 0x8c226bd8, 0x400008, -0x0, 0x2021, 0x2821, 0xc004ddb, -0x34068000, 0x24040010, 0x24050002, 0x24060002, -0x24020002, 0xc004ddb, 0xa7a20018, 0x24020002, -0x3c010001, 0x10000364, 0xac226dd4, 0x27b10018, -0xa7a00018, 0x8021, 0xc004d78, 0x24040001, -0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004d78, 0x2021, 0xc004d78, 0x24040001, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x24100010, 0x32020001, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fffa, -0x32020001, 0x24100010, 0xc004d78, 0x2021, -0x108042, 0x1600fffc, 0x0, 0xc004db9, -0x34108000, 0xc004db9, 0x0, 0xc004d58, -0x0, 0x50400005, 0x108042, 0x96220000, -0x501025, 0xa6220000, 0x108042, 0x1600fff7, -0x0, 0xc004db9, 0x0, 0x97a20018, -0x30428000, 0x14400004, 0x24020003, 0x3c010001, -0xac226dd4, 0x24020003, 0x3c010001, 0x1000032a, -0xac226dd4, 0x24040010, 0x24050002, 0x24060002, -0x24020002, 0xc004ddb, 0xa7a20018, 0x3c030001, -0x8c636e20, 0x24020001, 0x146201e1, 0x8021, -0x27b10018, 0xa7a00018, 0xc004d78, 0x24040001, -0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004d78, 0x2021, 0xc004d78, 0x24040001, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x24100010, 0x32020001, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fffa, -0x32020001, 0x24100010, 0x32020018, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020018, 0xc004db9, 0x34108000, -0xc004db9, 0x0, 0xc004d58, 0x0, -0x50400005, 0x108042, 0x96220000, 0x501025, -0xa6220000, 0x108042, 0x1600fff7, 0x0, -0xc004db9, 0x8021, 0x27b10018, 0xa7a00018, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x24040001, -0xc004d78, 0x2021, 0x24100010, 0x32020001, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x32020001, 0x24100010, -0x32020018, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020018, -0xc004db9, 0x34108000, 0xc004db9, 0x0, -0xc004d58, 0x0, 0x50400005, 0x108042, -0x96220000, 0x501025, 0xa6220000, 0x108042, -0x1600fff7, 0x0, 0xc004db9, 0x8021, -0x24040018, 0x2821, 0xc004ddb, 0x24060404, -0xa7a0001a, 0xc004d78, 0x24040001, 0x26100001, -0x2e020020, 0x1440fffb, 0x0, 0xc004d78, -0x2021, 0xc004d78, 0x24040001, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x24100010, -0x32020001, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020001, -0x24100010, 0x32020018, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fffa, -0x32020018, 0xc004db9, 0x34108000, 0xc004db9, -0x0, 0xc004d58, 0x0, 0x50400005, -0x108042, 0x97a2001a, 0x501025, 0xa7a2001a, -0x108042, 0x1600fff7, 0x0, 0xc004db9, -0x8021, 0xa7a0001a, 0xc004d78, 0x24040001, -0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004d78, 0x2021, 0xc004d78, 0x24040001, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x24100010, 0x32020001, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fffa, -0x32020001, 0x24100010, 0x32020018, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020018, 0xc004db9, 0x34108000, -0xc004db9, 0x0, 0xc004d58, 0x0, -0x50400005, 0x108042, 0x97a2001a, 0x501025, -0xa7a2001a, 0x108042, 0x1600fff7, 0x0, -0xc004db9, 0x8021, 0xa7a0001c, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x24040001, 0xc004d78, -0x2021, 0x24100010, 0xc004d78, 0x2021, -0x108042, 0x1600fffc, 0x0, 0x24100010, -0x3202001e, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x3202001e, -0xc004db9, 0x34108000, 0xc004db9, 0x0, -0xc004d58, 0x0, 0x50400005, 0x108042, -0x97a2001c, 0x501025, 0xa7a2001c, 0x108042, -0x1600fff7, 0x0, 0xc004db9, 0x8021, -0xa7a0001c, 0xc004d78, 0x24040001, 0x26100001, -0x2e020020, 0x1440fffb, 0x0, 0xc004d78, -0x2021, 0xc004d78, 0x24040001, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x24100010, -0xc004d78, 0x2021, 0x108042, 0x1600fffc, -0x0, 0x24100010, 0x3202001e, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x3202001e, 0xc004db9, 0x34108000, -0xc004db9, 0x0, 0xc004d58, 0x0, -0x50400005, 0x108042, 0x97a2001c, 0x501025, -0xa7a2001c, 0x108042, 0x1600fff7, 0x0, -0xc004db9, 0x8021, 0x24020002, 0xa7a2001e, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0x24100010, 0xc004d78, -0x2021, 0x108042, 0x1600fffc, 0x0, -0x24100010, 0x3202001e, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fffa, -0x3202001e, 0xc004d78, 0x24040001, 0xc004d78, -0x2021, 0x34108000, 0x97a2001e, 0x501024, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fff8, 0x0, 0xc004db9, -0x8021, 0xa7a00020, 0xc004d78, 0x24040001, -0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004d78, 0x2021, 0xc004d78, 0x24040001, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x24100010, 0xc004d78, 0x2021, 0x108042, -0x1600fffc, 0x0, 0x24100010, 0x3202001e, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x3202001e, 0xc004db9, -0x34108000, 0xc004db9, 0x0, 0xc004d58, -0x0, 0x50400005, 0x108042, 0x97a20020, -0x501025, 0xa7a20020, 0x108042, 0x1600fff7, -0x0, 0xc004db9, 0x8021, 0xa7a00020, -0xc004d78, 0x24040001, 0x26100001, 0x2e020020, -0x1440fffb, 0x0, 0xc004d78, 0x2021, -0xc004d78, 0x24040001, 0xc004d78, 0x24040001, -0xc004d78, 0x2021, 0x24100010, 0xc004d78, -0x2021, 0x108042, 0x1600fffc, 0x0, -0x24100010, 0x3202001e, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fffa, -0x3202001e, 0xc004db9, 0x34108000, 0xc004db9, -0x0, 0xc004d58, 0x0, 0x50400005, -0x108042, 0x97a20020, 0x501025, 0xa7a20020, -0x108042, 0x1600fff7, 0x0, 0xc004db9, -0x8021, 0xa7a00022, 0xc004d78, 0x24040001, -0x26100001, 0x2e020020, 0x1440fffb, 0x0, -0xc004d78, 0x2021, 0xc004d78, 0x24040001, -0xc004d78, 0x2021, 0xc004d78, 0x24040001, -0x24100010, 0xc004d78, 0x2021, 0x108042, -0x1600fffc, 0x0, 0x24100010, 0xc004d78, -0x2021, 0x108042, 0x1600fffc, 0x0, -0xc004d78, 0x24040001, 0xc004d78, 0x2021, -0x34108000, 0x97a20022, 0x501024, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fff8, 0x0, 0xc004db9, 0x0, -0x24040018, 0x24050002, 0xc004ddb, 0x24060004, -0x3c100001, 0x8e106e24, 0x24020001, 0x1602011d, -0x0, 0x3c020001, 0x94426f26, 0x3c010001, -0xac206e24, 0x24429fbc, 0x2c420004, 0x1040000c, -0x24040009, 0x24050001, 0xc004ddb, 0x24060400, -0x24040018, 0x24050001, 0xc004ddb, 0x24060020, -0x24040018, 0x24050001, 0xc004ddb, 0x24062000, -0x3c024000, 0x2421024, 0x10400123, 0x3c022000, -0x2421024, 0x10400004, 0x0, 0x3c010001, -0x10000003, 0xac306f1c, 0x3c010001, 0xac206f1c, -0x3c030001, 0x8c636f34, 0x24020005, 0x146200f9, -0x0, 0x3c020001, 0x8c426f1c, 0x10400067, -0x3c020004, 0x2421024, 0x10400011, 0xa7a00018, -0x3c020008, 0x2421024, 0x10400002, 0x24020200, -0xa7a20018, 0x3c020010, 0x2421024, 0x10400004, -0x0, 0x97a20018, 0x34420100, 0xa7a20018, -0x97a60018, 0x24040009, 0x10000004, 0x2821, -0x24040009, 0x2821, 0x3021, 0xc004ddb, -0x0, 0x24020001, 0xa7a2001a, 0x3c020008, -0x2421024, 0x1040000c, 0x3c020002, 0x2421024, -0x10400002, 0x24020101, 0xa7a2001a, 0x3c020001, -0x2421024, 0x10400005, 0x3c020010, 0x97a2001a, -0x34420040, 0xa7a2001a, 0x3c020010, 0x2421024, -0x1040000e, 0x3c020002, 0x2421024, 0x10400005, -0x3c020001, 0x97a2001a, 0x34420080, 0xa7a2001a, -0x3c020001, 0x2421024, 0x10400005, 0x3c0300a0, -0x97a2001a, 0x34420020, 0xa7a2001a, 0x3c0300a0, -0x2431024, 0x54430004, 0x3c020020, 0x97a2001a, -0x1000000c, 0x34420400, 0x2421024, 0x50400004, -0x3c020080, 0x97a2001a, 0x10000006, 0x34420800, -0x2421024, 0x10400004, 0x0, 0x97a2001a, -0x34420c00, 0xa7a2001a, 0x97a6001a, 0x24040004, -0xc004ddb, 0x2821, 0x3c020004, 0x2421024, -0x10400004, 0xa7a0001c, 0x32425000, 0x14400004, -0x0, 0x32424000, 0x10400005, 0x2021, -0xc004cf9, 0x2402021, 0x10000096, 0x0, -0x97a6001c, 0x2821, 0x34c61200, 0xc004ddb, -0xa7a6001c, 0x1000008f, 0x0, 0x2421024, -0x10400004, 0xa7a00018, 0x32425000, 0x14400004, -0x0, 0x32424000, 0x10400005, 0x3c020010, -0xc004cf9, 0x2402021, 0x10000019, 0xa7a0001a, -0x2421024, 0x10400004, 0x0, 0x97a20018, -0x10000004, 0xa7a20018, 0x97a20018, 0x34420100, -0xa7a20018, 0x3c020001, 0x2421024, 0x10400004, -0x0, 0x97a20018, 0x10000004, 0xa7a20018, -0x97a20018, 0x34422000, 0xa7a20018, 0x97a60018, -0x2021, 0xc004ddb, 0x2821, 0xa7a0001a, -0x8021, 0xc004d78, 0x24040001, 0x26100001, -0x2e020020, 0x1440fffb, 0x0, 0xc004d78, -0x2021, 0xc004d78, 0x24040001, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x24100010, -0x32020001, 0x10400002, 0x2021, 0x24040001, -0xc004d78, 0x108042, 0x1600fffa, 0x32020001, -0x24100010, 0xc004d78, 0x2021, 0x108042, -0x1600fffc, 0x0, 0xc004db9, 0x34108000, -0xc004db9, 0x0, 0xc004d58, 0x0, -0x50400005, 0x108042, 0x97a2001a, 0x501025, -0xa7a2001a, 0x108042, 0x1600fff7, 0x0, -0xc004db9, 0x8021, 0xa7a0001a, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x24040001, 0xc004d78, -0x2021, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0xc004d78, -0x2021, 0x108042, 0x1600fffc, 0x0, -0xc004db9, 0x34108000, 0xc004db9, 0x0, -0xc004d58, 0x0, 0x50400005, 0x108042, -0x97a2001a, 0x501025, 0xa7a2001a, 0x108042, -0x1600fff7, 0x0, 0xc004db9, 0x0, -0x3c040001, 0x24846bcc, 0x97a60018, 0x97a7001a, -0x3c020001, 0x8c426d98, 0x3c030001, 0x8c636f1c, -0x3c05000d, 0x34a50205, 0xafa20010, 0xc002b3b, -0xafa30014, 0x8f830054, 0x24020004, 0x3c010001, -0xac226dd4, 0x3c010001, 0x10000017, 0xac236f38, -0x8f830054, 0x3c020001, 0x8c426f38, 0x2463ff9c, -0x431023, 0x2c420064, 0x1440000f, 0x0, -0x8f820220, 0x24030005, 0x3c010001, 0xac236dd4, -0x3c03f700, 0x431025, 0x10000007, 0xaf820220, -0x24020006, 0x3c010001, 0xac226dd4, 0x24020011, -0x3c010001, 0xac226dd0, 0x8fbf0034, 0x8fb20030, -0x8fb1002c, 0x8fb00028, 0x3e00008, 0x27bd0038, -0x27bdffd8, 0xafb00018, 0x808021, 0xafb1001c, -0x8821, 0x32024000, 0x10400013, 0xafbf0020, -0x3c020010, 0x2021024, 0x2c420001, 0x21023, -0x30434100, 0x3c020001, 0x2021024, 0x14400006, -0x34714000, 0x3c020002, 0x2021024, 0x14400002, -0x34716000, 0x34714040, 0x2021, 0x2821, -0x10000036, 0x2203021, 0x32021000, 0x10400035, -0x2021, 0x2821, 0xc004ddb, 0x24060040, -0x24040018, 0x2821, 0xc004ddb, 0x24060c00, -0x24040017, 0x2821, 0xc004ddb, 0x24060400, -0x24040016, 0x2821, 0xc004ddb, 0x24060006, -0x24040017, 0x2821, 0xc004ddb, 0x24062500, -0x24040016, 0x2821, 0xc004ddb, 0x24060006, -0x24040017, 0x2821, 0xc004ddb, 0x24064600, -0x24040016, 0x2821, 0xc004ddb, 0x24060006, -0x24040017, 0x2821, 0xc004ddb, 0x24066700, -0x24040016, 0x2821, 0xc004ddb, 0x24060006, -0x2404001f, 0x2821, 0xc004ddb, 0x24060010, -0x24040009, 0x2821, 0xc004ddb, 0x24061500, -0x24040009, 0x2821, 0x24061d00, 0xc004ddb, -0x0, 0x3c040001, 0x24846bf0, 0x3c05000e, -0x34a50100, 0x2003021, 0x2203821, 0xafa00010, -0xc002b3b, 0xafa00014, 0x8fbf0020, 0x8fb1001c, -0x8fb00018, 0x3e00008, 0x27bd0028, 0x8f850044, -0x8f820044, 0x3c030001, 0x431025, 0x3c030008, -0xaf820044, 0x8f840054, 0x8f820054, 0xa32824, -0x10000002, 0x24840001, 0x8f820054, 0x821023, -0x2c420002, 0x1440fffc, 0x0, 0x8f820044, -0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044, -0x8f830054, 0x8f820054, 0x10000002, 0x24630001, -0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, -0x0, 0x3e00008, 0xa01021, 0x8f830044, -0x3c02fff0, 0x3442ffff, 0x42480, 0x621824, -0x3c020002, 0x822025, 0x641825, 0xaf830044, -0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024, -0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x8f820044, 0x3c030001, -0x431025, 0xaf820044, 0x8f830054, 0x8f820054, -0x10000002, 0x24630001, 0x8f820054, 0x621023, -0x2c420002, 0x1440fffc, 0x0, 0x3e00008, -0x0, 0x8f820044, 0x2403ff7f, 0x431024, -0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x8f820044, 0x34420080, -0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x3e00008, 0x0, -0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024, -0xaf820044, 0x8f820044, 0x3c030001, 0x431025, -0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, -0x24630001, 0x8f820054, 0x621023, 0x2c420002, -0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe, -0x3463ffff, 0x431024, 0xaf820044, 0x8f830054, -0x8f820054, 0x10000002, 0x24630001, 0x8f820054, -0x621023, 0x2c420002, 0x1440fffc, 0x0, -0x3e00008, 0x0, 0x27bdffc8, 0xafb30024, -0x809821, 0xafbe002c, 0xa0f021, 0xafb20020, -0xc09021, 0x33c2ffff, 0xafbf0030, 0xafb50028, -0xafb1001c, 0xafb00018, 0x14400034, 0xa7b20010, -0x3271ffff, 0x27b20010, 0x8021, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x2301024, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x2301024, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x34108000, -0x96420000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x12000075, -0x0, 0x1000fff6, 0x0, 0x3275ffff, -0x27b10010, 0xa7a00010, 0x8021, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x24040001, 0xc004d78, -0x2021, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x2b01024, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x2b01024, 0xc004db9, -0x34108000, 0xc004db9, 0x0, 0xc004d58, -0x0, 0x50400005, 0x108042, 0x96220000, -0x501025, 0xa6220000, 0x108042, 0x1600fff7, -0x0, 0xc004db9, 0x0, 0x33c5ffff, -0x24020001, 0x54a20004, 0x24020002, 0x97a20010, -0x10000006, 0x521025, 0x14a20006, 0x3271ffff, -0x97a20010, 0x121827, 0x431024, 0xa7a20010, -0x3271ffff, 0x27b20010, 0x8021, 0xc004d78, -0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, -0x0, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0xc004d78, -0x24040001, 0x24100010, 0x32020001, 0x10400002, -0x2021, 0x24040001, 0xc004d78, 0x108042, -0x1600fffa, 0x32020001, 0x24100010, 0x2301024, -0x10400002, 0x2021, 0x24040001, 0xc004d78, -0x108042, 0x1600fffa, 0x2301024, 0xc004d78, -0x24040001, 0xc004d78, 0x2021, 0x34108000, -0x96420000, 0x501024, 0x10400002, 0x2021, -0x24040001, 0xc004d78, 0x108042, 0x1600fff8, -0x0, 0xc004db9, 0x0, 0x8fbf0030, -0x8fbe002c, 0x8fb50028, 0x8fb30024, 0x8fb20020, -0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038, -0x0, 0x0, 0x0, 0x27bdffe8, -0xafbf0010, 0x8ee304b8, 0x24020008, 0x146201e0, -0x0, 0x3c020001, 0x8c426f1c, 0x14400005, -0x0, 0xc003daf, 0x8f840224, 0x100001d8, -0x0, 0x8f820220, 0x3c030008, 0x431024, -0x10400026, 0x24020001, 0x8f840224, 0x8f820220, -0x3c030400, 0x431024, 0x10400006, 0x0, -0x3c010002, 0xac208fa0, 0x3c010002, 0x1000000b, -0xac208fc0, 0x3c030002, 0x24638fa0, 0x8c620000, -0x24420001, 0xac620000, 0x2c420002, 0x14400003, -0x24020001, 0x3c010002, 0xac228fc0, 0x3c020002, -0x8c428fc0, 0x10400006, 0x30820040, 0x10400004, -0x24020001, 0x3c010002, 0x10000003, 0xac228fc4, -0x3c010002, 0xac208fc4, 0x3c010002, 0xac248f9c, -0x3c010002, 0x1000000b, 0xac208fd0, 0x3c010002, -0xac228fd0, 0x3c010002, 0xac208fc0, 0x3c010002, -0xac208fa0, 0x3c010002, 0xac208fc4, 0x3c010002, -0xac208f9c, 0x3c030002, 0x8c638f90, 0x3c020002, -0x8c428f94, 0x50620004, 0x2463ffff, 0x3c010002, -0xac238f94, 0x2463ffff, 0x2c62000e, 0x10400194, -0x31080, 0x3c010001, 0x220821, 0x8c226c00, -0x400008, 0x0, 0x24020002, 0x3c010002, -0xac208fc0, 0x3c010002, 0xac208fa0, 0x3c010002, -0xac208f9c, 0x3c010002, 0xac208fc4, 0x3c010002, -0xac208fb8, 0x3c010002, 0xac208fb0, 0xaf800224, -0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fd0, -0x1440004f, 0x3c02fdff, 0x3442ffff, 0xc003daf, -0x282a024, 0xaf800204, 0x8f820200, 0x2403fffd, -0x431024, 0xaf820200, 0x3c010002, 0xac208fe0, -0x8f830054, 0x3c020002, 0x8c428fb8, 0x24040001, -0x3c010002, 0xac248fcc, 0x24420001, 0x3c010002, -0xac228fb8, 0x2c420004, 0x3c010002, 0xac238fb4, -0x14400006, 0x24020003, 0x3c010001, 0xac246d9c, -0x3c010002, 0x1000015e, 0xac208fb8, 0x3c010002, -0x1000015b, 0xac228f90, 0x8f830054, 0x3c020002, -0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710, -0x14400003, 0x24020004, 0x3c010002, 0xac228f90, -0x3c020002, 0x8c428fd0, 0x14400021, 0x3c02fdff, -0x3442ffff, 0x1000014a, 0x282a024, 0x3c040001, -0x8c846f20, 0x3c010002, 0xc005084, 0xac208fa8, -0x3c020002, 0x8c428fdc, 0xaf820204, 0x3c020002, -0x8c428fd0, 0x14400012, 0x3c03fdff, 0x8f820204, -0x3463ffff, 0x30420030, 0x1440012f, 0x283a024, -0x3c030002, 0x8c638fdc, 0x24020005, 0x3c010002, -0xac228f90, 0x3c010002, 0x10000131, 0xac238fe0, -0x3c020002, 0x8c428fd0, 0x10400010, 0x3c02fdff, -0x3c020001, 0x8c426e3c, 0x24420001, 0x3c010001, -0xac226e3c, 0x2c420002, 0x14400125, 0x24020001, -0x3c010001, 0xac226e44, 0x3c010001, 0xac206e3c, -0x3c010001, 0x1000011e, 0xac226d9c, 0x3c030002, -0x8c638fc0, 0x3442ffff, 0x10600119, 0x282a024, -0x3c020002, 0x8c428f9c, 0x10400115, 0x0, -0x3c010002, 0xac228fc8, 0x24020003, 0x3c010002, -0xac228fa0, 0x100000b8, 0x24020006, 0x3c010002, -0xac208fa8, 0x8f820204, 0x34420040, 0xaf820204, -0x3c020002, 0x8c428fe0, 0x24030007, 0x3c010002, -0xac238f90, 0x34420040, 0x3c010002, 0xac228fe0, -0x3c020002, 0x8c428fc0, 0x10400005, 0x0, -0x3c020002, 0x8c428f9c, 0x104000f0, 0x24020002, -0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21, -0x104000ea, 0x24020002, 0x3c020002, 0x8c428fc4, -0x104000ef, 0x2404ffbf, 0x3c020002, 0x8c428f9c, -0x3c030002, 0x8c638fc8, 0x441024, 0x641824, -0x10430004, 0x24020001, 0x3c010002, 0x100000e4, -0xac228f90, 0x24020003, 0xaca20000, 0x24020008, -0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fcc, -0x1040000c, 0x24020001, 0x3c040002, 0xc005091, -0x8c848f9c, 0x3c020002, 0x8c428fe8, 0x14400005, -0x24020001, 0x3c020002, 0x8c428fe4, 0x10400006, -0x24020001, 0x3c010001, 0xac226d9c, 0x3c010002, -0x100000cb, 0xac208fb8, 0x3c020002, 0x8c428fb0, -0x3c030002, 0x8c638f9c, 0x2c420001, 0x210c0, -0x30630008, 0x3c010002, 0xac228fb0, 0x3c010002, -0xac238fac, 0x8f830054, 0x24020009, 0x3c010002, -0xac228f90, 0x3c010002, 0x100000b9, 0xac238fb4, -0x8f830054, 0x3c020002, 0x8c428fb4, 0x2463d8f0, -0x431023, 0x2c422710, 0x1440009f, 0x0, -0x3c020002, 0x8c428fc0, 0x10400005, 0x0, -0x3c020002, 0x8c428f9c, 0x104000a0, 0x24020002, -0x3c030002, 0x24638fa0, 0x8c620000, 0x2c424e21, -0x1040009a, 0x24020002, 0x3c020002, 0x8c428fcc, -0x1040000e, 0x0, 0x3c020002, 0x8c428f9c, -0x3c010002, 0xac208fcc, 0x30420080, 0x1040002f, -0x2402000c, 0x8f820204, 0x30420080, 0x1440000c, -0x24020003, 0x10000029, 0x2402000c, 0x3c020002, -0x8c428f9c, 0x30420080, 0x14400005, 0x24020003, -0x8f820204, 0x30420080, 0x1040001f, 0x24020003, -0xac620000, 0x2402000a, 0x3c010002, 0xac228f90, -0x3c040002, 0x24848fd8, 0x8c820000, 0x3c030002, -0x8c638fb0, 0x431025, 0xaf820204, 0x8c830000, -0x3c040002, 0x8c848fb0, 0x2402000b, 0x3c010002, -0xac228f90, 0x641825, 0x3c010002, 0xac238fe0, -0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21, -0x10400066, 0x24020002, 0x3c020002, 0x8c428fd0, -0x10400005, 0x0, 0x2402000c, 0x3c010002, -0x10000067, 0xac228f90, 0x3c020002, 0x8c428fc0, -0x10400063, 0x0, 0x3c040002, 0x8c848f9c, -0x10800055, 0x30820008, 0x3c030002, 0x8c638fac, -0x1062005b, 0x24020003, 0x3c010002, 0xac248fc8, -0xaca20000, 0x24020006, 0x3c010002, 0x10000054, -0xac228f90, 0x8f820200, 0x34420002, 0xaf820200, -0x8f830054, 0x2402000d, 0x3c010002, 0xac228f90, -0x3c010002, 0xac238fb4, 0x8f830054, 0x3c020002, -0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710, -0x14400031, 0x0, 0x3c020002, 0x8c428fd0, -0x10400020, 0x2402000e, 0x3c030002, 0x8c638fe4, -0x3c010002, 0x14600015, 0xac228f90, 0xc003e6d, -0x0, 0x3c050001, 0x8ca56d98, 0xc00529b, -0x2021, 0x3c030001, 0x8c636d98, 0x24020004, -0x14620005, 0x2403fffb, 0x3c020001, 0x8c426d94, -0x10000003, 0x2403fff7, 0x3c020001, 0x8c426d94, -0x431024, 0x3c010001, 0xac226d94, 0x8f830224, -0x3c020200, 0x3c010002, 0xac238fec, 0x10000020, -0x282a025, 0x3c020002, 0x8c428fc0, 0x10400005, -0x0, 0x3c020002, 0x8c428f9c, 0x1040000f, -0x24020002, 0x3c020002, 0x8c428fa0, 0x2c424e21, -0x1040000a, 0x24020002, 0x3c020002, 0x8c428fc0, -0x1040000f, 0x0, 0x3c020002, 0x8c428f9c, -0x1440000b, 0x0, 0x24020002, 0x3c010002, -0x10000007, 0xac228f90, 0x3c020002, 0x8c428fc0, -0x10400003, 0x0, 0xc003daf, 0x0, -0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, -0x8fbf0010, 0x3e00008, 0x27bd0018, 0x3c030002, -0x24638fe8, 0x8c620000, 0x10400005, 0x34422000, -0x3c010002, 0xac228fdc, 0x10000003, 0xac600000, -0x3c010002, 0xac248fdc, 0x3e00008, 0x0, -0x27bdffe0, 0x30820030, 0xafbf0018, 0x3c010002, -0xac228fe4, 0x14400067, 0x3c02ffff, 0x34421f0e, -0x821024, 0x14400061, 0x24020030, 0x30822000, -0x1040005d, 0x30838000, 0x31a02, 0x30820001, -0x21200, 0x3c040001, 0x8c846f20, 0x621825, -0x331c2, 0x3c030001, 0x24636e48, 0x30828000, -0x21202, 0x30840001, 0x42200, 0x441025, -0x239c2, 0x61080, 0x431021, 0x471021, -0x90430000, 0x24020001, 0x10620025, 0x0, -0x10600007, 0x24020002, 0x10620013, 0x24020003, -0x1062002c, 0x3c05000f, 0x10000037, 0x0, -0x8f820200, 0x2403feff, 0x431024, 0xaf820200, -0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024, -0xaf820220, 0x3c010002, 0xac209004, 0x3c010002, -0x10000034, 0xac20900c, 0x8f820200, 0x34420100, -0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff, -0x431024, 0xaf820220, 0x24020100, 0x3c010002, -0xac229004, 0x3c010002, 0x10000026, 0xac20900c, -0x8f820200, 0x2403feff, 0x431024, 0xaf820200, -0x8f820220, 0x3c030001, 0x431025, 0xaf820220, -0x3c010002, 0xac209004, 0x3c010002, 0x10000019, -0xac23900c, 0x8f820200, 0x34420100, 0xaf820200, -0x8f820220, 0x3c030001, 0x431025, 0xaf820220, -0x24020100, 0x3c010002, 0xac229004, 0x3c010002, -0x1000000c, 0xac23900c, 0x34a5ffff, 0x3c040001, -0x24846c38, 0xafa30010, 0xc002b3b, 0xafa00014, -0x10000004, 0x0, 0x24020030, 0x3c010002, -0xac228fe8, 0x8fbf0018, 0x3e00008, 0x27bd0020, -0x0, 0x0, 0x0, 0x27bdffc8, -0xafb20028, 0x809021, 0xafb3002c, 0xa09821, -0xafb00020, 0xc08021, 0x3c040001, 0x24846c50, -0x3c050009, 0x3c020001, 0x8c426d98, 0x34a59001, -0x2403021, 0x2603821, 0xafbf0030, 0xafb10024, -0xa7a0001a, 0xafb00014, 0xc002b3b, 0xafa20010, -0x24020002, 0x12620083, 0x2e620003, 0x10400005, -0x24020001, 0x1262000a, 0x0, 0x10000173, -0x0, 0x24020004, 0x126200f8, 0x24020008, -0x126200f7, 0x3c02ffec, 0x1000016c, 0x0, -0x3c020001, 0x8c426d94, 0x30420002, 0x14400004, -0x128940, 0x3c02fffb, 0x3442ffff, 0x2028024, -0x3c010002, 0x310821, 0xac308ffc, 0x3c024000, -0x2021024, 0x1040004e, 0x1023c2, 0x30840030, -0x101382, 0x3042001c, 0x3c030001, 0x24636dd8, -0x431021, 0x823821, 0x3c020020, 0x2021024, -0x10400006, 0x24020100, 0x3c010002, 0x310821, -0xac229000, 0x10000005, 0x3c020080, 0x3c010002, -0x310821, 0xac209000, 0x3c020080, 0x2021024, -0x10400006, 0x121940, 0x3c020001, 0x3c010002, -0x230821, 0x10000005, 0xac229008, 0x121140, -0x3c010002, 0x220821, 0xac209008, 0x94e40000, -0x3c030001, 0x8c636f40, 0x24020005, 0x10620010, -0xa7a40018, 0x32024000, 0x10400002, 0x34824000, -0xa7a20018, 0x24040001, 0x94e20002, 0x24050004, -0x24e60002, 0x34420001, 0xc0045be, 0xa4e20002, -0x24040001, 0x2821, 0xc0045be, 0x27a60018, -0x3c020001, 0x8c426d98, 0x24110001, 0x3c010001, -0xac316da4, 0x14530004, 0x32028000, 0xc003daf, -0x0, 0x32028000, 0x1040011c, 0x0, -0xc003daf, 0x0, 0x3c030001, 0x8c636f40, -0x24020005, 0x10620115, 0x24020002, 0x3c010001, -0xac316d9c, 0x3c010001, 0x10000110, 0xac226d98, -0x24040001, 0x24050004, 0x27b0001a, 0xc0045be, -0x2003021, 0x24040001, 0x2821, 0xc0045be, -0x2003021, 0x3c020002, 0x511021, 0x8c428ff4, -0x3c040001, 0x8c846d98, 0x3c03bfff, 0x3463ffff, -0x3c010001, 0xac336da4, 0x431024, 0x3c010002, -0x310821, 0x109300f7, 0xac228ff4, 0x100000f7, -0x0, 0x3c022000, 0x2021024, 0x10400005, -0x24020001, 0x3c010001, 0xac226f1c, 0x10000004, -0x128940, 0x3c010001, 0xac206f1c, 0x128940, -0x3c010002, 0x310821, 0xac308ff8, 0x3c024000, -0x2021024, 0x14400014, 0x0, 0x3c020001, -0x8c426f1c, 0x10400006, 0x24040004, 0x24050001, -0xc004ddb, 0x24062000, 0x24020001, 0xaee204b8, -0x3c020002, 0x511021, 0x8c428ff0, 0x3c03bfff, -0x3463ffff, 0x431024, 0x3c010002, 0x310821, -0x100000d0, 0xac228ff0, 0x3c020001, 0x8c426f1c, -0x10400028, 0x3c0300a0, 0x2031024, 0x5443000d, -0x3c020020, 0x3c020001, 0x8c426f20, 0x24030100, -0x3c010002, 0x310821, 0xac239004, 0x3c030001, -0x3c010002, 0x310821, 0xac23900c, 0x10000015, -0x34420400, 0x2021024, 0x10400008, 0x24030100, -0x3c020001, 0x8c426f20, 0x3c010002, 0x310821, -0xac239004, 0x1000000b, 0x34420800, 0x3c020080, -0x2021024, 0x1040002e, 0x3c030001, 0x3c020001, -0x8c426f20, 0x3c010002, 0x310821, 0xac23900c, -0x34420c00, 0x3c010001, 0xac226f20, 0x10000025, -0x24040001, 0x3c020020, 0x2021024, 0x10400006, -0x24020100, 0x3c010002, 0x310821, 0xac229004, -0x10000005, 0x3c020080, 0x3c010002, 0x310821, -0xac209004, 0x3c020080, 0x2021024, 0x10400007, -0x121940, 0x3c020001, 0x3c010002, 0x230821, -0xac22900c, 0x10000006, 0x24040001, 0x121140, -0x3c010002, 0x220821, 0xac20900c, 0x24040001, -0x2821, 0x27b0001e, 0xc00457c, 0x2003021, -0x24040001, 0x2821, 0xc00457c, 0x2003021, -0x24040001, 0x24050001, 0x27b0001c, 0xc00457c, -0x2003021, 0x24040001, 0x24050001, 0xc00457c, -0x2003021, 0x10000077, 0x0, 0x3c02ffec, -0x3442ffff, 0x2028024, 0x3c020008, 0x2028025, -0x121140, 0x3c010002, 0x220821, 0xac308ff8, -0x3c022000, 0x2021024, 0x10400009, 0x0, -0x3c020001, 0x8c426e44, 0x14400005, 0x24020001, -0x3c010001, 0xac226f1c, 0x10000004, 0x3c024000, -0x3c010001, 0xac206f1c, 0x3c024000, 0x2021024, -0x1440001d, 0x24020e01, 0x3c030001, 0x8c636f1c, -0xaf820238, 0x3c010001, 0xac206db0, 0x10600005, -0x24022020, 0x3c010001, 0xac226f20, 0x24020001, -0xaee204b8, 0x3c04bfff, 0x121940, 0x3c020002, -0x431021, 0x8c428ff0, 0x3c050001, 0x8ca56d98, -0x3484ffff, 0x441024, 0x3c010002, 0x230821, -0xac228ff0, 0x24020001, 0x10a20044, 0x0, -0x10000040, 0x0, 0x3c020001, 0x8c426f1c, -0x1040001c, 0x24022000, 0x3c010001, 0xac226f20, -0x3c0300a0, 0x2031024, 0x14430005, 0x121140, -0x3402a000, 0x3c010001, 0x1000002d, 0xac226f20, -0x3c030002, 0x621821, 0x8c638ff8, 0x3c020020, -0x621024, 0x10400004, 0x24022001, 0x3c010001, -0x10000023, 0xac226f20, 0x3c020080, 0x621024, -0x1040001f, 0x3402a001, 0x3c010001, 0x1000001c, -0xac226f20, 0x3c020020, 0x2021024, 0x10400007, -0x121940, 0x24020100, 0x3c010002, 0x230821, -0xac229004, 0x10000006, 0x3c020080, 0x121140, -0x3c010002, 0x220821, 0xac209004, 0x3c020080, -0x2021024, 0x10400006, 0x121940, 0x3c020001, -0x3c010002, 0x230821, 0x10000005, 0xac22900c, -0x121140, 0x3c010002, 0x220821, 0xac20900c, -0x3c030001, 0x8c636d98, 0x24020001, 0x10620003, -0x0, 0xc003daf, 0x0, 0x8fbf0030, -0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, -0x3e00008, 0x27bd0038, 0x27bdffb0, 0xafb3003c, -0x9821, 0xafb50040, 0xa821, 0xafb10034, -0x8821, 0x24020002, 0xafbf0048, 0xafbe0044, -0xafb20038, 0xafb00030, 0xafa4002c, 0xa7a0001a, -0xa7a00018, 0xa7a00020, 0xa7a0001e, 0xa7a00022, -0x10a20130, 0xa7a0001c, 0x2ca20003, 0x10400005, -0x24020001, 0x10a2000a, 0x3c024000, 0x1000025d, -0x2201021, 0x24020004, 0x10a2020a, 0x24020008, -0x10a20208, 0x2201021, 0x10000256, 0x0, -0x8fa8002c, 0x88140, 0x3c030002, 0x701821, -0x8c638ffc, 0x621024, 0x14400009, 0x24040001, -0x3c027fff, 0x3442ffff, 0x628824, 0x3c010002, -0x300821, 0xac318ff4, 0x10000246, 0x2201021, -0x24050001, 0xc00457c, 0x27a60018, 0x24040001, -0x24050001, 0xc00457c, 0x27a60018, 0x97a20018, -0x30420004, 0x104000d9, 0x3c114000, 0x3c020001, -0x8c426f40, 0x2443ffff, 0x2c620006, 0x104000d9, -0x31080, 0x3c010001, 0x220821, 0x8c226c68, -0x400008, 0x0, 0x24040001, 0x24050011, -0x27b0001a, 0xc00457c, 0x2003021, 0x24040001, -0x24050011, 0xc00457c, 0x2003021, 0x97a3001a, -0x30624000, 0x10400002, 0x3c150010, 0x3c150008, -0x30628000, 0x104000aa, 0x3c130001, 0x100000a8, -0x3c130002, 0x24040001, 0x24050014, 0x27b0001a, -0xc00457c, 0x2003021, 0x24040001, 0x24050014, -0xc00457c, 0x2003021, 0x97a3001a, 0x30621000, -0x10400002, 0x3c150010, 0x3c150008, 0x30620800, -0x10400097, 0x3c130001, 0x10000095, 0x3c130002, -0x24040001, 0x24050019, 0x27b0001c, 0xc00457c, -0x2003021, 0x24040001, 0x24050019, 0xc00457c, -0x2003021, 0x97a2001c, 0x30430700, 0x24020400, -0x10620027, 0x28620401, 0x1040000e, 0x24020200, -0x1062001f, 0x28620201, 0x10400005, 0x24020100, -0x5062001e, 0x3c130001, 0x1000001e, 0x24040001, -0x24020300, 0x50620019, 0x3c130002, 0x10000019, -0x24040001, 0x24020600, 0x1062000d, 0x28620601, -0x10400005, 0x24020500, 0x5062000b, 0x3c130002, -0x10000010, 0x24040001, 0x24020700, 0x1462000d, -0x24040001, 0x3c130004, 0x1000000a, 0x3c150008, -0x10000006, 0x3c130004, 0x10000005, 0x3c150008, -0x3c130001, 0x10000002, 0x3c150008, 0x3c150010, -0x24040001, 0x24050018, 0x27b0001e, 0xc00457c, -0x2003021, 0x24040001, 0x24050018, 0xc00457c, -0x2003021, 0x8fa8002c, 0x97a7001e, 0x81140, -0x3c060002, 0xc23021, 0x8cc68ff4, 0x97a20022, -0x3c100001, 0x26106c5c, 0x2002021, 0xafa20010, -0x97a2001c, 0x3c05000c, 0x34a50303, 0xc002b3b, -0xafa20014, 0x3c020004, 0x16620010, 0x3c020001, -0x8f840054, 0x24030001, 0x24020002, 0x3c010001, -0xac236d9c, 0x3c010001, 0xac226d98, 0x3c010001, -0xac236da4, 0x3c010001, 0xac236e24, 0x3c010001, -0xac246f30, 0x1000004f, 0x2b38825, 0x16620039, -0x3c028000, 0x3c020001, 0x8c426e20, 0x1440001e, -0x24040018, 0x2021, 0x2821, 0xc004ddb, -0x34068000, 0x8f830054, 0x8f820054, 0x2b38825, -0x10000002, 0x24630032, 0x8f820054, 0x621023, -0x2c420033, 0x1440fffc, 0x0, 0x8f830054, -0x24020001, 0x3c010001, 0xac226e20, 0x3c010001, -0xac226d9c, 0x3c010001, 0xac226d98, 0x3c010001, -0xac226da4, 0x3c010001, 0xac226e24, 0x3c010001, -0x1000002c, 0xac236f30, 0x2821, 0xc004ddb, -0x24060404, 0x2021, 0x2405001e, 0x27a60018, -0x24020002, 0xc0045be, 0xa7a20018, 0x2021, -0x2821, 0x27a60018, 0xc0045be, 0xa7a00018, -0x24040018, 0x24050002, 0xc004ddb, 0x24060004, -0x3c028000, 0x2221025, 0x2b31825, 0x10000015, -0x438825, 0x2221025, 0x2751825, 0x438825, -0x2002021, 0x97a6001c, 0x3c070001, 0x8ce76d98, -0x3c05000c, 0x34a50326, 0xafb30010, 0xc002b3b, -0xafb10014, 0x10000007, 0x0, 0x3c110002, -0x2308821, 0x8e318ffc, 0x3c027fff, 0x3442ffff, -0x2228824, 0x3c020001, 0x8c426da8, 0x1040001e, -0x0, 0x3c020001, 0x8c426f1c, 0x10400002, -0x3c022000, 0x2228825, 0x8fa8002c, 0x81140, -0x3c010002, 0x220821, 0x8c229000, 0x10400003, -0x3c020020, 0x10000005, 0x2228825, 0x3c02ffdf, -0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140, -0x3c010002, 0x220821, 0x8c229008, 0x10400003, -0x3c020080, 0x10000004, 0x2228825, 0x3c02ff7f, -0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140, -0x3c010002, 0x220821, 0xac318ff4, 0x10000135, -0x2201021, 0x8fa8002c, 0x8f140, 0x3c030002, -0x7e1821, 0x8c638ff8, 0x3c024000, 0x621024, -0x14400009, 0x24040001, 0x3c027fff, 0x3442ffff, -0x628824, 0x3c010002, 0x3e0821, 0xac318ff0, -0x10000124, 0x2201021, 0x2821, 0xc00457c, -0x27a60018, 0x24040001, 0x2821, 0xc00457c, -0x27a60018, 0x24040001, 0x24050001, 0x27b20020, -0xc00457c, 0x2403021, 0x24040001, 0x24050001, -0xc00457c, 0x2403021, 0x24040001, 0x24050004, -0x27b1001e, 0xc00457c, 0x2203021, 0x24040001, -0x24050004, 0xc00457c, 0x2203021, 0x24040001, -0x24050005, 0x27b00022, 0xc00457c, 0x2003021, -0x24040001, 0x24050005, 0xc00457c, 0x2003021, -0x24040001, 0x24050010, 0xc00457c, 0x27a60018, -0x24040001, 0x24050010, 0xc00457c, 0x27a60018, -0x24040001, 0x2405000a, 0xc00457c, 0x2403021, -0x24040001, 0x2405000a, 0xc00457c, 0x2403021, -0x24040001, 0x24050018, 0xc00457c, 0x2203021, -0x24040001, 0x24050018, 0xc00457c, 0x2203021, -0x24040001, 0x24050001, 0xc00457c, 0x27a60018, -0x24040001, 0x24050001, 0xc00457c, 0x27a60018, -0x97a20018, 0x30420004, 0x10400066, 0x3c114000, -0x3c030001, 0x8c636f34, 0x24020005, 0x14620067, -0x24040001, 0x24050019, 0x27b0001c, 0xc00457c, -0x2003021, 0x24040001, 0x24050019, 0xc00457c, -0x2003021, 0x97a2001c, 0x30430700, 0x24020400, -0x10620027, 0x28620401, 0x1040000e, 0x24020200, -0x1062001f, 0x28620201, 0x10400005, 0x24020100, -0x5062001e, 0x3c130001, 0x1000001e, 0x3c020004, -0x24020300, 0x50620019, 0x3c130002, 0x10000019, -0x3c020004, 0x24020600, 0x1062000d, 0x28620601, -0x10400005, 0x24020500, 0x5062000b, 0x3c130002, -0x10000010, 0x3c020004, 0x24020700, 0x1462000d, -0x3c020004, 0x3c130004, 0x1000000a, 0x3c150008, -0x10000006, 0x3c130004, 0x10000005, 0x3c150008, -0x3c130001, 0x10000002, 0x3c150008, 0x3c150010, -0x3c020004, 0x12620017, 0x3c028000, 0x8f820054, -0x24100001, 0x3c010001, 0xac306d9c, 0x3c010001, -0xac306d98, 0x3c010001, 0xac306da4, 0x3c010001, -0xac306e24, 0x3c010001, 0xac226f30, 0x3c020001, -0x16620022, 0x2758825, 0x2021, 0x2821, -0xc004ddb, 0x34068000, 0x3c010001, 0x1000001b, -0xac306e20, 0x2221025, 0x2b31825, 0x438825, -0x97a6001c, 0x3c020001, 0x8c426f1c, 0x3c070001, -0x8ce76d98, 0x3c040001, 0x24846c5c, 0xafa20010, -0x97a2001e, 0x3c05000c, 0x34a50323, 0x3c010001, -0xac206e20, 0xc002b3b, 0xafa20014, 0x10000007, -0x0, 0x3c110002, 0x23e8821, 0x8e318ff0, -0x3c027fff, 0x3442ffff, 0x2228824, 0x3c020001, -0x8c426da8, 0x10400069, 0x0, 0x3c020001, -0x8c426f1c, 0x10400002, 0x3c022000, 0x2228825, -0x8fa8002c, 0x81140, 0x3c010002, 0x220821, -0x8c229004, 0x10400003, 0x3c020020, 0x10000005, -0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824, -0x8fa8002c, 0x81140, 0x3c010002, 0x220821, -0x8c22900c, 0x10400003, 0x3c020080, 0x1000004f, -0x2228825, 0x3c02ff7f, 0x3442ffff, 0x1000004b, -0x2228824, 0x8fa8002c, 0x82940, 0x3c030002, -0x651821, 0x8c638ff8, 0x3c024000, 0x621024, -0x14400008, 0x3c027fff, 0x3442ffff, 0x628824, -0x3c010002, 0x250821, 0xac318ff0, 0x10000041, -0x2201021, 0x3c020001, 0x8c426da8, 0x10400034, -0x3c11c00c, 0x3c020001, 0x8c426e44, 0x3c04c00c, -0x34842000, 0x3c030001, 0x8c636f1c, 0x2102b, -0x21023, 0x441024, 0x10600003, 0x518825, -0x3c022000, 0x2228825, 0x3c020002, 0x451021, -0x8c429004, 0x10400003, 0x3c020020, 0x10000004, -0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824, -0x8fa8002c, 0x81140, 0x3c010002, 0x220821, -0x8c22900c, 0x10400003, 0x3c020080, 0x10000004, -0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824, -0x3c020001, 0x8c426e30, 0x10400002, 0x3c020800, -0x2228825, 0x3c020001, 0x8c426e34, 0x10400002, -0x3c020400, 0x2228825, 0x3c020001, 0x8c426e38, -0x10400006, 0x3c020100, 0x10000004, 0x2228825, -0x3c027fff, 0x3442ffff, 0x628824, 0x8fa8002c, -0x81140, 0x3c010002, 0x220821, 0xac318ff0, -0x2201021, 0x8fbf0048, 0x8fbe0044, 0x8fb50040, -0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, -0x3e00008, 0x27bd0050, 0x27bdffd0, 0xafb20028, -0x809021, 0xafbf002c, 0xafb10024, 0xafb00020, -0x8f840200, 0x3c100001, 0x8e106d98, 0x8f860220, -0x24020002, 0x1202005c, 0x2e020003, 0x10400005, -0x24020001, 0x1202000a, 0x121940, 0x1000010c, -0x0, 0x24020004, 0x120200bf, 0x24020008, -0x120200be, 0x128940, 0x10000105, 0x0, -0x3c050002, 0xa32821, 0x8ca58ffc, 0x3c100002, -0x2038021, 0x8e108ff4, 0x3c024000, 0xa21024, -0x10400038, 0x3c020008, 0x2021024, 0x10400020, -0x34840002, 0x3c020002, 0x431021, 0x8c429000, -0x10400005, 0x34840020, 0x34840100, 0x3c020020, -0x10000006, 0x2028025, 0x2402feff, 0x822024, -0x3c02ffdf, 0x3442ffff, 0x2028024, 0x121140, -0x3c010002, 0x220821, 0x8c229008, 0x10400005, -0x3c020001, 0xc23025, 0x3c020080, 0x10000016, -0x2028025, 0x3c02fffe, 0x3442ffff, 0xc23024, -0x3c02ff7f, 0x3442ffff, 0x1000000f, 0x2028024, -0x2402fedf, 0x822024, 0x3c02fffe, 0x3442ffff, -0xc23024, 0x3c02ff5f, 0x3442ffff, 0x2028024, -0x3c010002, 0x230821, 0xac209000, 0x3c010002, -0x230821, 0xac209008, 0xaf840200, 0xaf860220, -0x8f820220, 0x34420002, 0xaf820220, 0x1000000a, -0x121140, 0x3c02bfff, 0x3442ffff, 0x8f830200, -0x2028024, 0x2402fffd, 0x621824, 0xc003daf, -0xaf830200, 0x121140, 0x3c010002, 0x220821, -0x100000b7, 0xac308ff4, 0x3c020001, 0x8c426f1c, -0x10400069, 0x24050004, 0x24040001, 0xc00457c, -0x27a60018, 0x24040001, 0x24050005, 0xc00457c, -0x27a6001a, 0x97a30018, 0x97a2001a, 0x3c040001, -0x24846e48, 0x30630c00, 0x31a82, 0x30420c00, -0x21282, 0xa7a2001a, 0x21080, 0x441021, -0x431021, 0xa7a30018, 0x90480000, 0x24020001, -0x3103ffff, 0x10620029, 0x28620002, 0x10400005, -0x0, 0x10600009, 0x0, 0x1000003d, -0x0, 0x10700013, 0x24020003, 0x1062002c, -0x0, 0x10000037, 0x0, 0x8f820200, -0x2403feff, 0x431024, 0xaf820200, 0x8f820220, -0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220, -0x3c010002, 0xac209004, 0x3c010002, 0x10000032, -0xac20900c, 0x8f820200, 0x34420100, 0xaf820200, -0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024, -0xaf820220, 0x24020100, 0x3c010002, 0xac229004, -0x3c010002, 0x10000024, 0xac20900c, 0x8f820200, -0x2403feff, 0x431024, 0xaf820200, 0x8f820220, -0x3c030001, 0x431025, 0xaf820220, 0x3c010002, -0xac209004, 0x3c010002, 0x10000017, 0xac23900c, -0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, -0x3c030001, 0x431025, 0xaf820220, 0x24020100, -0x3c010002, 0xac229004, 0x3c010002, 0x1000000a, -0xac23900c, 0x3c040001, 0x24846c80, 0x97a6001a, -0x97a70018, 0x3c050001, 0x34a5ffff, 0xafa80010, -0xc002b3b, 0xafa00014, 0x8f820200, 0x34420002, -0x1000004b, 0xaf820200, 0x128940, 0x3c050002, -0xb12821, 0x8ca58ff8, 0x3c100002, 0x2118021, -0x8e108ff0, 0x3c024000, 0xa21024, 0x14400010, -0x0, 0x3c020001, 0x8c426f1c, 0x14400005, -0x3c02bfff, 0x8f820200, 0x34420002, 0xaf820200, -0x3c02bfff, 0x3442ffff, 0xc003daf, 0x2028024, -0x3c010002, 0x310821, 0x10000031, 0xac308ff0, -0x3c020001, 0x8c426f1c, 0x10400005, 0x3c020020, -0x3c020001, 0x8c426e44, 0x10400025, 0x3c020020, -0xa21024, 0x10400007, 0x34840020, 0x24020100, -0x3c010002, 0x310821, 0xac229004, 0x10000006, -0x34840100, 0x3c010002, 0x310821, 0xac209004, -0x2402feff, 0x822024, 0x3c020080, 0xa21024, -0x10400007, 0x121940, 0x3c020001, 0x3c010002, -0x230821, 0xac22900c, 0x10000008, 0xc23025, -0x121140, 0x3c010002, 0x220821, 0xac20900c, -0x3c02fffe, 0x3442ffff, 0xc23024, 0xaf840200, -0xaf860220, 0x8f820220, 0x34420002, 0xaf820220, -0x121140, 0x3c010002, 0x220821, 0xac308ff0, -0x8fbf002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, -0x3e00008, 0x27bd0030, 0x0, 0x1821, -0x308400ff, 0x2405ffdf, 0x2406ffbf, 0x641007, -0x30420001, 0x10400004, 0x0, 0x8f820044, -0x10000003, 0x34420040, 0x8f820044, 0x461024, -0xaf820044, 0x8f820044, 0x34420020, 0xaf820044, -0x8f820044, 0x451024, 0xaf820044, 0x24630001, -0x28620008, 0x5440ffee, 0x641007, 0x3e00008, -0x0, 0x2c820008, 0x1040001b, 0x0, -0x2405ffdf, 0x2406ffbf, 0x41880, 0x3c020001, -0x24426e60, 0x621821, 0x24640004, 0x90620000, -0x10400004, 0x0, 0x8f820044, 0x10000003, -0x34420040, 0x8f820044, 0x461024, 0xaf820044, -0x8f820044, 0x34420020, 0xaf820044, 0x8f820044, -0x451024, 0xaf820044, 0x24630001, 0x64102b, -0x1440ffee, 0x0, 0x3e00008, 0x0, -0x0, 0x0, 0x0, 0x8f8400c4, -0x8f8600e0, 0x8f8700e4, 0x2402fff8, 0xc22824, -0x10e5001a, 0x27623ff8, 0x14e20002, 0x24e80008, -0x27683000, 0x55050004, 0x8d0a0000, 0x30c20004, -0x14400012, 0x805021, 0x8ce90000, 0x8f42013c, -0x1494823, 0x49182b, 0x94eb0006, 0x10600002, -0x25630050, 0x494821, 0x123182b, 0x50400003, -0x8f4201fc, 0x3e00008, 0xe01021, 0xaf8800e8, -0x24420001, 0xaf4201fc, 0xaf8800e4, 0x3e00008, -0x1021, 0x3e00008, 0x0, 0x8f8300e4, -0x27623ff8, 0x10620004, 0x24620008, 0xaf8200e8, -0x3e00008, 0xaf8200e4, 0x27623000, 0xaf8200e8, -0x3e00008, 0xaf8200e4, 0x3e00008, 0x0, -0x0, 0x0, 0x0, 0x8f880120, -0x27624fe0, 0x8f830128, 0x15020002, 0x25090020, -0x27694800, 0x11230012, 0x8fa20010, 0xad040000, -0xad050004, 0xad060008, 0xa507000e, 0x8fa30014, -0xad020018, 0x8fa20018, 0xad03001c, 0x25030016, -0xad020010, 0xad030014, 0xaf890120, 0x8f4300fc, -0x24020001, 0x2463ffff, 0x3e00008, 0xaf4300fc, -0x8f430324, 0x1021, 0x24630001, 0x3e00008, -0xaf430324, 0x3e00008, 0x0, 0x8f880100, -0x276247e0, 0x8f830108, 0x15020002, 0x25090020, -0x27694000, 0x1123000f, 0x8fa20010, 0xad040000, -0xad050004, 0xad060008, 0xa507000e, 0x8fa30014, -0xad020018, 0x8fa20018, 0xad03001c, 0x25030016, -0xad020010, 0xad030014, 0xaf890100, 0x3e00008, -0x24020001, 0x8f430328, 0x1021, 0x24630001, -0x3e00008, 0xaf430328, 0x3e00008, 0x0, -0x0, 0x0, 0x0, 0x0 }; -static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { -0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f6677, 0x6d61696e, 0x2e632c76, 0x20312e31, -0x2e322e34, 0x35203139, 0x39392f30, 0x312f3234, -0x2030303a, 0x31303a35, 0x35207368, 0x75616e67, -0x20457870, 0x20240000, 0x65767452, 0x6e674600, -0x51657674, 0x46000000, 0x51657674, 0x505f4600, -0x4d657674, 0x526e6746, 0x0, 0x4d516576, -0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, -0x6e495f46, 0x0, 0x5173436f, 0x6e734600, -0x51725072, 0x6f644600, 0x6261644d, 0x656d537a, -0x0, 0x68775665, 0x72000000, 0x62616448, -0x77566572, 0x0, 0x2a2a4441, 0x574e5f41, -0x0, 0x74785278, 0x4266537a, 0x0, -0x62664174, 0x6e4d726b, 0x0, 0x7265645a, -0x6f6e6531, 0x0, 0x70636943, 0x6f6e6600, -0x67656e43, 0x6f6e6600, 0x2a646d61, 0x5244666c, -0x0, 0x2a50414e, 0x49432a00, 0x2e2e2f2e, -0x2e2f2e2e, 0x2f2e2e2f, 0x2e2e2f73, 0x72632f6e, -0x69632f66, 0x77322f63, 0x6f6d6d6f, 0x6e2f6677, -0x6d61696e, 0x2e630000, 0x72636246, 0x6c616773, -0x0, 0x62616452, 0x78526362, 0x0, -0x676c6f62, 0x466c6773, 0x0, 0x2b5f6469, -0x73705f6c, 0x6f6f7000, 0x2b65765f, 0x68616e64, -0x6c657200, 0x63616e74, 0x31446d61, 0x0, -0x2b715f64, 0x6d615f74, 0x6f5f6e69, 0x635f636b, -0x73756d00, 0x2b685f73, 0x656e645f, 0x64617461, -0x5f726561, 0x64795f63, 0x6b73756d, 0x0, -0x2b685f64, 0x6d615f72, 0x645f6173, 0x73697374, -0x5f636b73, 0x756d0000, 0x74436b73, 0x6d4f6e00, -0x2b715f64, 0x6d615f74, 0x6f5f6e69, 0x63000000, -0x2b685f73, 0x656e645f, 0x64617461, 0x5f726561, -0x64790000, 0x2b685f64, 0x6d615f72, 0x645f6173, -0x73697374, 0x0, 0x74436b73, 0x6d4f6666, -0x0, 0x2b685f73, 0x656e645f, 0x62645f72, -0x65616479, 0x0, 0x68737453, 0x52696e67, -0x0, 0x62616453, 0x52696e67, 0x0, -0x6e696353, 0x52696e67, 0x0, 0x77446d61, -0x416c6c41, 0x0, 0x2b715f64, 0x6d615f74, -0x6f5f686f, 0x73745f63, 0x6b73756d, 0x0, -0x2b685f6d, 0x61635f72, 0x785f636f, 0x6d705f63, -0x6b73756d, 0x0, 0x2b685f64, 0x6d615f77, -0x725f6173, 0x73697374, 0x5f636b73, 0x756d0000, -0x72436b73, 0x6d4f6e00, 0x2b715f64, 0x6d615f74, -0x6f5f686f, 0x73740000, 0x2b685f6d, 0x61635f72, -0x785f636f, 0x6d700000, 0x2b685f64, 0x6d615f77, -0x725f6173, 0x73697374, 0x0, 0x72436b73, -0x6d4f6666, 0x0, 0x2b685f72, 0x6563765f, -0x62645f72, 0x65616479, 0x0, 0x2b685f72, -0x6563765f, 0x6a756d62, 0x6f5f6264, 0x5f726561, -0x64790000, 0x2b685f72, 0x6563765f, 0x6d696e69, -0x5f62645f, 0x72656164, 0x79000000, 0x2b6d685f, -0x636f6d6d, 0x616e6400, 0x2b685f74, 0x696d6572, -0x0, 0x2b685f64, 0x6f5f7570, 0x64617465, -0x5f74785f, 0x636f6e73, 0x0, 0x2b685f64, -0x6f5f7570, 0x64617465, 0x5f72785f, 0x70726f64, -0x0, 0x2b636b73, 0x756d3136, 0x0, -0x2b706565, 0x6b5f6d61, 0x635f7278, 0x5f776100, -0x2b706565, 0x6b5f6d61, 0x635f7278, 0x0, -0x2b646571, 0x5f6d6163, 0x5f727800, 0x2b685f6d, -0x61635f72, 0x785f6174, 0x746e0000, 0x62616452, -0x6574537a, 0x0, 0x72784264, 0x4266537a, -0x0, 0x2b6e756c, 0x6c5f6861, 0x6e646c65, -0x72000000, 0x66774f70, 0x4661696c, 0x0, -0x2b685f75, 0x70646174, 0x655f6c65, 0x64340000, -0x2b685f75, 0x70646174, 0x655f6c65, 0x64360000, -0x2b685f75, 0x70646174, 0x655f6c65, 0x64320000, -0x696e7453, 0x74617465, 0x0, 0x2a2a696e, -0x69744370, 0x0, 0x23736372, 0x65616d00, -0x69537461, 0x636b4572, 0x0, 0x70726f62, -0x654d656d, 0x0, 0x2a2a4441, 0x574e5f42, -0x0, 0x2b73775f, 0x646d615f, 0x61737369, -0x73745f70, 0x6c75735f, 0x74696d65, 0x72000000, -0x2b267072, 0x656c6f61, 0x645f7772, 0x5f646573, -0x63720000, 0x2b267072, 0x656c6f61, 0x645f7264, -0x5f646573, 0x63720000, 0x2b685f68, 0x665f7469, -0x6d657200, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f7469, 0x6d65722e, 0x632c7620, 0x312e312e, -0x322e3335, 0x20313939, 0x392f3031, 0x2f323720, -0x31393a30, 0x393a3530, 0x20686179, 0x65732045, -0x78702024, 0x0, 0x65767452, 0x6e674600, -0x51657674, 0x46000000, 0x51657674, 0x505f4600, -0x4d657674, 0x526e6746, 0x0, 0x4d516576, -0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, -0x6e495f46, 0x0, 0x5173436f, 0x6e734600, -0x51725072, 0x6f644600, 0x542d446d, 0x61526432, -0x0, 0x542d446d, 0x61526431, 0x0, -0x542d446d, 0x61526442, 0x0, 0x542d446d, -0x61577232, 0x0, 0x542d446d, 0x61577231, -0x0, 0x542d446d, 0x61577242, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f636f, 0x6d6d616e, 0x642e632c, 0x7620312e, -0x312e322e, 0x32382031, 0x3939392f, 0x30312f32, -0x30203139, 0x3a34393a, 0x34392073, 0x6875616e, -0x67204578, 0x70202400, 0x65767452, 0x6e674600, -0x51657674, 0x46000000, 0x51657674, 0x505f4600, -0x4d657674, 0x526e6746, 0x0, 0x4d516576, -0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, -0x6e495f46, 0x0, 0x5173436f, 0x6e734600, -0x51725072, 0x6f644600, 0x3f48636d, 0x644d6278, -0x0, 0x3f636d64, 0x48737453, 0x0, -0x3f636d64, 0x4d634d64, 0x0, 0x3f636d64, -0x50726f6d, 0x0, 0x3f636d64, 0x4c696e6b, -0x0, 0x3f636d64, 0x45727200, 0x86ac, -0x8e5c, 0x8e5c, 0x8de4, 0x8b78, -0x8e30, 0x8e5c, 0x8790, 0x8800, -0x8990, 0x8a68, 0x8a34, 0x8e5c, -0x8870, 0x8b24, 0x8e5c, 0x8b34, -0x87b4, 0x8824, 0x0, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f6d63, 0x6173742e, 0x632c7620, 0x312e312e, -0x322e3820, 0x31393938, 0x2f31322f, 0x30382030, -0x323a3336, 0x3a333620, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x65767452, 0x6e674600, -0x51657674, 0x46000000, 0x51657674, 0x505f4600, -0x4d657674, 0x526e6746, 0x0, 0x4d516576, -0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, -0x6e495f46, 0x0, 0x5173436f, 0x6e734600, -0x51725072, 0x6f644600, 0x6164644d, 0x63447570, -0x0, 0x6164644d, 0x6346756c, 0x0, -0x64656c4d, 0x634e6f45, 0x0, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f646d, 0x612e632c, 0x7620312e, 0x312e322e, -0x32342031, 0x3939382f, 0x31322f32, 0x31203030, -0x3a33333a, 0x30392073, 0x6875616e, 0x67204578, -0x70202400, 0x65767452, 0x6e674600, 0x51657674, -0x46000000, 0x51657674, 0x505f4600, 0x4d657674, -0x526e6746, 0x0, 0x4d516576, 0x74460000, -0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, -0x0, 0x5173436f, 0x6e734600, 0x51725072, -0x6f644600, 0x7377446d, 0x614f6666, 0x0, -0x31446d61, 0x4f6e0000, 0x7377446d, 0x614f6e00, -0x2372446d, 0x6141544e, 0x0, 0x72446d61, -0x41544e30, 0x0, 0x72446d61, 0x41544e31, -0x0, 0x72446d61, 0x34476200, 0x2a50414e, -0x49432a00, 0x2e2e2f2e, 0x2e2f2e2e, 0x2f2e2e2f, -0x2e2e2f73, 0x72632f6e, 0x69632f66, 0x77322f63, -0x6f6d6d6f, 0x6e2f646d, 0x612e6300, 0x2377446d, -0x6141544e, 0x0, 0x77446d61, 0x41544e30, -0x0, 0x77446d61, 0x41544e31, 0x0, -0x77446d61, 0x34476200, 0x0, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f7472, 0x6163652e, 0x632c7620, 0x312e312e, -0x322e3520, 0x31393938, 0x2f30392f, 0x33302031, -0x383a3530, 0x3a323820, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x0, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f6461, 0x74612e63, 0x2c762031, 0x2e312e32, -0x2e313220, 0x31393939, 0x2f30312f, 0x32302031, -0x393a3439, 0x3a353120, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x46575f56, 0x45525349, -0x4f4e3a20, 0x23312046, 0x72692041, 0x70722037, -0x2031373a, 0x35373a35, 0x32205044, 0x54203230, -0x30300000, 0x46575f43, 0x4f4d5049, 0x4c455f54, -0x494d453a, 0x2031373a, 0x35373a35, 0x32000000, -0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064, -0x65767263, 0x73000000, 0x46575f43, 0x4f4d5049, -0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465, -0x0, 0x46575f43, 0x4f4d5049, 0x4c455f44, -0x4f4d4149, 0x4e3a2065, 0x6e672e61, 0x6374656f, -0x6e2e636f, 0x6d000000, 0x46575f43, 0x4f4d5049, -0x4c45523a, 0x20676363, 0x20766572, 0x73696f6e, -0x20322e37, 0x2e320000, 0x0, 0x12041100, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f6d65, 0x6d2e632c, 0x7620312e, 0x312e322e, -0x35203139, 0x39382f30, 0x392f3330, 0x2031383a, -0x35303a30, 0x38207368, 0x75616e67, 0x20457870, -0x20240000, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f7365, 0x6e642e63, 0x2c762031, 0x2e312e32, -0x2e343420, 0x31393938, 0x2f31322f, 0x32312030, -0x303a3333, 0x3a313820, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x65767452, 0x6e674600, -0x51657674, 0x46000000, 0x51657674, 0x505f4600, -0x4d657674, 0x526e6746, 0x0, 0x4d516576, -0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, -0x6e495f46, 0x0, 0x5173436f, 0x6e734600, -0x51725072, 0x6f644600, 0x69736e74, 0x54637055, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f7265, 0x63762e63, 0x2c762031, 0x2e312e32, -0x2e353320, 0x31393939, 0x2f30312f, 0x31362030, -0x323a3535, 0x3a343320, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x65767452, 0x6e674600, -0x51657674, 0x46000000, 0x51657674, 0x505f4600, -0x4d657674, 0x526e6746, 0x0, 0x4d516576, -0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, -0x6e495f46, 0x0, 0x5173436f, 0x6e734600, -0x51725072, 0x6f644600, 0x724d6163, 0x43686b30, -0x0, 0x72784672, 0x6d324c67, 0x0, -0x72784e6f, 0x53744264, 0x0, 0x72784e6f, -0x4d694264, 0x0, 0x72784e6f, 0x4a6d4264, -0x0, 0x7278436b, 0x446d6146, 0x0, -0x72785144, 0x6d457846, 0x0, 0x72785144, -0x6d614600, 0x72785144, 0x4c426446, 0x0, -0x72785144, 0x6d426446, 0x0, 0x72784372, -0x63506164, 0x0, 0x72536d51, 0x446d6146, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f6d61, 0x632e632c, 0x7620312e, 0x312e322e, -0x32322031, 0x3939382f, 0x31322f30, 0x38203032, -0x3a33363a, 0x33302073, 0x6875616e, 0x67204578, -0x70202400, 0x65767452, 0x6e674600, 0x51657674, -0x46000000, 0x51657674, 0x505f4600, 0x4d657674, -0x526e6746, 0x0, 0x4d516576, 0x74460000, -0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46, -0x0, 0x5173436f, 0x6e734600, 0x51725072, -0x6f644600, 0x6d616354, 0x68726573, 0x0, -0x23744d61, 0x6341544e, 0x0, 0x23724d61, -0x6341544e, 0x0, 0x72656d41, 0x73737274, -0x0, 0x6c696e6b, 0x444f574e, 0x0, -0x6c696e6b, 0x55500000, 0x0, 0x0, -0x0, 0x24486561, 0x6465723a, 0x202f7072, -0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, -0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, -0x6e2f636b, 0x73756d2e, 0x632c7620, 0x312e312e, -0x322e3920, 0x31393939, 0x2f30312f, 0x31342030, -0x303a3033, 0x3a343820, 0x73687561, 0x6e672045, -0x78702024, 0x0, 0x65767452, 0x6e674600, -0x51657674, 0x46000000, 0x51657674, 0x505f4600, -0x4d657674, 0x526e6746, 0x0, 0x4d516576, -0x74460000, 0x4d516576, 0x505f4600, 0x5173436f, -0x6e495f46, 0x0, 0x5173436f, 0x6e734600, -0x51725072, 0x6f644600, 0x0, 0x0, -0x0, 0x50726f62, 0x65506879, 0x0, -0x6c6e6b41, 0x53535254, 0x0, 0x109a4, -0x10a1c, 0x10a50, 0x10a7c, 0x11050, -0x10aa8, 0x10b10, 0x111fc, 0x10dc0, -0x10c68, 0x10c80, 0x10cc4, 0x10cec, -0x10d0c, 0x10d34, 0x111fc, 0x10dc0, -0x10df8, 0x10e10, 0x10e40, 0x10e68, -0x10e88, 0x10eb0, 0x0, 0x10fdc, -0x11008, 0x1102c, 0x111fc, 0x11050, -0x11078, 0x11108, 0x0, 0x0, -0x0, 0x1186c, 0x1193c, 0x11a14, -0x11ae4, 0x11b40, 0x11c1c, 0x11c44, -0x11d20, 0x11d48, 0x11ef0, 0x11f18, -0x120c0, 0x122b8, 0x1254c, 0x12460, -0x1254c, 0x12578, 0x120e8, 0x12290, -0x7273745f, 0x676d6969, 0x0, 0x12608, -0x12640, 0x12728, 0x13374, 0x133b4, -0x133cc, 0x7365746c, 0x6f6f7000, 0x0, -0x0, 0x13bbc, 0x13bfc, 0x13c8c, -0x13cd0, 0x13d34, 0x13dc0, 0x13df4, -0x13e7c, 0x13f14, 0x13fe4, 0x14024, -0x140a8, 0x140cc, 0x141dc, 0x646f4261, -0x73655067, 0x0, 0x0, 0x0, -0x0, 0x73746d61, 0x634c4e4b, 0x0, -0x6765746d, 0x636c6e6b, 0x0, 0x14ed8, -0x14ed8, 0x14b8c, 0x14bd8, 0x14c24, -0x14ed8, 0x7365746d, 0x61636163, 0x74000000, -0x0, 0x0 }; -static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { -0x1, -0x1, 0x1, 0xc001fc, 0x3ffc, -0xc00000, 0x416c7465, 0x6f6e2041, 0x63654e49, -0x43205600, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x416c7465, -0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242, -0x0, 0x0, 0x0, 0x1ffffc, -0x1fff7c, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x60cf00, -0x60, 0xcf000000, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x0, -0x0, 0x0, 0x3, 0x0, -0x1, 0x0, 0x0, 0x0, -0x1, 0x0, 0x1, 0x0, -0x0, 0x0, 0x0, 0x1, -0x1, 0x0, 0x0, 0x0, -0x0, 0x0, 0x1000000, 0x21000000, -0x12000140, 0x0, 0x0, 0x20000000, -0x120000a0, 0x0, 0x12000060, 0x12000180, -0x120001e0, 0x0, 0x0, 0x0, -0x1, 0x0, 0x0, 0x0, -0x0, 0x0, 0x0, 0x2, -0x0, 0x0, 0x30001, 0x1, -0x30201, 0x0, 0x0, 0x1010101, -0x1010100, 0x10100, 0x1010001, 0x10001, -0x1000101, 0x101, 0x0, 0x0 }; -- cgit From 025dfdafe77f20b3890981a394774baab7b9c827 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Thu, 16 Oct 2008 19:02:37 +0200 Subject: trivial: fix then -> than typos in comments and documentation - (better, more, bigger ...) then -> (...) than Signed-off-by: Frederik Schwarzer Signed-off-by: Jiri Kosina --- drivers/net/bnx2x_link.c | 2 +- drivers/net/e1000/e1000_hw.c | 4 ++-- drivers/net/slip.h | 2 +- drivers/net/tehuti.c | 4 ++-- drivers/net/tokenring/smctr.c | 2 +- drivers/net/wireless/ipw2x00/ipw2100.c | 2 +- drivers/net/wireless/rt2x00/rt2x00crypto.c | 4 ++-- drivers/net/wireless/strip.c | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index 67de94f1f30..fefa6ab1306 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -3359,7 +3359,7 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len) u8 shift = 8*4; u8 digit; if (len < 10) { - /* Need more then 10chars for this format */ + /* Need more than 10chars for this format */ *str_ptr = '\0'; return -EINVAL; } diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index d04eef53571..e1a3fc1303e 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -6758,7 +6758,7 @@ static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length, * returns: - E1000_ERR_XXX * E1000_SUCCESS * - * For phy's older then IGP, this function simply reads the polarity bit in the + * For phy's older than IGP, this function simply reads the polarity bit in the * Phy Status register. For IGP phy's, this bit is valid only if link speed is * 10 Mbps. If the link speed is 100 Mbps there is no polarity so this bit will * return 0. If the link speed is 1000 Mbps the polarity status is in the @@ -6834,7 +6834,7 @@ static s32 e1000_check_polarity(struct e1000_hw *hw, * returns: - E1000_ERR_XXX * E1000_SUCCESS * - * For phy's older then IGP, this function reads the Downshift bit in the Phy + * For phy's older than IGP, this function reads the Downshift bit in the Phy * Specific Status register. For IGP phy's, it reads the Downgrade bit in the * Link Health register. In IGP this bit is latched high, so the driver must * read it immediately after link is established. diff --git a/drivers/net/slip.h b/drivers/net/slip.h index 853e0f6ec71..9ea5c11287d 100644 --- a/drivers/net/slip.h +++ b/drivers/net/slip.h @@ -75,7 +75,7 @@ struct slip { unsigned long tx_errors; /* Planned stuff */ unsigned long rx_dropped; /* No memory for skb */ unsigned long tx_dropped; /* When MTU change */ - unsigned long rx_over_errors; /* Frame bigger then SLIP buf. */ + unsigned long rx_over_errors; /* Frame bigger than SLIP buf. */ #ifdef SL_INCLUDE_CSLIP unsigned long tx_compressed; unsigned long rx_compressed; diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index a10a83a11d9..a7a4dc4d631 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -1004,7 +1004,7 @@ static inline void bdx_rxdb_free_elem(struct rxdb *db, int n) * skb for rx. It assumes that Rx is desabled in HW * funcs are grouped for better cache usage * - * RxD fifo is smaller then RxF fifo by design. Upon high load, RxD will be + * RxD fifo is smaller than RxF fifo by design. Upon high load, RxD will be * filled and packets will be dropped by nic without getting into host or * cousing interrupt. Anyway, in that condition, host has no chance to proccess * all packets, but dropping in nic is cheaper, since it takes 0 cpu cycles @@ -1826,7 +1826,7 @@ static void bdx_tx_free(struct bdx_priv *priv) * * Pushes desc to TxD fifo and overlaps it if needed. * NOTE: this func does not check for available space. this is responsibility - * of the caller. Neither does it check that data size is smaller then + * of the caller. Neither does it check that data size is smaller than * fifo size. */ static void bdx_tx_push_desc(struct bdx_priv *priv, void *data, int size) diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index a011666342f..50eb29ce3c8 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -3064,7 +3064,7 @@ static int smctr_load_node_addr(struct net_device *dev) * will consequently cause a timeout. * * NOTE 1: If the monitor_state is MS_BEACON_TEST_STATE, all transmit - * queues other then the one used for the lobe_media_test should be + * queues other than the one used for the lobe_media_test should be * disabled.!? * * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 1667065b86a..753de1a9c4b 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1332,7 +1332,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv) IPW_AUX_HOST_RESET_REG_STOP_MASTER); /* Step 2. Wait for stop Master Assert - * (not more then 50us, otherwise ret error */ + * (not more than 50us, otherwise ret error */ i = 5; do { udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY); diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 37ad0d2fb64..aee9cba13eb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c @@ -184,8 +184,8 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, * Make room for new data, note that we increase both * headsize and tailsize when required. The tailsize is * only needed when ICV data needs to be inserted and - * the padding is smaller then the ICV data. - * When alignment requirements is greater then the + * the padding is smaller than the ICV data. + * When alignment requirements is greater than the * ICV data we must trim the skb to the correct size * because we need to remove the extra bytes. */ diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index dd0de3a9ed4..7015f248055 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -236,7 +236,7 @@ struct strip { unsigned long tx_errors; /* Planned stuff */ unsigned long rx_dropped; /* No memory for skb */ unsigned long tx_dropped; /* When MTU change */ - unsigned long rx_over_errors; /* Frame bigger then STRIP buf. */ + unsigned long rx_over_errors; /* Frame bigger than STRIP buf. */ unsigned long pps_timer; /* Timer to determine pps */ unsigned long rx_pps_count; /* Counter to determine pps */ -- cgit From d535295b16710552e9e8f9923670a95c447e842a Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Sat, 3 Jan 2009 18:51:33 +1100 Subject: trivial: Fix misspelling of "firmware" in atmel.c Fix misspelling of "firmware" in atmel.c It's spelled "firmware". Signed-off-by: Nick Andrew Signed-off-by: Jiri Kosina --- drivers/net/wireless/atmel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 350157fcd08..4223672c443 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -3836,7 +3836,7 @@ static int reset_atmel_card(struct net_device *dev) This routine is also responsible for initialising some hardware-specific fields in the atmel_private structure, including a copy of the firmware's hostinfo stucture - which is the route into the rest of the firmare datastructures. */ + which is the route into the rest of the firmware datastructures. */ struct atmel_private *priv = netdev_priv(dev); u8 configuration; -- cgit From 4407245ac5c5defa303c05828c57d7855aa7e5ee Mon Sep 17 00:00:00 2001 From: Nick Andrew Date: Sat, 3 Jan 2009 18:52:40 +1100 Subject: trivial: Fix misspelling of "firmware" in ipw2100.c Fix misspelling of "firmware" in ipw2100.c It's spelled "firmware". Signed-off-by: Nick Andrew Signed-off-by: Jiri Kosina --- drivers/net/wireless/ipw2x00/ipw2100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 753de1a9c4b..823c2bf5e31 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1830,7 +1830,7 @@ static void ipw2100_down(struct ipw2100_priv *priv) cancel_delayed_work(&priv->rf_kill); } - /* Kill the firmare hang check timer */ + /* Kill the firmware hang check timer */ if (!priv->stop_hang_check) { priv->stop_hang_check = 1; cancel_delayed_work(&priv->hang_check); -- cgit From af0490810cfa159b4894ddecfc5eb2e4432fb976 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Jan 2009 10:40:43 -0800 Subject: irda: convert to internal stats Convert IRDA drivers to use already existing net_device_stats structure in network device. This is a pre-cursor to conversion to net_device ops. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/irda/ali-ircc.c | 45 +++++++++--------------- drivers/net/irda/ali-ircc.h | 1 - drivers/net/irda/au1000_ircc.h | 1 - drivers/net/irda/au1k_ir.c | 9 ----- drivers/net/irda/donauboe.h | 1 - drivers/net/irda/irda-usb.c | 28 +++++---------- drivers/net/irda/irda-usb.h | 1 - drivers/net/irda/kingsun-sir.c | 20 +++-------- drivers/net/irda/ks959-sir.c | 22 ++++-------- drivers/net/irda/ksdazzle-sir.c | 26 +++++--------- drivers/net/irda/mcs7780.c | 49 +++++++++++--------------- drivers/net/irda/mcs7780.h | 2 -- drivers/net/irda/nsc-ircc.c | 45 ++++++++++-------------- drivers/net/irda/nsc-ircc.h | 1 - drivers/net/irda/pxaficp_ir.c | 52 ++++++++++++--------------- drivers/net/irda/sa1100_ir.c | 46 ++++++++++-------------- drivers/net/irda/sir-dev.h | 1 - drivers/net/irda/sir_dev.c | 26 +++++--------- drivers/net/irda/smsc-ircc2.c | 38 ++++++++------------ drivers/net/irda/stir4200.c | 44 +++++++++-------------- drivers/net/irda/via-ircc.c | 47 ++++++++++--------------- drivers/net/irda/via-ircc.h | 1 - drivers/net/irda/vlsi_ir.c | 78 +++++++++++++++++++---------------------- drivers/net/irda/vlsi_ir.h | 1 - drivers/net/irda/w83977af_ir.c | 35 +++++++----------- drivers/net/irda/w83977af_ir.h | 1 - 26 files changed, 230 insertions(+), 391 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 3c58e67ef1e..17779f9bffc 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -109,7 +109,6 @@ static int ali_ircc_net_open(struct net_device *dev); static int ali_ircc_net_close(struct net_device *dev); static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud); -static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev); /* SIR function */ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev); @@ -366,7 +365,6 @@ static int ali_ircc_open(int i, chipio_t *info) dev->open = ali_ircc_net_open; dev->stop = ali_ircc_net_close; dev->do_ioctl = ali_ircc_net_ioctl; - dev->get_stats = ali_ircc_net_get_stats; err = register_netdev(dev); if (err) { @@ -876,7 +874,7 @@ static void ali_ircc_sir_receive(struct ali_ircc_cb *self) * async_unwrap_char will deliver all found frames */ do { - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, + async_unwrap_char(self->netdev, &self->netdev->stats, &self->rx_buff, inb(iobase+UART_RX)); /* Make sure we don't stay here too long */ @@ -943,7 +941,7 @@ static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self) netif_wake_queue(self->netdev); } - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; /* Turn on receive interrupts */ outb(UART_IER_RDI, iobase+UART_IER); @@ -1467,7 +1465,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev) self->tx_fifo.queue[self->tx_fifo.free].len = skb->len; self->tx_fifo.tail += skb->len; - self->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; skb_copy_from_linear_data(skb, self->tx_fifo.queue[self->tx_fifo.free].start, skb->len); @@ -1661,12 +1659,12 @@ static int ali_ircc_dma_xmit_complete(struct ali_ircc_cb *self) { IRDA_ERROR("%s(), ********* LSR_FRAME_ABORT *********\n", __func__); - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; } else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; } /* Check if we need to change the speed */ @@ -1831,35 +1829,35 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) IRDA_DEBUG(0,"%s(), ************* RX Errors ************ \n", __func__ ); /* Skip frame */ - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; self->rx_buff.data += len; if (status & LSR_FIFO_UR) { - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; IRDA_DEBUG(0,"%s(), ************* FIFO Errors ************ \n", __func__ ); } if (status & LSR_FRAME_ERROR) { - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; IRDA_DEBUG(0,"%s(), ************* FRAME Errors ************ \n", __func__ ); } if (status & LSR_CRC_ERROR) { - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; IRDA_DEBUG(0,"%s(), ************* CRC Errors ************ \n", __func__ ); } if(self->rcvFramesOverflow) { - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; IRDA_DEBUG(0,"%s(), ************* Overran DMA buffer ************ \n", __func__ ); } if(len == 0) { - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; IRDA_DEBUG(0,"%s(), ********** Receive Frame Size = 0 ********* \n", __func__ ); } } @@ -1910,7 +1908,7 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) IRDA_WARNING("%s(), memory squeeze, " "dropping frame.\n", __func__); - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; return FALSE; } @@ -1924,8 +1922,8 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self) /* Move to next frame */ self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); @@ -1994,7 +1992,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev) self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + self->netdev->stats.tx_bytes += self->tx_buff.len; /* Turn on transmit finished interrupt. Will fire immediately! */ outb(UART_IER_THRI, iobase+UART_IER); @@ -2111,17 +2109,6 @@ static int ali_ircc_is_receiving(struct ali_ircc_cb *self) return status; } -static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev) -{ - struct ali_ircc_cb *self = netdev_priv(dev); - - IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ ); - - IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ ); - - return &self->stats; -} - static int ali_ircc_suspend(struct platform_device *dev, pm_message_t state) { struct ali_ircc_cb *self = platform_get_drvdata(dev); diff --git a/drivers/net/irda/ali-ircc.h b/drivers/net/irda/ali-ircc.h index ed35d99763d..0c8edb41bd0 100644 --- a/drivers/net/irda/ali-ircc.h +++ b/drivers/net/irda/ali-ircc.h @@ -191,7 +191,6 @@ struct ali_ircc_cb { struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ diff --git a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h index b4763f24dde..c072c09a8d9 100644 --- a/drivers/net/irda/au1000_ircc.h +++ b/drivers/net/irda/au1000_ircc.h @@ -107,7 +107,6 @@ struct au1k_private { iobuff_t rx_buff; struct net_device *netdev; - struct net_device_stats stats; struct timeval stamp; struct timeval now; diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 6c4b53ffbca..75a1d0a86de 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -53,7 +53,6 @@ static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *); static int au1k_irda_rx(struct net_device *); static void au1k_irda_interrupt(int, void *); static void au1k_tx_timeout(struct net_device *); -static struct net_device_stats *au1k_irda_stats(struct net_device *); static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int); static int au1k_irda_set_speed(struct net_device *dev, int speed); @@ -213,7 +212,6 @@ static int au1k_irda_net_init(struct net_device *dev) dev->open = au1k_irda_start; dev->hard_start_xmit = au1k_irda_hard_xmit; dev->stop = au1k_irda_stop; - dev->get_stats = au1k_irda_stats; dev->do_ioctl = au1k_irda_ioctl; dev->tx_timeout = au1k_tx_timeout; @@ -832,13 +830,6 @@ au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) return ret; } - -static struct net_device_stats *au1k_irda_stats(struct net_device *dev) -{ - struct au1k_private *aup = netdev_priv(dev); - return &aup->stats; -} - MODULE_AUTHOR("Pete Popov "); MODULE_DESCRIPTION("Au1000 IrDA Device Driver"); diff --git a/drivers/net/irda/donauboe.h b/drivers/net/irda/donauboe.h index 1e67720f106..0dbd1932b72 100644 --- a/drivers/net/irda/donauboe.h +++ b/drivers/net/irda/donauboe.h @@ -308,7 +308,6 @@ struct OboeRing struct toshoboe_cb { struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct tty_driver ttydev; struct irlap_cb *irlap; /* The link layer we are binded to */ diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 205e4e825a9..29118f58a14 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -122,7 +122,6 @@ static int irda_usb_net_open(struct net_device *dev); static int irda_usb_net_close(struct net_device *dev); static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void irda_usb_net_timeout(struct net_device *dev); -static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev); /************************ TRANSMIT ROUTINES ************************/ /* @@ -525,13 +524,13 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) /* Ask USB to send the packet - Irq disabled -> GFP_ATOMIC */ if ((res = usb_submit_urb(urb, GFP_ATOMIC))) { IRDA_WARNING("%s(), failed Tx URB\n", __func__); - self->stats.tx_errors++; + netdev->stats.tx_errors++; /* Let USB recover : We will catch that in the watchdog */ /*netif_start_queue(netdev);*/ } else { /* Increment packet stats */ - self->stats.tx_packets++; - self->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; netdev->trans_start = jiffies; } @@ -677,7 +676,7 @@ static void irda_usb_net_timeout(struct net_device *netdev) IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, urb->status, urb->transfer_flags); /* Increase error count */ - self->stats.tx_errors++; + netdev->stats.tx_errors++; #ifdef IU_BUG_KICK_TIMEOUT /* Can't be a bad idea to reset the speed ;-) - Jean II */ @@ -826,7 +825,7 @@ static void irda_usb_receive(struct urb *urb) if (urb->status != 0) { switch (urb->status) { case -EILSEQ: - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; /* Also precursor to a hot-unplug on UHCI. */ /* Fallthrough... */ case -ECONNRESET: @@ -839,7 +838,7 @@ static void irda_usb_receive(struct urb *urb) case -ETIME: /* Usually precursor to a hot-unplug on OHCI. */ default: - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; IRDA_DEBUG(0, "%s(), RX status %d, transfer_flags 0x%04X \n", __func__, urb->status, urb->transfer_flags); break; } @@ -890,7 +889,7 @@ static void irda_usb_receive(struct urb *urb) IRDA_SKB_MAX_MTU); if (!newskb) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; /* We could deliver the current skb, but this would stall * the Rx path. Better drop the packet... Jean II */ goto done; @@ -927,8 +926,8 @@ static void irda_usb_receive(struct urb *urb) netif_rx(dataskb); /* Keep stats up to date */ - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; done: /* Note : at this point, the URB we've just received (urb) @@ -1342,14 +1341,6 @@ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } /*------------------------------------------------------------------*/ -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev) -{ - struct irda_usb_cb *self = netdev_priv(dev); - return &self->stats; -} /********************* IRDA CONFIG SUBROUTINES *********************/ /* @@ -1428,7 +1419,6 @@ static inline int irda_usb_open(struct irda_usb_cb *self) netdev->watchdog_timeo = 250*HZ/1000; /* 250 ms > USB timeout */ netdev->open = irda_usb_net_open; netdev->stop = irda_usb_net_close; - netdev->get_stats = irda_usb_net_get_stats; netdev->do_ioctl = irda_usb_net_ioctl; return register_netdev(netdev); diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index a0ca9c1fe19..ac0443d52e5 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h @@ -152,7 +152,6 @@ struct irda_usb_cb { struct urb *speed_urb; /* URB used to send speed commands */ struct net_device *netdev; /* Yes! we are some kind of netdev. */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; char *speed_buff; /* Buffer for speed changes */ diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c index c747c874d44..b4a61717254 100644 --- a/drivers/net/irda/kingsun-sir.c +++ b/drivers/net/irda/kingsun-sir.c @@ -105,7 +105,7 @@ struct kingsun_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ - struct net_device_stats stats; /* network statistics */ + struct qos_info qos; __u8 *in_buf; /* receive buffer */ @@ -186,12 +186,12 @@ static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev) case -EPIPE: break; default: - kingsun->stats.tx_errors++; + netdev->stats.tx_errors++; netif_start_queue(netdev); } } else { - kingsun->stats.tx_packets++; - kingsun->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; } dev_kfree_skb(skb); @@ -232,7 +232,7 @@ static void kingsun_rcv_irq(struct urb *urb) if (bytes[0] >= 1 && bytes[0] < kingsun->max_rx) { for (i = 1; i <= bytes[0]; i++) { async_unwrap_char(kingsun->netdev, - &kingsun->stats, + &kingsun->netdev->stats, &kingsun->rx_buff, bytes[i]); } do_gettimeofday(&kingsun->rx_time); @@ -418,15 +418,6 @@ static int kingsun_net_ioctl(struct net_device *netdev, struct ifreq *rq, return ret; } -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats * -kingsun_net_get_stats(struct net_device *netdev) -{ - struct kingsun_cb *kingsun = netdev_priv(netdev); - return &kingsun->stats; -} /* * This routine is called by the USB subsystem for each new device @@ -532,7 +523,6 @@ static int kingsun_probe(struct usb_interface *intf, net->hard_start_xmit = kingsun_hard_xmit; net->open = kingsun_net_open; net->stop = kingsun_net_close; - net->get_stats = kingsun_net_get_stats; net->do_ioctl = kingsun_net_ioctl; ret = register_netdev(net); diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c index 600d96f9cdb..55322fb92cf 100644 --- a/drivers/net/irda/ks959-sir.c +++ b/drivers/net/irda/ks959-sir.c @@ -174,7 +174,7 @@ struct ks959_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ - struct net_device_stats stats; /* network statistics */ + struct qos_info qos; struct usb_ctrlrequest *tx_setuprequest; @@ -366,7 +366,7 @@ static void ks959_send_irq(struct urb *urb) case -EPIPE: break; default: - kingsun->stats.tx_errors++; + netdev->stats.tx_errors++; netif_start_queue(netdev); } } @@ -416,12 +416,12 @@ static int ks959_hard_xmit(struct sk_buff *skb, struct net_device *netdev) case -EPIPE: break; default: - kingsun->stats.tx_errors++; + netdev->stats.tx_errors++; netif_start_queue(netdev); } } else { - kingsun->stats.tx_packets++; - kingsun->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; } @@ -469,7 +469,7 @@ static void ks959_rcv_irq(struct urb *urb) */ if (kingsun->rx_variable_xormask != 0) { async_unwrap_char(kingsun->netdev, - &kingsun->stats, + &kingsun->netdev->stats, &kingsun->rx_unwrap_buff, bytes[i]); } @@ -668,15 +668,6 @@ static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) return ret; } -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats *ks959_net_get_stats(struct net_device *netdev) -{ - struct ks959_cb *kingsun = netdev_priv(netdev); - return &kingsun->stats; -} - /* * This routine is called by the USB subsystem for each new device * in the system. We need to check if the device is ours, and in @@ -792,7 +783,6 @@ static int ks959_probe(struct usb_interface *intf, net->hard_start_xmit = ks959_hard_xmit; net->open = ks959_net_open; net->stop = ks959_net_close; - net->get_stats = ks959_net_get_stats; net->do_ioctl = ks959_net_ioctl; ret = register_netdev(net); diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c index 0e7f89337b2..5b327b09acd 100644 --- a/drivers/net/irda/ksdazzle-sir.c +++ b/drivers/net/irda/ksdazzle-sir.c @@ -140,7 +140,7 @@ struct ksdazzle_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ - struct net_device_stats stats; /* network statistics */ + struct qos_info qos; struct urb *tx_urb; @@ -278,7 +278,7 @@ static void ksdazzle_send_irq(struct urb *urb) case -EPIPE: break; default: - kingsun->stats.tx_errors++; + netdev->stats.tx_errors++; netif_start_queue(netdev); } } @@ -329,12 +329,12 @@ static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev) case -EPIPE: break; default: - kingsun->stats.tx_errors++; + netdev->stats.tx_errors++; netif_start_queue(netdev); } } else { - kingsun->stats.tx_packets++; - kingsun->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; } @@ -348,9 +348,10 @@ static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev) static void ksdazzle_rcv_irq(struct urb *urb) { struct ksdazzle_cb *kingsun = urb->context; + struct net_device *netdev = kingsun->netdev; /* in process of stopping, just drop data */ - if (!netif_running(kingsun->netdev)) { + if (!netif_running(netdev)) { kingsun->receiving = 0; return; } @@ -368,7 +369,7 @@ static void ksdazzle_rcv_irq(struct urb *urb) unsigned int i; for (i = 0; i < urb->actual_length; i++) { - async_unwrap_char(kingsun->netdev, &kingsun->stats, + async_unwrap_char(netdev, &netdev->stats, &kingsun->rx_unwrap_buff, bytes[i]); } kingsun->receiving = @@ -561,16 +562,6 @@ static int ksdazzle_net_ioctl(struct net_device *netdev, struct ifreq *rq, return ret; } -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats *ksdazzle_net_get_stats(struct net_device - *netdev) -{ - struct ksdazzle_cb *kingsun = netdev_priv(netdev); - return &kingsun->stats; -} - /* * This routine is called by the USB subsystem for each new device * in the system. We need to check if the device is ours, and in @@ -696,7 +687,6 @@ static int ksdazzle_probe(struct usb_interface *intf, net->hard_start_xmit = ksdazzle_hard_xmit; net->open = ksdazzle_net_open; net->stop = ksdazzle_net_close; - net->get_stats = ksdazzle_net_get_stats; net->do_ioctl = ksdazzle_net_ioctl; ret = register_netdev(net); diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index 904c9610c0d..7eafdca19f3 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -403,8 +403,8 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) if(unlikely(new_len <= 0)) { IRDA_ERROR("%s short frame length %d\n", mcs->netdev->name, new_len); - ++mcs->stats.rx_errors; - ++mcs->stats.rx_length_errors; + ++mcs->netdev->stats.rx_errors; + ++mcs->netdev->stats.rx_length_errors; return; } fcs = 0; @@ -413,14 +413,14 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) if(fcs != GOOD_FCS) { IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len); - mcs->stats.rx_errors++; - mcs->stats.rx_crc_errors++; + mcs->netdev->stats.rx_errors++; + mcs->netdev->stats.rx_crc_errors++; return; } skb = dev_alloc_skb(new_len + 1); if(unlikely(!skb)) { - ++mcs->stats.rx_dropped; + ++mcs->netdev->stats.rx_dropped; return; } @@ -433,8 +433,8 @@ static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len) netif_rx(skb); - mcs->stats.rx_packets++; - mcs->stats.rx_bytes += new_len; + mcs->netdev->stats.rx_packets++; + mcs->netdev->stats.rx_bytes += new_len; return; } @@ -458,22 +458,22 @@ static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len) if(unlikely(new_len <= 0)) { IRDA_ERROR("%s short frame length %d\n", mcs->netdev->name, new_len); - ++mcs->stats.rx_errors; - ++mcs->stats.rx_length_errors; + ++mcs->netdev->stats.rx_errors; + ++mcs->netdev->stats.rx_length_errors; return; } fcs = ~(crc32_le(~0, buf, new_len)); if(fcs != get_unaligned_le32(buf + new_len)) { IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len); - mcs->stats.rx_errors++; - mcs->stats.rx_crc_errors++; + mcs->netdev->stats.rx_errors++; + mcs->netdev->stats.rx_crc_errors++; return; } skb = dev_alloc_skb(new_len + 1); if(unlikely(!skb)) { - ++mcs->stats.rx_dropped; + ++mcs->netdev->stats.rx_dropped; return; } @@ -486,8 +486,8 @@ static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len) netif_rx(skb); - mcs->stats.rx_packets++; - mcs->stats.rx_bytes += new_len; + mcs->netdev->stats.rx_packets++; + mcs->netdev->stats.rx_bytes += new_len; return; } @@ -756,14 +756,6 @@ static int mcs_net_open(struct net_device *netdev) return ret; } - -/* Get device stats for /proc/net/dev and ifconfig */ -static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev) -{ - struct mcs_cb *mcs = netdev_priv(netdev); - return &mcs->stats; -} - /* Receive callback function. */ static void mcs_receive_irq(struct urb *urb) { @@ -786,14 +778,14 @@ static void mcs_receive_irq(struct urb *urb) */ /* SIR speed */ if(mcs->speed < 576000) { - async_unwrap_char(mcs->netdev, &mcs->stats, + async_unwrap_char(mcs->netdev, &mcs->netdev->stats, &mcs->rx_buff, 0xc0); for (i = 0; i < urb->actual_length; i++) - async_unwrap_char(mcs->netdev, &mcs->stats, + async_unwrap_char(mcs->netdev, &mcs->netdev->stats, &mcs->rx_buff, bytes[i]); - async_unwrap_char(mcs->netdev, &mcs->stats, + async_unwrap_char(mcs->netdev, &mcs->netdev->stats, &mcs->rx_buff, 0xc1); } /* MIR speed */ @@ -868,12 +860,12 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev) case -EPIPE: break; default: - mcs->stats.tx_errors++; + mcs->netdev->stats.tx_errors++; netif_start_queue(ndev); } } else { - mcs->stats.tx_packets++; - mcs->stats.tx_bytes += skb->len; + mcs->netdev->stats.tx_packets++; + mcs->netdev->stats.tx_bytes += skb->len; } dev_kfree_skb(skb); @@ -931,7 +923,6 @@ static int mcs_probe(struct usb_interface *intf, ndev->hard_start_xmit = mcs_hard_xmit; ndev->open = mcs_net_open; ndev->stop = mcs_net_close; - ndev->get_stats = mcs_net_get_stats; ndev->do_ioctl = mcs_net_ioctl; if (!intf->cur_altsetting) diff --git a/drivers/net/irda/mcs7780.h b/drivers/net/irda/mcs7780.h index b18148cee63..6bdc621e67c 100644 --- a/drivers/net/irda/mcs7780.h +++ b/drivers/net/irda/mcs7780.h @@ -104,7 +104,6 @@ struct mcs_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ - struct net_device_stats stats; /* network statistics */ struct qos_info qos; unsigned int speed; /* Current speed */ unsigned int new_speed; /* new speed */ @@ -154,7 +153,6 @@ static int mcs_speed_change(struct mcs_cb *mcs); static int mcs_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd); static int mcs_net_close(struct net_device *netdev); static int mcs_net_open(struct net_device *netdev); -static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev); static void mcs_receive_irq(struct urb *urb); static void mcs_send_irq(struct urb *urb); diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 2c6bf2d11bb..61e509cb712 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -185,7 +185,6 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id); static int nsc_ircc_net_open(struct net_device *dev); static int nsc_ircc_net_close(struct net_device *dev); static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev); /* Globals */ static int pnp_registered; @@ -446,7 +445,6 @@ static int __init nsc_ircc_open(chipio_t *info) dev->open = nsc_ircc_net_open; dev->stop = nsc_ircc_net_close; dev->do_ioctl = nsc_ircc_net_ioctl; - dev->get_stats = nsc_ircc_net_get_stats; err = register_netdev(dev); if (err) { @@ -1401,7 +1399,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + dev->stats.tx_bytes += self->tx_buff.len; /* Add interrupt on tx low level (will fire immediately) */ switch_bank(iobase, BANK0); @@ -1473,7 +1471,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev) self->tx_fifo.queue[self->tx_fifo.free].len = skb->len; self->tx_fifo.tail += skb->len; - self->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; skb_copy_from_linear_data(skb, self->tx_fifo.queue[self->tx_fifo.free].start, skb->len); @@ -1652,13 +1650,13 @@ static int nsc_ircc_dma_xmit_complete(struct nsc_ircc_cb *self) /* Check for underrrun! */ if (inb(iobase+ASCR) & ASCR_TXUR) { - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; /* Clear bit, by writing 1 into it */ outb(ASCR_TXUR, iobase+ASCR); } else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; } /* Finished with this frame, so prepare for next */ @@ -1793,28 +1791,28 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) if (status & FRM_ST_ERR_MSK) { if (status & FRM_ST_LOST_FR) { /* Add number of lost frames to stats */ - self->stats.rx_errors += len; + self->netdev->stats.rx_errors += len; } else { /* Skip frame */ - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; self->rx_buff.data += len; if (status & FRM_ST_MAX_LEN) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; if (status & FRM_ST_PHY_ERR) - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; if (status & FRM_ST_BAD_CRC) - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FRM_ST_OVR1) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; if (status & FRM_ST_OVR2) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; } else { /* * First we must make sure that the frame we @@ -1863,7 +1861,7 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) IRDA_WARNING("%s(), memory squeeze, " "dropping frame.\n", __func__); - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; /* Restore bank register */ outb(bank, iobase+BSR); @@ -1889,8 +1887,8 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase) /* Move to next frame */ self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); @@ -1920,8 +1918,8 @@ static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self) /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RXD); - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, - byte); + async_unwrap_char(self->netdev, &self->netdev->stats, + &self->rx_buff, byte); } while (inb(iobase+LSR) & LSR_RXDA); /* Data available */ } @@ -1952,7 +1950,7 @@ static void nsc_ircc_sir_interrupt(struct nsc_ircc_cb *self, int eir) self->ier = IER_TXLDL_IE; else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; netif_wake_queue(self->netdev); self->ier = IER_TXEMP_IE; } @@ -2307,13 +2305,6 @@ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return ret; } -static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev) -{ - struct nsc_ircc_cb *self = netdev_priv(dev); - - return &self->stats; -} - static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state) { struct nsc_ircc_cb *self = platform_get_drvdata(dev); diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h index 71cd3c5a076..7ba7738759b 100644 --- a/drivers/net/irda/nsc-ircc.h +++ b/drivers/net/irda/nsc-ircc.h @@ -251,7 +251,6 @@ struct nsc_ircc_cb { struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 004a9aab3a5..31794c2363e 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -108,7 +108,6 @@ struct pxa_irda { int txdma; int rxdma; - struct net_device_stats stats; struct irlap_cb *irlap; struct qos_info qos; @@ -258,14 +257,15 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) data = STRBR; if (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) { printk(KERN_DEBUG "pxa_ir: sir receiving error\n"); - si->stats.rx_errors++; + dev->stats.rx_errors++; if (lsr & LSR_FE) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (lsr & LSR_OE) - si->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } else { - si->stats.rx_bytes++; - async_unwrap_char(dev, &si->stats, &si->rx_buff, data); + dev->stats.rx_bytes++; + async_unwrap_char(dev, &dev->stats, + &si->rx_buff, data); } lsr = STLSR; } @@ -277,8 +277,8 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) case 0x0C: /* Character Timeout Indication */ do { - si->stats.rx_bytes++; - async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR); + dev->stats.rx_bytes++; + async_unwrap_char(dev, &dev->stats, &si->rx_buff, STRBR); } while (STLSR & LSR_DR); si->last_oscr = OSCR; break; @@ -290,9 +290,8 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id) } if (si->tx_buff.len == 0) { - si->stats.tx_packets++; - si->stats.tx_bytes += si->tx_buff.data - - si->tx_buff.head; + dev->stats.tx_packets++; + dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; /* We need to ensure that the transmitter has finished. */ while ((STLSR & LSR_TEMT) == 0) @@ -343,10 +342,10 @@ static void pxa_irda_fir_dma_tx_irq(int channel, void *data) DCSR(channel) = dcsr & ~DCSR_RUN; if (dcsr & DCSR_ENDINTR) { - si->stats.tx_packets++; - si->stats.tx_bytes += si->dma_tx_buff_len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += si->dma_tx_buff_len; } else { - si->stats.tx_errors++; + dev->stats.tx_errors++; } while (ICSR1 & ICSR1_TBY) @@ -392,14 +391,14 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in data = ICDR; if (stat & (ICSR1_CRE | ICSR1_ROR)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (stat & ICSR1_CRE) { printk(KERN_DEBUG "pxa_ir: fir receive CRC error\n"); - si->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } if (stat & ICSR1_ROR) { printk(KERN_DEBUG "pxa_ir: fir receive overrun\n"); - si->stats.rx_over_errors++; + dev->stats.rx_over_errors++; } } else { si->dma_rx_buff[len++] = data; @@ -415,14 +414,14 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in if (icsr0 & ICSR0_FRE) { printk(KERN_ERR "pxa_ir: dropping erroneous frame\n"); - si->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } skb = alloc_skb(len+1,GFP_ATOMIC); if (!skb) { printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n"); - si->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } @@ -437,8 +436,8 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); - si->stats.rx_packets++; - si->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } } @@ -457,10 +456,10 @@ static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id) if (icsr0 & (ICSR0_FRE | ICSR0_RAB)) { if (icsr0 & ICSR0_FRE) { printk(KERN_DEBUG "pxa_ir: fir receive frame error\n"); - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; } else { printk(KERN_DEBUG "pxa_ir: fir receive abort\n"); - si->stats.rx_errors++; + dev->stats.rx_errors++; } ICSR0 = icsr0 & (ICSR0_FRE | ICSR0_RAB); } @@ -589,12 +588,6 @@ static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) return ret; } -static struct net_device_stats *pxa_irda_stats(struct net_device *dev) -{ - struct pxa_irda *si = netdev_priv(dev); - return &si->stats; -} - static void pxa_irda_startup(struct pxa_irda *si) { /* Disable STUART interrupts */ @@ -857,7 +850,6 @@ static int pxa_irda_probe(struct platform_device *pdev) dev->open = pxa_irda_start; dev->stop = pxa_irda_stop; dev->do_ioctl = pxa_irda_ioctl; - dev->get_stats = pxa_irda_stats; irda_init_max_qos_capabilies(&si->qos); diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index d302bcf4c14..7a2b003954c 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -60,7 +60,6 @@ struct sa1100_irda { dma_regs_t *txdma; dma_regs_t *rxdma; - struct net_device_stats stats; struct device *dev; struct irda_platform_data *pdata; struct irlap_cb *irlap; @@ -375,13 +374,13 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) data = Ser2UTDR; if (stat & (UTSR1_FRE | UTSR1_ROR)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (stat & UTSR1_FRE) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (stat & UTSR1_ROR) - si->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } else - async_unwrap_char(dev, &si->stats, &si->rx_buff, data); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, data); status = Ser2UTSR0; } @@ -396,9 +395,9 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) * There are at least 4 bytes in the FIFO. Read 3 bytes * and leave the rest to the block below. */ - async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); - async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); - async_unwrap_char(dev, &si->stats, &si->rx_buff, Ser2UTDR); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); } if (status & (UTSR0_RFS | UTSR0_RID)) { @@ -406,7 +405,7 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) * Fifo contains more than 1 character. */ do { - async_unwrap_char(dev, &si->stats, &si->rx_buff, + async_unwrap_char(dev, &dev->stats, &si->rx_buff, Ser2UTDR); } while (Ser2UTSR1 & UTSR1_RNE); @@ -422,8 +421,8 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev) } while (Ser2UTSR1 & UTSR1_TNF && si->tx_buff.len); if (si->tx_buff.len == 0) { - si->stats.tx_packets++; - si->stats.tx_bytes += si->tx_buff.data - + dev->stats.tx_packets++; + dev->stats.tx_bytes += si->tx_buff.data - si->tx_buff.head; /* @@ -482,11 +481,11 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev data = Ser2HSDR; if (stat & (HSSR1_CRE | HSSR1_ROR)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (stat & HSSR1_CRE) - si->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (stat & HSSR1_ROR) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; } else skb->data[len++] = data; @@ -505,8 +504,8 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev skb->dev = dev; skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); - si->stats.rx_packets++; - si->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; /* * Before we pass the buffer up, allocate a new one. @@ -545,10 +544,10 @@ static void sa1100_irda_fir_irq(struct net_device *dev) * from the fifo. */ if (Ser2HSSR0 & (HSSR0_FRE | HSSR0_RAB)) { - si->stats.rx_errors++; + dev->stats.rx_errors++; if (Ser2HSSR0 & HSSR0_FRE) - si->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; /* * Clear out the DMA... @@ -633,8 +632,8 @@ static void sa1100_irda_txdma_irq(void *id) */ if (skb) { dma_unmap_single(si->dev, si->txbuf_dma, skb->len, DMA_TO_DEVICE); - si->stats.tx_packets ++; - si->stats.tx_bytes += skb->len; + dev->stats.tx_packets ++; + dev->stats.tx_bytes += skb->len; dev_kfree_skb_irq(skb); } @@ -762,12 +761,6 @@ sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) return ret; } -static struct net_device_stats *sa1100_irda_stats(struct net_device *dev) -{ - struct sa1100_irda *si = netdev_priv(dev); - return &si->stats; -} - static int sa1100_irda_start(struct net_device *dev) { struct sa1100_irda *si = netdev_priv(dev); @@ -924,7 +917,6 @@ static int sa1100_irda_probe(struct platform_device *pdev) dev->open = sa1100_irda_start; dev->stop = sa1100_irda_stop; dev->do_ioctl = sa1100_irda_ioctl; - dev->get_stats = sa1100_irda_stats; dev->irq = IRQ_Ser2ICP; irda_init_max_qos_capabilies(&si->qos); diff --git a/drivers/net/irda/sir-dev.h b/drivers/net/irda/sir-dev.h index 2a57bc67ce3..6d5b1e2b128 100644 --- a/drivers/net/irda/sir-dev.h +++ b/drivers/net/irda/sir-dev.h @@ -160,7 +160,6 @@ static inline int sirdev_schedule_mode(struct sir_dev *dev, int mode) struct sir_dev { struct net_device *netdev; - struct net_device_stats stats; struct irlap_cb *irlap; diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index ceef040aa76..5b5862499de 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -455,8 +455,8 @@ void sirdev_write_complete(struct sir_dev *dev) if ((skb=dev->tx_skb) != NULL) { dev->tx_skb = NULL; dev_kfree_skb_any(skb); - dev->stats.tx_errors++; - dev->stats.tx_dropped++; + dev->netdev->stats.tx_errors++; + dev->netdev->stats.tx_dropped++; } dev->tx_buff.len = 0; } @@ -493,8 +493,8 @@ void sirdev_write_complete(struct sir_dev *dev) if ((skb=dev->tx_skb) != NULL) { dev->tx_skb = NULL; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; + dev->netdev->stats.tx_packets++; + dev->netdev->stats.tx_bytes += skb->len; dev_kfree_skb_any(skb); } @@ -548,7 +548,7 @@ int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) * just update stats and set media busy */ irda_device_set_media_busy(dev->netdev, TRUE); - dev->stats.rx_dropped++; + dev->netdev->stats.rx_dropped++; IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __func__, count); return 0; } @@ -557,7 +557,7 @@ int sirdev_receive(struct sir_dev *dev, const unsigned char *cp, size_t count) if (likely(atomic_read(&dev->enable_rx))) { while (count--) /* Unwrap and destuff one byte */ - async_unwrap_char(dev->netdev, &dev->stats, + async_unwrap_char(dev->netdev, &dev->netdev->stats, &dev->rx_buff, *cp++); } else { while (count--) { @@ -582,13 +582,6 @@ EXPORT_SYMBOL(sirdev_receive); /* callbacks from network layer */ -static struct net_device_stats *sirdev_get_stats(struct net_device *ndev) -{ - struct sir_dev *dev = netdev_priv(ndev); - - return (dev) ? &dev->stats : NULL; -} - static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) { struct sir_dev *dev = netdev_priv(ndev); @@ -654,7 +647,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) */ atomic_set(&dev->enable_rx, 0); if (unlikely(sirdev_is_receiving(dev))) - dev->stats.collisions++; + dev->netdev->stats.collisions++; actual = dev->drv->do_write(dev, dev->tx_buff.data, dev->tx_buff.len); @@ -669,8 +662,8 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev) IRDA_ERROR("%s: drv->do_write failed (%d)\n", __func__, actual); dev_kfree_skb_any(skb); - dev->stats.tx_errors++; - dev->stats.tx_dropped++; + dev->netdev->stats.tx_errors++; + dev->netdev->stats.tx_dropped++; netif_wake_queue(ndev); } spin_unlock_irqrestore(&dev->tx_lock, flags); @@ -918,7 +911,6 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n ndev->hard_start_xmit = sirdev_hard_xmit; ndev->open = sirdev_open; ndev->stop = sirdev_close; - ndev->get_stats = sirdev_get_stats; ndev->do_ioctl = sirdev_ioctl; if (register_netdev(ndev)) { diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 5d09e157e15..dd73cce1099 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -150,7 +150,6 @@ struct smsc_chip_address { /* Private data for each instance */ struct smsc_ircc_cb { struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ chipio_t io; /* IrDA controller information */ @@ -215,7 +214,6 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cm #if SMSC_IRCC2_C_NET_TIMEOUT static void smsc_ircc_timeout(struct net_device *dev); #endif -static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev); static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self); static void smsc_ircc_probe_transceiver(struct smsc_ircc_cb *self); static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 speed); @@ -529,7 +527,6 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u dev->open = smsc_ircc_net_open; dev->stop = smsc_ircc_net_close; dev->do_ioctl = smsc_ircc_net_ioctl; - dev->get_stats = smsc_ircc_net_get_stats; self = netdev_priv(dev); self->netdev = dev; @@ -834,13 +831,6 @@ static int smsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd return ret; } -static struct net_device_stats *smsc_ircc_net_get_stats(struct net_device *dev) -{ - struct smsc_ircc_cb *self = netdev_priv(dev); - - return &self->stats; -} - #if SMSC_IRCC2_C_NET_TIMEOUT /* * Function smsc_ircc_timeout (struct net_device *dev) @@ -920,7 +910,7 @@ static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev) self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + dev->stats.tx_bytes += self->tx_buff.len; /* Turn on transmit finished interrupt. Will fire immediately! */ outb(UART_IER_THRI, self->io.sir_base + UART_IER); @@ -1320,16 +1310,16 @@ static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self) /* Check for underrun! */ register_bank(iobase, 0); if (inb(iobase + IRCC_LSR) & IRCC_LSR_UNDERRUN) { - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; /* Reset error condition */ register_bank(iobase, 0); outb(IRCC_MASTER_ERROR_RESET, iobase + IRCC_MASTER); outb(0x00, iobase + IRCC_MASTER); } else { - self->stats.tx_packets++; - self->stats.tx_bytes += self->tx_buff.len; + self->netdev->stats.tx_packets++; + self->netdev->stats.tx_bytes += self->tx_buff.len; } /* Check if it's time to change the speed */ @@ -1429,15 +1419,15 @@ static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self) /* Look for errors */ if (lsr & (IRCC_LSR_FRAME_ERROR | IRCC_LSR_CRC_ERROR | IRCC_LSR_SIZE_ERROR)) { - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; if (lsr & IRCC_LSR_FRAME_ERROR) - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; if (lsr & IRCC_LSR_CRC_ERROR) - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; if (lsr & IRCC_LSR_SIZE_ERROR) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; if (lsr & (IRCC_LSR_UNDERRUN | IRCC_LSR_OVERRUN)) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; return; } @@ -1460,8 +1450,8 @@ static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self) skb_reserve(skb, 1); memcpy(skb_put(skb, len), self->rx_buff.data, len); - self->stats.rx_packets++; - self->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; skb->dev = self->netdev; skb_reset_mac_header(skb); @@ -1489,7 +1479,7 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) * async_unwrap_char will deliver all found frames */ do { - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, + async_unwrap_char(self->netdev, &self->netdev->stats, &self->rx_buff, inb(iobase + UART_RX)); /* Make sure we don't stay here to long */ @@ -1992,7 +1982,7 @@ static void smsc_ircc_sir_write_wakeup(struct smsc_ircc_cb *self) /* Tell network layer that we want more frames */ netif_wake_queue(self->netdev); } - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; if (self->io.speed <= 115200) { /* diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index ca4cd9266e5..8b1658c6c92 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -164,7 +164,7 @@ struct stir_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ - struct net_device_stats stats; /* network statistics */ + struct qos_info qos; unsigned speed; /* Current speed */ @@ -323,16 +323,16 @@ static void fir_eof(struct stir_cb *stir) pr_debug("%s: short frame len %d\n", stir->netdev->name, len); - ++stir->stats.rx_errors; - ++stir->stats.rx_length_errors; + ++stir->netdev->stats.rx_errors; + ++stir->netdev->stats.rx_length_errors; return; } fcs = ~(crc32_le(~0, rx_buff->data, len)); if (fcs != get_unaligned_le32(rx_buff->data + len)) { pr_debug("crc error calc 0x%x len %d\n", fcs, len); - stir->stats.rx_errors++; - stir->stats.rx_crc_errors++; + stir->netdev->stats.rx_errors++; + stir->netdev->stats.rx_crc_errors++; return; } @@ -340,7 +340,7 @@ static void fir_eof(struct stir_cb *stir) if (len < IRDA_RX_COPY_THRESHOLD) { nskb = dev_alloc_skb(len + 1); if (unlikely(!nskb)) { - ++stir->stats.rx_dropped; + ++stir->netdev->stats.rx_dropped; return; } skb_reserve(nskb, 1); @@ -349,7 +349,7 @@ static void fir_eof(struct stir_cb *stir) } else { nskb = dev_alloc_skb(rx_buff->truesize); if (unlikely(!nskb)) { - ++stir->stats.rx_dropped; + ++stir->netdev->stats.rx_dropped; return; } skb_reserve(nskb, 1); @@ -366,8 +366,8 @@ static void fir_eof(struct stir_cb *stir) netif_rx(skb); - stir->stats.rx_packets++; - stir->stats.rx_bytes += len; + stir->netdev->stats.rx_packets++; + stir->netdev->stats.rx_bytes += len; rx_buff->data = rx_buff->head; rx_buff->len = 0; @@ -437,7 +437,7 @@ static void stir_fir_chars(struct stir_cb *stir, if (unlikely(rx_buff->len >= rx_buff->truesize)) { pr_debug("%s: fir frame exceeds %d\n", stir->netdev->name, rx_buff->truesize); - ++stir->stats.rx_over_errors; + ++stir->netdev->stats.rx_over_errors; goto error_recovery; } @@ -445,10 +445,10 @@ static void stir_fir_chars(struct stir_cb *stir, continue; frame_error: - ++stir->stats.rx_frame_errors; + ++stir->netdev->stats.rx_frame_errors; error_recovery: - ++stir->stats.rx_errors; + ++stir->netdev->stats.rx_errors; rx_buff->state = OUTSIDE_FRAME; rx_buff->in_frame = FALSE; } @@ -461,7 +461,7 @@ static void stir_sir_chars(struct stir_cb *stir, int i; for (i = 0; i < len; i++) - async_unwrap_char(stir->netdev, &stir->stats, + async_unwrap_char(stir->netdev, &stir->netdev->stats, &stir->rx_buff, bytes[i]); } @@ -692,7 +692,7 @@ static void receive_stop(struct stir_cb *stir) usb_kill_urb(stir->rx_urb); if (stir->rx_buff.in_frame) - stir->stats.collisions++; + stir->netdev->stats.collisions++; } /* * Wrap data in socket buffer and send it. @@ -718,15 +718,15 @@ static void stir_send(struct stir_cb *stir, struct sk_buff *skb) if (!first_frame) fifo_txwait(stir, wraplen); - stir->stats.tx_packets++; - stir->stats.tx_bytes += skb->len; + stir->netdev->stats.tx_packets++; + stir->netdev->stats.tx_bytes += skb->len; stir->netdev->trans_start = jiffies; pr_debug("send %d (%d)\n", skb->len, wraplen); if (usb_bulk_msg(stir->usbdev, usb_sndbulkpipe(stir->usbdev, 1), stir->io_buf, wraplen, NULL, TRANSMIT_TIMEOUT)) - stir->stats.tx_errors++; + stir->netdev->stats.tx_errors++; } /* @@ -1007,15 +1007,6 @@ static int stir_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) return ret; } -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats *stir_net_get_stats(struct net_device *netdev) -{ - struct stir_cb *stir = netdev_priv(netdev); - return &stir->stats; -} - /* * This routine is called by the USB subsystem for each new device * in the system. We need to check if the device is ours, and in @@ -1066,7 +1057,6 @@ static int stir_probe(struct usb_interface *intf, net->hard_start_xmit = stir_hard_xmit; net->open = stir_net_open; net->stop = stir_net_close; - net->get_stats = stir_net_get_stats; net->do_ioctl = stir_net_ioctl; ret = register_netdev(net); diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 74c78cf7a33..8b3e545924c 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -101,8 +101,6 @@ static int via_ircc_net_open(struct net_device *dev); static int via_ircc_net_close(struct net_device *dev); static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *via_ircc_net_get_stats(struct net_device - *dev); static void via_ircc_change_dongle_speed(int iobase, int speed, int dongle_id); static int RxTimerHandler(struct via_ircc_cb *self, int iobase); @@ -434,7 +432,6 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) dev->open = via_ircc_net_open; dev->stop = via_ircc_net_close; dev->do_ioctl = via_ircc_net_ioctl; - dev->get_stats = via_ircc_net_get_stats; err = register_netdev(dev); if (err) @@ -855,7 +852,7 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb, async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize); - self->stats.tx_bytes += self->tx_buff.len; + dev->stats.tx_bytes += self->tx_buff.len; /* Send this frame with old speed */ SetBaudRate(iobase, self->io.speed); SetPulseWidth(iobase, 12); @@ -921,7 +918,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb, self->tx_fifo.queue[self->tx_fifo.free].len = skb->len; self->tx_fifo.tail += skb->len; - self->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; skb_copy_from_linear_data(skb, self->tx_fifo.queue[self->tx_fifo.free].start, skb->len); self->tx_fifo.len++; @@ -990,12 +987,12 @@ static int via_ircc_dma_xmit_complete(struct via_ircc_cb *self) /* Clear bit, by writing 1 into it */ Tx_status = GetTXStatus(iobase); if (Tx_status & 0x08) { - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; hwreset(self); // how to clear underrrun ? } else { - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; ResetChip(iobase, 3); ResetChip(iobase, 4); } @@ -1119,8 +1116,8 @@ static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, } // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); @@ -1180,7 +1177,7 @@ F01_E */ */ if ((skb == NULL) || (skb->data == NULL) || (self->rx_buff.data == NULL) || (len < 6)) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; return TRUE; } skb_reserve(skb, 1); @@ -1192,8 +1189,8 @@ F01_E */ // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); @@ -1220,13 +1217,13 @@ static int upload_rxdata(struct via_ircc_cb *self, int iobase) IRDA_DEBUG(2, "%s(): len=%x\n", __func__, len); if ((len - 4) < 2) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; return FALSE; } skb = dev_alloc_skb(len + 1); if (skb == NULL) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; return FALSE; } skb_reserve(skb, 1); @@ -1238,8 +1235,8 @@ static int upload_rxdata(struct via_ircc_cb *self, int iobase) st_fifo->tail = 0; // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); @@ -1295,7 +1292,7 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) */ if ((skb == NULL) || (skb->data == NULL) || (self->rx_buff.data == NULL) || (len < 6)) { - self->stats.rx_dropped++; + self->netdev->stats.rx_dropped++; continue; } skb_reserve(skb, 1); @@ -1307,8 +1304,8 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) // Move to next frame self->rx_buff.data += len; - self->stats.rx_bytes += len; - self->stats.rx_packets++; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IRDA); @@ -1523,7 +1520,7 @@ static int via_ircc_net_open(struct net_device *dev) IRDA_ASSERT(dev != NULL, return -1;); self = netdev_priv(dev); - self->stats.rx_packets = 0; + dev->stats.rx_packets = 0; IRDA_ASSERT(self != NULL, return 0;); iobase = self->io.fir_base; if (request_irq(self->io.irq, via_ircc_interrupt, 0, dev->name, dev)) { @@ -1660,14 +1657,6 @@ static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, return ret; } -static struct net_device_stats *via_ircc_net_get_stats(struct net_device - *dev) -{ - struct via_ircc_cb *self = netdev_priv(dev); - - return &self->stats; -} - MODULE_AUTHOR("VIA Technologies,inc"); MODULE_DESCRIPTION("VIA IrDA Device Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h index 403c3f77634..d9d1db03fa2 100644 --- a/drivers/net/irda/via-ircc.h +++ b/drivers/net/irda/via-ircc.h @@ -95,7 +95,6 @@ struct via_ircc_cb { struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 0d30f8d659a..723c4588c80 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -291,14 +291,14 @@ static void vlsi_proc_ndev(struct seq_file *seq, struct net_device *ndev) now.tv_sec - idev->last_rx.tv_sec - delta1, delta2); seq_printf(seq, "RX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu", - idev->stats.rx_packets, idev->stats.rx_bytes, idev->stats.rx_errors, - idev->stats.rx_dropped); + ndev->stats.rx_packets, ndev->stats.rx_bytes, ndev->stats.rx_errors, + ndev->stats.rx_dropped); seq_printf(seq, " / overrun=%lu / length=%lu / frame=%lu / crc=%lu\n", - idev->stats.rx_over_errors, idev->stats.rx_length_errors, - idev->stats.rx_frame_errors, idev->stats.rx_crc_errors); + ndev->stats.rx_over_errors, ndev->stats.rx_length_errors, + ndev->stats.rx_frame_errors, ndev->stats.rx_crc_errors); seq_printf(seq, "TX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu / fifo=%lu\n", - idev->stats.tx_packets, idev->stats.tx_bytes, idev->stats.tx_errors, - idev->stats.tx_dropped, idev->stats.tx_fifo_errors); + ndev->stats.tx_packets, ndev->stats.tx_bytes, ndev->stats.tx_errors, + ndev->stats.tx_dropped, ndev->stats.tx_fifo_errors); } @@ -651,21 +651,21 @@ static void vlsi_rx_interrupt(struct net_device *ndev) if (ret < 0) { ret = -ret; - idev->stats.rx_errors++; + ndev->stats.rx_errors++; if (ret & VLSI_RX_DROP) - idev->stats.rx_dropped++; + ndev->stats.rx_dropped++; if (ret & VLSI_RX_OVER) - idev->stats.rx_over_errors++; + ndev->stats.rx_over_errors++; if (ret & VLSI_RX_LENGTH) - idev->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; if (ret & VLSI_RX_FRAME) - idev->stats.rx_frame_errors++; + ndev->stats.rx_frame_errors++; if (ret & VLSI_RX_CRC) - idev->stats.rx_crc_errors++; + ndev->stats.rx_crc_errors++; } else if (ret > 0) { - idev->stats.rx_packets++; - idev->stats.rx_bytes += ret; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += ret; } } @@ -686,6 +686,7 @@ static void vlsi_rx_interrupt(struct net_device *ndev) static void vlsi_unarm_rx(vlsi_irda_dev_t *idev) { + struct net_device *ndev = pci_get_drvdata(idev->pdev); struct vlsi_ring *r = idev->rx_ring; struct ring_descr *rd; int ret; @@ -711,21 +712,21 @@ static void vlsi_unarm_rx(vlsi_irda_dev_t *idev) if (ret < 0) { ret = -ret; - idev->stats.rx_errors++; + ndev->stats.rx_errors++; if (ret & VLSI_RX_DROP) - idev->stats.rx_dropped++; + ndev->stats.rx_dropped++; if (ret & VLSI_RX_OVER) - idev->stats.rx_over_errors++; + ndev->stats.rx_over_errors++; if (ret & VLSI_RX_LENGTH) - idev->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; if (ret & VLSI_RX_FRAME) - idev->stats.rx_frame_errors++; + ndev->stats.rx_frame_errors++; if (ret & VLSI_RX_CRC) - idev->stats.rx_crc_errors++; + ndev->stats.rx_crc_errors++; } else if (ret > 0) { - idev->stats.rx_packets++; - idev->stats.rx_bytes += ret; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += ret; } } } @@ -1050,8 +1051,8 @@ drop_unlock: drop: IRDA_WARNING("%s: dropping packet - %s\n", __func__, msg); dev_kfree_skb_any(skb); - idev->stats.tx_errors++; - idev->stats.tx_dropped++; + ndev->stats.tx_errors++; + ndev->stats.tx_dropped++; /* Don't even think about returning NET_XMIT_DROP (=1) here! * In fact any retval!=0 causes the packet scheduler to requeue the * packet for later retry of transmission - which isn't exactly @@ -1078,15 +1079,15 @@ static void vlsi_tx_interrupt(struct net_device *ndev) if (ret < 0) { ret = -ret; - idev->stats.tx_errors++; + ndev->stats.tx_errors++; if (ret & VLSI_TX_DROP) - idev->stats.tx_dropped++; + ndev->stats.tx_dropped++; if (ret & VLSI_TX_FIFO) - idev->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; } else if (ret > 0){ - idev->stats.tx_packets++; - idev->stats.tx_bytes += ret; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += ret; } } @@ -1122,6 +1123,7 @@ static void vlsi_tx_interrupt(struct net_device *ndev) static void vlsi_unarm_tx(vlsi_irda_dev_t *idev) { + struct net_device *ndev = pci_get_drvdata(idev->pdev); struct vlsi_ring *r = idev->tx_ring; struct ring_descr *rd; int ret; @@ -1145,15 +1147,15 @@ static void vlsi_unarm_tx(vlsi_irda_dev_t *idev) if (ret < 0) { ret = -ret; - idev->stats.tx_errors++; + ndev->stats.tx_errors++; if (ret & VLSI_TX_DROP) - idev->stats.tx_dropped++; + ndev->stats.tx_dropped++; if (ret & VLSI_TX_FIFO) - idev->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; } else if (ret > 0){ - idev->stats.tx_packets++; - idev->stats.tx_bytes += ret; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += ret; } } @@ -1373,13 +1375,6 @@ static int vlsi_stop_hw(vlsi_irda_dev_t *idev) /**************************************************************/ -static struct net_device_stats * vlsi_get_stats(struct net_device *ndev) -{ - vlsi_irda_dev_t *idev = netdev_priv(ndev); - - return &idev->stats; -} - static void vlsi_tx_timeout(struct net_device *ndev) { vlsi_irda_dev_t *idev = netdev_priv(ndev); @@ -1615,7 +1610,6 @@ static int vlsi_irda_init(struct net_device *ndev) ndev->open = vlsi_open; ndev->stop = vlsi_close; - ndev->get_stats = vlsi_get_stats; ndev->hard_start_xmit = vlsi_hard_start_xmit; ndev->do_ioctl = vlsi_ioctl; ndev->tx_timeout = vlsi_tx_timeout; diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index 9b1884329fb..3050d1a0ccc 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -712,7 +712,6 @@ static inline struct ring_descr *ring_get(struct vlsi_ring *r) typedef struct vlsi_irda_dev { struct pci_dev *pdev; - struct net_device_stats stats; struct irlap_cb *irlap; diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 30ec9131c5c..dc0a2e4d830 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -102,7 +102,6 @@ static int w83977af_is_receiving(struct w83977af_ir *self); static int w83977af_net_open(struct net_device *dev); static int w83977af_net_close(struct net_device *dev); static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev); /* * Function w83977af_init () @@ -237,7 +236,6 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq, dev->open = w83977af_net_open; dev->stop = w83977af_net_close; dev->do_ioctl = w83977af_net_ioctl; - dev->get_stats = w83977af_net_get_stats; err = register_netdev(dev); if (err) { @@ -702,13 +700,13 @@ static void w83977af_dma_xmit_complete(struct w83977af_ir *self) if (inb(iobase+AUDR) & AUDR_UNDR) { IRDA_DEBUG(0, "%s(), Transmit underrun!\n", __func__ ); - self->stats.tx_errors++; - self->stats.tx_fifo_errors++; + self->netdev->stats.tx_errors++; + self->netdev->stats.tx_fifo_errors++; /* Clear bit, by writing 1 to it */ outb(AUDR_UNDR, iobase+AUDR); } else - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; if (self->new_speed) { @@ -846,28 +844,28 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self) if (status & FS_FO_ERR_MSK) { if (status & FS_FO_LST_FR) { /* Add number of lost frames to stats */ - self->stats.rx_errors += len; + self->netdev->stats.rx_errors += len; } else { /* Skip frame */ - self->stats.rx_errors++; + self->netdev->stats.rx_errors++; self->rx_buff.data += len; if (status & FS_FO_MX_LEX) - self->stats.rx_length_errors++; + self->netdev->stats.rx_length_errors++; if (status & FS_FO_PHY_ERR) - self->stats.rx_frame_errors++; + self->netdev->stats.rx_frame_errors++; if (status & FS_FO_CRC_ERR) - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FS_FO_RX_OV) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; if (status & FS_FO_FSF_OV) - self->stats.rx_fifo_errors++; + self->netdev->stats.rx_fifo_errors++; } else { /* Check if we have transferred all data to memory */ @@ -917,7 +915,7 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self) /* Move to next frame */ self->rx_buff.data += len; - self->stats.rx_packets++; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); @@ -951,7 +949,7 @@ static void w83977af_pio_receive(struct w83977af_ir *self) /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RBR); - async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, + async_unwrap_char(self->netdev, &self->netdev->stats, &self->rx_buff, byte); } while (inb(iobase+USR) & USR_RDR); /* Data available */ } @@ -994,7 +992,7 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr) outb(AUDR_SFEND, iobase+AUDR); outb(set, iobase+SSR); - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; /* Feed me more packets */ netif_wake_queue(self->netdev); @@ -1336,13 +1334,6 @@ out: return ret; } -static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev) -{ - struct w83977af_ir *self = netdev_priv(dev); - - return &self->stats; -} - MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/w83977af_ir.h b/drivers/net/irda/w83977af_ir.h index 87c3975baf6..fefe9b11e20 100644 --- a/drivers/net/irda/w83977af_ir.h +++ b/drivers/net/irda/w83977af_ir.h @@ -172,7 +172,6 @@ struct w83977af_ir { int tx_len; /* Number of frames in tx_buff */ struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; /* QoS capabilities for this device */ -- cgit From 53a3294e26c49622daa14c1d8540500f568ded99 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Jan 2009 10:41:56 -0800 Subject: bonding: use net_device_ops Use the correct pointer in debug message. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 460c2cad275..9fb388388fb 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4148,7 +4148,7 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu) bond_for_each_slave(bond, slave, i) { pr_debug("s %p s->p %p c_m %p\n", slave, - slave->prev, slave->dev->change_mtu); + slave->prev, slave->dev->netdev_ops->ndo_change_mtu); res = dev_set_mtu(slave->dev, new_mtu); -- cgit From 76288b4e573e06318fda65678052cfbde98fed1d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Jan 2009 10:44:22 -0800 Subject: virtio: convert to net_device_ops Signed-off-by: Stephen Hemminger Acked-by: Mark McLoughlin Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b7004ff3645..43f6523c40b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -624,6 +624,18 @@ static int virtnet_change_mtu(struct net_device *dev, int new_mtu) return 0; } +static const struct net_device_ops virtnet_netdev = { + .ndo_open = virtnet_open, + .ndo_stop = virtnet_close, + .ndo_start_xmit = start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = virtnet_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = virtnet_netpoll, +#endif +}; + static int virtnet_probe(struct virtio_device *vdev) { int err; @@ -636,14 +648,8 @@ static int virtnet_probe(struct virtio_device *vdev) return -ENOMEM; /* Set up network device as normal. */ - dev->open = virtnet_open; - dev->stop = virtnet_close; - dev->hard_start_xmit = start_xmit; - dev->change_mtu = virtnet_change_mtu; + dev->netdev_ops = &virtnet_netdev; dev->features = NETIF_F_HIGHDMA; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = virtnet_netpoll; -#endif SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops); SET_NETDEV_DEV(dev, &vdev->dev); -- cgit From 0a0b9d2edc3d7b56386dd980f7d17eaaad15cf6a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Jan 2009 10:44:55 -0800 Subject: xen-netfront: convert to net_device_ops Convert Xen device to new API. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 761635be910..cd6184ee08e 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1105,6 +1105,16 @@ static void xennet_uninit(struct net_device *dev) gnttab_free_grant_references(np->gref_rx_head); } +static const struct net_device_ops xennet_netdev_ops = { + .ndo_open = xennet_open, + .ndo_uninit = xennet_uninit, + .ndo_stop = xennet_close, + .ndo_start_xmit = xennet_start_xmit, + .ndo_change_mtu = xennet_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev) { int i, err; @@ -1161,12 +1171,9 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev goto exit_free_tx; } - netdev->open = xennet_open; - netdev->hard_start_xmit = xennet_start_xmit; - netdev->stop = xennet_close; + netdev->netdev_ops = &xennet_netdev_ops; + netif_napi_add(netdev, &np->napi, xennet_poll, 64); - netdev->uninit = xennet_uninit; - netdev->change_mtu = xennet_change_mtu; netdev->features = NETIF_F_IP_CSUM; SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); -- cgit From 8be35bdeb2969b6dcb9a2e4f756e193325c4db33 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 10:47:16 -0800 Subject: net/ehea: use consistant type ehea_plpar_hcall9() takes an "unsigned long" array to return its results, so change the arrays we pass to it to match. This is currently only 64 bit code, so the transformation is actually a noop, but because ehea_plpar_hcall9() copies the values of registers into the array, if this was ported to a 32 bit hypervisor interface "unsigned long" would probably still be the correct type. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_phyp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 2a33a613d9e..8fe9dcaa753 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -214,7 +214,7 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle, u64 *qp_handle, struct h_epas *h_epas) { u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; u64 allocate_controls = EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0) @@ -312,7 +312,7 @@ u64 ehea_h_alloc_resource_cq(const u64 adapter_handle, u64 *cq_handle, struct h_epas *epas) { u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, outs, @@ -374,7 +374,7 @@ u64 ehea_h_alloc_resource_eq(const u64 adapter_handle, struct ehea_eq_attr *eq_attr, u64 *eq_handle) { u64 hret, allocate_controls; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; /* resource type */ allocate_controls = @@ -407,7 +407,7 @@ u64 ehea_h_modify_ehea_qp(const u64 adapter_handle, const u8 cat, u16 *out_swr, u16 *out_rwr) { u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; hret = ehea_plpar_hcall9(H_MODIFY_HEA_QP, outs, @@ -449,7 +449,7 @@ u64 ehea_h_register_smr(const u64 adapter_handle, const u64 orig_mr_handle, struct ehea_mr *mr) { u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; hret = ehea_plpar_hcall9(H_REGISTER_SMR, outs, @@ -468,7 +468,7 @@ u64 ehea_h_register_smr(const u64 adapter_handle, const u64 orig_mr_handle, u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle) { - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; return ehea_plpar_hcall9(H_DISABLE_AND_GET_HEA, outs, @@ -493,7 +493,7 @@ u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, const u32 pd, u64 *mr_handle, u32 *lkey) { u64 hret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, outs, @@ -564,7 +564,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, const u8 cb_cat, const u64 select_mask, void *cb_addr) { - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; u64 port_info; u64 arr_index = 0; u64 cb_logaddr = virt_to_abs(cb_addr); -- cgit From ff5bfc3584efdadf826a21bc76ef42bdfcf3f612 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 10:47:44 -0800 Subject: ibmveth: use consistent types These variables are only used with an interface that just dumps their values into registers to be passed to the hypervisor. The arguments to that interface are declared to be "unsigned long", so make these variables match. The macros are only used with these variables, so make them match as well. This code is currently only built for 64bit powerpc, so the transformation is really a noop. If the interface was ever ported to 32 bit, it would almost certainly still use registers to pass the parameters and so "unsigned long" would still be appropriate. Signed-off-by: Stephen Rothwell Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 4 ++-- drivers/net/ibmveth.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 9bc0f178f24..ca3bb9f7321 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -754,7 +754,7 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, void (*done) (struct net_device *, u32)) { struct ibmveth_adapter *adapter = netdev_priv(dev); - u64 set_attr, clr_attr, ret_attr; + unsigned long set_attr, clr_attr, ret_attr; long ret; int rc1 = 0, rc2 = 0; int restart = 0; @@ -1209,7 +1209,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ long ret; struct net_device *netdev; struct ibmveth_adapter *adapter; - u64 set_attr, ret_attr; + unsigned long set_attr, ret_attr; unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index d2818694875..ec76ace66c6 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -39,11 +39,11 @@ #define IbmVethMcastRemoveFilter 0x2UL #define IbmVethMcastClearFilterTable 0x3UL -#define IBMVETH_ILLAN_PADDED_PKT_CSUM 0x0000000000002000ULL -#define IBMVETH_ILLAN_TRUNK_PRI_MASK 0x0000000000000F00ULL -#define IBMVETH_ILLAN_IPV6_TCP_CSUM 0x0000000000000004ULL -#define IBMVETH_ILLAN_IPV4_TCP_CSUM 0x0000000000000002ULL -#define IBMVETH_ILLAN_ACTIVE_TRUNK 0x0000000000000001ULL +#define IBMVETH_ILLAN_PADDED_PKT_CSUM 0x0000000000002000UL +#define IBMVETH_ILLAN_TRUNK_PRI_MASK 0x0000000000000F00UL +#define IBMVETH_ILLAN_IPV6_TCP_CSUM 0x0000000000000004UL +#define IBMVETH_ILLAN_IPV4_TCP_CSUM 0x0000000000000002UL +#define IBMVETH_ILLAN_ACTIVE_TRUNK 0x0000000000000001UL /* hcall macros */ #define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \ -- cgit From 20f10aa07d8d4d43ae8e129c39a84e1670b0d5ab Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 6 Jan 2009 10:55:10 -0800 Subject: dm9601: handle corrupt mac address Some cheap devices ship with dangling EEPROM pins! They always return invalid address ff:ff:ff:ff:ff:ff. Inherit the auto-generated address in this case, so that these products can work with zero configuration. Signed-off-by: Wu Fengguang Signed-off-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index edd244f3acb..69a0436d394 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -414,6 +414,7 @@ static int dm9601_set_mac_address(struct net_device *net, void *p) static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) { int ret; + u8 mac[ETH_ALEN]; ret = usbnet_get_endpoints(dev, intf); if (ret) @@ -438,12 +439,18 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) udelay(20); /* read MAC */ - if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr) < 0) { + if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, mac) < 0) { printk(KERN_ERR "Error reading MAC address\n"); ret = -ENODEV; goto out; } + /* + * Overwrite the auto-generated address only with good ones. + */ + if (is_valid_ether_addr(mac)) + memcpy(dev->net->dev_addr, mac, ETH_ALEN); + /* power up phy */ dm_write_reg(dev, DM_GPR_CTRL, 1); dm_write_reg(dev, DM_GPR_DATA, 0); -- cgit From 98658bc9dc37cfb7c3bf5585ca73ce44aeb05c9e Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 6 Jan 2009 10:56:07 -0800 Subject: dm9601: bring datasheet URL up to date Signed-off-by: Wu Fengguang Signed-off-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 69a0436d394..49a30bde7a8 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -23,7 +23,7 @@ #include /* datasheet: - http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf + http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf */ /* control requests */ -- cgit From 3f4528d6e91cffde49894f5252e6657d420d3d74 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 6 Jan 2009 13:20:38 -0800 Subject: sparc64: Fix unsigned long long warnings in drivers. Fix warnings caused by the unsigned long long usage in sparc specific drivers. The drivers were considered sparc specific more or less from the filename alone. Signed-off-by: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/sunvnet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index 233f1cda36e..611230fef2b 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c @@ -336,7 +336,7 @@ static int vnet_walk_rx_one(struct vnet_port *port, if (IS_ERR(desc)) return PTR_ERR(desc); - viodbg(DATA, "vio_walk_rx_one desc[%02x:%02x:%08x:%08x:%lx:%lx]\n", + viodbg(DATA, "vio_walk_rx_one desc[%02x:%02x:%08x:%08x:%llx:%llx]\n", desc->hdr.state, desc->hdr.ack, desc->size, desc->ncookies, desc->cookies[0].cookie_addr, @@ -394,14 +394,14 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf) struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_RX_RING]; struct vio_driver_state *vio = &port->vio; - viodbg(DATA, "vnet_rx stype_env[%04x] seq[%016lx] rcv_nxt[%016lx]\n", + viodbg(DATA, "vnet_rx stype_env[%04x] seq[%016llx] rcv_nxt[%016llx]\n", pkt->tag.stype_env, pkt->seq, dr->rcv_nxt); if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA)) return 0; if (unlikely(pkt->seq != dr->rcv_nxt)) { - printk(KERN_ERR PFX "RX out of sequence seq[0x%lx] " - "rcv_nxt[0x%lx]\n", pkt->seq, dr->rcv_nxt); + printk(KERN_ERR PFX "RX out of sequence seq[0x%llx] " + "rcv_nxt[0x%llx]\n", pkt->seq, dr->rcv_nxt); return 0; } -- cgit From f430e49e9e0cf821c090abedb399b80ebf0cb4c6 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Tue, 6 Jan 2009 14:08:10 -0800 Subject: gianfar: ensure ECNTRL[R100] is cleared on link state change When changing the link between 100Mbps and 1Gbps in SGMII mode it was found out that the link would stop working. The issue is that ECNTRL[R100] needs to be cleared when in 1Gbps mode. Older reference manuals didn't require the explicitly clearing but has since been found it that it is needed. Signed-off-by: Li Yang Signed-off-by: Kumar Gala Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index c672ecfc959..7fcc3af3f86 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1973,6 +1973,8 @@ static void adjust_link(struct net_device *dev) case 1000: tempval = ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII); + + ecntrl &= ~(ECNTRL_R100); break; case 100: case 10: -- cgit From da2bbdcc3838ce75c30bda8c3f9a6e55ece47ee1 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 29 Oct 2008 14:25:51 -0700 Subject: USB: avoid needless address-taking of function parameters There's no need to take the address of the function params or local variables when the direct value byteswapping routines are available. Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/kaweth.c | 6 +++--- drivers/net/usb/pegasus.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 2ee034f70d1..3073ca25a0b 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -283,9 +283,9 @@ static int kaweth_control(struct kaweth_device *kaweth, dr->bRequestType= requesttype; dr->bRequest = request; - dr->wValue = cpu_to_le16p(&value); - dr->wIndex = cpu_to_le16p(&index); - dr->wLength = cpu_to_le16p(&size); + dr->wValue = cpu_to_le16(value); + dr->wIndex = cpu_to_le16(index); + dr->wLength = cpu_to_le16(size); return kaweth_internal_control_msg(kaweth->dev, pipe, diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 166880c113d..d9241f1c080 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -150,8 +150,8 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->dr.bRequestType = PEGASUS_REQT_READ; pegasus->dr.bRequest = PEGASUS_REQ_GET_REGS; pegasus->dr.wValue = cpu_to_le16(0); - pegasus->dr.wIndex = cpu_to_le16p(&indx); - pegasus->dr.wLength = cpu_to_le16p(&size); + pegasus->dr.wIndex = cpu_to_le16(indx); + pegasus->dr.wLength = cpu_to_le16(size); pegasus->ctrl_urb->transfer_buffer_length = size; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, @@ -208,8 +208,8 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->dr.bRequestType = PEGASUS_REQT_WRITE; pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS; pegasus->dr.wValue = cpu_to_le16(0); - pegasus->dr.wIndex = cpu_to_le16p(&indx); - pegasus->dr.wLength = cpu_to_le16p(&size); + pegasus->dr.wIndex = cpu_to_le16(indx); + pegasus->dr.wLength = cpu_to_le16(size); pegasus->ctrl_urb->transfer_buffer_length = size; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, @@ -261,7 +261,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) pegasus->dr.bRequestType = PEGASUS_REQT_WRITE; pegasus->dr.bRequest = PEGASUS_REQ_SET_REG; pegasus->dr.wValue = cpu_to_le16(data); - pegasus->dr.wIndex = cpu_to_le16p(&indx); + pegasus->dr.wIndex = cpu_to_le16(indx); pegasus->dr.wLength = cpu_to_le16(1); pegasus->ctrl_urb->transfer_buffer_length = 1; @@ -476,7 +476,7 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id) for (i = 0; i < 3; i++) { read_eprom_word(pegasus, i, &w16); - ((__le16 *) id)[i] = cpu_to_le16p(&w16); + ((__le16 *) id)[i] = cpu_to_le16(w16); } } -- cgit From ea24652d253eabfb83e955e55ce032228d9d99b9 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:43 -0800 Subject: i2400m: host/device procotol and core driver definitions The wimax/i2400m.h defines the structures and constants for the host-device protocols: - boot / firmware upload protocol - general data transport protocol - control protocol It is done in such a way that can also be used verbatim by user space. drivers/net/wimax/i2400m.h defines all the APIs used by the core, bus-generic driver (i2400m) and the bus specific drivers (i2400m-BUSNAME). It also gives a roadmap to the driver implementation. debug-levels.h adds the core driver's debug settings. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/debug-levels.h | 45 ++ drivers/net/wimax/i2400m/i2400m.h | 755 ++++++++++++++++++++++++++++++++ 2 files changed, 800 insertions(+) create mode 100644 drivers/net/wimax/i2400m/debug-levels.h create mode 100644 drivers/net/wimax/i2400m/i2400m.h (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/debug-levels.h b/drivers/net/wimax/i2400m/debug-levels.h new file mode 100644 index 00000000000..3183baa16a5 --- /dev/null +++ b/drivers/net/wimax/i2400m/debug-levels.h @@ -0,0 +1,45 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Debug levels control file for the i2400m module + * + * + * Copyright (C) 2007-2008 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#ifndef __debug_levels__h__ +#define __debug_levels__h__ + +/* Maximum compile and run time debug level for all submodules */ +#define D_MODULENAME i2400m +#define D_MASTER CONFIG_WIMAX_I2400M_DEBUG_LEVEL + +#include + +/* List of all the enabled modules */ +enum d_module { + D_SUBMODULE_DECLARE(control), + D_SUBMODULE_DECLARE(driver), + D_SUBMODULE_DECLARE(debugfs), + D_SUBMODULE_DECLARE(fw), + D_SUBMODULE_DECLARE(netdev), + D_SUBMODULE_DECLARE(rfkill), + D_SUBMODULE_DECLARE(rx), + D_SUBMODULE_DECLARE(tx), +}; + + +#endif /* #ifndef __debug_levels__h__ */ diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h new file mode 100644 index 00000000000..067c871cc22 --- /dev/null +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -0,0 +1,755 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Declarations for bus-generic internal APIs + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Inaky Perez-Gonzalez + * Yanir Lubetkin + * - Initial implementation + * + * + * GENERAL DRIVER ARCHITECTURE + * + * The i2400m driver is split in the following two major parts: + * + * - bus specific driver + * - bus generic driver (this part) + * + * The bus specific driver sets up stuff specific to the bus the + * device is connected to (USB, SDIO, PCI, tam-tam...non-authoritative + * nor binding list) which is basically the device-model management + * (probe/disconnect, etc), moving data from device to kernel and + * back, doing the power saving details and reseting the device. + * + * For details on each bus-specific driver, see it's include file, + * i2400m-BUSNAME.h + * + * The bus-generic functionality break up is: + * + * - Firmware upload: fw.c - takes care of uploading firmware to the + * device. bus-specific driver just needs to provides a way to + * execute boot-mode commands and to reset the device. + * + * - RX handling: rx.c - receives data from the bus-specific code and + * feeds it to the network or WiMAX stack or uses it to modify + * the driver state. bus-specific driver only has to receive + * frames and pass them to this module. + * + * - TX handling: tx.c - manages the TX FIFO queue and provides means + * for the bus-specific TX code to pull data from the FIFO + * queue. bus-specific code just pulls frames from this module + * to sends them to the device. + * + * - netdev glue: netdev.c - interface with Linux networking + * stack. Pass around data frames, and configure when the + * device is up and running or shutdown (through ifconfig up / + * down). Bus-generic only. + * + * - control ops: control.c - implements various commmands for + * controlling the device. bus-generic only. + * + * - device model glue: driver.c - implements helpers for the + * device-model glue done by the bus-specific layer + * (setup/release the driver resources), turning the device on + * and off, handling the device reboots/resets and a few simple + * WiMAX stack ops. + * + * Code is also broken up in linux-glue / device-glue. + * + * Linux glue contains functions that deal mostly with gluing with the + * rest of the Linux kernel. + * + * Device-glue are functions that deal mostly with the way the device + * does things and talk the device's language. + * + * device-glue code is licensed BSD so other open source OSes can take + * it to implement their drivers. + * + * + * APIs AND HEADER FILES + * + * This bus generic code exports three APIs: + * + * - HDI (host-device interface) definitions common to all busses + * (include/linux/wimax/i2400m.h); these can be also used by user + * space code. + * - internal API for the bus-generic code + * - external API for the bus-specific drivers + * + * + * LIFE CYCLE: + * + * When the bus-specific driver probes, it allocates a network device + * with enough space for it's data structue, that must contain a + * &struct i2400m at the top. + * + * On probe, it needs to fill the i2400m members marked as [fill], as + * well as i2400m->wimax_dev.net_dev and call i2400m_setup(). The + * i2400m driver will only register with the WiMAX and network stacks; + * the only access done to the device is to read the MAC address so we + * can register a network device. This calls i2400m_dev_start() to + * load firmware, setup communication with the device and configure it + * for operation. + * + * At this point, control and data communications are possible. + * + * On disconnect/driver unload, the bus-specific disconnect function + * calls i2400m_release() to undo i2400m_setup(). i2400m_dev_stop() + * shuts the firmware down and releases resources uses to communicate + * with the device. + * + * While the device is up, it might reset. The bus-specific driver has + * to catch that situation and call i2400m_dev_reset_handle() to deal + * with it (reset the internal driver structures and go back to square + * one). + */ + +#ifndef __I2400M_H__ +#define __I2400M_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Misc constants */ +enum { + /* Firmware uploading */ + I2400M_BOOT_RETRIES = 3, + /* Size of the Boot Mode Command buffer */ + I2400M_BM_CMD_BUF_SIZE = 16 * 1024, + I2400M_BM_ACK_BUF_SIZE = 256, +}; + + +/* Firmware version we request when pulling the fw image file */ +#define I2400M_FW_VERSION "1.3" + + +/** + * i2400m_reset_type - methods to reset a device + * + * @I2400M_RT_WARM: Reset without device disconnection, device handles + * are kept valid but state is back to power on, with firmware + * re-uploaded. + * @I2400M_RT_COLD: Tell the device to disconnect itself from the bus + * and reconnect. Renders all device handles invalid. + * @I2400M_RT_BUS: Tells the bus to reset the device; last measure + * used when both types above don't work. + */ +enum i2400m_reset_type { + I2400M_RT_WARM, /* first measure */ + I2400M_RT_COLD, /* second measure */ + I2400M_RT_BUS, /* call in artillery */ +}; + +struct i2400m_reset_ctx; + +/** + * struct i2400m - descriptor for an Intel 2400m + * + * Members marked with [fill] must be filled out/initialized before + * calling i2400m_setup(). + * + * @bus_tx_block_size: [fill] SDIO imposes a 256 block size, USB 16, + * so we have a tx_blk_size variable that the bus layer sets to + * tell the engine how much of that we need. + * + * @bus_pl_size_max: [fill] Maximum payload size. + * + * @bus_dev_start: [fill] Function called by the bus-generic code + * [i2400m_dev_start()] to setup the bus-specific communications + * to the the device. See LIFE CYCLE above. + * + * NOTE: Doesn't need to upload the firmware, as that is taken + * care of by the bus-generic code. + * + * @bus_dev_stop: [fill] Function called by the bus-generic code + * [i2400m_dev_stop()] to shutdown the bus-specific communications + * to the the device. See LIFE CYCLE above. + * + * This function does not need to reset the device, just tear down + * all the host resources created to handle communication with + * the device. + * + * @bus_tx_kick: [fill] Function called by the bus-generic code to let + * the bus-specific code know that there is data available in the + * TX FIFO for transmission to the device. + * + * This function cannot sleep. + * + * @bus_reset: [fill] Function called by the bus-generic code to reset + * the device in in various ways. Doesn't need to wait for the + * reset to finish. + * + * If warm or cold reset fail, this function is expected to do a + * bus-specific reset (eg: USB reset) to get the device to a + * working state (even if it implies device disconecction). + * + * Note the warm reset is used by the firmware uploader to + * reinitialize the device. + * + * IMPORTANT: this is called very early in the device setup + * process, so it cannot rely on common infrastructure being laid + * out. + * + * @bus_bm_cmd_send: [fill] Function called to send a boot-mode + * command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This + * is synchronous and has to return 0 if ok or < 0 errno code in + * any error condition. + * + * @bus_bm_wait_for_ack: [fill] Function called to wait for a + * boot-mode notification (that can be a response to a previously + * issued command or an asynchronous one). Will read until all the + * indicated size is read or timeout. Reading more or less data + * than asked for is an error condition. Return 0 if ok, < 0 errno + * code on error. + * + * The caller to this function will check if the response is a + * barker that indicates the device going into reset mode. + * + * @bus_fw_name: [fill] name of the firmware image (in most cases, + * they are all the same for a single release, except that they + * have the type of the bus embedded in the name (eg: + * i2400m-fw-X-VERSION.sbcf, where X is the bus name). + * + * @bus_bm_mac_addr_impaired: [fill] Set to true if the device's MAC + * address provided in boot mode is kind of broken and needs to + * be re-read later on. + * + * + * @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX + * stack. Due to the way a net_device is allocated, we need to + * force this to be the first field so that we can get from + * netdev_priv() the right pointer. + * + * @state: device's state (as reported by it) + * + * @state_wq: waitqueue that is woken up whenever the state changes + * + * @tx_lock: spinlock to protect TX members + * + * @tx_buf: FIFO buffer for TX; we queue data here + * + * @tx_in: FIFO index for incoming data. Note this doesn't wrap around + * and it is always greater than @tx_out. + * + * @tx_out: FIFO index for outgoing data + * + * @tx_msg: current TX message that is active in the FIFO for + * appending payloads. + * + * @tx_sequence: current sequence number for TX messages from the + * device to the host. + * + * @tx_msg_size: size of the current message being transmitted by the + * bus-specific code. + * + * @tx_pl_num: total number of payloads sent + * + * @tx_pl_max: maximum number of payloads sent in a TX message + * + * @tx_pl_min: minimum number of payloads sent in a TX message + * + * @tx_num: number of TX messages sent + * + * @tx_size_acc: number of bytes in all TX messages sent + * (this is different to net_dev's statistics as it also counts + * control messages). + * + * @tx_size_min: smallest TX message sent. + * + * @tx_size_max: biggest TX message sent. + * + * @rx_lock: spinlock to protect RX members + * + * @rx_pl_num: total number of payloads received + * + * @rx_pl_max: maximum number of payloads received in a RX message + * + * @rx_pl_min: minimum number of payloads received in a RX message + * + * @rx_num: number of RX messages received + * + * @rx_size_acc: number of bytes in all RX messages received + * (this is different to net_dev's statistics as it also counts + * control messages). + * + * @rx_size_min: smallest RX message received. + * + * @rx_size_max: buggest RX message received. + * + * @init_mutex: Mutex used for serializing the device bringup + * sequence; this way if the device reboots in the middle, we + * don't try to do a bringup again while we are tearing down the + * one that failed. + * + * Can't reuse @msg_mutex because from within the bringup sequence + * we need to send messages to the device and thus use @msg_mutex. + * + * @msg_mutex: mutex used to send control commands to the device (we + * only allow one at a time, per host-device interface design). + * + * @msg_completion: used to wait for an ack to a control command sent + * to the device. + * + * @ack_skb: used to store the actual ack to a control command if the + * reception of the command was successful. Otherwise, a ERR_PTR() + * errno code that indicates what failed with the ack reception. + * + * Only valid after @msg_completion is woken up. Only updateable + * if @msg_completion is armed. Only touched by + * i2400m_msg_to_dev(). + * + * Protected by @rx_lock. In theory the command execution flow is + * sequential, but in case the device sends an out-of-phase or + * very delayed response, we need to avoid it trampling current + * execution. + * + * @bm_cmd_buf: boot mode command buffer for composing firmware upload + * commands. + * + * USB can't r/w to stack, vmalloc, etc...as well, we end up + * having to alloc/free a lot to compose commands, so we use these + * for stagging and not having to realloc all the time. + * + * This assumes the code always runs serialized. Only one thread + * can call i2400m_bm_cmd() at the same time. + * + * @bm_ack_buf: boot mode acknoledge buffer for staging reception of + * responses to commands. + * + * See @bm_cmd_buf. + * + * @work_queue: work queue for processing device reports. This + * workqueue cannot be used for processing TX or RX to the device, + * as from it we'll process device reports, which might require + * further communication with the device. + * + * @debugfs_dentry: hookup for debugfs files. + * These have to be in a separate directory, a child of + * (wimax_dev->debugfs_dentry) so they can be removed when the + * module unloads, as we don't keep each dentry. + */ +struct i2400m { + struct wimax_dev wimax_dev; /* FIRST! See doc */ + + unsigned updown:1; /* Network device is up or down */ + unsigned boot_mode:1; /* is the device in boot mode? */ + unsigned sboot:1; /* signed or unsigned fw boot */ + unsigned ready:1; /* all probing steps done */ + u8 trace_msg_from_user; /* echo rx msgs to 'trace' pipe */ + /* typed u8 so debugfs/u8 can tweak */ + enum i2400m_system_state state; + wait_queue_head_t state_wq; /* Woken up when on state updates */ + + size_t bus_tx_block_size; + size_t bus_pl_size_max; + int (*bus_dev_start)(struct i2400m *); + void (*bus_dev_stop)(struct i2400m *); + void (*bus_tx_kick)(struct i2400m *); + int (*bus_reset)(struct i2400m *, enum i2400m_reset_type); + ssize_t (*bus_bm_cmd_send)(struct i2400m *, + const struct i2400m_bootrom_header *, + size_t, int flags); + ssize_t (*bus_bm_wait_for_ack)(struct i2400m *, + struct i2400m_bootrom_header *, size_t); + const char *bus_fw_name; + unsigned bus_bm_mac_addr_impaired:1; + + spinlock_t tx_lock; /* protect TX state */ + void *tx_buf; + size_t tx_in, tx_out; + struct i2400m_msg_hdr *tx_msg; + size_t tx_sequence, tx_msg_size; + /* TX stats */ + unsigned tx_pl_num, tx_pl_max, tx_pl_min, + tx_num, tx_size_acc, tx_size_min, tx_size_max; + + /* RX stats */ + spinlock_t rx_lock; /* protect RX state */ + unsigned rx_pl_num, rx_pl_max, rx_pl_min, + rx_num, rx_size_acc, rx_size_min, rx_size_max; + + struct mutex msg_mutex; /* serialize command execution */ + struct completion msg_completion; + struct sk_buff *ack_skb; /* protected by rx_lock */ + + void *bm_ack_buf; /* for receiving acks over USB */ + void *bm_cmd_buf; /* for issuing commands over USB */ + + struct workqueue_struct *work_queue; + + struct mutex init_mutex; /* protect bringup seq */ + struct i2400m_reset_ctx *reset_ctx; /* protected by init_mutex */ + + struct work_struct wake_tx_ws; + struct sk_buff *wake_tx_skb; + + struct dentry *debugfs_dentry; +}; + + +/* + * Initialize a 'struct i2400m' from all zeroes + * + * This is a bus-generic API call. + */ +static inline +void i2400m_init(struct i2400m *i2400m) +{ + wimax_dev_init(&i2400m->wimax_dev); + + i2400m->boot_mode = 1; + init_waitqueue_head(&i2400m->state_wq); + + spin_lock_init(&i2400m->tx_lock); + i2400m->tx_pl_min = UINT_MAX; + i2400m->tx_size_min = UINT_MAX; + + spin_lock_init(&i2400m->rx_lock); + i2400m->rx_pl_min = UINT_MAX; + i2400m->rx_size_min = UINT_MAX; + + mutex_init(&i2400m->msg_mutex); + init_completion(&i2400m->msg_completion); + + mutex_init(&i2400m->init_mutex); + /* wake_tx_ws is initialized in i2400m_tx_setup() */ +} + + +/* + * Bus-generic internal APIs + * ------------------------- + */ + +static inline +struct i2400m *wimax_dev_to_i2400m(struct wimax_dev *wimax_dev) +{ + return container_of(wimax_dev, struct i2400m, wimax_dev); +} + +static inline +struct i2400m *net_dev_to_i2400m(struct net_device *net_dev) +{ + return wimax_dev_to_i2400m(netdev_priv(net_dev)); +} + +/* + * Boot mode support + */ + +/** + * i2400m_bm_cmd_flags - flags to i2400m_bm_cmd() + * + * @I2400M_BM_CMD_RAW: send the command block as-is, without doing any + * extra processing for adding CRC. + */ +enum i2400m_bm_cmd_flags { + I2400M_BM_CMD_RAW = 1 << 2, +}; + +/** + * i2400m_bri - Boot-ROM indicators + * + * Flags for i2400m_bootrom_init() and i2400m_dev_bootstrap() [which + * are passed from things like i2400m_setup()]. Can be combined with + * |. + * + * @I2400M_BRI_SOFT: The device rebooted already and a reboot + * barker received, proceed directly to ack the boot sequence. + * @I2400M_BRI_NO_REBOOT: Do not reboot the device and proceed + * directly to wait for a reboot barker from the device. + * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot + * rom after reading the MAC adress. This is quite a dirty hack, + * if you ask me -- the device requires the bootrom to be + * intialized after reading the MAC address. + */ +enum i2400m_bri { + I2400M_BRI_SOFT = 1 << 1, + I2400M_BRI_NO_REBOOT = 1 << 2, + I2400M_BRI_MAC_REINIT = 1 << 3, +}; + +extern void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *); +extern int i2400m_dev_bootstrap(struct i2400m *, enum i2400m_bri); +extern int i2400m_read_mac_addr(struct i2400m *); +extern int i2400m_bootrom_init(struct i2400m *, enum i2400m_bri); + +/* Make/grok boot-rom header commands */ + +static inline +__le32 i2400m_brh_command(enum i2400m_brh_opcode opcode, unsigned use_checksum, + unsigned direct_access) +{ + return cpu_to_le32( + I2400M_BRH_SIGNATURE + | (direct_access ? I2400M_BRH_DIRECT_ACCESS : 0) + | I2400M_BRH_RESPONSE_REQUIRED /* response always required */ + | (use_checksum ? I2400M_BRH_USE_CHECKSUM : 0) + | (opcode & I2400M_BRH_OPCODE_MASK)); +} + +static inline +void i2400m_brh_set_opcode(struct i2400m_bootrom_header *hdr, + enum i2400m_brh_opcode opcode) +{ + hdr->command = cpu_to_le32( + (le32_to_cpu(hdr->command) & ~I2400M_BRH_OPCODE_MASK) + | (opcode & I2400M_BRH_OPCODE_MASK)); +} + +static inline +unsigned i2400m_brh_get_opcode(const struct i2400m_bootrom_header *hdr) +{ + return le32_to_cpu(hdr->command) & I2400M_BRH_OPCODE_MASK; +} + +static inline +unsigned i2400m_brh_get_response(const struct i2400m_bootrom_header *hdr) +{ + return (le32_to_cpu(hdr->command) & I2400M_BRH_RESPONSE_MASK) + >> I2400M_BRH_RESPONSE_SHIFT; +} + +static inline +unsigned i2400m_brh_get_use_checksum(const struct i2400m_bootrom_header *hdr) +{ + return le32_to_cpu(hdr->command) & I2400M_BRH_USE_CHECKSUM; +} + +static inline +unsigned i2400m_brh_get_response_required( + const struct i2400m_bootrom_header *hdr) +{ + return le32_to_cpu(hdr->command) & I2400M_BRH_RESPONSE_REQUIRED; +} + +static inline +unsigned i2400m_brh_get_direct_access(const struct i2400m_bootrom_header *hdr) +{ + return le32_to_cpu(hdr->command) & I2400M_BRH_DIRECT_ACCESS; +} + +static inline +unsigned i2400m_brh_get_signature(const struct i2400m_bootrom_header *hdr) +{ + return (le32_to_cpu(hdr->command) & I2400M_BRH_SIGNATURE_MASK) + >> I2400M_BRH_SIGNATURE_SHIFT; +} + + +/* + * Driver / device setup and internal functions + */ +extern void i2400m_netdev_setup(struct net_device *net_dev); +extern int i2400m_tx_setup(struct i2400m *); +extern void i2400m_wake_tx_work(struct work_struct *); +extern void i2400m_tx_release(struct i2400m *); + +extern void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned, + const void *, int); +enum i2400m_pt; +extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt); + +#ifdef CONFIG_DEBUG_FS +extern int i2400m_debugfs_add(struct i2400m *); +extern void i2400m_debugfs_rm(struct i2400m *); +#else +static inline int i2400m_debugfs_add(struct i2400m *i2400m) +{ + return 0; +} +static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {} +#endif + +/* Called by _dev_start()/_dev_stop() to initialize the device itself */ +extern int i2400m_dev_initialize(struct i2400m *); +extern void i2400m_dev_shutdown(struct i2400m *); + +extern struct attribute_group i2400m_dev_attr_group; + +extern int i2400m_schedule_work(struct i2400m *, + void (*)(struct work_struct *), gfp_t); + +/* HDI message's payload description handling */ + +static inline +size_t i2400m_pld_size(const struct i2400m_pld *pld) +{ + return I2400M_PLD_SIZE_MASK & le32_to_cpu(pld->val); +} + +static inline +enum i2400m_pt i2400m_pld_type(const struct i2400m_pld *pld) +{ + return (I2400M_PLD_TYPE_MASK & le32_to_cpu(pld->val)) + >> I2400M_PLD_TYPE_SHIFT; +} + +static inline +void i2400m_pld_set(struct i2400m_pld *pld, size_t size, + enum i2400m_pt type) +{ + pld->val = cpu_to_le32( + ((type << I2400M_PLD_TYPE_SHIFT) & I2400M_PLD_TYPE_MASK) + | (size & I2400M_PLD_SIZE_MASK)); +} + + +/* + * API for the bus-specific drivers + * -------------------------------- + */ + +static inline +struct i2400m *i2400m_get(struct i2400m *i2400m) +{ + dev_hold(i2400m->wimax_dev.net_dev); + return i2400m; +} + +static inline +void i2400m_put(struct i2400m *i2400m) +{ + dev_put(i2400m->wimax_dev.net_dev); +} + +extern int i2400m_dev_reset_handle(struct i2400m *); + +/* + * _setup()/_release() are called by the probe/disconnect functions of + * the bus-specific drivers. + */ +extern int i2400m_setup(struct i2400m *, enum i2400m_bri bm_flags); +extern void i2400m_release(struct i2400m *); + +extern int i2400m_rx(struct i2400m *, struct sk_buff *); +extern struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *); +extern void i2400m_tx_msg_sent(struct i2400m *); + +static const __le32 i2400m_NBOOT_BARKER[4] = { + __constant_cpu_to_le32(I2400M_NBOOT_BARKER), + __constant_cpu_to_le32(I2400M_NBOOT_BARKER), + __constant_cpu_to_le32(I2400M_NBOOT_BARKER), + __constant_cpu_to_le32(I2400M_NBOOT_BARKER) +}; + +static const __le32 i2400m_SBOOT_BARKER[4] = { + __constant_cpu_to_le32(I2400M_SBOOT_BARKER), + __constant_cpu_to_le32(I2400M_SBOOT_BARKER), + __constant_cpu_to_le32(I2400M_SBOOT_BARKER), + __constant_cpu_to_le32(I2400M_SBOOT_BARKER) +}; + + +/* + * Utility functions + */ + +static inline +struct device *i2400m_dev(struct i2400m *i2400m) +{ + return i2400m->wimax_dev.net_dev->dev.parent; +} + +/* + * Helper for scheduling simple work functions + * + * This struct can get any kind of payload attached (normally in the + * form of a struct where you pack the stuff you want to pass to the + * _work function). + */ +struct i2400m_work { + struct work_struct ws; + struct i2400m *i2400m; + u8 pl[0]; +}; +extern int i2400m_queue_work(struct i2400m *, + void (*)(struct work_struct *), gfp_t, + const void *, size_t); + +extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *, + char *, size_t); +extern int i2400m_msg_size_check(struct i2400m *, + const struct i2400m_l3l4_hdr *, size_t); +extern struct sk_buff *i2400m_msg_to_dev(struct i2400m *, const void *, size_t); +extern void i2400m_msg_to_dev_cancel_wait(struct i2400m *, int); +extern void i2400m_msg_ack_hook(struct i2400m *, + const struct i2400m_l3l4_hdr *, size_t); +extern void i2400m_report_hook(struct i2400m *, + const struct i2400m_l3l4_hdr *, size_t); +extern int i2400m_cmd_enter_powersave(struct i2400m *); +extern int i2400m_cmd_get_state(struct i2400m *); +extern int i2400m_cmd_exit_idle(struct i2400m *); +extern struct sk_buff *i2400m_get_device_info(struct i2400m *); +extern int i2400m_firmware_check(struct i2400m *); +extern int i2400m_set_init_config(struct i2400m *, + const struct i2400m_tlv_hdr **, size_t); + +static inline +struct usb_endpoint_descriptor *usb_get_epd(struct usb_interface *iface, int ep) +{ + return &iface->cur_altsetting->endpoint[ep].desc; +} + +extern int i2400m_op_rfkill_sw_toggle(struct wimax_dev *, + enum wimax_rf_state); +extern void i2400m_report_tlv_rf_switches_status( + struct i2400m *, const struct i2400m_tlv_rf_switches_status *); + + +/* + * Do a millisecond-sleep for allowing wireshark to dump all the data + * packets. Used only for debugging. + */ +static inline +void __i2400m_msleep(unsigned ms) +{ +#if 1 +#else + msleep(ms); +#endif +} + +/* Module parameters */ + +extern int i2400m_idle_mode_disabled; + + +#endif /* #ifndef __I2400M_H__ */ -- cgit From 024f7f31ed15c471f80408d8b5045497e27e1135 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:44 -0800 Subject: i2400m: Generic probe/disconnect, reset and message passing Implements the generic probe and disconnect functions that will be called by the USB and SDIO driver's probe/disconnect functions. Implements the backends for the WiMAX stack's basic operations: message passing, rfkill control and reset. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/driver.c | 728 +++++++++++++++++++++++++++++++++++ drivers/net/wimax/i2400m/op-rfkill.c | 207 ++++++++++ 2 files changed, 935 insertions(+) create mode 100644 drivers/net/wimax/i2400m/driver.c create mode 100644 drivers/net/wimax/i2400m/op-rfkill.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c new file mode 100644 index 00000000000..5f98047e18c --- /dev/null +++ b/drivers/net/wimax/i2400m/driver.c @@ -0,0 +1,728 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Generic probe/disconnect, reset and message passing + * + * + * Copyright (C) 2007-2008 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * See i2400m.h for driver documentation. This contains helpers for + * the driver model glue [_setup()/_release()], handling device resets + * [_dev_reset_handle()], and the backends for the WiMAX stack ops + * reset [_op_reset()] and message from user [_op_msg_from_user()]. + * + * ROADMAP: + * + * i2400m_op_msg_from_user() + * i2400m_msg_to_dev() + * wimax_msg_to_user_send() + * + * i2400m_op_reset() + * i240m->bus_reset() + * + * i2400m_dev_reset_handle() + * __i2400m_dev_reset_handle() + * __i2400m_dev_stop() + * __i2400m_dev_start() + * + * i2400m_setup() + * i2400m_bootrom_init() + * register_netdev() + * i2400m_dev_start() + * __i2400m_dev_start() + * i2400m_dev_bootstrap() + * i2400m_tx_setup() + * i2400m->bus_dev_start() + * i2400m_check_mac_addr() + * wimax_dev_add() + * + * i2400m_release() + * wimax_dev_rm() + * i2400m_dev_stop() + * __i2400m_dev_stop() + * i2400m_dev_shutdown() + * i2400m->bus_dev_stop() + * i2400m_tx_release() + * unregister_netdev() + */ +#include "i2400m.h" +#include +#include +#include + +#define D_SUBMODULE driver +#include "debug-levels.h" + + +int i2400m_idle_mode_disabled; /* 0 (idle mode enabled) by default */ +module_param_named(idle_mode_disabled, i2400m_idle_mode_disabled, int, 0644); +MODULE_PARM_DESC(idle_mode_disabled, + "If true, the device will not enable idle mode negotiation " + "with the base station (when connected) to save power."); + +/** + * i2400m_queue_work - schedule work on a i2400m's queue + * + * @i2400m: device descriptor + * + * @fn: function to run to execute work. It gets passed a 'struct + * work_struct' that is wrapped in a 'struct i2400m_work'. Once + * done, you have to (1) i2400m_put(i2400m_work->i2400m) and then + * (2) kfree(i2400m_work). + * + * @gfp_flags: GFP flags for memory allocation. + * + * @pl: pointer to a payload buffer that you want to pass to the _work + * function. Use this to pack (for example) a struct with extra + * arguments. + * + * @pl_size: size of the payload buffer. + * + * We do this quite often, so this just saves typing; allocate a + * wrapper for a i2400m, get a ref to it, pack arguments and launch + * the work. + * + * A usual workflow is: + * + * struct my_work_args { + * void *something; + * int whatever; + * }; + * ... + * + * struct my_work_args my_args = { + * .something = FOO, + * .whaetever = BLAH + * }; + * i2400m_queue_work(i2400m, 1, my_work_function, GFP_KERNEL, + * &args, sizeof(args)) + * + * And now the work function can unpack the arguments and call the + * real function (or do the job itself): + * + * static + * void my_work_fn((struct work_struct *ws) + * { + * struct i2400m_work *iw = + * container_of(ws, struct i2400m_work, ws); + * struct my_work_args *my_args = (void *) iw->pl; + * + * my_work(iw->i2400m, my_args->something, my_args->whatevert); + * } + */ +int i2400m_queue_work(struct i2400m *i2400m, + void (*fn)(struct work_struct *), gfp_t gfp_flags, + const void *pl, size_t pl_size) +{ + int result; + struct i2400m_work *iw; + + BUG_ON(i2400m->work_queue == NULL); + result = -ENOMEM; + iw = kzalloc(sizeof(*iw) + pl_size, gfp_flags); + if (iw == NULL) + goto error_kzalloc; + iw->i2400m = i2400m_get(i2400m); + memcpy(iw->pl, pl, pl_size); + INIT_WORK(&iw->ws, fn); + result = queue_work(i2400m->work_queue, &iw->ws); +error_kzalloc: + return result; +} +EXPORT_SYMBOL_GPL(i2400m_queue_work); + + +/* + * Schedule i2400m's specific work on the system's queue. + * + * Used for a few cases where we really need it; otherwise, identical + * to i2400m_queue_work(). + * + * Returns < 0 errno code on error, 1 if ok. + * + * If it returns zero, something really bad happened, as it means the + * works struct was already queued, but we have just allocated it, so + * it should not happen. + */ +int i2400m_schedule_work(struct i2400m *i2400m, + void (*fn)(struct work_struct *), gfp_t gfp_flags) +{ + int result; + struct i2400m_work *iw; + + BUG_ON(i2400m->work_queue == NULL); + result = -ENOMEM; + iw = kzalloc(sizeof(*iw), gfp_flags); + if (iw == NULL) + goto error_kzalloc; + iw->i2400m = i2400m_get(i2400m); + INIT_WORK(&iw->ws, fn); + result = schedule_work(&iw->ws); + if (result == 0) + result = -ENXIO; +error_kzalloc: + return result; +} + + +/* + * WiMAX stack operation: relay a message from user space + * + * @wimax_dev: device descriptor + * @pipe_name: named pipe the message is for + * @msg_buf: pointer to the message bytes + * @msg_len: length of the buffer + * @genl_info: passed by the generic netlink layer + * + * The WiMAX stack will call this function when a message was received + * from user space. + * + * For the i2400m, this is an L3L4 message, as specified in + * include/linux/wimax/i2400m.h, and thus prefixed with a 'struct + * i2400m_l3l4_hdr'. Driver (and device) expect the messages to be + * coded in Little Endian. + * + * This function just verifies that the header declaration and the + * payload are consistent and then deals with it, either forwarding it + * to the device or procesing it locally. + * + * In the i2400m, messages are basically commands that will carry an + * ack, so we use i2400m_msg_to_dev() and then deliver the ack back to + * user space. The rx.c code might intercept the response and use it + * to update the driver's state, but then it will pass it on so it can + * be relayed back to user space. + * + * Note that asynchronous events from the device are processed and + * sent to user space in rx.c. + */ +static +int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev, + const char *pipe_name, + const void *msg_buf, size_t msg_len, + const struct genl_info *genl_info) +{ + int result; + struct i2400m *i2400m = wimax_dev_to_i2400m(wimax_dev); + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + + d_fnstart(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p " + "msg_len %zu genl_info %p)\n", wimax_dev, i2400m, + msg_buf, msg_len, genl_info); + ack_skb = i2400m_msg_to_dev(i2400m, msg_buf, msg_len); + result = PTR_ERR(ack_skb); + if (IS_ERR(ack_skb)) + goto error_msg_to_dev; + if (unlikely(i2400m->trace_msg_from_user)) + wimax_msg(&i2400m->wimax_dev, "trace", + msg_buf, msg_len, GFP_KERNEL); + result = wimax_msg_send(&i2400m->wimax_dev, ack_skb); +error_msg_to_dev: + d_fnend(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu " + "genl_info %p) = %d\n", wimax_dev, i2400m, msg_buf, msg_len, + genl_info, result); + return result; +} + + +/* + * Context to wait for a reset to finalize + */ +struct i2400m_reset_ctx { + struct completion completion; + int result; +}; + + +/* + * WiMAX stack operation: reset a device + * + * @wimax_dev: device descriptor + * + * See the documentation for wimax_reset() and wimax_dev->op_reset for + * the requirements of this function. The WiMAX stack guarantees + * serialization on calls to this function. + * + * Do a warm reset on the device; if it fails, resort to a cold reset + * and return -ENODEV. On successful warm reset, we need to block + * until it is complete. + * + * The bus-driver implementation of reset takes care of falling back + * to cold reset if warm fails. + */ +static +int i2400m_op_reset(struct wimax_dev *wimax_dev) +{ + int result; + struct i2400m *i2400m = wimax_dev_to_i2400m(wimax_dev); + struct device *dev = i2400m_dev(i2400m); + struct i2400m_reset_ctx ctx = { + .completion = COMPLETION_INITIALIZER_ONSTACK(ctx.completion), + .result = 0, + }; + + d_fnstart(4, dev, "(wimax_dev %p)\n", wimax_dev); + mutex_lock(&i2400m->init_mutex); + i2400m->reset_ctx = &ctx; + mutex_unlock(&i2400m->init_mutex); + result = i2400m->bus_reset(i2400m, I2400M_RT_WARM); + if (result < 0) + goto out; + result = wait_for_completion_timeout(&ctx.completion, 4*HZ); + if (result == 0) + result = -ETIMEDOUT; + else if (result > 0) + result = ctx.result; + /* if result < 0, pass it on */ + mutex_lock(&i2400m->init_mutex); + i2400m->reset_ctx = NULL; + mutex_unlock(&i2400m->init_mutex); +out: + d_fnend(4, dev, "(wimax_dev %p) = %d\n", wimax_dev, result); + return result; +} + + +/* + * Check the MAC address we got from boot mode is ok + * + * @i2400m: device descriptor + * + * Returns: 0 if ok, < 0 errno code on error. + */ +static +int i2400m_check_mac_addr(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *skb; + const struct i2400m_tlv_detailed_device_info *ddi; + struct net_device *net_dev = i2400m->wimax_dev.net_dev; + const unsigned char zeromac[ETH_ALEN] = { 0 }; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + skb = i2400m_get_device_info(i2400m); + if (IS_ERR(skb)) { + result = PTR_ERR(skb); + dev_err(dev, "Cannot verify MAC address, error reading: %d\n", + result); + goto error; + } + /* Extract MAC addresss */ + ddi = (void *) skb->data; + BUILD_BUG_ON(ETH_ALEN != sizeof(ddi->mac_address)); + d_printf(2, dev, "GET DEVICE INFO: mac addr " + "%02x:%02x:%02x:%02x:%02x:%02x\n", + ddi->mac_address[0], ddi->mac_address[1], + ddi->mac_address[2], ddi->mac_address[3], + ddi->mac_address[4], ddi->mac_address[5]); + if (!memcmp(net_dev->perm_addr, ddi->mac_address, + sizeof(ddi->mac_address))) + goto ok; + dev_warn(dev, "warning: device reports a different MAC address " + "to that of boot mode's\n"); + dev_warn(dev, "device reports %02x:%02x:%02x:%02x:%02x:%02x\n", + ddi->mac_address[0], ddi->mac_address[1], + ddi->mac_address[2], ddi->mac_address[3], + ddi->mac_address[4], ddi->mac_address[5]); + dev_warn(dev, "boot mode reported %02x:%02x:%02x:%02x:%02x:%02x\n", + net_dev->perm_addr[0], net_dev->perm_addr[1], + net_dev->perm_addr[2], net_dev->perm_addr[3], + net_dev->perm_addr[4], net_dev->perm_addr[5]); + if (!memcmp(zeromac, ddi->mac_address, sizeof(zeromac))) + dev_err(dev, "device reports an invalid MAC address, " + "not updating\n"); + else { + dev_warn(dev, "updating MAC address\n"); + net_dev->addr_len = ETH_ALEN; + memcpy(net_dev->perm_addr, ddi->mac_address, ETH_ALEN); + memcpy(net_dev->dev_addr, ddi->mac_address, ETH_ALEN); + } +ok: + result = 0; + kfree_skb(skb); +error: + d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); + return result; +} + + +/** + * __i2400m_dev_start - Bring up driver communication with the device + * + * @i2400m: device descriptor + * @flags: boot mode flags + * + * Returns: 0 if ok, < 0 errno code on error. + * + * Uploads firmware and brings up all the resources needed to be able + * to communicate with the device. + * + * TX needs to be setup before the bus-specific code (otherwise on + * shutdown, the bus-tx code could try to access it). + */ +static +int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) +{ + int result; + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + struct net_device *net_dev = wimax_dev->net_dev; + struct device *dev = i2400m_dev(i2400m); + int times = 3; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); +retry: + result = i2400m_dev_bootstrap(i2400m, flags); + if (result < 0) { + dev_err(dev, "cannot bootstrap device: %d\n", result); + goto error_bootstrap; + } + result = i2400m_tx_setup(i2400m); + if (result < 0) + goto error_tx_setup; + result = i2400m->bus_dev_start(i2400m); + if (result < 0) + goto error_bus_dev_start; + i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name); + if (i2400m->work_queue == NULL) { + result = -ENOMEM; + dev_err(dev, "cannot create workqueue\n"); + goto error_create_workqueue; + } + /* At this point is ok to send commands to the device */ + result = i2400m_check_mac_addr(i2400m); + if (result < 0) + goto error_check_mac_addr; + i2400m->ready = 1; + wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED); + result = i2400m_dev_initialize(i2400m); + if (result < 0) + goto error_dev_initialize; + /* At this point, reports will come for the device and set it + * to the right state if it is different than UNINITIALIZED */ + d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", + net_dev, i2400m, result); + return result; + +error_dev_initialize: +error_check_mac_addr: + destroy_workqueue(i2400m->work_queue); +error_create_workqueue: + i2400m->bus_dev_stop(i2400m); +error_bus_dev_start: + i2400m_tx_release(i2400m); +error_tx_setup: +error_bootstrap: + if (result == -ERESTARTSYS && times-- > 0) { + flags = I2400M_BRI_SOFT; + goto retry; + } + d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", + net_dev, i2400m, result); + return result; +} + + +static +int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags) +{ + int result; + mutex_lock(&i2400m->init_mutex); /* Well, start the device */ + result = __i2400m_dev_start(i2400m, bm_flags); + if (result >= 0) + i2400m->updown = 1; + mutex_unlock(&i2400m->init_mutex); + return result; +} + + +/** + * i2400m_dev_stop - Tear down driver communication with the device + * + * @i2400m: device descriptor + * + * Returns: 0 if ok, < 0 errno code on error. + * + * Releases all the resources allocated to communicate with the device. + */ +static +void __i2400m_dev_stop(struct i2400m *i2400m) +{ + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); + i2400m_dev_shutdown(i2400m); + i2400m->ready = 0; + destroy_workqueue(i2400m->work_queue); + i2400m->bus_dev_stop(i2400m); + i2400m_tx_release(i2400m); + wimax_state_change(wimax_dev, WIMAX_ST_DOWN); + d_fnend(3, dev, "(i2400m %p) = 0\n", i2400m); +} + + +/* + * Watch out -- we only need to stop if there is a need for it. The + * device could have reset itself and failed to come up again (see + * _i2400m_dev_reset_handle()). + */ +static +void i2400m_dev_stop(struct i2400m *i2400m) +{ + mutex_lock(&i2400m->init_mutex); + if (i2400m->updown) { + __i2400m_dev_stop(i2400m); + i2400m->updown = 0; + } + mutex_unlock(&i2400m->init_mutex); +} + + +/* + * The device has rebooted; fix up the device and the driver + * + * Tear down the driver communication with the device, reload the + * firmware and reinitialize the communication with the device. + * + * If someone calls a reset when the device's firmware is down, in + * theory we won't see it because we are not listening. However, just + * in case, leave the code to handle it. + * + * If there is a reset context, use it; this means someone is waiting + * for us to tell him when the reset operation is complete and the + * device is ready to rock again. + * + * NOTE: if we are in the process of bringing up or down the + * communication with the device [running i2400m_dev_start() or + * _stop()], don't do anything, let it fail and handle it. + * + * This function is ran always in a thread context + */ +static +void __i2400m_dev_reset_handle(struct work_struct *ws) +{ + int result; + struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws); + struct i2400m *i2400m = iw->i2400m; + struct device *dev = i2400m_dev(i2400m); + enum wimax_st wimax_state; + struct i2400m_reset_ctx *ctx = i2400m->reset_ctx; + + d_fnstart(3, dev, "(ws %p i2400m %p)\n", ws, i2400m); + result = 0; + if (mutex_trylock(&i2400m->init_mutex) == 0) { + /* We are still in i2400m_dev_start() [let it fail] or + * i2400m_dev_stop() [we are shutting down anyway, so + * ignore it] or we are resetting somewhere else. */ + dev_err(dev, "device rebooted\n"); + i2400m_msg_to_dev_cancel_wait(i2400m, -ERESTARTSYS); + complete(&i2400m->msg_completion); + goto out; + } + wimax_state = wimax_state_get(&i2400m->wimax_dev); + if (wimax_state < WIMAX_ST_UNINITIALIZED) { + dev_info(dev, "device rebooted: it is down, ignoring\n"); + goto out_unlock; /* ifconfig up/down wasn't called */ + } + dev_err(dev, "device rebooted: reinitializing driver\n"); + __i2400m_dev_stop(i2400m); + i2400m->updown = 0; + result = __i2400m_dev_start(i2400m, + I2400M_BRI_SOFT | I2400M_BRI_MAC_REINIT); + if (result < 0) { + dev_err(dev, "device reboot: cannot start the device: %d\n", + result); + result = i2400m->bus_reset(i2400m, I2400M_RT_BUS); + if (result >= 0) + result = -ENODEV; + } else + i2400m->updown = 1; +out_unlock: + if (i2400m->reset_ctx) { + ctx->result = result; + complete(&ctx->completion); + } + mutex_unlock(&i2400m->init_mutex); +out: + i2400m_put(i2400m); + kfree(iw); + d_fnend(3, dev, "(ws %p i2400m %p) = void\n", ws, i2400m); + return; +} + + +/** + * i2400m_dev_reset_handle - Handle a device's reset in a thread context + * + * Schedule a device reset handling out on a thread context, so it + * is safe to call from atomic context. We can't use the i2400m's + * queue as we are going to destroy it and reinitialize it as part of + * the driver bringup/bringup process. + * + * See __i2400m_dev_reset_handle() for details; that takes care of + * reinitializing the driver to handle the reset, calling into the + * bus-specific functions ops as needed. + */ +int i2400m_dev_reset_handle(struct i2400m *i2400m) +{ + return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle, + GFP_ATOMIC); +} +EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle); + + +/** + * i2400m_setup - bus-generic setup function for the i2400m device + * + * @i2400m: device descriptor (bus-specific parts have been initialized) + * + * Returns: 0 if ok, < 0 errno code on error. + * + * Initializes the bus-generic parts of the i2400m driver; the + * bus-specific parts have been initialized, function pointers filled + * out by the bus-specific probe function. + * + * As well, this registers the WiMAX and net device nodes. Once this + * function returns, the device is operative and has to be ready to + * receive and send network traffic and WiMAX control operations. + */ +int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) +{ + int result = -ENODEV; + struct device *dev = i2400m_dev(i2400m); + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + struct net_device *net_dev = i2400m->wimax_dev.net_dev; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + + snprintf(wimax_dev->name, sizeof(wimax_dev->name), + "i2400m-%s:%s", dev->bus->name, dev->bus_id); + + i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL); + if (i2400m->bm_cmd_buf == NULL) { + dev_err(dev, "cannot allocate USB command buffer\n"); + goto error_bm_cmd_kzalloc; + } + i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL); + if (i2400m->bm_ack_buf == NULL) { + dev_err(dev, "cannot allocate USB ack buffer\n"); + goto error_bm_ack_buf_kzalloc; + } + result = i2400m_bootrom_init(i2400m, bm_flags); + if (result < 0) { + dev_err(dev, "read mac addr: bootrom init " + "failed: %d\n", result); + goto error_bootrom_init; + } + result = i2400m_read_mac_addr(i2400m); + if (result < 0) + goto error_read_mac_addr; + + result = register_netdev(net_dev); /* Okey dokey, bring it up */ + if (result < 0) { + dev_err(dev, "cannot register i2400m network device: %d\n", + result); + goto error_register_netdev; + } + netif_carrier_off(net_dev); + + result = i2400m_dev_start(i2400m, bm_flags); + if (result < 0) + goto error_dev_start; + + i2400m->wimax_dev.op_msg_from_user = i2400m_op_msg_from_user; + i2400m->wimax_dev.op_rfkill_sw_toggle = i2400m_op_rfkill_sw_toggle; + i2400m->wimax_dev.op_reset = i2400m_op_reset; + result = wimax_dev_add(&i2400m->wimax_dev, net_dev); + if (result < 0) + goto error_wimax_dev_add; + /* User space needs to do some init stuff */ + wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED); + + /* Now setup all that requires a registered net and wimax device. */ + result = i2400m_debugfs_add(i2400m); + if (result < 0) { + dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result); + goto error_debugfs_setup; + } + d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); + return result; + +error_debugfs_setup: + wimax_dev_rm(&i2400m->wimax_dev); +error_wimax_dev_add: + i2400m_dev_stop(i2400m); +error_dev_start: + unregister_netdev(net_dev); +error_register_netdev: +error_read_mac_addr: +error_bootrom_init: + kfree(i2400m->bm_ack_buf); +error_bm_ack_buf_kzalloc: + kfree(i2400m->bm_cmd_buf); +error_bm_cmd_kzalloc: + d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); + return result; +} +EXPORT_SYMBOL_GPL(i2400m_setup); + + +/** + * i2400m_release - release the bus-generic driver resources + * + * Sends a disconnect message and undoes any setup done by i2400m_setup() + */ +void i2400m_release(struct i2400m *i2400m) +{ + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + netif_stop_queue(i2400m->wimax_dev.net_dev); + + i2400m_debugfs_rm(i2400m); + wimax_dev_rm(&i2400m->wimax_dev); + i2400m_dev_stop(i2400m); + unregister_netdev(i2400m->wimax_dev.net_dev); + kfree(i2400m->bm_ack_buf); + kfree(i2400m->bm_cmd_buf); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); +} +EXPORT_SYMBOL_GPL(i2400m_release); + + +static +int __init i2400m_driver_init(void) +{ + return 0; +} +module_init(i2400m_driver_init); + +static +void __exit i2400m_driver_exit(void) +{ + /* for scheds i2400m_dev_reset_handle() */ + flush_scheduled_work(); + return; +} +module_exit(i2400m_driver_exit); + +MODULE_AUTHOR("Intel Corporation "); +MODULE_DESCRIPTION("Intel 2400M WiMAX networking bus-generic driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c new file mode 100644 index 00000000000..487ec58cea4 --- /dev/null +++ b/drivers/net/wimax/i2400m/op-rfkill.c @@ -0,0 +1,207 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Implement backend for the WiMAX stack rfkill support + * + * + * Copyright (C) 2007-2008 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * The WiMAX kernel stack integrates into RF-Kill and keeps the + * switches's status. We just need to: + * + * - report changes in the HW RF Kill switch [with + * wimax_rfkill_{sw,hw}_report(), which happens when we detect those + * indications coming through hardware reports]. We also do it on + * initialization to let the stack know the intial HW state. + * + * - implement indications from the stack to change the SW RF Kill + * switch (coming from sysfs, the wimax stack or user space). + */ +#include "i2400m.h" +#include + + + +#define D_SUBMODULE rfkill +#include "debug-levels.h" + +/* + * Return true if the i2400m radio is in the requested wimax_rf_state state + * + */ +static +int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state) +{ + if (state == WIMAX_RF_OFF) + return i2400m->state == I2400M_SS_RF_OFF + || i2400m->state == I2400M_SS_RF_SHUTDOWN; + else if (state == WIMAX_RF_ON) + /* state == WIMAX_RF_ON */ + return i2400m->state != I2400M_SS_RF_OFF + && i2400m->state != I2400M_SS_RF_SHUTDOWN; + else + BUG(); +} + + +/* + * WiMAX stack operation: implement SW RFKill toggling + * + * @wimax_dev: device descriptor + * @skb: skb where the message has been received; skb->data is + * expected to point to the message payload. + * @genl_info: passed by the generic netlink layer + * + * Generic Netlink will call this function when a message is sent from + * userspace to change the software RF-Kill switch status. + * + * This function will set the device's sofware RF-Kill switch state to + * match what is requested. + * + * NOTE: the i2400m has a strict state machine; we can only set the + * RF-Kill switch when it is on, the HW RF-Kill is on and the + * device is initialized. So we ignore errors steaming from not + * being in the right state (-EILSEQ). + */ +int i2400m_op_rfkill_sw_toggle(struct wimax_dev *wimax_dev, + enum wimax_rf_state state) +{ + int result; + struct i2400m *i2400m = wimax_dev_to_i2400m(wimax_dev); + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + struct { + struct i2400m_l3l4_hdr hdr; + struct i2400m_tlv_rf_operation sw_rf; + } __attribute__((packed)) *cmd; + char strerr[32]; + + d_fnstart(4, dev, "(wimax_dev %p state %d)\n", wimax_dev, state); + + result = -ENOMEM; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + goto error_alloc; + cmd->hdr.type = cpu_to_le16(I2400M_MT_CMD_RF_CONTROL); + cmd->hdr.length = sizeof(cmd->sw_rf); + cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION); + cmd->sw_rf.hdr.type = cpu_to_le16(I2400M_TLV_RF_OPERATION); + cmd->sw_rf.hdr.length = cpu_to_le16(sizeof(cmd->sw_rf.status)); + switch (state) { + case WIMAX_RF_OFF: /* RFKILL ON, radio OFF */ + cmd->sw_rf.status = cpu_to_le32(2); + break; + case WIMAX_RF_ON: /* RFKILL OFF, radio ON */ + cmd->sw_rf.status = cpu_to_le32(1); + break; + default: + BUG(); + } + + ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); + result = PTR_ERR(ack_skb); + if (IS_ERR(ack_skb)) { + dev_err(dev, "Failed to issue 'RF Control' command: %d\n", + result); + goto error_msg_to_dev; + } + result = i2400m_msg_check_status(wimax_msg_data(ack_skb), + strerr, sizeof(strerr)); + if (result < 0) { + dev_err(dev, "'RF Control' (0x%04x) command failed: %d - %s\n", + I2400M_MT_CMD_RF_CONTROL, result, strerr); + goto error_cmd; + } + + /* Now we wait for the state to change to RADIO_OFF or RADIO_ON */ + result = wait_event_timeout( + i2400m->state_wq, i2400m_radio_is(i2400m, state), + 5 * HZ); + if (result == 0) + result = -ETIMEDOUT; + if (result < 0) + dev_err(dev, "Error waiting for device to toggle RF state: " + "%d\n", result); + result = 0; +error_cmd: + kfree_skb(ack_skb); +error_msg_to_dev: +error_alloc: + d_fnend(4, dev, "(wimax_dev %p state %d) = %d\n", + wimax_dev, state, result); + return result; +} + + +/* + * Inform the WiMAX stack of changes in the RF Kill switches reported + * by the device + * + * @i2400m: device descriptor + * @rfss: TLV for RF Switches status; already validated + * + * NOTE: the reports on RF switch status cannot be trusted + * or used until the device is in a state of RADIO_OFF + * or greater. + */ +void i2400m_report_tlv_rf_switches_status( + struct i2400m *i2400m, + const struct i2400m_tlv_rf_switches_status *rfss) +{ + struct device *dev = i2400m_dev(i2400m); + enum i2400m_rf_switch_status hw, sw; + enum wimax_st wimax_state; + + sw = le32_to_cpu(rfss->sw_rf_switch); + hw = le32_to_cpu(rfss->hw_rf_switch); + + d_fnstart(3, dev, "(i2400m %p rfss %p [hw %u sw %u])\n", + i2400m, rfss, hw, sw); + /* We only process rw switch evens when the device has been + * fully initialized */ + wimax_state = wimax_state_get(&i2400m->wimax_dev); + if (wimax_state < WIMAX_ST_RADIO_OFF) { + d_printf(3, dev, "ignoring RF switches report, state %u\n", + wimax_state); + goto out; + } + switch (sw) { + case I2400M_RF_SWITCH_ON: /* RF Kill disabled (radio on) */ + wimax_report_rfkill_sw(&i2400m->wimax_dev, WIMAX_RF_ON); + break; + case I2400M_RF_SWITCH_OFF: /* RF Kill enabled (radio off) */ + wimax_report_rfkill_sw(&i2400m->wimax_dev, WIMAX_RF_OFF); + break; + default: + dev_err(dev, "HW BUG? Unknown RF SW state 0x%x\n", sw); + } + + switch (hw) { + case I2400M_RF_SWITCH_ON: /* RF Kill disabled (radio on) */ + wimax_report_rfkill_hw(&i2400m->wimax_dev, WIMAX_RF_ON); + break; + case I2400M_RF_SWITCH_OFF: /* RF Kill enabled (radio off) */ + wimax_report_rfkill_hw(&i2400m->wimax_dev, WIMAX_RF_OFF); + break; + default: + dev_err(dev, "HW BUG? Unknown RF HW state 0x%x\n", hw); + } +out: + d_fnend(3, dev, "(i2400m %p rfss %p [hw %u sw %u]) = void\n", + i2400m, rfss, hw, sw); +} -- cgit From ce6cde92803e961d95ddacdf74bd8b067f82f7d4 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:45 -0800 Subject: i2400m: linkage to the networking stack Implementation of the glue to the network stack so the WiMAX device shows up as an Ethernet device. Initially we shot for implementing a Pure IP device -- however, the world seems to turn around Ethernet devices. Main issues were with the ISC DHCP client and servers (as they don't understand types other than Ethernet and Token Ring). We proceeded to register with IANA the PureIP hw type, so that DHCP requests could declare such. We also created patches to the main ISC DHCP versions to support it. However, until all that permeates into deployments, there is going to be a long time. So we moved back to wrap Ethernet frames around the PureIP device. At the time being this has overhead; we need to reallocate with space for an Ethernet header. The reason is the device-to-host protocol coalesces many network packets into a single message, so we can't introduce Ethernet headers without overwriting valid data from other packets. Coming-soon versions of the firmware have this issue solved. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/netdev.c | 524 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 524 insertions(+) create mode 100644 drivers/net/wimax/i2400m/netdev.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c new file mode 100644 index 00000000000..63fe708e8a3 --- /dev/null +++ b/drivers/net/wimax/i2400m/netdev.c @@ -0,0 +1,524 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Glue with the networking stack + * + * + * Copyright (C) 2007 Intel Corporation + * Yanir Lubetkin + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * This implements an ethernet device for the i2400m. + * + * We fake being an ethernet device to simplify the support from user + * space and from the other side. The world is (sadly) configured to + * take in only Ethernet devices... + * + * Because of this, currently there is an copy-each-rxed-packet + * overhead on the RX path. Each IP packet has to be reallocated to + * add an ethernet header (as there is no space in what we get from + * the device). This is a known drawback and coming versions of the + * device's firmware are being changed to add header space that can be + * used to insert the ethernet header without having to reallocate and + * copy. + * + * TX error handling is tricky; because we have to FIFO/queue the + * buffers for transmission (as the hardware likes it aggregated), we + * just give the skb to the TX subsystem and by the time it is + * transmitted, we have long forgotten about it. So we just don't care + * too much about it. + * + * Note that when the device is in idle mode with the basestation, we + * need to negotiate coming back up online. That involves negotiation + * and possible user space interaction. Thus, we defer to a workqueue + * to do all that. By default, we only queue a single packet and drop + * the rest, as potentially the time to go back from idle to normal is + * long. + * + * ROADMAP + * + * i2400m_open Called on ifconfig up + * i2400m_stop Called on ifconfig down + * + * i2400m_hard_start_xmit Called by the network stack to send a packet + * i2400m_net_wake_tx Wake up device from basestation-IDLE & TX + * i2400m_wake_tx_work + * i2400m_cmd_exit_idle + * i2400m_tx + * i2400m_net_tx TX a data frame + * i2400m_tx + * + * i2400m_change_mtu Called on ifconfig mtu XXX + * + * i2400m_tx_timeout Called when the device times out + * + * i2400m_net_rx Called by the RX code when a data frame is + * available. + * i2400m_netdev_setup Called to setup all the netdev stuff from + * alloc_netdev. + */ +#include +#include +#include "i2400m.h" + + +#define D_SUBMODULE netdev +#include "debug-levels.h" + +enum { +/* netdev interface */ + /* + * Out of NWG spec (R1_v1.2.2), 3.3.3 ASN Bearer Plane MTU Size + * + * The MTU is 1400 or less + */ + I2400M_MAX_MTU = 1400, + I2400M_TX_TIMEOUT = HZ, + I2400M_TX_QLEN = 5, +}; + + +static +int i2400m_open(struct net_device *net_dev) +{ + int result; + struct i2400m *i2400m = net_dev_to_i2400m(net_dev); + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m); + if (i2400m->ready == 0) { + dev_err(dev, "Device is still initializing\n"); + result = -EBUSY; + } else + result = 0; + d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", + net_dev, i2400m, result); + return result; +} + + +/* + * + * On kernel versions where cancel_work_sync() didn't return anything, + * we rely on wake_tx_skb() being non-NULL. + */ +static +int i2400m_stop(struct net_device *net_dev) +{ + struct i2400m *i2400m = net_dev_to_i2400m(net_dev); + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m); + /* See i2400m_hard_start_xmit(), references are taken there + * and here we release them if the work was still + * pending. Note we can't differentiate work not pending vs + * never scheduled, so the NULL check does that. */ + if (cancel_work_sync(&i2400m->wake_tx_ws) == 0 + && i2400m->wake_tx_skb != NULL) { + unsigned long flags; + struct sk_buff *wake_tx_skb; + spin_lock_irqsave(&i2400m->tx_lock, flags); + wake_tx_skb = i2400m->wake_tx_skb; /* compat help */ + i2400m->wake_tx_skb = NULL; /* compat help */ + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + i2400m_put(i2400m); + kfree_skb(wake_tx_skb); + } + d_fnend(3, dev, "(net_dev %p [i2400m %p]) = 0\n", net_dev, i2400m); + return 0; +} + + +/* + * Wake up the device and transmit a held SKB, then restart the net queue + * + * When the device goes into basestation-idle mode, we need to tell it + * to exit that mode; it will negotiate with the base station, user + * space may have to intervene to rehandshake crypto and then tell us + * when it is ready to transmit the packet we have "queued". Still we + * need to give it sometime after it reports being ok. + * + * On error, there is not much we can do. If the error was on TX, we + * still wake the queue up to see if the next packet will be luckier. + * + * If _cmd_exit_idle() fails...well, it could be many things; most + * commonly it is that something else took the device out of IDLE mode + * (for example, the base station). In that case we get an -EILSEQ and + * we are just going to ignore that one. If the device is back to + * connected, then fine -- if it is someother state, the packet will + * be dropped anyway. + */ +void i2400m_wake_tx_work(struct work_struct *ws) +{ + int result; + struct i2400m *i2400m = container_of(ws, struct i2400m, wake_tx_ws); + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *skb = i2400m->wake_tx_skb; + unsigned long flags; + + spin_lock_irqsave(&i2400m->tx_lock, flags); + skb = i2400m->wake_tx_skb; + i2400m->wake_tx_skb = NULL; + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + + d_fnstart(3, dev, "(ws %p i2400m %p skb %p)\n", ws, i2400m, skb); + result = -EINVAL; + if (skb == NULL) { + dev_err(dev, "WAKE&TX: skb dissapeared!\n"); + goto out_put; + } + result = i2400m_cmd_exit_idle(i2400m); + if (result == -EILSEQ) + result = 0; + if (result < 0) { + dev_err(dev, "WAKE&TX: device didn't get out of idle: " + "%d\n", result); + goto error; + } + result = wait_event_timeout(i2400m->state_wq, + i2400m->state != I2400M_SS_IDLE, 5 * HZ); + if (result == 0) + result = -ETIMEDOUT; + if (result < 0) { + dev_err(dev, "WAKE&TX: error waiting for device to exit IDLE: " + "%d\n", result); + goto error; + } + msleep(20); /* device still needs some time or it drops it */ + result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA); + netif_wake_queue(i2400m->wimax_dev.net_dev); +error: + kfree_skb(skb); /* refcount transferred by _hard_start_xmit() */ +out_put: + i2400m_put(i2400m); + d_fnend(3, dev, "(ws %p i2400m %p skb %p) = void [%d]\n", + ws, i2400m, skb, result); +} + + +/* + * Prepare the data payload TX header + * + * The i2400m expects a 4 byte header in front of a data packet. + * + * Because we pretend to be an ethernet device, this packet comes with + * an ethernet header. Pull it and push our header. + */ +static +void i2400m_tx_prep_header(struct sk_buff *skb) +{ + struct i2400m_pl_data_hdr *pl_hdr; + skb_pull(skb, ETH_HLEN); + pl_hdr = (struct i2400m_pl_data_hdr *) skb_push(skb, sizeof(*pl_hdr)); + pl_hdr->reserved = 0; +} + + +/* + * TX an skb to an idle device + * + * When the device is in basestation-idle mode, we need to wake it up + * and then TX. So we queue a work_struct for doing so. + * + * We need to get an extra ref for the skb (so it is not dropped), as + * well as be careful not to queue more than one request (won't help + * at all). If more than one request comes or there are errors, we + * just drop the packets (see i2400m_hard_start_xmit()). + */ +static +int i2400m_net_wake_tx(struct i2400m *i2400m, struct net_device *net_dev, + struct sk_buff *skb) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + unsigned long flags; + + d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); + if (net_ratelimit()) { + d_printf(3, dev, "WAKE&NETTX: " + "skb %p sending %d bytes to radio\n", + skb, skb->len); + d_dump(4, dev, skb->data, skb->len); + } + /* We hold a ref count for i2400m and skb, so when + * stopping() the device, we need to cancel that work + * and if pending, release those resources. */ + result = 0; + spin_lock_irqsave(&i2400m->tx_lock, flags); + if (!work_pending(&i2400m->wake_tx_ws)) { + netif_stop_queue(net_dev); + i2400m_get(i2400m); + i2400m->wake_tx_skb = skb_get(skb); /* transfer ref count */ + i2400m_tx_prep_header(skb); + result = schedule_work(&i2400m->wake_tx_ws); + WARN_ON(result == 0); + } + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + if (result == 0) { + /* Yes, this happens even if we stopped the + * queue -- blame the queue disciplines that + * queue without looking -- I guess there is a reason + * for that. */ + if (net_ratelimit()) + d_printf(1, dev, "NETTX: device exiting idle, " + "dropping skb %p, queue running %d\n", + skb, netif_queue_stopped(net_dev)); + result = -EBUSY; + } + d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result); + return result; +} + + +/* + * Transmit a packet to the base station on behalf of the network stack. + * + * Returns: 0 if ok, < 0 errno code on error. + * + * We need to pull the ethernet header and add the hardware header, + * which is currently set to all zeroes and reserved. + */ +static +int i2400m_net_tx(struct i2400m *i2400m, struct net_device *net_dev, + struct sk_buff *skb) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(i2400m %p net_dev %p skb %p)\n", + i2400m, net_dev, skb); + /* FIXME: check eth hdr, only IPv4 is routed by the device as of now */ + net_dev->trans_start = jiffies; + i2400m_tx_prep_header(skb); + d_printf(3, dev, "NETTX: skb %p sending %d bytes to radio\n", + skb, skb->len); + d_dump(4, dev, skb->data, skb->len); + result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA); + d_fnend(3, dev, "(i2400m %p net_dev %p skb %p) = %d\n", + i2400m, net_dev, skb, result); + return result; +} + + +/* + * Transmit a packet to the base station on behalf of the network stack + * + * + * Returns: NETDEV_TX_OK (always, even in case of error) + * + * In case of error, we just drop it. Reasons: + * + * - we add a hw header to each skb, and if the network stack + * retries, we have no way to know if that skb has it or not. + * + * - network protocols have their own drop-recovery mechanisms + * + * - there is not much else we can do + * + * If the device is idle, we need to wake it up; that is an operation + * that will sleep. See i2400m_net_wake_tx() for details. + */ +static +int i2400m_hard_start_xmit(struct sk_buff *skb, + struct net_device *net_dev) +{ + int result; + struct i2400m *i2400m = net_dev_to_i2400m(net_dev); + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); + if (i2400m->state == I2400M_SS_IDLE) + result = i2400m_net_wake_tx(i2400m, net_dev, skb); + else + result = i2400m_net_tx(i2400m, net_dev, skb); + if (result < 0) + net_dev->stats.tx_dropped++; + else { + net_dev->stats.tx_packets++; + net_dev->stats.tx_bytes += skb->len; + } + kfree_skb(skb); + result = NETDEV_TX_OK; + d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result); + return result; +} + + +static +int i2400m_change_mtu(struct net_device *net_dev, int new_mtu) +{ + int result; + struct i2400m *i2400m = net_dev_to_i2400m(net_dev); + struct device *dev = i2400m_dev(i2400m); + + if (new_mtu >= I2400M_MAX_MTU) { + dev_err(dev, "Cannot change MTU to %d (max is %d)\n", + new_mtu, I2400M_MAX_MTU); + result = -EINVAL; + } else { + net_dev->mtu = new_mtu; + result = 0; + } + return result; +} + + +static +void i2400m_tx_timeout(struct net_device *net_dev) +{ + /* + * We might want to kick the device + * + * There is not much we can do though, as the device requires + * that we send the data aggregated. By the time we receive + * this, there might be data pending to be sent or not... + */ + net_dev->stats.tx_errors++; + return; +} + + +/* + * Create a fake ethernet header + * + * For emulating an ethernet device, every received IP header has to + * be prefixed with an ethernet header. + * + * What we receive has (potentially) many IP packets concatenated with + * no ETH_HLEN bytes prefixed. Thus there is no space for an eth + * header. + * + * We would have to reallocate or do ugly fragment tricks in order to + * add it. + * + * But what we do is use the header space of the RX transaction + * (*msg_hdr) as we don't need it anymore; then we'll point all the + * data skbs there, as they share the same backing store. + * + * We only support IPv4 for v3 firmware. + */ +static +void i2400m_rx_fake_eth_header(struct net_device *net_dev, + void *_eth_hdr) +{ + struct ethhdr *eth_hdr = _eth_hdr; + + memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest)); + memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest)); + eth_hdr->h_proto = __constant_cpu_to_be16(ETH_P_IP); +} + + +/* + * i2400m_net_rx - pass a network packet to the stack + * + * @i2400m: device instance + * @skb_rx: the skb where the buffer pointed to by @buf is + * @i: 1 if payload is the only one + * @buf: pointer to the buffer containing the data + * @len: buffer's length + * + * We just clone the skb and set it up so that it's skb->data pointer + * points to "buf" and it's length. + * + * Note that if the payload is the last (or the only one) in a + * multi-payload message, we don't clone the SKB but just reuse it. + * + * This function is normally run from a thread context. However, we + * still use netif_rx() instead of netif_receive_skb() as was + * recommended in the mailing list. Reason is in some stress tests + * when sending/receiving a lot of data we seem to hit a softlock in + * the kernel's TCP implementation [aroudn tcp_delay_timer()]. Using + * netif_rx() took care of the issue. + * + * This is, of course, still open to do more research on why running + * with netif_receive_skb() hits this softlock. FIXME. + * + * FIXME: currently we don't do any efforts at distinguishing if what + * we got was an IPv4 or IPv6 header, to setup the protocol field + * correctly. + */ +void i2400m_net_rx(struct i2400m *i2400m, struct sk_buff *skb_rx, + unsigned i, const void *buf, int buf_len) +{ + struct net_device *net_dev = i2400m->wimax_dev.net_dev; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *skb; + + d_fnstart(2, dev, "(i2400m %p buf %p buf_len %d)\n", + i2400m, buf, buf_len); + if (i) { + skb = skb_get(skb_rx); + d_printf(2, dev, "RX: reusing first payload skb %p\n", skb); + skb_pull(skb, buf - (void *) skb->data); + skb_trim(skb, (void *) skb_end_pointer(skb) - buf); + } else { + /* Yes, this is bad -- a lot of overhead -- see + * comments at the top of the file */ + skb = __netdev_alloc_skb(net_dev, buf_len, GFP_KERNEL); + if (skb == NULL) { + dev_err(dev, "NETRX: no memory to realloc skb\n"); + net_dev->stats.rx_dropped++; + goto error_skb_realloc; + } + memcpy(skb_put(skb, buf_len), buf, buf_len); + } + i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev, + skb->data - ETH_HLEN); + skb_set_mac_header(skb, -ETH_HLEN); + skb->dev = i2400m->wimax_dev.net_dev; + skb->protocol = htons(ETH_P_IP); + net_dev->stats.rx_packets++; + net_dev->stats.rx_bytes += buf_len; + d_printf(3, dev, "NETRX: receiving %d bytes to network stack\n", + buf_len); + d_dump(4, dev, buf, buf_len); + netif_rx_ni(skb); /* see notes in function header */ +error_skb_realloc: + d_fnend(2, dev, "(i2400m %p buf %p buf_len %d) = void\n", + i2400m, buf, buf_len); +} + + +/** + * i2400m_netdev_setup - Setup setup @net_dev's i2400m private data + * + * Called by alloc_netdev() + */ +void i2400m_netdev_setup(struct net_device *net_dev) +{ + d_fnstart(3, NULL, "(net_dev %p)\n", net_dev); + ether_setup(net_dev); + net_dev->mtu = I2400M_MAX_MTU; + net_dev->tx_queue_len = I2400M_TX_QLEN; + net_dev->features = + NETIF_F_VLAN_CHALLENGED + | NETIF_F_HIGHDMA; + net_dev->flags = + IFF_NOARP /* i2400m is apure IP device */ + & (~IFF_BROADCAST /* i2400m is P2P */ + & ~IFF_MULTICAST); + net_dev->watchdog_timeo = I2400M_TX_TIMEOUT; + net_dev->open = i2400m_open; + net_dev->stop = i2400m_stop; + net_dev->hard_start_xmit = i2400m_hard_start_xmit; + net_dev->change_mtu = i2400m_change_mtu; + net_dev->tx_timeout = i2400m_tx_timeout; + d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev); +} +EXPORT_SYMBOL_GPL(i2400m_netdev_setup); + -- cgit From 467cc396fb4665957bc7d182c96e45a4d7c575e4 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:46 -0800 Subject: i2400m: firmware loading and bootrom initialization Implements the firmware loader (using the bus-specific driver's backends for the actual upload). The most critical thing in here is the piece that puts the device in boot-mode from any other (undetermined) state, otherwise, it is just pushing the bytes from the firmware file to the device. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/fw.c | 1095 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1095 insertions(+) create mode 100644 drivers/net/wimax/i2400m/fw.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c new file mode 100644 index 00000000000..1d8271f34c3 --- /dev/null +++ b/drivers/net/wimax/i2400m/fw.c @@ -0,0 +1,1095 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Firmware uploader + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * Inaky Perez-Gonzalez + * - Initial implementation + * + * + * THE PROCEDURE + * + * (this is decribed for USB, but for SDIO is similar) + * + * The 2400m works in two modes: boot-mode or normal mode. In boot + * mode we can execute only a handful of commands targeted at + * uploading the firmware and launching it. + * + * The 2400m enters boot mode when it is first connected to the + * system, when it crashes and when you ask it to reboot. There are + * two submodes of the boot mode: signed and non-signed. Signed takes + * firmwares signed with a certain private key, non-signed takes any + * firmware. Normal hardware takes only signed firmware. + * + * Upon entrance to boot mode, the device sends a few zero length + * packets (ZLPs) on the notification endpoint, then a reboot barker + * (4 le32 words with value I2400M_{S,N}BOOT_BARKER). We ack it by + * sending the same barker on the bulk out endpoint. The device acks + * with a reboot ack barker (4 le32 words with value 0xfeedbabe) and + * then the device is fully rebooted. At this point we can upload the + * firmware. + * + * This process is accomplished by the i2400m_bootrom_init() + * function. All the device interaction happens through the + * i2400m_bm_cmd() [boot mode command]. Special return values will + * indicate if the device resets. + * + * After this, we read the MAC address and then (if needed) + * reinitialize the device. We need to read it ahead of time because + * in the future, we might not upload the firmware until userspace + * 'ifconfig up's the device. + * + * We can then upload the firmware file. The file is composed of a BCF + * header (basic data, keys and signatures) and a list of write + * commands and payloads. We first upload the header + * [i2400m_dnload_init()] and then pass the commands and payloads + * verbatim to the i2400m_bm_cmd() function + * [i2400m_dnload_bcf()]. Then we tell the device to jump to the new + * firmware [i2400m_dnload_finalize()]. + * + * Once firmware is uploaded, we are good to go :) + * + * When we don't know in which mode we are, we first try by sending a + * warm reset request that will take us to boot-mode. If we time out + * waiting for a reboot barker, that means maybe we are already in + * boot mode, so we send a reboot barker. + * + * COMMAND EXECUTION + * + * This code (and process) is single threaded; for executing commands, + * we post a URB to the notification endpoint, post the command, wait + * for data on the notification buffer. We don't need to worry about + * others as we know we are the only ones in there. + * + * BACKEND IMPLEMENTATION + * + * This code is bus-generic; the bus-specific driver provides back end + * implementations to send a boot mode command to the device and to + * read an acknolwedgement from it (or an asynchronous notification) + * from it. + * + * ROADMAP + * + * i2400m_dev_bootstrap Called by __i2400m_dev_start() + * request_firmware + * i2400m_fw_check + * i2400m_fw_dnload + * release_firmware + * + * i2400m_fw_dnload + * i2400m_bootrom_init + * i2400m_bm_cmd + * i2400m->bus_reset + * i2400m_dnload_init + * i2400m_dnload_init_signed + * i2400m_dnload_init_nonsigned + * i2400m_download_chunk + * i2400m_bm_cmd + * i2400m_dnload_bcf + * i2400m_bm_cmd + * i2400m_dnload_finalize + * i2400m_bm_cmd + * + * i2400m_bm_cmd + * i2400m->bus_bm_cmd_send() + * i2400m->bus_bm_wait_for_ack + * __i2400m_bm_ack_verify + * + * i2400m_bm_cmd_prepare Used by bus-drivers to prep + * commands before sending + */ +#include +#include +#include +#include "i2400m.h" + + +#define D_SUBMODULE fw +#include "debug-levels.h" + + +static const __le32 i2400m_ACK_BARKER[4] = { + __constant_cpu_to_le32(I2400M_ACK_BARKER), + __constant_cpu_to_le32(I2400M_ACK_BARKER), + __constant_cpu_to_le32(I2400M_ACK_BARKER), + __constant_cpu_to_le32(I2400M_ACK_BARKER) +}; + + +/** + * Prepare a boot-mode command for delivery + * + * @cmd: pointer to bootrom header to prepare + * + * Computes checksum if so needed. After calling this function, DO NOT + * modify the command or header as the checksum won't work anymore. + * + * We do it from here because some times we cannot do it in the + * original context the command was sent (it is a const), so when we + * copy it to our staging buffer, we add the checksum there. + */ +void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *cmd) +{ + if (i2400m_brh_get_use_checksum(cmd)) { + int i; + u32 checksum = 0; + const u32 *checksum_ptr = (void *) cmd->payload; + for (i = 0; i < cmd->data_size / 4; i++) + checksum += cpu_to_le32(*checksum_ptr++); + checksum += cmd->command + cmd->target_addr + cmd->data_size; + cmd->block_checksum = cpu_to_le32(checksum); + } +} +EXPORT_SYMBOL_GPL(i2400m_bm_cmd_prepare); + + +/* + * Verify the ack data received + * + * Given a reply to a boot mode command, chew it and verify everything + * is ok. + * + * @opcode: opcode which generated this ack. For error messages. + * @ack: pointer to ack data we received + * @ack_size: size of that data buffer + * @flags: I2400M_BM_CMD_* flags we called the command with. + * + * Way too long function -- maybe it should be further split + */ +static +ssize_t __i2400m_bm_ack_verify(struct i2400m *i2400m, int opcode, + struct i2400m_bootrom_header *ack, + size_t ack_size, int flags) +{ + ssize_t result = -ENOMEM; + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(8, dev, "(i2400m %p opcode %d ack %p size %zu)\n", + i2400m, opcode, ack, ack_size); + if (ack_size < sizeof(*ack)) { + result = -EIO; + dev_err(dev, "boot-mode cmd %d: HW BUG? notification didn't " + "return enough data (%zu bytes vs %zu expected)\n", + opcode, ack_size, sizeof(*ack)); + goto error_ack_short; + } + if (ack_size == sizeof(i2400m_NBOOT_BARKER) + && memcmp(ack, i2400m_NBOOT_BARKER, sizeof(*ack)) == 0) { + result = -ERESTARTSYS; + i2400m->sboot = 0; + d_printf(6, dev, "boot-mode cmd %d: " + "HW non-signed boot barker\n", opcode); + goto error_reboot; + } + if (ack_size == sizeof(i2400m_SBOOT_BARKER) + && memcmp(ack, i2400m_SBOOT_BARKER, sizeof(*ack)) == 0) { + result = -ERESTARTSYS; + i2400m->sboot = 1; + d_printf(6, dev, "boot-mode cmd %d: HW signed reboot barker\n", + opcode); + goto error_reboot; + } + if (ack_size == sizeof(i2400m_ACK_BARKER) + && memcmp(ack, i2400m_ACK_BARKER, sizeof(*ack)) == 0) { + result = -EISCONN; + d_printf(3, dev, "boot-mode cmd %d: HW reboot ack barker\n", + opcode); + goto error_reboot_ack; + } + result = 0; + if (flags & I2400M_BM_CMD_RAW) + goto out_raw; + ack->data_size = le32_to_cpu(ack->data_size); + ack->target_addr = le32_to_cpu(ack->target_addr); + ack->block_checksum = le32_to_cpu(ack->block_checksum); + d_printf(5, dev, "boot-mode cmd %d: notification for opcode %u " + "response %u csum %u rr %u da %u\n", + opcode, i2400m_brh_get_opcode(ack), + i2400m_brh_get_response(ack), + i2400m_brh_get_use_checksum(ack), + i2400m_brh_get_response_required(ack), + i2400m_brh_get_direct_access(ack)); + result = -EIO; + if (i2400m_brh_get_signature(ack) != 0xcbbc) { + dev_err(dev, "boot-mode cmd %d: HW BUG? wrong signature " + "0x%04x\n", opcode, i2400m_brh_get_signature(ack)); + goto error_ack_signature; + } + if (opcode != -1 && opcode != i2400m_brh_get_opcode(ack)) { + dev_err(dev, "boot-mode cmd %d: HW BUG? " + "received response for opcode %u, expected %u\n", + opcode, i2400m_brh_get_opcode(ack), opcode); + goto error_ack_opcode; + } + if (i2400m_brh_get_response(ack) != 0) { /* failed? */ + dev_err(dev, "boot-mode cmd %d: error; hw response %u\n", + opcode, i2400m_brh_get_response(ack)); + goto error_ack_failed; + } + if (ack_size < ack->data_size + sizeof(*ack)) { + dev_err(dev, "boot-mode cmd %d: SW BUG " + "driver provided only %zu bytes for %zu bytes " + "of data\n", opcode, ack_size, + (size_t) le32_to_cpu(ack->data_size) + sizeof(*ack)); + goto error_ack_short_buffer; + } + result = ack_size; + /* Don't you love this stack of empty targets? Well, I don't + * either, but it helps track exactly who comes in here and + * why :) */ +error_ack_short_buffer: +error_ack_failed: +error_ack_opcode: +error_ack_signature: +out_raw: +error_reboot_ack: +error_reboot: +error_ack_short: + d_fnend(8, dev, "(i2400m %p opcode %d ack %p size %zu) = %d\n", + i2400m, opcode, ack, ack_size, (int) result); + return result; +} + + +/** + * i2400m_bm_cmd - Execute a boot mode command + * + * @cmd: buffer containing the command data (pointing at the header). + * This data can be ANYWHERE (for USB, we will copy it to an + * specific buffer). Make sure everything is in proper little + * endian. + * + * A raw buffer can be also sent, just cast it and set flags to + * I2400M_BM_CMD_RAW. + * + * This function will generate a checksum for you if the + * checksum bit in the command is set (unless I2400M_BM_CMD_RAW + * is set). + * + * You can use the i2400m->bm_cmd_buf to stage your commands and + * send them. + * + * If NULL, no command is sent (we just wait for an ack). + * + * @cmd_size: size of the command. Will be auto padded to the + * bus-specific drivers padding requirements. + * + * @ack: buffer where to place the acknowledgement. If it is a regular + * command response, all fields will be returned with the right, + * native endianess. + * + * You *cannot* use i2400m->bm_ack_buf for this buffer. + * + * @ack_size: size of @ack, 16 aligned; you need to provide at least + * sizeof(*ack) bytes and then enough to contain the return data + * from the command + * + * @flags: see I2400M_BM_CMD_* above. + * + * @returns: bytes received by the notification; if < 0, an errno code + * denoting an error or: + * + * -ERESTARTSYS The device has rebooted + * + * Executes a boot-mode command and waits for a response, doing basic + * validation on it; if a zero length response is received, it retries + * waiting for a response until a non-zero one is received (timing out + * after %I2400M_BOOT_RETRIES retries). + */ +static +ssize_t i2400m_bm_cmd(struct i2400m *i2400m, + const struct i2400m_bootrom_header *cmd, size_t cmd_size, + struct i2400m_bootrom_header *ack, size_t ack_size, + int flags) +{ + ssize_t result = -ENOMEM, rx_bytes; + struct device *dev = i2400m_dev(i2400m); + int opcode = cmd == NULL ? -1 : i2400m_brh_get_opcode(cmd); + + d_fnstart(6, dev, "(i2400m %p cmd %p size %zu ack %p size %zu)\n", + i2400m, cmd, cmd_size, ack, ack_size); + BUG_ON(ack_size < sizeof(*ack)); + BUG_ON(i2400m->boot_mode == 0); + + if (cmd != NULL) { /* send the command */ + memcpy(i2400m->bm_cmd_buf, cmd, cmd_size); + result = i2400m->bus_bm_cmd_send(i2400m, cmd, cmd_size, flags); + if (result < 0) + goto error_cmd_send; + if ((flags & I2400M_BM_CMD_RAW) == 0) + d_printf(5, dev, + "boot-mode cmd %d csum %u rr %u da %u: " + "addr 0x%04x size %u block csum 0x%04x\n", + opcode, i2400m_brh_get_use_checksum(cmd), + i2400m_brh_get_response_required(cmd), + i2400m_brh_get_direct_access(cmd), + cmd->target_addr, cmd->data_size, + cmd->block_checksum); + } + result = i2400m->bus_bm_wait_for_ack(i2400m, ack, ack_size); + if (result < 0) { + dev_err(dev, "boot-mode cmd %d: error waiting for an ack: %d\n", + opcode, (int) result); /* bah, %zd doesn't work */ + goto error_wait_for_ack; + } + rx_bytes = result; + /* verify the ack and read more if neccessary [result is the + * final amount of bytes we get in the ack] */ + result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags); + if (result < 0) + goto error_bad_ack; + /* Don't you love this stack of empty targets? Well, I don't + * either, but it helps track exactly who comes in here and + * why :) */ + result = rx_bytes; +error_bad_ack: +error_wait_for_ack: +error_cmd_send: + d_fnend(6, dev, "(i2400m %p cmd %p size %zu ack %p size %zu) = %d\n", + i2400m, cmd, cmd_size, ack, ack_size, (int) result); + return result; +} + + +/** + * i2400m_download_chunk - write a single chunk of data to the device's memory + * + * @i2400m: device descriptor + * @buf: the buffer to write + * @buf_len: length of the buffer to write + * @addr: address in the device memory space + * @direct: bootrom write mode + * @do_csum: should a checksum validation be performed + */ +static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk, + size_t __chunk_len, unsigned long addr, + unsigned int direct, unsigned int do_csum) +{ + int ret; + size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_PAD); + struct device *dev = i2400m_dev(i2400m); + struct { + struct i2400m_bootrom_header cmd; + u8 cmd_payload[chunk_len]; + } __attribute__((packed)) *buf; + struct i2400m_bootrom_header ack; + + d_fnstart(5, dev, "(i2400m %p chunk %p __chunk_len %zu addr 0x%08lx " + "direct %u do_csum %u)\n", i2400m, chunk, __chunk_len, + addr, direct, do_csum); + buf = i2400m->bm_cmd_buf; + memcpy(buf->cmd_payload, chunk, __chunk_len); + memset(buf->cmd_payload + __chunk_len, 0xad, chunk_len - __chunk_len); + + buf->cmd.command = i2400m_brh_command(I2400M_BRH_WRITE, + __chunk_len & 0x3 ? 0 : do_csum, + __chunk_len & 0xf ? 0 : direct); + buf->cmd.target_addr = cpu_to_le32(addr); + buf->cmd.data_size = cpu_to_le32(__chunk_len); + ret = i2400m_bm_cmd(i2400m, &buf->cmd, sizeof(buf->cmd) + chunk_len, + &ack, sizeof(ack), 0); + if (ret >= 0) + ret = 0; + d_fnend(5, dev, "(i2400m %p chunk %p __chunk_len %zu addr 0x%08lx " + "direct %u do_csum %u) = %d\n", i2400m, chunk, __chunk_len, + addr, direct, do_csum, ret); + return ret; +} + + +/* + * Download a BCF file's sections to the device + * + * @i2400m: device descriptor + * @bcf: pointer to firmware data (followed by the payloads). Assumed + * verified and consistent. + * @bcf_len: length (in bytes) of the @bcf buffer. + * + * Returns: < 0 errno code on error or the offset to the jump instruction. + * + * Given a BCF file, downloads each section (a command and a payload) + * to the device's address space. Actually, it just executes each + * command i the BCF file. + * + * The section size has to be aligned to 4 bytes AND the padding has + * to be taken from the firmware file, as the signature takes it into + * account. + */ +static +ssize_t i2400m_dnload_bcf(struct i2400m *i2400m, + const struct i2400m_bcf_hdr *bcf, size_t bcf_len) +{ + ssize_t ret; + struct device *dev = i2400m_dev(i2400m); + size_t offset, /* iterator offset */ + data_size, /* Size of the data payload */ + section_size, /* Size of the whole section (cmd + payload) */ + section = 1; + const struct i2400m_bootrom_header *bh; + struct i2400m_bootrom_header ack; + + d_fnstart(3, dev, "(i2400m %p bcf %p bcf_len %zu)\n", + i2400m, bcf, bcf_len); + /* Iterate over the command blocks in the BCF file that start + * after the header */ + offset = le32_to_cpu(bcf->header_len) * sizeof(u32); + while (1) { /* start sending the file */ + bh = (void *) bcf + offset; + data_size = le32_to_cpu(bh->data_size); + section_size = ALIGN(sizeof(*bh) + data_size, 4); + d_printf(7, dev, + "downloading section #%zu (@%zu %zu B) to 0x%08x\n", + section, offset, sizeof(*bh) + data_size, + le32_to_cpu(bh->target_addr)); + if (i2400m_brh_get_opcode(bh) == I2400M_BRH_SIGNED_JUMP) { + /* Secure boot needs to stop here */ + d_printf(5, dev, "signed jump found @%zu\n", offset); + break; + } + if (offset + section_size == bcf_len) + /* Non-secure boot stops here */ + break; + if (offset + section_size > bcf_len) { + dev_err(dev, "fw %s: bad section #%zu, " + "end (@%zu) beyond EOF (@%zu)\n", + i2400m->bus_fw_name, section, + offset + section_size, bcf_len); + ret = -EINVAL; + goto error_section_beyond_eof; + } + __i2400m_msleep(20); + ret = i2400m_bm_cmd(i2400m, bh, section_size, + &ack, sizeof(ack), I2400M_BM_CMD_RAW); + if (ret < 0) { + dev_err(dev, "fw %s: section #%zu (@%zu %zu B) " + "failed %d\n", i2400m->bus_fw_name, section, + offset, sizeof(*bh) + data_size, (int) ret); + goto error_send; + } + offset += section_size; + section++; + } + ret = offset; +error_section_beyond_eof: +error_send: + d_fnend(3, dev, "(i2400m %p bcf %p bcf_len %zu) = %d\n", + i2400m, bcf, bcf_len, (int) ret); + return ret; +} + + +/* + * Do the final steps of uploading firmware + * + * Depending on the boot mode (signed vs non-signed), different + * actions need to be taken. + */ +static +int i2400m_dnload_finalize(struct i2400m *i2400m, + const struct i2400m_bcf_hdr *bcf, size_t offset) +{ + int ret = 0; + struct device *dev = i2400m_dev(i2400m); + struct i2400m_bootrom_header *cmd, ack; + struct { + struct i2400m_bootrom_header cmd; + u8 cmd_pl[0]; + } __attribute__((packed)) *cmd_buf; + size_t signature_block_offset, signature_block_size; + + d_fnstart(3, dev, "offset %zu\n", offset); + cmd = (void *) bcf + offset; + if (i2400m->sboot == 0) { + struct i2400m_bootrom_header jump_ack; + d_printf(3, dev, "unsecure boot, jumping to 0x%08x\n", + le32_to_cpu(cmd->target_addr)); + i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP); + cmd->data_size = 0; + ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), + &jump_ack, sizeof(jump_ack), 0); + } else { + d_printf(3, dev, "secure boot, jumping to 0x%08x\n", + le32_to_cpu(cmd->target_addr)); + cmd_buf = i2400m->bm_cmd_buf; + memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd)); + signature_block_offset = + sizeof(*bcf) + + le32_to_cpu(bcf->key_size) * sizeof(u32) + + le32_to_cpu(bcf->exponent_size) * sizeof(u32); + signature_block_size = + le32_to_cpu(bcf->modulus_size) * sizeof(u32); + memcpy(cmd_buf->cmd_pl, (void *) bcf + signature_block_offset, + signature_block_size); + ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd, + sizeof(cmd_buf->cmd) + signature_block_size, + &ack, sizeof(ack), I2400M_BM_CMD_RAW); + } + d_fnend(3, dev, "returning %d\n", ret); + return ret; +} + + +/** + * i2400m_bootrom_init - Reboots a powered device into boot mode + * + * @i2400m: device descriptor + * @flags: + * I2400M_BRI_SOFT: a reboot notification has been seen + * already, so don't wait for it. + * + * I2400M_BRI_NO_REBOOT: Don't send a reboot command, but wait + * for a reboot barker notification. This is a one shot; if + * the state machine needs to send a reboot command it will. + * + * Returns: + * + * < 0 errno code on error, 0 if ok. + * + * i2400m->sboot set to 0 for unsecure boot process, 1 for secure + * boot process. + * + * Description: + * + * Tries hard enough to put the device in boot-mode. There are two + * main phases to this: + * + * a. (1) send a reboot command and (2) get a reboot barker + * b. (1) ack the reboot sending a reboot barker and (2) getting an + * ack barker in return + * + * We want to skip (a) in some cases [soft]. The state machine is + * horrible, but it is basically: on each phase, send what has to be + * sent (if any), wait for the answer and act on the answer. We might + * have to backtrack and retry, so we keep a max tries counter for + * that. + * + * If we get a timeout after sending a warm reset, we do it again. + */ +int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct i2400m_bootrom_header *cmd; + struct i2400m_bootrom_header ack; + int count = I2400M_BOOT_RETRIES; + int ack_timeout_cnt = 1; + + BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_NBOOT_BARKER)); + BUILD_BUG_ON(sizeof(ack) != sizeof(i2400m_ACK_BARKER)); + + d_fnstart(4, dev, "(i2400m %p flags 0x%08x)\n", i2400m, flags); + result = -ENOMEM; + cmd = i2400m->bm_cmd_buf; + if (flags & I2400M_BRI_SOFT) + goto do_reboot_ack; +do_reboot: + if (--count < 0) + goto error_timeout; + d_printf(4, dev, "device reboot: reboot command [%d # left]\n", + count); + if ((flags & I2400M_BRI_NO_REBOOT) == 0) + i2400m->bus_reset(i2400m, I2400M_RT_WARM); + result = i2400m_bm_cmd(i2400m, NULL, 0, &ack, sizeof(ack), + I2400M_BM_CMD_RAW); + flags &= ~I2400M_BRI_NO_REBOOT; + switch (result) { + case -ERESTARTSYS: + d_printf(4, dev, "device reboot: got reboot barker\n"); + break; + case -EISCONN: /* we don't know how it got here...but we follow it */ + d_printf(4, dev, "device reboot: got ack barker - whatever\n"); + goto do_reboot; + case -ETIMEDOUT: /* device has timed out, we might be in boot + * mode already and expecting an ack, let's try + * that */ + dev_info(dev, "warm reset timed out, trying an ack\n"); + goto do_reboot_ack; + case -EPROTO: + case -ESHUTDOWN: /* dev is gone */ + case -EINTR: /* user cancelled */ + goto error_dev_gone; + default: + dev_err(dev, "device reboot: error %d while waiting " + "for reboot barker - rebooting\n", result); + goto do_reboot; + } + /* At this point we ack back with 4 REBOOT barkers and expect + * 4 ACK barkers. This is ugly, as we send a raw command -- + * hence the cast. _bm_cmd() will catch the reboot ack + * notification and report it as -EISCONN. */ +do_reboot_ack: + d_printf(4, dev, "device reboot ack: sending ack [%d # left]\n", count); + if (i2400m->sboot == 0) + memcpy(cmd, i2400m_NBOOT_BARKER, + sizeof(i2400m_NBOOT_BARKER)); + else + memcpy(cmd, i2400m_SBOOT_BARKER, + sizeof(i2400m_SBOOT_BARKER)); + result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), + &ack, sizeof(ack), I2400M_BM_CMD_RAW); + switch (result) { + case -ERESTARTSYS: + d_printf(4, dev, "reboot ack: got reboot barker - retrying\n"); + if (--count < 0) + goto error_timeout; + goto do_reboot_ack; + case -EISCONN: + d_printf(4, dev, "reboot ack: got ack barker - good\n"); + break; + case -ETIMEDOUT: /* no response, maybe it is the other type? */ + if (ack_timeout_cnt-- >= 0) { + d_printf(4, dev, "reboot ack timedout: " + "trying the other type?\n"); + i2400m->sboot = !i2400m->sboot; + goto do_reboot_ack; + } else { + dev_err(dev, "reboot ack timedout too long: " + "trying reboot\n"); + goto do_reboot; + } + break; + case -EPROTO: + case -ESHUTDOWN: /* dev is gone */ + goto error_dev_gone; + default: + dev_err(dev, "device reboot ack: error %d while waiting for " + "reboot ack barker - rebooting\n", result); + goto do_reboot; + } + d_printf(2, dev, "device reboot ack: got ack barker - boot done\n"); + result = 0; +exit_timeout: +error_dev_gone: + d_fnend(4, dev, "(i2400m %p flags 0x%08x) = %d\n", + i2400m, flags, result); + return result; + +error_timeout: + dev_err(dev, "Timed out waiting for reboot ack, resetting\n"); + i2400m->bus_reset(i2400m, I2400M_RT_BUS); + result = -ETIMEDOUT; + goto exit_timeout; +} + + +/* + * Read the MAC addr + * + * The position this function reads is fixed in device memory and + * always available, even without firmware. + * + * Note we specify we want to read only six bytes, but provide space + * for 16, as we always get it rounded up. + */ +int i2400m_read_mac_addr(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct net_device *net_dev = i2400m->wimax_dev.net_dev; + struct i2400m_bootrom_header *cmd; + struct { + struct i2400m_bootrom_header ack; + u8 ack_pl[16]; + } __attribute__((packed)) ack_buf; + + d_fnstart(5, dev, "(i2400m %p)\n", i2400m); + cmd = i2400m->bm_cmd_buf; + cmd->command = i2400m_brh_command(I2400M_BRH_READ, 0, 1); + cmd->target_addr = cpu_to_le32(0x00203fe8); + cmd->data_size = cpu_to_le32(6); + result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), + &ack_buf.ack, sizeof(ack_buf), 0); + if (result < 0) { + dev_err(dev, "BM: read mac addr failed: %d\n", result); + goto error_read_mac; + } + d_printf(2, dev, + "mac addr is %02x:%02x:%02x:%02x:%02x:%02x\n", + ack_buf.ack_pl[0], ack_buf.ack_pl[1], + ack_buf.ack_pl[2], ack_buf.ack_pl[3], + ack_buf.ack_pl[4], ack_buf.ack_pl[5]); + if (i2400m->bus_bm_mac_addr_impaired == 1) { + ack_buf.ack_pl[0] = 0x00; + ack_buf.ack_pl[1] = 0x16; + ack_buf.ack_pl[2] = 0xd3; + get_random_bytes(&ack_buf.ack_pl[3], 3); + dev_err(dev, "BM is MAC addr impaired, faking MAC addr to " + "mac addr is %02x:%02x:%02x:%02x:%02x:%02x\n", + ack_buf.ack_pl[0], ack_buf.ack_pl[1], + ack_buf.ack_pl[2], ack_buf.ack_pl[3], + ack_buf.ack_pl[4], ack_buf.ack_pl[5]); + result = 0; + } + net_dev->addr_len = ETH_ALEN; + memcpy(net_dev->perm_addr, ack_buf.ack_pl, ETH_ALEN); + memcpy(net_dev->dev_addr, ack_buf.ack_pl, ETH_ALEN); +error_read_mac: + d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, result); + return result; +} + + +/* + * Initialize a non signed boot + * + * This implies sending some magic values to the device's memory. Note + * we convert the values to little endian in the same array + * declaration. + */ +static +int i2400m_dnload_init_nonsigned(struct i2400m *i2400m) +{ +#define POKE(a, d) { \ + .address = __constant_cpu_to_le32(a), \ + .data = __constant_cpu_to_le32(d) \ +} + static const struct { + __le32 address; + __le32 data; + } i2400m_pokes[] = { + POKE(0x081A58, 0xA7810230), + POKE(0x080040, 0x00000000), + POKE(0x080048, 0x00000082), + POKE(0x08004C, 0x0000081F), + POKE(0x080054, 0x00000085), + POKE(0x080058, 0x00000180), + POKE(0x08005C, 0x00000018), + POKE(0x080060, 0x00000010), + POKE(0x080574, 0x00000001), + POKE(0x080550, 0x00000005), + POKE(0xAE0000, 0x00000000), + }; +#undef POKE + unsigned i; + int ret; + struct device *dev = i2400m_dev(i2400m); + + dev_warn(dev, "WARNING!!! non-signed boot UNTESTED PATH!\n"); + + d_fnstart(5, dev, "(i2400m %p)\n", i2400m); + for (i = 0; i < ARRAY_SIZE(i2400m_pokes); i++) { + ret = i2400m_download_chunk(i2400m, &i2400m_pokes[i].data, + sizeof(i2400m_pokes[i].data), + i2400m_pokes[i].address, 1, 1); + if (ret < 0) + break; + } + d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); + return ret; +} + + +/* + * Initialize the signed boot process + * + * @i2400m: device descriptor + * + * @bcf_hdr: pointer to the firmware header; assumes it is fully in + * memory (it has gone through basic validation). + * + * Returns: 0 if ok, < 0 errno code on error, -ERESTARTSYS if the hw + * rebooted. + * + * This writes the firmware BCF header to the device using the + * HASH_PAYLOAD_ONLY command. + */ +static +int i2400m_dnload_init_signed(struct i2400m *i2400m, + const struct i2400m_bcf_hdr *bcf_hdr) +{ + int ret; + struct device *dev = i2400m_dev(i2400m); + struct { + struct i2400m_bootrom_header cmd; + struct i2400m_bcf_hdr cmd_pl; + } __attribute__((packed)) *cmd_buf; + struct i2400m_bootrom_header ack; + + d_fnstart(5, dev, "(i2400m %p bcf_hdr %p)\n", i2400m, bcf_hdr); + cmd_buf = i2400m->bm_cmd_buf; + cmd_buf->cmd.command = + i2400m_brh_command(I2400M_BRH_HASH_PAYLOAD_ONLY, 0, 0); + cmd_buf->cmd.target_addr = 0; + cmd_buf->cmd.data_size = cpu_to_le32(sizeof(cmd_buf->cmd_pl)); + memcpy(&cmd_buf->cmd_pl, bcf_hdr, sizeof(*bcf_hdr)); + ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd, sizeof(*cmd_buf), + &ack, sizeof(ack), 0); + if (ret >= 0) + ret = 0; + d_fnend(5, dev, "(i2400m %p bcf_hdr %p) = %d\n", i2400m, bcf_hdr, ret); + return ret; +} + + +/* + * Initialize the firmware download at the device size + * + * Multiplex to the one that matters based on the device's mode + * (signed or non-signed). + */ +static +int i2400m_dnload_init(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + u32 module_id = le32_to_cpu(bcf->module_id); + + if (i2400m->sboot == 0 + && (module_id & I2400M_BCF_MOD_ID_POKES) == 0) { + /* non-signed boot process without pokes */ + result = i2400m_dnload_init_nonsigned(i2400m); + if (result == -ERESTARTSYS) + return result; + if (result < 0) + dev_err(dev, "fw %s: non-signed download " + "initialization failed: %d\n", + i2400m->bus_fw_name, result); + } else if (i2400m->sboot == 0 + && (module_id & I2400M_BCF_MOD_ID_POKES)) { + /* non-signed boot process with pokes, nothing to do */ + result = 0; + } else { /* signed boot process */ + result = i2400m_dnload_init_signed(i2400m, bcf); + if (result == -ERESTARTSYS) + return result; + if (result < 0) + dev_err(dev, "fw %s: signed boot download " + "initialization failed: %d\n", + i2400m->bus_fw_name, result); + } + return result; +} + + +/* + * Run quick consistency tests on the firmware file + * + * Check for the firmware being made for the i2400m device, + * etc...These checks are mostly informative, as the device will make + * them too; but the driver's response is more informative on what + * went wrong. + */ +static +int i2400m_fw_check(struct i2400m *i2400m, + const struct i2400m_bcf_hdr *bcf, + size_t bcf_size) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + unsigned module_type, header_len, major_version, minor_version, + module_id, module_vendor, date, size; + + /* Check hard errors */ + result = -EINVAL; + if (bcf_size < sizeof(*bcf)) { /* big enough header? */ + dev_err(dev, "firmware %s too short: " + "%zu B vs %zu (at least) expected\n", + i2400m->bus_fw_name, bcf_size, sizeof(*bcf)); + goto error; + } + + module_type = bcf->module_type; + header_len = sizeof(u32) * le32_to_cpu(bcf->header_len); + major_version = le32_to_cpu(bcf->header_version) & 0xffff0000 >> 16; + minor_version = le32_to_cpu(bcf->header_version) & 0x0000ffff; + module_id = le32_to_cpu(bcf->module_id); + module_vendor = le32_to_cpu(bcf->module_vendor); + date = le32_to_cpu(bcf->date); + size = sizeof(u32) * le32_to_cpu(bcf->size); + + if (bcf_size != size) { /* annoyingly paranoid */ + dev_err(dev, "firmware %s: bad size, got " + "%zu B vs %u expected\n", + i2400m->bus_fw_name, bcf_size, size); + goto error; + } + + d_printf(2, dev, "type 0x%x id 0x%x vendor 0x%x; header v%u.%u (%zu B) " + "date %08x (%zu B)\n", + module_type, module_id, module_vendor, + major_version, minor_version, (size_t) header_len, + date, (size_t) size); + + if (module_type != 6) { /* built for the right hardware? */ + dev_err(dev, "bad fw %s: unexpected module type 0x%x; " + "aborting\n", i2400m->bus_fw_name, module_type); + goto error; + } + + /* Check soft-er errors */ + result = 0; + if (module_vendor != 0x8086) + dev_err(dev, "bad fw %s? unexpected vendor 0x%04x\n", + i2400m->bus_fw_name, module_vendor); + if (date < 0x20080300) + dev_err(dev, "bad fw %s? build date too old %08x\n", + i2400m->bus_fw_name, date); +error: + return result; +} + + +/* + * Download the firmware to the device + * + * @i2400m: device descriptor + * @bcf: pointer to loaded (and minimally verified for consistency) + * firmware + * @bcf_size: size of the @bcf buffer (header plus payloads) + * + * The process for doing this is described in this file's header. + * + * Note we only reinitialize boot-mode if the flags say so. Some hw + * iterations need it, some don't. In any case, if we loop, we always + * need to reinitialize the boot room, hence the flags modification. + */ +static +int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, + size_t bcf_size, enum i2400m_bri flags) +{ + int ret = 0; + struct device *dev = i2400m_dev(i2400m); + int count = I2400M_BOOT_RETRIES; + + d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n", + i2400m, bcf, bcf_size); + i2400m->boot_mode = 1; +hw_reboot: + if (count-- == 0) { + ret = -ERESTARTSYS; + dev_err(dev, "device rebooted too many times, aborting\n"); + goto error_too_many_reboots; + } + if (flags & I2400M_BRI_MAC_REINIT) { + ret = i2400m_bootrom_init(i2400m, flags); + if (ret < 0) { + dev_err(dev, "bootrom init failed: %d\n", ret); + goto error_bootrom_init; + } + } + flags |= I2400M_BRI_MAC_REINIT; + + /* + * Initialize the download, push the bytes to the device and + * then jump to the new firmware. Note @ret is passed with the + * offset of the jump instruction to _dnload_finalize() + */ + ret = i2400m_dnload_init(i2400m, bcf); /* Init device's dnload */ + if (ret == -ERESTARTSYS) + goto error_dev_rebooted; + if (ret < 0) + goto error_dnload_init; + + ret = i2400m_dnload_bcf(i2400m, bcf, bcf_size); + if (ret == -ERESTARTSYS) + goto error_dev_rebooted; + if (ret < 0) { + dev_err(dev, "fw %s: download failed: %d\n", + i2400m->bus_fw_name, ret); + goto error_dnload_bcf; + } + + ret = i2400m_dnload_finalize(i2400m, bcf, ret); + if (ret == -ERESTARTSYS) + goto error_dev_rebooted; + if (ret < 0) { + dev_err(dev, "fw %s: " + "download finalization failed: %d\n", + i2400m->bus_fw_name, ret); + goto error_dnload_finalize; + } + + d_printf(2, dev, "fw %s successfully uploaded\n", + i2400m->bus_fw_name); + i2400m->boot_mode = 0; +error_dnload_finalize: +error_dnload_bcf: +error_dnload_init: +error_bootrom_init: +error_too_many_reboots: + d_fnend(5, dev, "(i2400m %p bcf %p size %zu) = %d\n", + i2400m, bcf, bcf_size, ret); + return ret; + +error_dev_rebooted: + dev_err(dev, "device rebooted, %d tries left\n", count); + /* we got the notification already, no need to wait for it again */ + flags |= I2400M_BRI_SOFT; + goto hw_reboot; +} + + +/** + * i2400m_dev_bootstrap - Bring the device to a known state and upload firmware + * + * @i2400m: device descriptor + * + * Returns: >= 0 if ok, < 0 errno code on error. + * + * This sets up the firmware upload environment, loads the firmware + * file from disk, verifies and then calls the firmware upload process + * per se. + * + * Can be called either from probe, or after a warm reset. Can not be + * called from within an interrupt. All the flow in this code is + * single-threade; all I/Os are synchronous. + */ +int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags) +{ + int ret = 0; + struct device *dev = i2400m_dev(i2400m); + const struct firmware *fw; + const struct i2400m_bcf_hdr *bcf; /* Firmware data */ + + d_fnstart(5, dev, "(i2400m %p)\n", i2400m); + /* Load firmware files to memory. */ + ret = request_firmware(&fw, i2400m->bus_fw_name, dev); + if (ret) { + dev_err(dev, "fw %s: request failed: %d\n", + i2400m->bus_fw_name, ret); + goto error_fw_req; + } + bcf = (void *) fw->data; + + ret = i2400m_fw_check(i2400m, bcf, fw->size); + if (ret < 0) + goto error_fw_bad; + ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags); +error_fw_bad: + release_firmware(fw); +error_fw_req: + d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); + return ret; +} +EXPORT_SYMBOL_GPL(i2400m_dev_bootstrap); -- cgit From aa5a7acabe31ec27a212cbd25cad9f72aa476591 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:47 -0800 Subject: i2400m: RX and TX data/control paths Handling of TX/RX data to/from the i2400m device (IP packets, control and diagnostics). On RX, this parses the received read transaction from the device, breaks it in chunks and passes it to the corresponding subsystems (network and control). Transmission to the device is done through a software FIFO, as data/control frames can be coalesced (while the device is reading the previous tx transaction, others accumulate). A FIFO is used because at the end it is resource-cheaper that scatter/gather over USB. As well, most traffic is going to be download (vs upload). Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/rx.c | 534 +++++++++++++++++++++++++++ drivers/net/wimax/i2400m/tx.c | 817 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1351 insertions(+) create mode 100644 drivers/net/wimax/i2400m/rx.c create mode 100644 drivers/net/wimax/i2400m/tx.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c new file mode 100644 index 00000000000..6922022710a --- /dev/null +++ b/drivers/net/wimax/i2400m/rx.c @@ -0,0 +1,534 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Handle incoming traffic and deliver it to the control or data planes + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * - Initial implementation + * Inaky Perez-Gonzalez + * - Use skb_clone(), break up processing in chunks + * - Split transport/device specific + * - Make buffer size dynamic to exert less memory pressure + * + * + * This handles the RX path. + * + * We receive an RX message from the bus-specific driver, which + * contains one or more payloads that have potentially different + * destinataries (data or control paths). + * + * So we just take that payload from the transport specific code in + * the form of an skb, break it up in chunks (a cloned skb each in the + * case of network packets) and pass it to netdev or to the + * command/ack handler (and from there to the WiMAX stack). + * + * PROTOCOL FORMAT + * + * The format of the buffer is: + * + * HEADER (struct i2400m_msg_hdr) + * PAYLOAD DESCRIPTOR 0 (struct i2400m_pld) + * PAYLOAD DESCRIPTOR 1 + * ... + * PAYLOAD DESCRIPTOR N + * PAYLOAD 0 (raw bytes) + * PAYLOAD 1 + * ... + * PAYLOAD N + * + * See tx.c for a deeper description on alignment requirements and + * other fun facts of it. + * + * ROADMAP + * + * i2400m_rx + * i2400m_rx_msg_hdr_check + * i2400m_rx_pl_descr_check + * i2400m_rx_payload + * i2400m_net_rx + * i2400m_rx_ctl + * i2400m_msg_size_check + * i2400m_report_hook_work [in a workqueue] + * i2400m_report_hook + * wimax_msg_to_user + * i2400m_rx_ctl_ack + * wimax_msg_to_user_alloc + * i2400m_rx_trace + * i2400m_msg_size_check + * wimax_msg + */ +#include +#include +#include +#include +#include "i2400m.h" + + +#define D_SUBMODULE rx +#include "debug-levels.h" + +struct i2400m_report_hook_args { + struct sk_buff *skb_rx; + const struct i2400m_l3l4_hdr *l3l4_hdr; + size_t size; +}; + + +/* + * Execute i2400m_report_hook in a workqueue + * + * Unpacks arguments from the deferred call, executes it and then + * drops the references. + * + * Obvious NOTE: References are needed because we are a separate + * thread; otherwise the buffer changes under us because it is + * released by the original caller. + */ +static +void i2400m_report_hook_work(struct work_struct *ws) +{ + struct i2400m_work *iw = + container_of(ws, struct i2400m_work, ws); + struct i2400m_report_hook_args *args = (void *) iw->pl; + i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size); + kfree_skb(args->skb_rx); + i2400m_put(iw->i2400m); + kfree(iw); +} + + +/* + * Process an ack to a command + * + * @i2400m: device descriptor + * @payload: pointer to message + * @size: size of the message + * + * Pass the acknodledgment (in an skb) to the thread that is waiting + * for it in i2400m->msg_completion. + * + * We need to coordinate properly with the thread waiting for the + * ack. Check if it is waiting or if it is gone. We loose the spinlock + * to avoid allocating on atomic contexts (yeah, could use GFP_ATOMIC, + * but this is not so speed critical). + */ +static +void i2400m_rx_ctl_ack(struct i2400m *i2400m, + const void *payload, size_t size) +{ + struct device *dev = i2400m_dev(i2400m); + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + unsigned long flags; + struct sk_buff *ack_skb; + + /* Anyone waiting for an answer? */ + spin_lock_irqsave(&i2400m->rx_lock, flags); + if (i2400m->ack_skb != ERR_PTR(-EINPROGRESS)) { + dev_err(dev, "Huh? reply to command with no waiters\n"); + goto error_no_waiter; + } + spin_unlock_irqrestore(&i2400m->rx_lock, flags); + + ack_skb = wimax_msg_alloc(wimax_dev, NULL, payload, size, GFP_KERNEL); + + /* Check waiter didn't time out waiting for the answer... */ + spin_lock_irqsave(&i2400m->rx_lock, flags); + if (i2400m->ack_skb != ERR_PTR(-EINPROGRESS)) { + d_printf(1, dev, "Huh? waiter for command reply cancelled\n"); + goto error_waiter_cancelled; + } + if (ack_skb == NULL) { + dev_err(dev, "CMD/GET/SET ack: cannot allocate SKB\n"); + i2400m->ack_skb = ERR_PTR(-ENOMEM); + } else + i2400m->ack_skb = ack_skb; + spin_unlock_irqrestore(&i2400m->rx_lock, flags); + complete(&i2400m->msg_completion); + return; + +error_waiter_cancelled: + if (ack_skb) + kfree_skb(ack_skb); +error_no_waiter: + spin_unlock_irqrestore(&i2400m->rx_lock, flags); + return; +} + + +/* + * Receive and process a control payload + * + * @i2400m: device descriptor + * @skb_rx: skb that contains the payload (for reference counting) + * @payload: pointer to message + * @size: size of the message + * + * There are two types of control RX messages: reports (asynchronous, + * like your every day interrupts) and 'acks' (reponses to a command, + * get or set request). + * + * If it is a report, we run hooks on it (to extract information for + * things we need to do in the driver) and then pass it over to the + * WiMAX stack to send it to user space. + * + * NOTE: report processing is done in a workqueue specific to the + * generic driver, to avoid deadlocks in the system. + * + * If it is not a report, it is an ack to a previously executed + * command, set or get, so wake up whoever is waiting for it from + * i2400m_msg_to_dev(). i2400m_rx_ctl_ack() takes care of that. + * + * Note that the sizes we pass to other functions from here are the + * sizes of the _l3l4_hdr + payload, not full buffer sizes, as we have + * verified in _msg_size_check() that they are congruent. + * + * For reports: We can't clone the original skb where the data is + * because we need to send this up via netlink; netlink has to add + * headers and we can't overwrite what's preceeding the payload...as + * it is another message. So we just dup them. + */ +static +void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx, + const void *payload, size_t size) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + const struct i2400m_l3l4_hdr *l3l4_hdr = payload; + unsigned msg_type; + + result = i2400m_msg_size_check(i2400m, l3l4_hdr, size); + if (result < 0) { + dev_err(dev, "HW BUG? device sent a bad message: %d\n", + result); + goto error_check; + } + msg_type = le16_to_cpu(l3l4_hdr->type); + d_printf(1, dev, "%s 0x%04x: %zu bytes\n", + msg_type & I2400M_MT_REPORT_MASK ? "REPORT" : "CMD/SET/GET", + msg_type, size); + d_dump(2, dev, l3l4_hdr, size); + if (msg_type & I2400M_MT_REPORT_MASK) { + /* These hooks have to be ran serialized; as well, the + * handling might force the execution of commands, and + * that might cause reentrancy issues with + * bus-specific subdrivers and workqueues. So we run + * it in a separate workqueue. */ + struct i2400m_report_hook_args args = { + .skb_rx = skb_rx, + .l3l4_hdr = l3l4_hdr, + .size = size + }; + if (unlikely(i2400m->ready == 0)) /* only send if up */ + return; + skb_get(skb_rx); + i2400m_queue_work(i2400m, i2400m_report_hook_work, + GFP_KERNEL, &args, sizeof(args)); + result = wimax_msg(&i2400m->wimax_dev, NULL, l3l4_hdr, size, + GFP_KERNEL); + if (result < 0) + dev_err(dev, "error sending report to userspace: %d\n", + result); + } else /* an ack to a CMD, GET or SET */ + i2400m_rx_ctl_ack(i2400m, payload, size); +error_check: + return; +} + + + + +/* + * Receive and send up a trace + * + * @i2400m: device descriptor + * @skb_rx: skb that contains the trace (for reference counting) + * @payload: pointer to trace message inside the skb + * @size: size of the message + * + * THe i2400m might produce trace information (diagnostics) and we + * send them through a different kernel-to-user pipe (to avoid + * clogging it). + * + * As in i2400m_rx_ctl(), we can't clone the original skb where the + * data is because we need to send this up via netlink; netlink has to + * add headers and we can't overwrite what's preceeding the + * payload...as it is another message. So we just dup them. + */ +static +void i2400m_rx_trace(struct i2400m *i2400m, + const void *payload, size_t size) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + const struct i2400m_l3l4_hdr *l3l4_hdr = payload; + unsigned msg_type; + + result = i2400m_msg_size_check(i2400m, l3l4_hdr, size); + if (result < 0) { + dev_err(dev, "HW BUG? device sent a bad trace message: %d\n", + result); + goto error_check; + } + msg_type = le16_to_cpu(l3l4_hdr->type); + d_printf(1, dev, "Trace %s 0x%04x: %zu bytes\n", + msg_type & I2400M_MT_REPORT_MASK ? "REPORT" : "CMD/SET/GET", + msg_type, size); + d_dump(2, dev, l3l4_hdr, size); + if (unlikely(i2400m->ready == 0)) /* only send if up */ + return; + result = wimax_msg(wimax_dev, "trace", l3l4_hdr, size, GFP_KERNEL); + if (result < 0) + dev_err(dev, "error sending trace to userspace: %d\n", + result); +error_check: + return; +} + + +/* + * Act on a received payload + * + * @i2400m: device instance + * @skb_rx: skb where the transaction was received + * @single: 1 if there is only one payload, 0 otherwise + * @pld: payload descriptor + * @payload: payload data + * + * Upon reception of a payload, look at its guts in the payload + * descriptor and decide what to do with it. + */ +static +void i2400m_rx_payload(struct i2400m *i2400m, struct sk_buff *skb_rx, + unsigned single, const struct i2400m_pld *pld, + const void *payload) +{ + struct device *dev = i2400m_dev(i2400m); + size_t pl_size = i2400m_pld_size(pld); + enum i2400m_pt pl_type = i2400m_pld_type(pld); + + switch (pl_type) { + case I2400M_PT_DATA: + d_printf(3, dev, "RX: data payload %zu bytes\n", pl_size); + i2400m_net_rx(i2400m, skb_rx, single, payload, pl_size); + break; + case I2400M_PT_CTRL: + i2400m_rx_ctl(i2400m, skb_rx, payload, pl_size); + break; + case I2400M_PT_TRACE: + i2400m_rx_trace(i2400m, payload, pl_size); + break; + default: /* Anything else shouldn't come to the host */ + if (printk_ratelimit()) + dev_err(dev, "RX: HW BUG? unexpected payload type %u\n", + pl_type); + } +} + + +/* + * Check a received transaction's message header + * + * @i2400m: device descriptor + * @msg_hdr: message header + * @buf_size: size of the received buffer + * + * Check that the declarations done by a RX buffer message header are + * sane and consistent with the amount of data that was received. + */ +static +int i2400m_rx_msg_hdr_check(struct i2400m *i2400m, + const struct i2400m_msg_hdr *msg_hdr, + size_t buf_size) +{ + int result = -EIO; + struct device *dev = i2400m_dev(i2400m); + if (buf_size < sizeof(*msg_hdr)) { + dev_err(dev, "RX: HW BUG? message with short header (%zu " + "vs %zu bytes expected)\n", buf_size, sizeof(*msg_hdr)); + goto error; + } + if (msg_hdr->barker != cpu_to_le32(I2400M_D2H_MSG_BARKER)) { + dev_err(dev, "RX: HW BUG? message received with unknown " + "barker 0x%08x (buf_size %zu bytes)\n", + le32_to_cpu(msg_hdr->barker), buf_size); + goto error; + } + if (msg_hdr->num_pls == 0) { + dev_err(dev, "RX: HW BUG? zero payload packets in message\n"); + goto error; + } + if (le16_to_cpu(msg_hdr->num_pls) > I2400M_MAX_PLS_IN_MSG) { + dev_err(dev, "RX: HW BUG? message contains more payload " + "than maximum; ignoring.\n"); + goto error; + } + result = 0; +error: + return result; +} + + +/* + * Check a payload descriptor against the received data + * + * @i2400m: device descriptor + * @pld: payload descriptor + * @pl_itr: offset (in bytes) in the received buffer the payload is + * located + * @buf_size: size of the received buffer + * + * Given a payload descriptor (part of a RX buffer), check it is sane + * and that the data it declares fits in the buffer. + */ +static +int i2400m_rx_pl_descr_check(struct i2400m *i2400m, + const struct i2400m_pld *pld, + size_t pl_itr, size_t buf_size) +{ + int result = -EIO; + struct device *dev = i2400m_dev(i2400m); + size_t pl_size = i2400m_pld_size(pld); + enum i2400m_pt pl_type = i2400m_pld_type(pld); + + if (pl_size > i2400m->bus_pl_size_max) { + dev_err(dev, "RX: HW BUG? payload @%zu: size %zu is " + "bigger than maximum %zu; ignoring message\n", + pl_itr, pl_size, i2400m->bus_pl_size_max); + goto error; + } + if (pl_itr + pl_size > buf_size) { /* enough? */ + dev_err(dev, "RX: HW BUG? payload @%zu: size %zu " + "goes beyond the received buffer " + "size (%zu bytes); ignoring message\n", + pl_itr, pl_size, buf_size); + goto error; + } + if (pl_type >= I2400M_PT_ILLEGAL) { + dev_err(dev, "RX: HW BUG? illegal payload type %u; " + "ignoring message\n", pl_type); + goto error; + } + result = 0; +error: + return result; +} + + +/** + * i2400m_rx - Receive a buffer of data from the device + * + * @i2400m: device descriptor + * @skb: skbuff where the data has been received + * + * Parse in a buffer of data that contains an RX message sent from the + * device. See the file header for the format. Run all checks on the + * buffer header, then run over each payload's descriptors, verify + * their consistency and act on each payload's contents. If + * everything is succesful, update the device's statistics. + * + * Note: You need to set the skb to contain only the length of the + * received buffer; for that, use skb_trim(skb, RECEIVED_SIZE). + * + * Returns: + * + * 0 if ok, < 0 errno on error + * + * If ok, this function owns now the skb and the caller DOESN'T have + * to run kfree_skb() on it. However, on error, the caller still owns + * the skb and it is responsible for releasing it. + */ +int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) +{ + int i, result; + struct device *dev = i2400m_dev(i2400m); + const struct i2400m_msg_hdr *msg_hdr; + size_t pl_itr, pl_size, skb_len; + unsigned long flags; + unsigned num_pls; + + skb_len = skb->len; + d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n", + i2400m, skb, skb_len); + result = -EIO; + msg_hdr = (void *) skb->data; + result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb->len); + if (result < 0) + goto error_msg_hdr_check; + result = -EIO; + num_pls = le16_to_cpu(msg_hdr->num_pls); + pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ + num_pls * sizeof(msg_hdr->pld[0]); + pl_itr = ALIGN(pl_itr, I2400M_PL_PAD); + if (pl_itr > skb->len) { /* got all the payload descriptors? */ + dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " + "%u payload descriptors (%zu each, total %zu)\n", + skb->len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr); + goto error_pl_descr_short; + } + /* Walk each payload payload--check we really got it */ + for (i = 0; i < num_pls; i++) { + /* work around old gcc warnings */ + pl_size = i2400m_pld_size(&msg_hdr->pld[i]); + result = i2400m_rx_pl_descr_check(i2400m, &msg_hdr->pld[i], + pl_itr, skb->len); + if (result < 0) + goto error_pl_descr_check; + i2400m_rx_payload(i2400m, skb, num_pls == 1, &msg_hdr->pld[i], + skb->data + pl_itr); + pl_itr += ALIGN(pl_size, I2400M_PL_PAD); + cond_resched(); /* Don't monopolize */ + } + kfree_skb(skb); + /* Update device statistics */ + spin_lock_irqsave(&i2400m->rx_lock, flags); + i2400m->rx_pl_num += i; + if (i > i2400m->rx_pl_max) + i2400m->rx_pl_max = i; + if (i < i2400m->rx_pl_min) + i2400m->rx_pl_min = i; + i2400m->rx_num++; + i2400m->rx_size_acc += skb->len; + if (skb->len < i2400m->rx_size_min) + i2400m->rx_size_min = skb->len; + if (skb->len > i2400m->rx_size_max) + i2400m->rx_size_max = skb->len; + spin_unlock_irqrestore(&i2400m->rx_lock, flags); +error_pl_descr_check: +error_pl_descr_short: +error_msg_hdr_check: + d_fnend(4, dev, "(i2400m %p skb %p [size %zu]) = %d\n", + i2400m, skb, skb_len, result); + return result; +} +EXPORT_SYMBOL_GPL(i2400m_rx); diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c new file mode 100644 index 00000000000..613a88ffd65 --- /dev/null +++ b/drivers/net/wimax/i2400m/tx.c @@ -0,0 +1,817 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Generic (non-bus specific) TX handling + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * - Initial implementation + * + * Intel Corporation + * Inaky Perez-Gonzalez + * - Rewritten to use a single FIFO to lower the memory allocation + * pressure and optimize cache hits when copying to the queue, as + * well as splitting out bus-specific code. + * + * + * Implements data transmission to the device; this is done through a + * software FIFO, as data/control frames can be coalesced (while the + * device is reading the previous tx transaction, others accumulate). + * + * A FIFO is used because at the end it is resource-cheaper that trying + * to implement scatter/gather over USB. As well, most traffic is going + * to be download (vs upload). + * + * The format for sending/receiving data to/from the i2400m is + * described in detail in rx.c:PROTOCOL FORMAT. In here we implement + * the transmission of that. This is split between a bus-independent + * part that just prepares everything and a bus-specific part that + * does the actual transmission over the bus to the device (in the + * bus-specific driver). + * + * + * The general format of a device-host transaction is MSG-HDR, PLD1, + * PLD2...PLDN, PL1, PL2,...PLN, PADDING. + * + * Because we need the send payload descriptors and then payloads and + * because it is kind of expensive to do scatterlists in USB (one URB + * per node), it becomes cheaper to append all the data to a FIFO + * (copying to a FIFO potentially in cache is cheaper). + * + * Then the bus-specific code takes the parts of that FIFO that are + * written and passes them to the device. + * + * So the concepts to keep in mind there are: + * + * We use a FIFO to queue the data in a linear buffer. We first append + * a MSG-HDR, space for I2400M_TX_PLD_MAX payload descriptors and then + * go appending payloads until we run out of space or of payload + * descriptors. Then we append padding to make the whole transaction a + * multiple of i2400m->bus_tx_block_size (as defined by the bus layer). + * + * - A TX message: a combination of a message header, payload + * descriptors and payloads. + * + * Open: it is marked as active (i2400m->tx_msg is valid) and we + * can keep adding payloads to it. + * + * Closed: we are not appending more payloads to this TX message + * (exahusted space in the queue, too many payloads or + * whichever). We have appended padding so the whole message + * length is aligned to i2400m->bus_tx_block_size (as set by the + * bus/transport layer). + * + * - Most of the time we keep a TX message open to which we append + * payloads. + * + * - If we are going to append and there is no more space (we are at + * the end of the FIFO), we close the message, mark the rest of the + * FIFO space unusable (skip_tail), create a new message at the + * beginning of the FIFO (if there is space) and append the message + * there. + * + * This is because we need to give linear TX messages to the bus + * engine. So we don't write a message to the remaining FIFO space + * until the tail and continue at the head of it. + * + * - We overload one of the fields in the message header to use it as + * 'size' of the TX message, so we can iterate over them. It also + * contains a flag that indicates if we have to skip it or not. + * When we send the buffer, we update that to its real on-the-wire + * value. + * + * - The MSG-HDR PLD1...PLD2 stuff has to be a size multiple of 16. + * + * It follows that if MSG-HDR says we have N messages, the whole + * header + descriptors is 16 + 4*N; for those to be a multiple of + * 16, it follows that N can be 4, 8, 12, ... (32, 48, 64, 80... + * bytes). + * + * So if we have only 1 payload, we have to submit a header that in + * all truth has space for 4. + * + * The implication is that we reserve space for 12 (64 bytes); but + * if we fill up only (eg) 2, our header becomes 32 bytes only. So + * the TX engine has to shift those 32 bytes of msg header and 2 + * payloads and padding so that right after it the payloads start + * and the TX engine has to know about that. + * + * It is cheaper to move the header up than the whole payloads down. + * + * We do this in i2400m_tx_close(). See 'i2400m_msg_hdr->offset'. + * + * - Each payload has to be size-padded to 16 bytes; before appending + * it, we just do it. + * + * - The whole message has to be padded to i2400m->bus_tx_block_size; + * we do this at close time. Thus, when reserving space for the + * payload, we always make sure there is also free space for this + * padding that sooner or later will happen. + * + * When we append a message, we tell the bus specific code to kick in + * TXs. It will TX (in parallel) until the buffer is exhausted--hence + * the lockin we do. The TX code will only send a TX message at the + * time (which remember, might contain more than one payload). Of + * course, when the bus-specific driver attempts to TX a message that + * is still open, it gets closed first. + * + * Gee, this is messy; well a picture. In the example below we have a + * partially full FIFO, with a closed message ready to be delivered + * (with a moved message header to make sure it is size-aligned to + * 16), TAIL room that was unusable (and thus is marked with a message + * header that says 'skip this') and at the head of the buffer, an + * imcomplete message with a couple of payloads. + * + * N ___________________________________________________ + * | | + * | TAIL room | + * | | + * | msg_hdr to skip (size |= 0x80000) | + * |---------------------------------------------------|------- + * | | /|\ + * | | | + * | TX message padding | | + * | | | + * | | | + * |- - - - - - - - - - - - - - - - - - - - - - - - - -| | + * | | | + * | payload 1 | | + * | | N * tx_block_size + * | | | + * |- - - - - - - - - - - - - - - - - - - - - - - - - -| | + * | | | + * | payload 1 | | + * | | | + * | | | + * |- - - - - - - - - - - - - - - - - - - - - - - - - -|- -|- - - - + * | padding 3 /|\ | | /|\ + * | padding 2 | | | | + * | pld 1 32 bytes (2 * 16) | | | + * | pld 0 | | | | + * | moved msg_hdr \|/ | \|/ | + * |- - - - - - - - - - - - - - - - - - - - - - - - - -|- - - | + * | | _PLD_SIZE + * | unused | | + * | | | + * |- - - - - - - - - - - - - - - - - - - - - - - - - -| | + * | msg_hdr (size X) [this message is closed] | \|/ + * |===================================================|========== <=== OUT + * | | + * | | + * | | + * | Free rooom | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * |===================================================|========== <=== IN + * | | + * | | + * | | + * | | + * | payload 1 | + * | | + * | | + * |- - - - - - - - - - - - - - - - - - - - - - - - - -| + * | | + * | payload 0 | + * | | + * | | + * |- - - - - - - - - - - - - - - - - - - - - - - - - -| + * | pld 11 /|\ | + * | ... | | + * | pld 1 64 bytes (2 * 16) | + * | pld 0 | | + * | msg_hdr (size X) \|/ [message is open] | + * 0 --------------------------------------------------- + * + * + * ROADMAP + * + * i2400m_tx_setup() Called by i2400m_setup + * i2400m_tx_release() Called by i2400m_release() + * + * i2400m_tx() Called to send data or control frames + * i2400m_tx_fifo_push() Allocates append-space in the FIFO + * i2400m_tx_new() Opens a new message in the FIFO + * i2400m_tx_fits() Checks if a new payload fits in the message + * i2400m_tx_close() Closes an open message in the FIFO + * i2400m_tx_skip_tail() Marks unusable FIFO tail space + * i2400m->bus_tx_kick() + * + * Now i2400m->bus_tx_kick() is the the bus-specific driver backend + * implementation; that would do: + * + * i2400m->bus_tx_kick() + * i2400m_tx_msg_get() Gets first message ready to go + * ...sends it... + * i2400m_tx_msg_sent() Ack the message is sent; repeat from + * _tx_msg_get() until it returns NULL + * (FIFO empty). + */ +#include +#include "i2400m.h" + + +#define D_SUBMODULE tx +#include "debug-levels.h" + +enum { + /** + * TX Buffer size + * + * Doc says maximum transaction is 16KiB. If we had 16KiB en + * route and 16KiB being queued, it boils down to needing + * 32KiB. + */ + I2400M_TX_BUF_SIZE = 32768, + /** + * Message header and payload descriptors have to be 16 + * aligned (16 + 4 * N = 16 * M). If we take that average sent + * packets are MTU size (~1400-~1500) it follows that we could + * fit at most 10-11 payloads in one transaction. To meet the + * alignment requirement, that means we need to leave space + * for 12 (64 bytes). To simplify, we leave space for that. If + * at the end there are less, we pad up to the nearest + * multiple of 16. + */ + I2400M_TX_PLD_MAX = 12, + I2400M_TX_PLD_SIZE = sizeof(struct i2400m_msg_hdr) + + I2400M_TX_PLD_MAX * sizeof(struct i2400m_pld), + I2400M_TX_SKIP = 0x80000000, +}; + +#define TAIL_FULL ((void *)~(unsigned long)NULL) + +/* + * Allocate @size bytes in the TX fifo, return a pointer to it + * + * @i2400m: device descriptor + * @size: size of the buffer we need to allocate + * @padding: ensure that there is at least this many bytes of free + * contiguous space in the fifo. This is needed because later on + * we might need to add padding. + * + * Returns: + * + * Pointer to the allocated space. NULL if there is no + * space. TAIL_FULL if there is no space at the tail but there is at + * the head (Case B below). + * + * These are the two basic cases we need to keep an eye for -- it is + * much better explained in linux/kernel/kfifo.c, but this code + * basically does the same. No rocket science here. + * + * Case A Case B + * N ___________ ___________ + * | tail room | | data | + * | | | | + * |<- IN ->| |<- OUT ->| + * | | | | + * | data | | room | + * | | | | + * |<- OUT ->| |<- IN ->| + * | | | | + * | head room | | data | + * 0 ----------- ----------- + * + * We allocate only *contiguous* space. + * + * We can allocate only from 'room'. In Case B, it is simple; in case + * A, we only try from the tail room; if it is not enough, we just + * fail and return TAIL_FULL and let the caller figure out if we wants to + * skip the tail room and try to allocate from the head. + * + * Note: + * + * Assumes i2400m->tx_lock is taken, and we use that as a barrier + * + * The indexes keep increasing and we reset them to zero when we + * pop data off the queue + */ +static +void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding) +{ + struct device *dev = i2400m_dev(i2400m); + size_t room, tail_room, needed_size; + void *ptr; + + needed_size = size + padding; + room = I2400M_TX_BUF_SIZE - (i2400m->tx_in - i2400m->tx_out); + if (room < needed_size) { /* this takes care of Case B */ + d_printf(2, dev, "fifo push %zu/%zu: no space\n", + size, padding); + return NULL; + } + /* Is there space at the tail? */ + tail_room = I2400M_TX_BUF_SIZE - i2400m->tx_in % I2400M_TX_BUF_SIZE; + if (tail_room < needed_size) { + if (i2400m->tx_out % I2400M_TX_BUF_SIZE + < i2400m->tx_in % I2400M_TX_BUF_SIZE) { + d_printf(2, dev, "fifo push %zu/%zu: tail full\n", + size, padding); + return TAIL_FULL; /* There might be head space */ + } else { + d_printf(2, dev, "fifo push %zu/%zu: no head space\n", + size, padding); + return NULL; /* There is no space */ + } + } + ptr = i2400m->tx_buf + i2400m->tx_in % I2400M_TX_BUF_SIZE; + d_printf(2, dev, "fifo push %zu/%zu: at @%zu\n", size, padding, + i2400m->tx_in % I2400M_TX_BUF_SIZE); + i2400m->tx_in += size; + return ptr; +} + + +/* + * Mark the tail of the FIFO buffer as 'to-skip' + * + * We should never hit the BUG_ON() because all the sizes we push to + * the FIFO are padded to be a multiple of 16 -- the size of *msg + * (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the + * header). + * + * Note: + * + * Assumes i2400m->tx_lock is taken, and we use that as a barrier + */ +static +void i2400m_tx_skip_tail(struct i2400m *i2400m) +{ + struct device *dev = i2400m_dev(i2400m); + size_t tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE; + size_t tail_room = I2400M_TX_BUF_SIZE - tx_in; + struct i2400m_msg_hdr *msg = i2400m->tx_buf + tx_in; + BUG_ON(tail_room < sizeof(*msg)); + msg->size = tail_room | I2400M_TX_SKIP; + d_printf(2, dev, "skip tail: skipping %zu bytes @%zu\n", + tail_room, tx_in); + i2400m->tx_in += tail_room; +} + + +/* + * Check if a skb will fit in the TX queue's current active TX + * message (if there are still descriptors left unused). + * + * Returns: + * 0 if the message won't fit, 1 if it will. + * + * Note: + * + * Assumes a TX message is active (i2400m->tx_msg). + * + * Assumes i2400m->tx_lock is taken, and we use that as a barrier + */ +static +unsigned i2400m_tx_fits(struct i2400m *i2400m) +{ + struct i2400m_msg_hdr *msg_hdr = i2400m->tx_msg; + return le16_to_cpu(msg_hdr->num_pls) < I2400M_TX_PLD_MAX; + +} + + +/* + * Start a new TX message header in the queue. + * + * Reserve memory from the base FIFO engine and then just initialize + * the message header. + * + * We allocate the biggest TX message header we might need (one that'd + * fit I2400M_TX_PLD_MAX payloads) -- when it is closed it will be + * 'ironed it out' and the unneeded parts removed. + * + * NOTE: + * + * Assumes that the previous message is CLOSED (eg: either + * there was none or 'i2400m_tx_close()' was called on it). + * + * Assumes i2400m->tx_lock is taken, and we use that as a barrier + */ +static +void i2400m_tx_new(struct i2400m *i2400m) +{ + struct device *dev = i2400m_dev(i2400m); + struct i2400m_msg_hdr *tx_msg; + BUG_ON(i2400m->tx_msg != NULL); +try_head: + tx_msg = i2400m_tx_fifo_push(i2400m, I2400M_TX_PLD_SIZE, 0); + if (tx_msg == NULL) + goto out; + else if (tx_msg == TAIL_FULL) { + i2400m_tx_skip_tail(i2400m); + d_printf(2, dev, "new TX message: tail full, trying head\n"); + goto try_head; + } + memset(tx_msg, 0, I2400M_TX_PLD_SIZE); + tx_msg->size = I2400M_TX_PLD_SIZE; +out: + i2400m->tx_msg = tx_msg; + d_printf(2, dev, "new TX message: %p @%zu\n", + tx_msg, (void *) tx_msg - i2400m->tx_buf); +} + + +/* + * Finalize the current TX message header + * + * Sets the message header to be at the proper location depending on + * how many descriptors we have (check documentation at the file's + * header for more info on that). + * + * Appends padding bytes to make sure the whole TX message (counting + * from the 'relocated' message header) is aligned to + * tx_block_size. We assume the _append() code has left enough space + * in the FIFO for that. If there are no payloads, just pass, as it + * won't be transferred. + * + * The amount of padding bytes depends on how many payloads are in the + * TX message, as the "msg header and payload descriptors" will be + * shifted up in the buffer. + */ +static +void i2400m_tx_close(struct i2400m *i2400m) +{ + struct device *dev = i2400m_dev(i2400m); + struct i2400m_msg_hdr *tx_msg = i2400m->tx_msg; + struct i2400m_msg_hdr *tx_msg_moved; + size_t aligned_size, padding, hdr_size; + void *pad_buf; + + if (tx_msg->size & I2400M_TX_SKIP) /* a skipper? nothing to do */ + goto out; + + /* Relocate the message header + * + * Find the current header size, align it to 16 and if we need + * to move it so the tail is next to the payloads, move it and + * set the offset. + * + * If it moved, this header is good only for transmission; the + * original one (it is kept if we moved) is still used to + * figure out where the next TX message starts (and where the + * offset to the moved header is). + */ + hdr_size = sizeof(*tx_msg) + + le16_to_cpu(tx_msg->num_pls) * sizeof(tx_msg->pld[0]); + hdr_size = ALIGN(hdr_size, I2400M_PL_PAD); + tx_msg->offset = I2400M_TX_PLD_SIZE - hdr_size; + tx_msg_moved = (void *) tx_msg + tx_msg->offset; + memmove(tx_msg_moved, tx_msg, hdr_size); + tx_msg_moved->size -= tx_msg->offset; + /* + * Now figure out how much we have to add to the (moved!) + * message so the size is a multiple of i2400m->bus_tx_block_size. + */ + aligned_size = ALIGN(tx_msg_moved->size, i2400m->bus_tx_block_size); + padding = aligned_size - tx_msg_moved->size; + if (padding > 0) { + pad_buf = i2400m_tx_fifo_push(i2400m, padding, 0); + if (unlikely(WARN_ON(pad_buf == NULL + || pad_buf == TAIL_FULL))) { + /* This should not happen -- append should verify + * there is always space left at least to append + * tx_block_size */ + dev_err(dev, + "SW BUG! Possible data leakage from memory the " + "device should not read for padding - " + "size %lu aligned_size %zu tx_buf %p in " + "%zu out %zu\n", + (unsigned long) tx_msg_moved->size, + aligned_size, i2400m->tx_buf, i2400m->tx_in, + i2400m->tx_out); + } else + memset(pad_buf, 0xad, padding); + } + tx_msg_moved->padding = cpu_to_le16(padding); + tx_msg_moved->size += padding; + if (tx_msg != tx_msg_moved) + tx_msg->size += padding; +out: + i2400m->tx_msg = NULL; +} + + +/** + * i2400m_tx - send the data in a buffer to the device + * + * @buf: pointer to the buffer to transmit + * + * @buf_len: buffer size + * + * @pl_type: type of the payload we are sending. + * + * Returns: + * 0 if ok, < 0 errno code on error (-ENOSPC, if there is no more + * room for the message in the queue). + * + * Appends the buffer to the TX FIFO and notifies the bus-specific + * part of the driver that there is new data ready to transmit. + * Once this function returns, the buffer has been copied, so it can + * be reused. + * + * The steps followed to append are explained in detail in the file + * header. + * + * Whenever we write to a message, we increase msg->size, so it + * reflects exactly how big the message is. This is needed so that if + * we concatenate two messages before they can be sent, the code that + * sends the messages can find the boundaries (and it will replace the + * size with the real barker before sending). + * + * Note: + * + * Cold and warm reset payloads need to be sent as a single + * payload, so we handle that. + */ +int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len, + enum i2400m_pt pl_type) +{ + int result = -ENOSPC; + struct device *dev = i2400m_dev(i2400m); + unsigned long flags; + size_t padded_len; + void *ptr; + unsigned is_singleton = pl_type == I2400M_PT_RESET_WARM + || pl_type == I2400M_PT_RESET_COLD; + + d_fnstart(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u)\n", + i2400m, buf, buf_len, pl_type); + padded_len = ALIGN(buf_len, I2400M_PL_PAD); + d_printf(5, dev, "padded_len %zd buf_len %zd\n", padded_len, buf_len); + /* If there is no current TX message, create one; if the + * current one is out of payload slots or we have a singleton, + * close it and start a new one */ + spin_lock_irqsave(&i2400m->tx_lock, flags); +try_new: + if (unlikely(i2400m->tx_msg == NULL)) + i2400m_tx_new(i2400m); + else if (unlikely(!i2400m_tx_fits(i2400m) + || (is_singleton && i2400m->tx_msg->num_pls != 0))) { + d_printf(2, dev, "closing TX message (fits %u singleton " + "%u num_pls %u)\n", i2400m_tx_fits(i2400m), + is_singleton, i2400m->tx_msg->num_pls); + i2400m_tx_close(i2400m); + i2400m_tx_new(i2400m); + } + if (i2400m->tx_msg->size + padded_len > I2400M_TX_BUF_SIZE / 2) { + d_printf(2, dev, "TX: message too big, going new\n"); + i2400m_tx_close(i2400m); + i2400m_tx_new(i2400m); + } + if (i2400m->tx_msg == NULL) + goto error_tx_new; + /* So we have a current message header; now append space for + * the message -- if there is not enough, try the head */ + ptr = i2400m_tx_fifo_push(i2400m, padded_len, + i2400m->bus_tx_block_size); + if (ptr == TAIL_FULL) { /* Tail is full, try head */ + d_printf(2, dev, "pl append: tail full\n"); + i2400m_tx_close(i2400m); + i2400m_tx_skip_tail(i2400m); + goto try_new; + } else if (ptr == NULL) { /* All full */ + result = -ENOSPC; + d_printf(2, dev, "pl append: all full\n"); + } else { /* Got space, copy it, set padding */ + struct i2400m_msg_hdr *tx_msg = i2400m->tx_msg; + unsigned num_pls = le16_to_cpu(tx_msg->num_pls); + memcpy(ptr, buf, buf_len); + memset(ptr + buf_len, 0xad, padded_len - buf_len); + i2400m_pld_set(&tx_msg->pld[num_pls], buf_len, pl_type); + d_printf(3, dev, "pld 0x%08x (type 0x%1x len 0x%04zx\n", + le32_to_cpu(tx_msg->pld[num_pls].val), + pl_type, buf_len); + tx_msg->num_pls = le16_to_cpu(num_pls+1); + tx_msg->size += padded_len; + d_printf(2, dev, "TX: appended %zu b (up to %u b) pl #%u \n", + padded_len, tx_msg->size, num_pls+1); + d_printf(2, dev, + "TX: appended hdr @%zu %zu b pl #%u @%zu %zu/%zu b\n", + (void *)tx_msg - i2400m->tx_buf, (size_t)tx_msg->size, + num_pls+1, ptr - i2400m->tx_buf, buf_len, padded_len); + result = 0; + if (is_singleton) + i2400m_tx_close(i2400m); + } +error_tx_new: + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + i2400m->bus_tx_kick(i2400m); /* always kick, might free up space */ + d_fnend(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u) = %d\n", + i2400m, buf, buf_len, pl_type, result); + return result; +} +EXPORT_SYMBOL_GPL(i2400m_tx); + + +/** + * i2400m_tx_msg_get - Get the first TX message in the FIFO to start sending it + * + * @i2400m: device descriptors + * @bus_size: where to place the size of the TX message + * + * Called by the bus-specific driver to get the first TX message at + * the FIF that is ready for transmission. + * + * It sets the state in @i2400m to indicate the bus-specific driver is + * transfering that message (i2400m->tx_msg_size). + * + * Once the transfer is completed, call i2400m_tx_msg_sent(). + * + * Notes: + * + * The size of the TX message to be transmitted might be smaller than + * that of the TX message in the FIFO (in case the header was + * shorter). Hence, we copy it in @bus_size, for the bus layer to + * use. We keep the message's size in i2400m->tx_msg_size so that + * when the bus later is done transferring we know how much to + * advance the fifo. + * + * We collect statistics here as all the data is available and we + * assume it is going to work [see i2400m_tx_msg_sent()]. + */ +struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *i2400m, + size_t *bus_size) +{ + struct device *dev = i2400m_dev(i2400m); + struct i2400m_msg_hdr *tx_msg, *tx_msg_moved; + unsigned long flags, pls; + + d_fnstart(3, dev, "(i2400m %p bus_size %p)\n", i2400m, bus_size); + spin_lock_irqsave(&i2400m->tx_lock, flags); +skip: + tx_msg_moved = NULL; + if (i2400m->tx_in == i2400m->tx_out) { /* Empty FIFO? */ + i2400m->tx_in = 0; + i2400m->tx_out = 0; + d_printf(2, dev, "TX: FIFO empty: resetting\n"); + goto out_unlock; + } + tx_msg = i2400m->tx_buf + i2400m->tx_out % I2400M_TX_BUF_SIZE; + if (tx_msg->size & I2400M_TX_SKIP) { /* skip? */ + d_printf(2, dev, "TX: skip: msg @%zu (%zu b)\n", + i2400m->tx_out % I2400M_TX_BUF_SIZE, + (size_t) tx_msg->size & ~I2400M_TX_SKIP); + i2400m->tx_out += tx_msg->size & ~I2400M_TX_SKIP; + goto skip; + } + + if (tx_msg->num_pls == 0) { /* No payloads? */ + if (tx_msg == i2400m->tx_msg) { /* open, we are done */ + d_printf(2, dev, + "TX: FIFO empty: open msg w/o payloads @%zu\n", + (void *) tx_msg - i2400m->tx_buf); + tx_msg = NULL; + goto out_unlock; + } else { /* closed, skip it */ + d_printf(2, dev, + "TX: skip msg w/o payloads @%zu (%zu b)\n", + (void *) tx_msg - i2400m->tx_buf, + (size_t) tx_msg->size); + i2400m->tx_out += tx_msg->size & ~I2400M_TX_SKIP; + goto skip; + } + } + if (tx_msg == i2400m->tx_msg) /* open msg? */ + i2400m_tx_close(i2400m); + + /* Now we have a valid TX message (with payloads) to TX */ + tx_msg_moved = (void *) tx_msg + tx_msg->offset; + i2400m->tx_msg_size = tx_msg->size; + *bus_size = tx_msg_moved->size; + d_printf(2, dev, "TX: pid %d msg hdr at @%zu offset +@%zu " + "size %zu bus_size %zu\n", + current->pid, (void *) tx_msg - i2400m->tx_buf, + (size_t) tx_msg->offset, (size_t) tx_msg->size, + (size_t) tx_msg_moved->size); + tx_msg_moved->barker = le32_to_cpu(I2400M_H2D_PREVIEW_BARKER); + tx_msg_moved->sequence = le32_to_cpu(i2400m->tx_sequence++); + + pls = le32_to_cpu(tx_msg_moved->num_pls); + i2400m->tx_pl_num += pls; /* Update stats */ + if (pls > i2400m->tx_pl_max) + i2400m->tx_pl_max = pls; + if (pls < i2400m->tx_pl_min) + i2400m->tx_pl_min = pls; + i2400m->tx_num++; + i2400m->tx_size_acc += *bus_size; + if (*bus_size < i2400m->tx_size_min) + i2400m->tx_size_min = *bus_size; + if (*bus_size > i2400m->tx_size_max) + i2400m->tx_size_max = *bus_size; +out_unlock: + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + d_fnstart(3, dev, "(i2400m %p bus_size %p [%zu]) = %p\n", + i2400m, bus_size, *bus_size, tx_msg_moved); + return tx_msg_moved; +} +EXPORT_SYMBOL_GPL(i2400m_tx_msg_get); + + +/** + * i2400m_tx_msg_sent - indicate the transmission of a TX message + * + * @i2400m: device descriptor + * + * Called by the bus-specific driver when a message has been sent; + * this pops it from the FIFO; and as there is space, start the queue + * in case it was stopped. + * + * Should be called even if the message send failed and we are + * dropping this TX message. + */ +void i2400m_tx_msg_sent(struct i2400m *i2400m) +{ + unsigned n; + unsigned long flags; + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + spin_lock_irqsave(&i2400m->tx_lock, flags); + i2400m->tx_out += i2400m->tx_msg_size; + d_printf(2, dev, "TX: sent %zu b\n", (size_t) i2400m->tx_msg_size); + i2400m->tx_msg_size = 0; + BUG_ON(i2400m->tx_out > i2400m->tx_in); + /* level them FIFO markers off */ + n = i2400m->tx_out / I2400M_TX_BUF_SIZE; + i2400m->tx_out %= I2400M_TX_BUF_SIZE; + i2400m->tx_in -= n * I2400M_TX_BUF_SIZE; + netif_start_queue(i2400m->wimax_dev.net_dev); + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); +} +EXPORT_SYMBOL_GPL(i2400m_tx_msg_sent); + + +/** + * i2400m_tx_setup - Initialize the TX queue and infrastructure + * + * Make sure we reset the TX sequence to zero, as when this function + * is called, the firmware has been just restarted. + */ +int i2400m_tx_setup(struct i2400m *i2400m) +{ + int result; + + /* Do this here only once -- can't do on + * i2400m_hard_start_xmit() as we'll cause race conditions if + * the WS was scheduled on another CPU */ + INIT_WORK(&i2400m->wake_tx_ws, i2400m_wake_tx_work); + + i2400m->tx_sequence = 0; + i2400m->tx_buf = kmalloc(I2400M_TX_BUF_SIZE, GFP_KERNEL); + if (i2400m->tx_buf == NULL) + result = -ENOMEM; + else + result = 0; + /* Huh? the bus layer has to define this... */ + BUG_ON(i2400m->bus_tx_block_size == 0); + return result; + +} + + +/** + * i2400m_tx_release - Tear down the TX queue and infrastructure + */ +void i2400m_tx_release(struct i2400m *i2400m) +{ + kfree(i2400m->tx_buf); +} -- cgit From 3a35a1d0bdf7cc32cddc234b956605e6d4db4673 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:48 -0800 Subject: i2400m: various functions for device management This is a collection of functions used to control the device (plus a few helpers). There are utilities for handling TLV buffers, hooks on the device's reports to act on device changes of state [i2400m_report_hook()], on acks to commands [i2400m_msg_ack_hook()], a helper for sending commands to the device and blocking until a reply arrives [i2400m_msg_to_dev()], a few high level commands for manipulating the device state, powersaving mode and configuration plus the routines to setup the device once communication is established with it [i2400m_dev_initialize()]. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/control.c | 1291 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1291 insertions(+) create mode 100644 drivers/net/wimax/i2400m/control.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c new file mode 100644 index 00000000000..d3d37fed689 --- /dev/null +++ b/drivers/net/wimax/i2400m/control.c @@ -0,0 +1,1291 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Miscellaneous control functions for managing the device + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Inaky Perez-Gonzalez + * - Initial implementation + * + * This is a collection of functions used to control the device (plus + * a few helpers). + * + * There are utilities for handling TLV buffers, hooks on the device's + * reports to act on device changes of state [i2400m_report_hook()], + * on acks to commands [i2400m_msg_ack_hook()], a helper for sending + * commands to the device and blocking until a reply arrives + * [i2400m_msg_to_dev()], a few high level commands for manipulating + * the device state, powersving mode and configuration plus the + * routines to setup the device once communication is stablished with + * it [i2400m_dev_initialize()]. + * + * ROADMAP + * + * i2400m_dev_initalize() Called by i2400m_dev_start() + * i2400m_set_init_config() + * i2400m_firmware_check() + * i2400m_cmd_get_state() + * i2400m_dev_shutdown() Called by i2400m_dev_stop() + * i2400m->bus_reset() + * + * i2400m_{cmd,get,set}_*() + * i2400m_msg_to_dev() + * i2400m_msg_check_status() + * + * i2400m_report_hook() Called on reception of an event + * i2400m_report_state_hook() + * i2400m_tlv_buffer_walk() + * i2400m_tlv_match() + * i2400m_report_tlv_system_state() + * i2400m_report_tlv_rf_switches_status() + * i2400m_report_tlv_media_status() + * i2400m_cmd_enter_powersave() + * + * i2400m_msg_ack_hook() Called on reception of a reply to a + * command, get or set + */ + +#include +#include "i2400m.h" +#include +#include + + +#define D_SUBMODULE control +#include "debug-levels.h" + + +/* + * Return if a TLV is of a give type and size + * + * @tlv_hdr: pointer to the TLV + * @tlv_type: type of the TLV we are looking for + * @tlv_size: expected size of the TLV we are looking for (if -1, + * don't check the size). This includes the header + * Returns: 0 if the TLV matches + * < 0 if it doesn't match at all + * > 0 total TLV + payload size, if the type matches, but not + * the size + */ +static +ssize_t i2400m_tlv_match(const struct i2400m_tlv_hdr *tlv, + enum i2400m_tlv tlv_type, ssize_t tlv_size) +{ + if (le16_to_cpu(tlv->type) != tlv_type) /* Not our type? skip */ + return -1; + if (tlv_size != -1 + && le16_to_cpu(tlv->length) + sizeof(*tlv) != tlv_size) { + size_t size = le16_to_cpu(tlv->length) + sizeof(*tlv); + printk(KERN_WARNING "W: tlv type 0x%x mismatched because of " + "size (got %zu vs %zu expected)\n", + tlv_type, size, tlv_size); + return size; + } + return 0; +} + + +/* + * Given a buffer of TLVs, iterate over them + * + * @i2400m: device instance + * @tlv_buf: pointer to the beginning of the TLV buffer + * @buf_size: buffer size in bytes + * @tlv_pos: seek position; this is assumed to be a pointer returned + * by i2400m_tlv_buffer_walk() [and thus, validated]. The + * TLV returned will be the one following this one. + * + * Usage: + * + * tlv_itr = NULL; + * while (tlv_itr = i2400m_tlv_buffer_walk(i2400m, buf, size, tlv_itr)) { + * ... + * // Do stuff with tlv_itr, DON'T MODIFY IT + * ... + * } + */ +static +const struct i2400m_tlv_hdr *i2400m_tlv_buffer_walk( + struct i2400m *i2400m, + const void *tlv_buf, size_t buf_size, + const struct i2400m_tlv_hdr *tlv_pos) +{ + struct device *dev = i2400m_dev(i2400m); + const struct i2400m_tlv_hdr *tlv_top = tlv_buf + buf_size; + size_t offset, length, avail_size; + unsigned type; + + if (tlv_pos == NULL) /* Take the first one? */ + tlv_pos = tlv_buf; + else /* Nope, the next one */ + tlv_pos = (void *) tlv_pos + + le16_to_cpu(tlv_pos->length) + sizeof(*tlv_pos); + if (tlv_pos == tlv_top) { /* buffer done */ + tlv_pos = NULL; + goto error_beyond_end; + } + if (tlv_pos > tlv_top) { + tlv_pos = NULL; + WARN_ON(1); + goto error_beyond_end; + } + offset = (void *) tlv_pos - (void *) tlv_buf; + avail_size = buf_size - offset; + if (avail_size < sizeof(*tlv_pos)) { + dev_err(dev, "HW BUG? tlv_buf %p [%zu bytes], tlv @%zu: " + "short header\n", tlv_buf, buf_size, offset); + goto error_short_header; + } + type = le16_to_cpu(tlv_pos->type); + length = le16_to_cpu(tlv_pos->length); + if (avail_size < sizeof(*tlv_pos) + length) { + dev_err(dev, "HW BUG? tlv_buf %p [%zu bytes], " + "tlv type 0x%04x @%zu: " + "short data (%zu bytes vs %zu needed)\n", + tlv_buf, buf_size, type, offset, avail_size, + sizeof(*tlv_pos) + length); + goto error_short_header; + } +error_short_header: +error_beyond_end: + return tlv_pos; +} + + +/* + * Find a TLV in a buffer of sequential TLVs + * + * @i2400m: device descriptor + * @tlv_hdr: pointer to the first TLV in the sequence + * @size: size of the buffer in bytes; all TLVs are assumed to fit + * fully in the buffer (otherwise we'll complain). + * @tlv_type: type of the TLV we are looking for + * @tlv_size: expected size of the TLV we are looking for (if -1, + * don't check the size). This includes the header + * + * Returns: NULL if the TLV is not found, otherwise a pointer to + * it. If the sizes don't match, an error is printed and NULL + * returned. + */ +static +const struct i2400m_tlv_hdr *i2400m_tlv_find( + struct i2400m *i2400m, + const struct i2400m_tlv_hdr *tlv_hdr, size_t size, + enum i2400m_tlv tlv_type, ssize_t tlv_size) +{ + ssize_t match; + struct device *dev = i2400m_dev(i2400m); + const struct i2400m_tlv_hdr *tlv = NULL; + while ((tlv = i2400m_tlv_buffer_walk(i2400m, tlv_hdr, size, tlv))) { + match = i2400m_tlv_match(tlv, tlv_type, tlv_size); + if (match == 0) /* found it :) */ + break; + if (match > 0) + dev_warn(dev, "TLV type 0x%04x found with size " + "mismatch (%zu vs %zu needed)\n", + tlv_type, match, tlv_size); + } + return tlv; +} + + +static const struct +{ + char *msg; + int errno; +} ms_to_errno[I2400M_MS_MAX] = { + [I2400M_MS_DONE_OK] = { "", 0 }, + [I2400M_MS_DONE_IN_PROGRESS] = { "", 0 }, + [I2400M_MS_INVALID_OP] = { "invalid opcode", -ENOSYS }, + [I2400M_MS_BAD_STATE] = { "invalid state", -EILSEQ }, + [I2400M_MS_ILLEGAL_VALUE] = { "illegal value", -EINVAL }, + [I2400M_MS_MISSING_PARAMS] = { "missing parameters", -ENOMSG }, + [I2400M_MS_VERSION_ERROR] = { "bad version", -EIO }, + [I2400M_MS_ACCESSIBILITY_ERROR] = { "accesibility error", -EIO }, + [I2400M_MS_BUSY] = { "busy", -EBUSY }, + [I2400M_MS_CORRUPTED_TLV] = { "corrupted TLV", -EILSEQ }, + [I2400M_MS_UNINITIALIZED] = { "not unitialized", -EILSEQ }, + [I2400M_MS_UNKNOWN_ERROR] = { "unknown error", -EIO }, + [I2400M_MS_PRODUCTION_ERROR] = { "production error", -EIO }, + [I2400M_MS_NO_RF] = { "no RF", -EIO }, + [I2400M_MS_NOT_READY_FOR_POWERSAVE] = + { "not ready for powersave", -EACCES }, + [I2400M_MS_THERMAL_CRITICAL] = { "thermal critical", -EL3HLT }, +}; + + +/* + * i2400m_msg_check_status - translate a message's status code + * + * @i2400m: device descriptor + * @l3l4_hdr: message header + * @strbuf: buffer to place a formatted error message (unless NULL). + * @strbuf_size: max amount of available space; larger messages will + * be truncated. + * + * Returns: errno code corresponding to the status code in @l3l4_hdr + * and a message in @strbuf describing the error. + */ +int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *l3l4_hdr, + char *strbuf, size_t strbuf_size) +{ + int result; + enum i2400m_ms status = le16_to_cpu(l3l4_hdr->status); + const char *str; + + if (status == 0) + return 0; + if (status > ARRAY_SIZE(ms_to_errno)) { + str = "unknown status code"; + result = -EBADR; + } else { + str = ms_to_errno[status].msg; + result = ms_to_errno[status].errno; + } + if (strbuf) + snprintf(strbuf, strbuf_size, "%s (%d)", str, status); + return result; +} + + +/* + * Act on a TLV System State reported by the device + * + * @i2400m: device descriptor + * @ss: validated System State TLV + */ +static +void i2400m_report_tlv_system_state(struct i2400m *i2400m, + const struct i2400m_tlv_system_state *ss) +{ + struct device *dev = i2400m_dev(i2400m); + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + enum i2400m_system_state i2400m_state = le32_to_cpu(ss->state); + + d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state); + + if (unlikely(i2400m->ready == 0)) /* act if up */ + goto out; + if (i2400m->state != i2400m_state) { + i2400m->state = i2400m_state; + wake_up_all(&i2400m->state_wq); + } + switch (i2400m_state) { + case I2400M_SS_UNINITIALIZED: + case I2400M_SS_INIT: + case I2400M_SS_CONFIG: + case I2400M_SS_PRODUCTION: + wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED); + break; + + case I2400M_SS_RF_OFF: + case I2400M_SS_RF_SHUTDOWN: + wimax_state_change(wimax_dev, WIMAX_ST_RADIO_OFF); + break; + + case I2400M_SS_READY: + case I2400M_SS_STANDBY: + case I2400M_SS_SLEEPACTIVE: + wimax_state_change(wimax_dev, WIMAX_ST_READY); + break; + + case I2400M_SS_CONNECTING: + case I2400M_SS_WIMAX_CONNECTED: + wimax_state_change(wimax_dev, WIMAX_ST_READY); + break; + + case I2400M_SS_SCAN: + case I2400M_SS_OUT_OF_ZONE: + wimax_state_change(wimax_dev, WIMAX_ST_SCANNING); + break; + + case I2400M_SS_IDLE: + d_printf(1, dev, "entering BS-negotiated idle mode\n"); + case I2400M_SS_DISCONNECTING: + case I2400M_SS_DATA_PATH_CONNECTED: + wimax_state_change(wimax_dev, WIMAX_ST_CONNECTED); + break; + + default: + /* Huh? just in case, shut it down */ + dev_err(dev, "HW BUG? unknown state %u: shutting down\n", + i2400m_state); + i2400m->bus_reset(i2400m, I2400M_RT_WARM); + break; + }; +out: + d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n", + i2400m, ss, i2400m_state); +} + + +/* + * Parse and act on a TLV Media Status sent by the device + * + * @i2400m: device descriptor + * @ms: validated Media Status TLV + * + * This will set the carrier up on down based on the device's link + * report. This is done asides of what the WiMAX stack does based on + * the device's state as sometimes we need to do a link-renew (the BS + * wants us to renew a DHCP lease, for example). + * + * In fact, doc says that everytime we get a link-up, we should do a + * DHCP negotiation... + */ +static +void i2400m_report_tlv_media_status(struct i2400m *i2400m, + const struct i2400m_tlv_media_status *ms) +{ + struct device *dev = i2400m_dev(i2400m); + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + struct net_device *net_dev = wimax_dev->net_dev; + enum i2400m_media_status status = le32_to_cpu(ms->media_status); + + d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status); + + if (unlikely(i2400m->ready == 0)) /* act if up */ + goto out; + switch (status) { + case I2400M_MEDIA_STATUS_LINK_UP: + netif_carrier_on(net_dev); + break; + case I2400M_MEDIA_STATUS_LINK_DOWN: + netif_carrier_off(net_dev); + break; + /* + * This is the network telling us we need to retrain the DHCP + * lease -- so far, we are trusting the WiMAX Network Service + * in user space to pick this up and poke the DHCP client. + */ + case I2400M_MEDIA_STATUS_LINK_RENEW: + netif_carrier_on(net_dev); + break; + default: + dev_err(dev, "HW BUG? unknown media status %u\n", + status); + }; +out: + d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n", + i2400m, ms, status); +} + + +/* + * Parse a 'state report' and extract carrier on/off information + * + * @i2400m: device descriptor + * @l3l4_hdr: pointer to message; it has been already validated for + * consistent size. + * @size: size of the message (header + payload). The header length + * declaration is assumed to be congruent with @size (as in + * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) + * + * Extract from the report state the system state TLV and infer from + * there if we have a carrier or not. Update our local state and tell + * netdev. + * + * When setting the carrier, it's fine to set OFF twice (for example), + * as netif_carrier_off() will not generate two OFF events (just on + * the transitions). + */ +static +void i2400m_report_state_hook(struct i2400m *i2400m, + const struct i2400m_l3l4_hdr *l3l4_hdr, + size_t size, const char *tag) +{ + struct device *dev = i2400m_dev(i2400m); + const struct i2400m_tlv_hdr *tlv; + const struct i2400m_tlv_system_state *ss; + const struct i2400m_tlv_rf_switches_status *rfss; + const struct i2400m_tlv_media_status *ms; + size_t tlv_size = le16_to_cpu(l3l4_hdr->length); + + d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n", + i2400m, l3l4_hdr, size, tag); + tlv = NULL; + + while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl, + tlv_size, tlv))) { + if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, + sizeof(*ss))) { + ss = container_of(tlv, typeof(*ss), hdr); + d_printf(2, dev, "%s: system state TLV " + "found (0x%04x), state 0x%08x\n", + tag, I2400M_TLV_SYSTEM_STATE, + le32_to_cpu(ss->state)); + i2400m_report_tlv_system_state(i2400m, ss); + } + if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, + sizeof(*rfss))) { + rfss = container_of(tlv, typeof(*rfss), hdr); + d_printf(2, dev, "%s: RF status TLV " + "found (0x%04x), sw 0x%02x hw 0x%02x\n", + tag, I2400M_TLV_RF_STATUS, + le32_to_cpu(rfss->sw_rf_switch), + le32_to_cpu(rfss->hw_rf_switch)); + i2400m_report_tlv_rf_switches_status(i2400m, rfss); + } + if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, + sizeof(*ms))) { + ms = container_of(tlv, typeof(*ms), hdr); + d_printf(2, dev, "%s: Media Status TLV: %u\n", + tag, le32_to_cpu(ms->media_status)); + i2400m_report_tlv_media_status(i2400m, ms); + } + } + d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n", + i2400m, l3l4_hdr, size, tag); +} + + +/* + * i2400m_report_hook - (maybe) act on a report + * + * @i2400m: device descriptor + * @l3l4_hdr: pointer to message; it has been already validated for + * consistent size. + * @size: size of the message (header + payload). The header length + * declaration is assumed to be congruent with @size (as in + * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) + * + * Extract information we might need (like carrien on/off) from a + * device report. + */ +void i2400m_report_hook(struct i2400m *i2400m, + const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size) +{ + struct device *dev = i2400m_dev(i2400m); + unsigned msg_type; + + d_fnstart(3, dev, "(i2400m %p l3l4_hdr %p size %zu)\n", + i2400m, l3l4_hdr, size); + /* Chew on the message, we might need some information from + * here */ + msg_type = le16_to_cpu(l3l4_hdr->type); + switch (msg_type) { + case I2400M_MT_REPORT_STATE: /* carrier detection... */ + i2400m_report_state_hook(i2400m, + l3l4_hdr, size, "REPORT STATE"); + break; + /* If the device is ready for power save, then ask it to do + * it. */ + case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */ + if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) { + d_printf(1, dev, "ready for powersave, requesting\n"); + i2400m_cmd_enter_powersave(i2400m); + } + break; + }; + d_fnend(3, dev, "(i2400m %p l3l4_hdr %p size %zu) = void\n", + i2400m, l3l4_hdr, size); +} + + +/* + * i2400m_msg_ack_hook - process cmd/set/get ack for internal status + * + * @i2400m: device descriptor + * @l3l4_hdr: pointer to message; it has been already validated for + * consistent size. + * @size: size of the message + * + * Extract information we might need from acks to commands and act on + * it. This is akin to i2400m_report_hook(). Note most of this + * processing should be done in the function that calls the + * command. This is here for some cases where it can't happen... + */ +void i2400m_msg_ack_hook(struct i2400m *i2400m, + const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + unsigned ack_type, ack_status; + char strerr[32]; + + /* Chew on the message, we might need some information from + * here */ + ack_type = le16_to_cpu(l3l4_hdr->type); + ack_status = le16_to_cpu(l3l4_hdr->status); + switch (ack_type) { + case I2400M_MT_CMD_ENTER_POWERSAVE: + /* This is just left here for the sake of example, as + * the processing is done somewhere else. */ + if (0) { + result = i2400m_msg_check_status( + l3l4_hdr, strerr, sizeof(strerr)); + if (result >= 0) + d_printf(1, dev, "ready for power save: %zd\n", + size); + } + break; + }; + return; +} + + +/* + * i2400m_msg_size_check() - verify message size and header are congruent + * + * It is ok if the total message size is larger than the expected + * size, as there can be padding. + */ +int i2400m_msg_size_check(struct i2400m *i2400m, + const struct i2400m_l3l4_hdr *l3l4_hdr, + size_t msg_size) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + size_t expected_size; + d_fnstart(4, dev, "(i2400m %p l3l4_hdr %p msg_size %zu)\n", + i2400m, l3l4_hdr, msg_size); + if (msg_size < sizeof(*l3l4_hdr)) { + dev_err(dev, "bad size for message header " + "(expected at least %zu, got %zu)\n", + (size_t) sizeof(*l3l4_hdr), msg_size); + result = -EIO; + goto error_hdr_size; + } + expected_size = le16_to_cpu(l3l4_hdr->length) + sizeof(*l3l4_hdr); + if (msg_size < expected_size) { + dev_err(dev, "bad size for message code 0x%04x (expected %zu, " + "got %zu)\n", le16_to_cpu(l3l4_hdr->type), + expected_size, msg_size); + result = -EIO; + } else + result = 0; +error_hdr_size: + d_fnend(4, dev, + "(i2400m %p l3l4_hdr %p msg_size %zu) = %d\n", + i2400m, l3l4_hdr, msg_size, result); + return result; +} + + + +/* + * Cancel a wait for a command ACK + * + * @i2400m: device descriptor + * @code: [negative] errno code to cancel with (don't use + * -EINPROGRESS) + * + * If there is an ack already filled out, free it. + */ +void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code) +{ + struct sk_buff *ack_skb; + unsigned long flags; + + spin_lock_irqsave(&i2400m->rx_lock, flags); + ack_skb = i2400m->ack_skb; + if (ack_skb && !IS_ERR(ack_skb)) + kfree(ack_skb); + i2400m->ack_skb = ERR_PTR(code); + spin_unlock_irqrestore(&i2400m->rx_lock, flags); +} + + +/** + * i2400m_msg_to_dev - Send a control message to the device and get a response + * + * @i2400m: device descriptor + * + * @msg_skb: an skb * + * + * @buf: pointer to the buffer containing the message to be sent; it + * has to start with a &struct i2400M_l3l4_hdr and then + * followed by the payload. Once this function returns, the + * buffer can be reused. + * + * @buf_len: buffer size + * + * Returns: + * + * Pointer to skb containing the ack message. You need to check the + * pointer with IS_ERR(), as it might be an error code. Error codes + * could happen because: + * + * - the message wasn't formatted correctly + * - couldn't send the message + * - failed waiting for a response + * - the ack message wasn't formatted correctly + * + * The returned skb has been allocated with wimax_msg_to_user_alloc(), + * it contains the reponse in a netlink attribute and is ready to be + * passed up to user space with wimax_msg_to_user_send(). To access + * the payload and its length, use wimax_msg_{data,len}() on the skb. + * + * The skb has to be freed with kfree_skb() once done. + * + * Description: + * + * This function delivers a message/command to the device and waits + * for an ack to be received. The format is described in + * linux/wimax/i2400m.h. In summary, a command/get/set is followed by an + * ack. + * + * This function will not check the ack status, that's left up to the + * caller. Once done with the ack skb, it has to be kfree_skb()ed. + * + * The i2400m handles only one message at the same time, thus we need + * the mutex to exclude other players. + * + * We write the message and then wait for an answer to come back. The + * RX path intercepts control messages and handles them in + * i2400m_rx_ctl(). Reports (notifications) are (maybe) processed + * locally and then forwarded (as needed) to user space on the WiMAX + * stack message pipe. Acks are saved and passed back to us through an + * skb in i2400m->ack_skb which is ready to be given to generic + * netlink if need be. + */ +struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m, + const void *buf, size_t buf_len) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + const struct i2400m_l3l4_hdr *msg_l3l4_hdr; + struct sk_buff *ack_skb; + const struct i2400m_l3l4_hdr *ack_l3l4_hdr; + size_t ack_len; + int ack_timeout; + unsigned msg_type; + unsigned long flags; + + d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n", + i2400m, buf, buf_len); + + if (i2400m->boot_mode) + return ERR_PTR(-ENODEV); + + msg_l3l4_hdr = buf; + /* Check msg & payload consistency */ + result = i2400m_msg_size_check(i2400m, msg_l3l4_hdr, buf_len); + if (result < 0) + goto error_bad_msg; + msg_type = le16_to_cpu(msg_l3l4_hdr->type); + d_printf(1, dev, "CMD/GET/SET 0x%04x %zu bytes\n", + msg_type, buf_len); + d_dump(2, dev, buf, buf_len); + + /* Setup the completion, ack_skb ("we are waiting") and send + * the message to the device */ + mutex_lock(&i2400m->msg_mutex); + spin_lock_irqsave(&i2400m->rx_lock, flags); + i2400m->ack_skb = ERR_PTR(-EINPROGRESS); + spin_unlock_irqrestore(&i2400m->rx_lock, flags); + init_completion(&i2400m->msg_completion); + result = i2400m_tx(i2400m, buf, buf_len, I2400M_PT_CTRL); + if (result < 0) { + dev_err(dev, "can't send message 0x%04x: %d\n", + le16_to_cpu(msg_l3l4_hdr->type), result); + goto error_tx; + } + + /* Some commands take longer to execute because of crypto ops, + * so we give them some more leeway on timeout */ + switch (msg_type) { + case I2400M_MT_GET_TLS_OPERATION_RESULT: + case I2400M_MT_CMD_SEND_EAP_RESPONSE: + ack_timeout = 5 * HZ; + break; + default: + ack_timeout = HZ; + }; + + /* The RX path in rx.c will put any response for this message + * in i2400m->ack_skb and wake us up. If we cancel the wait, + * we need to change the value of i2400m->ack_skb to something + * not -EINPROGRESS so RX knows there is no one waiting. */ + result = wait_for_completion_interruptible_timeout( + &i2400m->msg_completion, ack_timeout); + if (result == 0) { + dev_err(dev, "timeout waiting for reply to message 0x%04x\n", + msg_type); + result = -ETIMEDOUT; + i2400m_msg_to_dev_cancel_wait(i2400m, result); + goto error_wait_for_completion; + } else if (result < 0) { + dev_err(dev, "error waiting for reply to message 0x%04x: %d\n", + msg_type, result); + i2400m_msg_to_dev_cancel_wait(i2400m, result); + goto error_wait_for_completion; + } + + /* Pull out the ack data from i2400m->ack_skb -- see if it is + * an error and act accordingly */ + spin_lock_irqsave(&i2400m->rx_lock, flags); + ack_skb = i2400m->ack_skb; + if (IS_ERR(ack_skb)) + result = PTR_ERR(ack_skb); + else + result = 0; + i2400m->ack_skb = NULL; + spin_unlock_irqrestore(&i2400m->rx_lock, flags); + if (result < 0) + goto error_ack_status; + ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len); + + /* Check the ack and deliver it if it is ok */ + result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len); + if (result < 0) { + dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n", + msg_type, result); + goto error_bad_ack_len; + } + if (msg_type != le16_to_cpu(ack_l3l4_hdr->type)) { + dev_err(dev, "HW BUG? bad reply 0x%04x to message 0x%04x\n", + le16_to_cpu(ack_l3l4_hdr->type), msg_type); + result = -EIO; + goto error_bad_ack_type; + } + i2400m_msg_ack_hook(i2400m, ack_l3l4_hdr, ack_len); + mutex_unlock(&i2400m->msg_mutex); + d_fnend(3, dev, "(i2400m %p buf %p len %zu) = %p\n", + i2400m, buf, buf_len, ack_skb); + return ack_skb; + +error_bad_ack_type: +error_bad_ack_len: + kfree_skb(ack_skb); +error_ack_status: +error_wait_for_completion: +error_tx: + mutex_unlock(&i2400m->msg_mutex); +error_bad_msg: + d_fnend(3, dev, "(i2400m %p buf %p len %zu) = %d\n", + i2400m, buf, buf_len, result); + return ERR_PTR(result); +} + + +/* + * Definitions for the Enter Power Save command + * + * The Enter Power Save command requests the device to go into power + * saving mode. The device will ack or nak the command depending on it + * being ready for it. If it acks, we tell the USB subsystem to + * + * As well, the device might request to go into power saving mode by + * sending a report (REPORT_POWERSAVE_READY), in which case, we issue + * this command. The hookups in the RX coder allow + */ +enum { + I2400M_WAKEUP_ENABLED = 0x01, + I2400M_WAKEUP_DISABLED = 0x02, + I2400M_TLV_TYPE_WAKEUP_MODE = 144, +}; + +struct i2400m_cmd_enter_power_save { + struct i2400m_l3l4_hdr hdr; + struct i2400m_tlv_hdr tlv; + __le32 val; +} __attribute__((packed)); + + +/* + * Request entering power save + * + * This command is (mainly) executed when the device indicates that it + * is ready to go into powersave mode via a REPORT_POWERSAVE_READY. + */ +int i2400m_cmd_enter_powersave(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + struct i2400m_cmd_enter_power_save *cmd; + char strerr[32]; + + result = -ENOMEM; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + goto error_alloc; + cmd->hdr.type = cpu_to_le16(I2400M_MT_CMD_ENTER_POWERSAVE); + cmd->hdr.length = cpu_to_le16(sizeof(*cmd) - sizeof(cmd->hdr)); + cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION); + cmd->tlv.type = cpu_to_le16(I2400M_TLV_TYPE_WAKEUP_MODE); + cmd->tlv.length = cpu_to_le16(sizeof(cmd->val)); + cmd->val = cpu_to_le32(I2400M_WAKEUP_ENABLED); + + ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); + result = PTR_ERR(ack_skb); + if (IS_ERR(ack_skb)) { + dev_err(dev, "Failed to issue 'Enter power save' command: %d\n", + result); + goto error_msg_to_dev; + } + result = i2400m_msg_check_status(wimax_msg_data(ack_skb), + strerr, sizeof(strerr)); + if (result == -EACCES) + d_printf(1, dev, "Cannot enter power save mode\n"); + else if (result < 0) + dev_err(dev, "'Enter power save' (0x%04x) command failed: " + "%d - %s\n", I2400M_MT_CMD_ENTER_POWERSAVE, + result, strerr); + else + d_printf(1, dev, "device ready to power save\n"); + kfree_skb(ack_skb); +error_msg_to_dev: + kfree(cmd); +error_alloc: + return result; +} +EXPORT_SYMBOL_GPL(i2400m_cmd_enter_powersave); + + +/* + * Definitions for getting device information + */ +enum { + I2400M_TLV_DETAILED_DEVICE_INFO = 140 +}; + +/** + * i2400m_get_device_info - Query the device for detailed device information + * + * @i2400m: device descriptor + * + * Returns: an skb whose skb->data points to a 'struct + * i2400m_tlv_detailed_device_info'. When done, kfree_skb() it. The + * skb is *guaranteed* to contain the whole TLV data structure. + * + * On error, IS_ERR(skb) is true and ERR_PTR(skb) is the error + * code. + */ +struct sk_buff *i2400m_get_device_info(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + struct i2400m_l3l4_hdr *cmd; + const struct i2400m_l3l4_hdr *ack; + size_t ack_len; + const struct i2400m_tlv_hdr *tlv; + const struct i2400m_tlv_detailed_device_info *ddi; + char strerr[32]; + + ack_skb = ERR_PTR(-ENOMEM); + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + goto error_alloc; + cmd->type = cpu_to_le16(I2400M_MT_GET_DEVICE_INFO); + cmd->length = 0; + cmd->version = cpu_to_le16(I2400M_L3L4_VERSION); + + ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); + if (IS_ERR(ack_skb)) { + dev_err(dev, "Failed to issue 'get device info' command: %ld\n", + PTR_ERR(ack_skb)); + goto error_msg_to_dev; + } + ack = wimax_msg_data_len(ack_skb, &ack_len); + result = i2400m_msg_check_status(ack, strerr, sizeof(strerr)); + if (result < 0) { + dev_err(dev, "'get device info' (0x%04x) command failed: " + "%d - %s\n", I2400M_MT_GET_DEVICE_INFO, result, + strerr); + goto error_cmd_failed; + } + tlv = i2400m_tlv_find(i2400m, ack->pl, ack_len - sizeof(*ack), + I2400M_TLV_DETAILED_DEVICE_INFO, sizeof(*ddi)); + if (tlv == NULL) { + dev_err(dev, "GET DEVICE INFO: " + "detailed device info TLV not found (0x%04x)\n", + I2400M_TLV_DETAILED_DEVICE_INFO); + result = -EIO; + goto error_no_tlv; + } + skb_pull(ack_skb, (void *) tlv - (void *) ack_skb->data); +error_msg_to_dev: + kfree(cmd); +error_alloc: + return ack_skb; + +error_no_tlv: +error_cmd_failed: + kfree_skb(ack_skb); + kfree(cmd); + return ERR_PTR(result); +} + + +/* Firmware interface versions we support */ +enum { + I2400M_HDIv_MAJOR = 9, + I2400M_HDIv_MAJOR_2 = 8, + I2400M_HDIv_MINOR = 1, +}; + + +/** + * i2400m_firmware_check - check firmware versions are compatible with + * the driver + * + * @i2400m: device descriptor + * + * Returns: 0 if ok, < 0 errno code an error and a message in the + * kernel log. + * + * Long function, but quite simple; first chunk launches the command + * and double checks the reply for the right TLV. Then we process the + * TLV (where the meat is). + */ +int i2400m_firmware_check(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + struct i2400m_l3l4_hdr *cmd; + const struct i2400m_l3l4_hdr *ack; + size_t ack_len; + const struct i2400m_tlv_hdr *tlv; + const struct i2400m_tlv_l4_message_versions *l4mv; + char strerr[32]; + unsigned major, minor, branch; + + result = -ENOMEM; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + goto error_alloc; + cmd->type = cpu_to_le16(I2400M_MT_GET_LM_VERSION); + cmd->length = 0; + cmd->version = cpu_to_le16(I2400M_L3L4_VERSION); + + ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); + if (IS_ERR(ack_skb)) { + result = PTR_ERR(ack_skb); + dev_err(dev, "Failed to issue 'get lm version' command: %-d\n", + result); + goto error_msg_to_dev; + } + ack = wimax_msg_data_len(ack_skb, &ack_len); + result = i2400m_msg_check_status(ack, strerr, sizeof(strerr)); + if (result < 0) { + dev_err(dev, "'get lm version' (0x%04x) command failed: " + "%d - %s\n", I2400M_MT_GET_LM_VERSION, result, + strerr); + goto error_cmd_failed; + } + tlv = i2400m_tlv_find(i2400m, ack->pl, ack_len - sizeof(*ack), + I2400M_TLV_L4_MESSAGE_VERSIONS, sizeof(*l4mv)); + if (tlv == NULL) { + dev_err(dev, "get lm version: TLV not found (0x%04x)\n", + I2400M_TLV_L4_MESSAGE_VERSIONS); + result = -EIO; + goto error_no_tlv; + } + l4mv = container_of(tlv, typeof(*l4mv), hdr); + major = le16_to_cpu(l4mv->major); + minor = le16_to_cpu(l4mv->minor); + branch = le16_to_cpu(l4mv->branch); + result = -EINVAL; + if (major != I2400M_HDIv_MAJOR + && major != I2400M_HDIv_MAJOR_2) { + dev_err(dev, "unsupported major fw interface version " + "%u.%u.%u\n", major, minor, branch); + goto error_bad_major; + } + if (major == I2400M_HDIv_MAJOR_2) + dev_err(dev, "deprecated major fw interface version " + "%u.%u.%u\n", major, minor, branch); + result = 0; + if (minor != I2400M_HDIv_MINOR) + dev_warn(dev, "untested minor fw firmware version %u.%u.%u\n", + major, minor, branch); +error_bad_major: + dev_info(dev, "firmware interface version %u.%u.%u\n", + major, minor, branch); +error_no_tlv: +error_cmd_failed: + kfree_skb(ack_skb); +error_msg_to_dev: + kfree(cmd); +error_alloc: + return result; +} + + +/* + * Send an DoExitIdle command to the device to ask it to go out of + * basestation-idle mode. + * + * @i2400m: device descriptor + * + * This starts a renegotiation with the basestation that might involve + * another crypto handshake with user space. + * + * Returns: 0 if ok, < 0 errno code on error. + */ +int i2400m_cmd_exit_idle(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + struct i2400m_l3l4_hdr *cmd; + char strerr[32]; + + result = -ENOMEM; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + goto error_alloc; + cmd->type = cpu_to_le16(I2400M_MT_CMD_EXIT_IDLE); + cmd->length = 0; + cmd->version = cpu_to_le16(I2400M_L3L4_VERSION); + + ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); + result = PTR_ERR(ack_skb); + if (IS_ERR(ack_skb)) { + dev_err(dev, "Failed to issue 'exit idle' command: %d\n", + result); + goto error_msg_to_dev; + } + result = i2400m_msg_check_status(wimax_msg_data(ack_skb), + strerr, sizeof(strerr)); + kfree_skb(ack_skb); +error_msg_to_dev: + kfree(cmd); +error_alloc: + return result; + +} + + +/* + * Query the device for its state, update the WiMAX stack's idea of it + * + * @i2400m: device descriptor + * + * Returns: 0 if ok, < 0 errno code on error. + * + * Executes a 'Get State' command and parses the returned + * TLVs. + * + * Because this is almost identical to a 'Report State', we use + * i2400m_report_state_hook() to parse the answer. This will set the + * carrier state, as well as the RF Kill switches state. + */ +int i2400m_cmd_get_state(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + struct i2400m_l3l4_hdr *cmd; + const struct i2400m_l3l4_hdr *ack; + size_t ack_len; + char strerr[32]; + + result = -ENOMEM; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + goto error_alloc; + cmd->type = cpu_to_le16(I2400M_MT_GET_STATE); + cmd->length = 0; + cmd->version = cpu_to_le16(I2400M_L3L4_VERSION); + + ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); + if (IS_ERR(ack_skb)) { + dev_err(dev, "Failed to issue 'get state' command: %ld\n", + PTR_ERR(ack_skb)); + result = PTR_ERR(ack_skb); + goto error_msg_to_dev; + } + ack = wimax_msg_data_len(ack_skb, &ack_len); + result = i2400m_msg_check_status(ack, strerr, sizeof(strerr)); + if (result < 0) { + dev_err(dev, "'get state' (0x%04x) command failed: " + "%d - %s\n", I2400M_MT_GET_STATE, result, strerr); + goto error_cmd_failed; + } + i2400m_report_state_hook(i2400m, ack, ack_len - sizeof(*ack), + "GET STATE"); + result = 0; + kfree_skb(ack_skb); +error_cmd_failed: +error_msg_to_dev: + kfree(cmd); +error_alloc: + return result; +} +EXPORT_SYMBOL_GPL(i2400m_cmd_get_state); + + +/** + * Set basic configuration settings + * + * @i2400m: device descriptor + * @args: array of pointers to the TLV headers to send for + * configuration (each followed by its payload). + * TLV headers and payloads must be properly initialized, with the + * right endianess (LE). + * @arg_size: number of pointers in the @args array + */ +int i2400m_set_init_config(struct i2400m *i2400m, + const struct i2400m_tlv_hdr **arg, size_t args) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct sk_buff *ack_skb; + struct i2400m_l3l4_hdr *cmd; + char strerr[32]; + unsigned argc, argsize, tlv_size; + const struct i2400m_tlv_hdr *tlv_hdr; + void *buf, *itr; + + d_fnstart(3, dev, "(i2400m %p arg %p args %zu)\n", i2400m, arg, args); + result = 0; + if (args == 0) + goto none; + /* Compute the size of all the TLVs, so we can alloc a + * contiguous command block to copy them. */ + argsize = 0; + for (argc = 0; argc < args; argc++) { + tlv_hdr = arg[argc]; + argsize += sizeof(*tlv_hdr) + le16_to_cpu(tlv_hdr->length); + } + WARN_ON(argc >= 9); /* As per hw spec */ + + /* Alloc the space for the command and TLVs*/ + result = -ENOMEM; + buf = kzalloc(sizeof(*cmd) + argsize, GFP_KERNEL); + if (buf == NULL) + goto error_alloc; + cmd = buf; + cmd->type = cpu_to_le16(I2400M_MT_SET_INIT_CONFIG); + cmd->length = cpu_to_le16(argsize); + cmd->version = cpu_to_le16(I2400M_L3L4_VERSION); + + /* Copy the TLVs */ + itr = buf + sizeof(*cmd); + for (argc = 0; argc < args; argc++) { + tlv_hdr = arg[argc]; + tlv_size = sizeof(*tlv_hdr) + le16_to_cpu(tlv_hdr->length); + memcpy(itr, tlv_hdr, tlv_size); + itr += tlv_size; + } + + /* Send the message! */ + ack_skb = i2400m_msg_to_dev(i2400m, buf, sizeof(*cmd) + argsize); + result = PTR_ERR(ack_skb); + if (IS_ERR(ack_skb)) { + dev_err(dev, "Failed to issue 'init config' command: %d\n", + result); + + goto error_msg_to_dev; + } + result = i2400m_msg_check_status(wimax_msg_data(ack_skb), + strerr, sizeof(strerr)); + if (result < 0) + dev_err(dev, "'init config' (0x%04x) command failed: %d - %s\n", + I2400M_MT_SET_INIT_CONFIG, result, strerr); + kfree_skb(ack_skb); +error_msg_to_dev: + kfree(buf); +error_alloc: +none: + d_fnend(3, dev, "(i2400m %p arg %p args %zu) = %d\n", + i2400m, arg, args, result); + return result; + +} +EXPORT_SYMBOL_GPL(i2400m_set_init_config); + + +/** + * i2400m_dev_initialize - Initialize the device once communications are ready + * + * @i2400m: device descriptor + * + * Returns: 0 if ok, < 0 errno code on error. + * + * Configures the device to work the way we like it. + * + * At the point of this call, the device is registered with the WiMAX + * and netdev stacks, firmware is uploaded and we can talk to the + * device normally. + */ +int i2400m_dev_initialize(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct i2400m_tlv_config_idle_parameters idle_params; + const struct i2400m_tlv_hdr *args[9]; + unsigned argc = 0; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + /* Useless for now...might change */ + if (i2400m_idle_mode_disabled) { + idle_params.hdr.type = + cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS); + idle_params.hdr.length = cpu_to_le16( + sizeof(idle_params) - sizeof(idle_params.hdr)); + idle_params.idle_timeout = 0; + idle_params.idle_paging_interval = 0; + args[argc++] = &idle_params.hdr; + } + result = i2400m_set_init_config(i2400m, args, argc); + if (result < 0) + goto error; + result = i2400m_firmware_check(i2400m); /* fw versions ok? */ + if (result < 0) + goto error; + /* + * Update state: Here it just calls a get state; parsing the + * result (System State TLV and RF Status TLV [done in the rx + * path hooks]) will set the hardware and software RF-Kill + * status. + */ + result = i2400m_cmd_get_state(i2400m); +error: + d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); + return result; +} + + +/** + * i2400m_dev_shutdown - Shutdown a running device + * + * @i2400m: device descriptor + * + * Gracefully stops the device, moving it to the lowest power + * consumption state possible. + */ +void i2400m_dev_shutdown(struct i2400m *i2400m) +{ + int result = -ENODEV; + struct device *dev = i2400m_dev(i2400m); + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + result = i2400m->bus_reset(i2400m, I2400M_RT_WARM); + d_fnend(3, dev, "(i2400m %p) = void [%d]\n", i2400m, result); + return; +} -- cgit From c71228caf91ec6320b489dec5cd0087b64da9fb5 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:49 -0800 Subject: i2400m: debugfs controls Expose knobs to control the device (induce reset, power saving, querying tx or rx stats, internal debug information and debug level manipulation). Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/debugfs.c | 392 +++++++++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 drivers/net/wimax/i2400m/debugfs.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c new file mode 100644 index 00000000000..62663298597 --- /dev/null +++ b/drivers/net/wimax/i2400m/debugfs.c @@ -0,0 +1,392 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Debugfs interfaces to manipulate driver and device information + * + * + * Copyright (C) 2007 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include "i2400m.h" + + +#define D_SUBMODULE debugfs +#include "debug-levels.h" + +static +int debugfs_netdev_queue_stopped_get(void *data, u64 *val) +{ + struct i2400m *i2400m = data; + *val = netif_queue_stopped(i2400m->wimax_dev.net_dev); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_netdev_queue_stopped, + debugfs_netdev_queue_stopped_get, + NULL, "%llu\n"); + + +static +struct dentry *debugfs_create_netdev_queue_stopped( + const char *name, struct dentry *parent, struct i2400m *i2400m) +{ + return debugfs_create_file(name, 0400, parent, i2400m, + &fops_netdev_queue_stopped); +} + + +/* + * inode->i_private has the @data argument to debugfs_create_file() + */ +static +int i2400m_stats_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + +/* + * We don't allow partial reads of this file, as then the reader would + * get weirdly confused data as it is updated. + * + * So or you read it all or nothing; if you try to read with an offset + * != 0, we consider you are done reading. + */ +static +ssize_t i2400m_rx_stats_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct i2400m *i2400m = filp->private_data; + char buf[128]; + unsigned long flags; + + if (*ppos != 0) + return 0; + if (count < sizeof(buf)) + return -ENOSPC; + spin_lock_irqsave(&i2400m->rx_lock, flags); + snprintf(buf, sizeof(buf), "%u %u %u %u %u %u %u\n", + i2400m->rx_pl_num, i2400m->rx_pl_min, + i2400m->rx_pl_max, i2400m->rx_num, + i2400m->rx_size_acc, + i2400m->rx_size_min, i2400m->rx_size_max); + spin_unlock_irqrestore(&i2400m->rx_lock, flags); + return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); +} + + +/* Any write clears the stats */ +static +ssize_t i2400m_rx_stats_write(struct file *filp, const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct i2400m *i2400m = filp->private_data; + unsigned long flags; + + spin_lock_irqsave(&i2400m->rx_lock, flags); + i2400m->rx_pl_num = 0; + i2400m->rx_pl_max = 0; + i2400m->rx_pl_min = UINT_MAX; + i2400m->rx_num = 0; + i2400m->rx_size_acc = 0; + i2400m->rx_size_min = UINT_MAX; + i2400m->rx_size_max = 0; + spin_unlock_irqrestore(&i2400m->rx_lock, flags); + return count; +} + +static +const struct file_operations i2400m_rx_stats_fops = { + .owner = THIS_MODULE, + .open = i2400m_stats_open, + .read = i2400m_rx_stats_read, + .write = i2400m_rx_stats_write, +}; + + +/* See i2400m_rx_stats_read() */ +static +ssize_t i2400m_tx_stats_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct i2400m *i2400m = filp->private_data; + char buf[128]; + unsigned long flags; + + if (*ppos != 0) + return 0; + if (count < sizeof(buf)) + return -ENOSPC; + spin_lock_irqsave(&i2400m->tx_lock, flags); + snprintf(buf, sizeof(buf), "%u %u %u %u %u %u %u\n", + i2400m->tx_pl_num, i2400m->tx_pl_min, + i2400m->tx_pl_max, i2400m->tx_num, + i2400m->tx_size_acc, + i2400m->tx_size_min, i2400m->tx_size_max); + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); +} + +/* Any write clears the stats */ +static +ssize_t i2400m_tx_stats_write(struct file *filp, const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct i2400m *i2400m = filp->private_data; + unsigned long flags; + + spin_lock_irqsave(&i2400m->tx_lock, flags); + i2400m->tx_pl_num = 0; + i2400m->tx_pl_max = 0; + i2400m->tx_pl_min = UINT_MAX; + i2400m->tx_num = 0; + i2400m->tx_size_acc = 0; + i2400m->tx_size_min = UINT_MAX; + i2400m->tx_size_max = 0; + spin_unlock_irqrestore(&i2400m->tx_lock, flags); + return count; +} + +static +const struct file_operations i2400m_tx_stats_fops = { + .owner = THIS_MODULE, + .open = i2400m_stats_open, + .read = i2400m_tx_stats_read, + .write = i2400m_tx_stats_write, +}; + + +/* Write 1 to ask the device to go into suspend */ +static +int debugfs_i2400m_suspend_set(void *data, u64 val) +{ + int result; + struct i2400m *i2400m = data; + result = i2400m_cmd_enter_powersave(i2400m); + if (result >= 0) + result = 0; + return result; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_suspend, + NULL, debugfs_i2400m_suspend_set, + "%llu\n"); + +static +struct dentry *debugfs_create_i2400m_suspend( + const char *name, struct dentry *parent, struct i2400m *i2400m) +{ + return debugfs_create_file(name, 0200, parent, i2400m, + &fops_i2400m_suspend); +} + + +/* + * Reset the device + * + * Write 0 to ask the device to soft reset, 1 to cold reset, 2 to bus + * reset (as defined by enum i2400m_reset_type). + */ +static +int debugfs_i2400m_reset_set(void *data, u64 val) +{ + int result; + struct i2400m *i2400m = data; + enum i2400m_reset_type rt = val; + switch(rt) { + case I2400M_RT_WARM: + case I2400M_RT_COLD: + case I2400M_RT_BUS: + result = i2400m->bus_reset(i2400m, rt); + if (result >= 0) + result = 0; + default: + result = -EINVAL; + } + return result; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_reset, + NULL, debugfs_i2400m_reset_set, + "%llu\n"); + +static +struct dentry *debugfs_create_i2400m_reset( + const char *name, struct dentry *parent, struct i2400m *i2400m) +{ + return debugfs_create_file(name, 0200, parent, i2400m, + &fops_i2400m_reset); +} + +/* + * Debug levels control; see debug.h + */ +struct d_level D_LEVEL[] = { + D_SUBMODULE_DEFINE(control), + D_SUBMODULE_DEFINE(driver), + D_SUBMODULE_DEFINE(debugfs), + D_SUBMODULE_DEFINE(fw), + D_SUBMODULE_DEFINE(netdev), + D_SUBMODULE_DEFINE(rfkill), + D_SUBMODULE_DEFINE(rx), + D_SUBMODULE_DEFINE(tx), +}; +size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); + +#define __debugfs_register(prefix, name, parent) \ +do { \ + result = d_level_register_debugfs(prefix, name, parent); \ + if (result < 0) \ + goto error; \ +} while (0) + + +int i2400m_debugfs_add(struct i2400m *i2400m) +{ + int result; + struct device *dev = i2400m_dev(i2400m); + struct dentry *dentry = i2400m->wimax_dev.debugfs_dentry; + struct dentry *fd; + + dentry = debugfs_create_dir("i2400m", dentry); + result = PTR_ERR(dentry); + if (IS_ERR(dentry)) { + if (result == -ENODEV) + result = 0; /* No debugfs support */ + goto error; + } + i2400m->debugfs_dentry = dentry; + __debugfs_register("dl_", control, dentry); + __debugfs_register("dl_", driver, dentry); + __debugfs_register("dl_", debugfs, dentry); + __debugfs_register("dl_", fw, dentry); + __debugfs_register("dl_", netdev, dentry); + __debugfs_register("dl_", rfkill, dentry); + __debugfs_register("dl_", rx, dentry); + __debugfs_register("dl_", tx, dentry); + + fd = debugfs_create_size_t("tx_in", 0400, dentry, + &i2400m->tx_in); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "tx_in: %d\n", result); + goto error; + } + + fd = debugfs_create_size_t("tx_out", 0400, dentry, + &i2400m->tx_out); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "tx_out: %d\n", result); + goto error; + } + + fd = debugfs_create_u32("state", 0600, dentry, + &i2400m->state); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "state: %d\n", result); + goto error; + } + + /* + * Trace received messages from user space + * + * In order to tap the bidirectional message stream in the + * 'msg' pipe, user space can read from the 'msg' pipe; + * however, due to limitations in libnl, we can't know what + * the different applications are sending down to the kernel. + * + * So we have this hack where the driver will echo any message + * received on the msg pipe from user space [through a call to + * wimax_dev->op_msg_from_user() into + * i2400m_op_msg_from_user()] into the 'trace' pipe that this + * driver creates. + * + * So then, reading from both the 'trace' and 'msg' pipes in + * user space will provide a full dump of the traffic. + * + * Write 1 to activate, 0 to clear. + * + * It is not really very atomic, but it is also not too + * critical. + */ + fd = debugfs_create_u8("trace_msg_from_user", 0600, dentry, + &i2400m->trace_msg_from_user); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "trace_msg_from_user: %d\n", result); + goto error; + } + + fd = debugfs_create_netdev_queue_stopped("netdev_queue_stopped", + dentry, i2400m); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "netdev_queue_stopped: %d\n", result); + goto error; + } + + fd = debugfs_create_file("rx_stats", 0600, dentry, i2400m, + &i2400m_rx_stats_fops); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "rx_stats: %d\n", result); + goto error; + } + + fd = debugfs_create_file("tx_stats", 0600, dentry, i2400m, + &i2400m_tx_stats_fops); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "tx_stats: %d\n", result); + goto error; + } + + fd = debugfs_create_i2400m_suspend("suspend", dentry, i2400m); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry suspend: %d\n", + result); + goto error; + } + + fd = debugfs_create_i2400m_reset("reset", dentry, i2400m); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry reset: %d\n", result); + goto error; + } + + result = 0; +error: + return result; +} + +void i2400m_debugfs_rm(struct i2400m *i2400m) +{ + debugfs_remove_recursive(i2400m->debugfs_dentry); +} -- cgit From 11a7d0e3140d2f3e8052a856e8582ce9b021972c Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:50 -0800 Subject: i2400m/USB: header for the USB bus driver This contains the common function declaration and constants for the USB driver for the 2400m Wireless WiMAX Connection, as well as it's debug level settings. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/i2400m-usb.h | 264 ++++++++++++++++++++++++++++ drivers/net/wimax/i2400m/usb-debug-levels.h | 42 +++++ 2 files changed, 306 insertions(+) create mode 100644 drivers/net/wimax/i2400m/i2400m-usb.h create mode 100644 drivers/net/wimax/i2400m/usb-debug-levels.h (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/i2400m-usb.h b/drivers/net/wimax/i2400m/i2400m-usb.h new file mode 100644 index 00000000000..6f76558b170 --- /dev/null +++ b/drivers/net/wimax/i2400m/i2400m-usb.h @@ -0,0 +1,264 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * USB-specific i2400m driver definitions + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Inaky Perez-Gonzalez + * Yanir Lubetkin + * - Initial implementation + * + * + * This driver implements the bus-specific part of the i2400m for + * USB. Check i2400m.h for a generic driver description. + * + * ARCHITECTURE + * + * This driver listens to notifications sent from the notification + * endpoint (in usb-notif.c); when data is ready to read, the code in + * there schedules a read from the device (usb-rx.c) and then passes + * the data to the generic RX code (rx.c). + * + * When the generic driver needs to send data (network or control), it + * queues up in the TX FIFO (tx.c) and that will notify the driver + * through the i2400m->bus_tx_kick() callback + * (usb-tx.c:i2400mu_bus_tx_kick) which will send the items in the + * FIFO queue. + * + * This driver, as well, implements the USB-specific ops for the generic + * driver to be able to setup/teardown communication with the device + * [i2400m_bus_dev_start() and i2400m_bus_dev_stop()], reseting the + * device [i2400m_bus_reset()] and performing firmware upload + * [i2400m_bus_bm_cmd() and i2400_bus_bm_wait_for_ack()]. + */ + +#ifndef __I2400M_USB_H__ +#define __I2400M_USB_H__ + +#include "i2400m.h" +#include + + +/* + * Error Density Count: cheapo error density (over time) counter + * + * Originally by Reinette Chatre + * + * Embed an 'struct edc' somewhere. Each time there is a soft or + * retryable error, call edc_inc() and check if the error top + * watermark has been reached. + */ +enum { + EDC_MAX_ERRORS = 10, + EDC_ERROR_TIMEFRAME = HZ, +}; + +/* error density counter */ +struct edc { + unsigned long timestart; + u16 errorcount; +}; + +static inline void edc_init(struct edc *edc) +{ + edc->timestart = jiffies; +} + +/** + * edc_inc - report a soft error and check if we are over the watermark + * + * @edc: pointer to error density counter. + * @max_err: maximum number of errors we can accept over the timeframe + * @timeframe: lenght of the timeframe (in jiffies). + * + * Returns: !0 1 if maximum acceptable errors per timeframe has been + * exceeded. 0 otherwise. + * + * This is way to determine if the number of acceptable errors per time + * period has been exceeded. It is not accurate as there are cases in which + * this scheme will not work, for example if there are periodic occurences + * of errors that straddle updates to the start time. This scheme is + * sufficient for our usage. + * + * To use, embed a 'struct edc' somewhere, initialize it with + * edc_init() and when an error hits: + * + * if (do_something_fails_with_a_soft_error) { + * if (edc_inc(&my->edc, MAX_ERRORS, MAX_TIMEFRAME)) + * Ops, hard error, do something about it + * else + * Retry or ignore, depending on whatever + * } + */ +static inline int edc_inc(struct edc *edc, u16 max_err, u16 timeframe) +{ + unsigned long now; + + now = jiffies; + if (now - edc->timestart > timeframe) { + edc->errorcount = 1; + edc->timestart = now; + } else if (++edc->errorcount > max_err) { + edc->errorcount = 0; + edc->timestart = now; + return 1; + } + return 0; +} + +/* Host-Device interface for USB */ +enum { + I2400MU_MAX_NOTIFICATION_LEN = 256, + I2400MU_BLK_SIZE = 16, + I2400MU_PL_SIZE_MAX = 0x3EFF, + + /* Endpoints */ + I2400MU_EP_BULK_OUT = 0, + I2400MU_EP_NOTIFICATION, + I2400MU_EP_RESET_COLD, + I2400MU_EP_BULK_IN, +}; + + +/** + * struct i2400mu - descriptor for a USB connected i2400m + * + * @i2400m: bus-generic i2400m implementation; has to be first (see + * it's documentation in i2400m.h). + * + * @usb_dev: pointer to our USB device + * + * @usb_iface: pointer to our USB interface + * + * @urb_edc: error density counter; used to keep a density-on-time tab + * on how many soft (retryable or ignorable) errors we get. If we + * go over the threshold, we consider the bus transport is failing + * too much and reset. + * + * @notif_urb: URB for receiving notifications from the device. + * + * @tx_kthread: thread we use for data TX. We use a thread because in + * order to do deep power saving and put the device to sleep, we + * need to call usb_autopm_*() [blocking functions]. + * + * @tx_wq: waitqueue for the TX kthread to sleep when there is no data + * to be sent; when more data is available, it is woken up by + * i2400mu_bus_tx_kick(). + * + * @rx_kthread: thread we use for data RX. We use a thread because in + * order to do deep power saving and put the device to sleep, we + * need to call usb_autopm_*() [blocking functions]. + * + * @rx_wq: waitqueue for the RX kthread to sleep when there is no data + * to receive. When data is available, it is woken up by + * usb-notif.c:i2400mu_notification_grok(). + * + * @rx_pending_count: number of rx-data-ready notifications that were + * still not handled by the RX kthread. + * + * @rx_size: current RX buffer size that is being used. + * + * @rx_size_acc: accumulator of the sizes of the previous read + * transactions. + * + * @rx_size_cnt: number of read transactions accumulated in + * @rx_size_acc. + * + * @do_autopm: disable(0)/enable(>0) calling the + * usb_autopm_get/put_interface() barriers when executing + * commands. See doc in i2400mu_suspend() for more information. + * + * @rx_size_auto_shrink: if true, the rx_size is shrinked + * automatically based on the average size of the received + * transactions. This allows the receive code to allocate smaller + * chunks of memory and thus reduce pressure on the memory + * allocator by not wasting so much space. By default it is + * enabled. + * + * @debugfs_dentry: hookup for debugfs files. + * These have to be in a separate directory, a child of + * (wimax_dev->debugfs_dentry) so they can be removed when the + * module unloads, as we don't keep each dentry. + */ +struct i2400mu { + struct i2400m i2400m; /* FIRST! See doc */ + + struct usb_device *usb_dev; + struct usb_interface *usb_iface; + struct edc urb_edc; /* Error density counter */ + + struct urb *notif_urb; + struct task_struct *tx_kthread; + wait_queue_head_t tx_wq; + + struct task_struct *rx_kthread; + wait_queue_head_t rx_wq; + atomic_t rx_pending_count; + size_t rx_size, rx_size_acc, rx_size_cnt; + atomic_t do_autopm; + u8 rx_size_auto_shrink; + + struct dentry *debugfs_dentry; +}; + + +static inline +void i2400mu_init(struct i2400mu *i2400mu) +{ + i2400m_init(&i2400mu->i2400m); + edc_init(&i2400mu->urb_edc); + init_waitqueue_head(&i2400mu->tx_wq); + atomic_set(&i2400mu->rx_pending_count, 0); + init_waitqueue_head(&i2400mu->rx_wq); + i2400mu->rx_size = PAGE_SIZE - sizeof(struct skb_shared_info); + atomic_set(&i2400mu->do_autopm, 1); + i2400mu->rx_size_auto_shrink = 1; +} + +extern int i2400mu_notification_setup(struct i2400mu *); +extern void i2400mu_notification_release(struct i2400mu *); + +extern int i2400mu_rx_setup(struct i2400mu *); +extern void i2400mu_rx_release(struct i2400mu *); +extern void i2400mu_rx_kick(struct i2400mu *); + +extern int i2400mu_tx_setup(struct i2400mu *); +extern void i2400mu_tx_release(struct i2400mu *); +extern void i2400mu_bus_tx_kick(struct i2400m *); + +extern ssize_t i2400mu_bus_bm_cmd_send(struct i2400m *, + const struct i2400m_bootrom_header *, + size_t, int); +extern ssize_t i2400mu_bus_bm_wait_for_ack(struct i2400m *, + struct i2400m_bootrom_header *, + size_t); +#endif /* #ifndef __I2400M_USB_H__ */ diff --git a/drivers/net/wimax/i2400m/usb-debug-levels.h b/drivers/net/wimax/i2400m/usb-debug-levels.h new file mode 100644 index 00000000000..e4358bd880b --- /dev/null +++ b/drivers/net/wimax/i2400m/usb-debug-levels.h @@ -0,0 +1,42 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Debug levels control file for the i2400m-usb module + * + * + * Copyright (C) 2007-2008 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#ifndef __debug_levels__h__ +#define __debug_levels__h__ + +/* Maximum compile and run time debug level for all submodules */ +#define D_MODULENAME i2400m_usb +#define D_MASTER CONFIG_WIMAX_I2400M_DEBUG_LEVEL + +#include + +/* List of all the enabled modules */ +enum d_module { + D_SUBMODULE_DECLARE(usb), + D_SUBMODULE_DECLARE(fw), + D_SUBMODULE_DECLARE(notif), + D_SUBMODULE_DECLARE(rx), + D_SUBMODULE_DECLARE(tx), +}; + + +#endif /* #ifndef __debug_levels__h__ */ -- cgit From f398e4240fce962d0dd74dc11c59fe20860e7a71 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:51 -0800 Subject: i2400m/USB: probe/disconnect, dev init/shutdown and reset backends Implements probe/disconnect for the USB device, as well as main backends for the generic driver to control the USB device (bus_dev_start(), bus_dev_stop() and bus_reset()). Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/usb.c | 591 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 591 insertions(+) create mode 100644 drivers/net/wimax/i2400m/usb.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c new file mode 100644 index 00000000000..6d4b65fd9c1 --- /dev/null +++ b/drivers/net/wimax/i2400m/usb.c @@ -0,0 +1,591 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Linux driver model glue for USB device, reset & fw upload + * + * + * Copyright (C) 2007-2008 Intel Corporation + * Inaky Perez-Gonzalez + * Yanir Lubetkin + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * See i2400m-usb.h for a general description of this driver. + * + * This file implements driver model glue, and hook ups for the + * generic driver to implement the bus-specific functions (device + * communication setup/tear down, firmware upload and resetting). + * + * ROADMAP + * + * i2400mu_probe() + * alloc_netdev()... + * i2400mu_netdev_setup() + * i2400mu_init() + * i2400m_netdev_setup() + * i2400m_setup()... + * + * i2400mu_disconnect + * i2400m_release() + * free_netdev() + * + * i2400mu_suspend() + * i2400m_cmd_enter_powersave() + * i2400mu_notification_release() + * + * i2400mu_resume() + * i2400mu_notification_setup() + * + * i2400mu_bus_dev_start() Called by i2400m_dev_start() [who is + * i2400mu_tx_setup() called by i2400m_setup()] + * i2400mu_rx_setup() + * i2400mu_notification_setup() + * + * i2400mu_bus_dev_stop() Called by i2400m_dev_stop() [who is + * i2400mu_notification_release() called by i2400m_release()] + * i2400mu_rx_release() + * i2400mu_tx_release() + * + * i2400mu_bus_reset() Called by i2400m->bus_reset + * __i2400mu_reset() + * __i2400mu_send_barker() + * usb_reset_device() + */ +#include "i2400m-usb.h" +#include +#include + + +#define D_SUBMODULE usb +#include "usb-debug-levels.h" + + +/* Our firmware file name */ +#define I2400MU_FW_FILE_NAME "i2400m-fw-usb-" I2400M_FW_VERSION ".sbcf" + +static +int i2400mu_bus_dev_start(struct i2400m *i2400m) +{ + int result; + struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); + struct device *dev = &i2400mu->usb_iface->dev; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + result = i2400mu_tx_setup(i2400mu); + if (result < 0) + goto error_usb_tx_setup; + result = i2400mu_rx_setup(i2400mu); + if (result < 0) + goto error_usb_rx_setup; + result = i2400mu_notification_setup(i2400mu); + if (result < 0) + goto error_notif_setup; + d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); + return result; + +error_notif_setup: + i2400mu_rx_release(i2400mu); +error_usb_rx_setup: + i2400mu_tx_release(i2400mu); +error_usb_tx_setup: + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); + return result; +} + + +static +void i2400mu_bus_dev_stop(struct i2400m *i2400m) +{ + struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); + struct device *dev = &i2400mu->usb_iface->dev; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + i2400mu_notification_release(i2400mu); + i2400mu_rx_release(i2400mu); + i2400mu_tx_release(i2400mu); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); +} + + +/* + * Sends a barker buffer to the device + * + * This helper will allocate a kmalloced buffer and use it to transmit + * (then free it). Reason for this is that other arches cannot use + * stack/vmalloc/text areas for DMA transfers. + * + * Error recovery here is simpler: anything is considered a hard error + * and will move the reset code to use a last-resort bus-based reset. + */ +static +int __i2400mu_send_barker(struct i2400mu *i2400mu, + const __le32 *barker, + size_t barker_size, + unsigned endpoint) +{ + struct usb_endpoint_descriptor *epd = NULL; + int pipe, actual_len, ret; + struct device *dev = &i2400mu->usb_iface->dev; + void *buffer; + int do_autopm = 1; + + ret = usb_autopm_get_interface(i2400mu->usb_iface); + if (ret < 0) { + dev_err(dev, "RESET: can't get autopm: %d\n", ret); + do_autopm = 0; + } + ret = -ENOMEM; + buffer = kmalloc(barker_size, GFP_KERNEL); + if (buffer == NULL) + goto error_kzalloc; + epd = usb_get_epd(i2400mu->usb_iface, endpoint); + pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); + memcpy(buffer, barker, barker_size); + ret = usb_bulk_msg(i2400mu->usb_dev, pipe, buffer, barker_size, + &actual_len, HZ); + if (ret < 0) { + if (ret != -EINVAL) + dev_err(dev, "E: barker error: %d\n", ret); + } else if (actual_len != barker_size) { + dev_err(dev, "E: only %d bytes transmitted\n", actual_len); + ret = -EIO; + } + kfree(buffer); +error_kzalloc: + if (do_autopm) + usb_autopm_put_interface(i2400mu->usb_iface); + return ret; +} + + +/* + * Reset a device at different levels (warm, cold or bus) + * + * @i2400m: device descriptor + * @reset_type: soft, warm or bus reset (I2400M_RT_WARM/SOFT/BUS) + * + * Warm and cold resets get a USB reset if they fail. + * + * Warm reset: + * + * The device will be fully reset internally, but won't be + * disconnected from the USB bus (so no reenumeration will + * happen). Firmware upload will be neccessary. + * + * The device will send a reboot barker in the notification endpoint + * that will trigger the driver to reinitialize the state + * automatically from notif.c:i2400m_notification_grok() into + * i2400m_dev_bootstrap_delayed(). + * + * Cold and bus (USB) reset: + * + * The device will be fully reset internally, disconnected from the + * USB bus an a reenumeration will happen. Firmware upload will be + * neccessary. Thus, we don't do any locking or struct + * reinitialization, as we are going to be fully disconnected and + * reenumerated. + * + * Note we need to return -ENODEV if a warm reset was requested and we + * had to resort to a bus reset. See i2400m_op_reset(), wimax_reset() + * and wimax_dev->op_reset. + * + * WARNING: no driver state saved/fixed + */ +static +int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) +{ + int result; + struct i2400mu *i2400mu = + container_of(i2400m, struct i2400mu, i2400m); + struct device *dev = i2400m_dev(i2400m); + static const __le32 i2400m_WARM_BOOT_BARKER[4] = { + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + }; + static const __le32 i2400m_COLD_BOOT_BARKER[4] = { + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + }; + + d_fnstart(3, dev, "(i2400m %p rt %u)\n", i2400m, rt); + if (rt == I2400M_RT_WARM) + result = __i2400mu_send_barker(i2400mu, i2400m_WARM_BOOT_BARKER, + sizeof(i2400m_WARM_BOOT_BARKER), + I2400MU_EP_BULK_OUT); + else if (rt == I2400M_RT_COLD) + result = __i2400mu_send_barker(i2400mu, i2400m_COLD_BOOT_BARKER, + sizeof(i2400m_COLD_BOOT_BARKER), + I2400MU_EP_RESET_COLD); + else if (rt == I2400M_RT_BUS) { +do_bus_reset: + result = usb_reset_device(i2400mu->usb_dev); + switch (result) { + case 0: + case -EINVAL: /* device is gone */ + case -ENODEV: + case -ENOENT: + case -ESHUTDOWN: + result = rt == I2400M_RT_WARM ? -ENODEV : 0; + break; /* We assume the device is disconnected */ + default: + dev_err(dev, "USB reset failed (%d), giving up!\n", + result); + } + } else + BUG(); + if (result < 0 + && result != -EINVAL /* device is gone */ + && rt != I2400M_RT_BUS) { + dev_err(dev, "%s reset failed (%d); trying USB reset\n", + rt == I2400M_RT_WARM ? "warm" : "cold", result); + rt = I2400M_RT_BUS; + goto do_bus_reset; + } + d_fnend(3, dev, "(i2400m %p rt %u) = %d\n", i2400m, rt, result); + return result; +} + + +static +void i2400mu_netdev_setup(struct net_device *net_dev) +{ + struct i2400m *i2400m = net_dev_to_i2400m(net_dev); + struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); + i2400mu_init(i2400mu); + i2400m_netdev_setup(net_dev); +} + + +/* + * Debug levels control; see debug.h + */ +struct d_level D_LEVEL[] = { + D_SUBMODULE_DEFINE(usb), + D_SUBMODULE_DEFINE(fw), + D_SUBMODULE_DEFINE(notif), + D_SUBMODULE_DEFINE(rx), + D_SUBMODULE_DEFINE(tx), +}; +size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); + + +#define __debugfs_register(prefix, name, parent) \ +do { \ + result = d_level_register_debugfs(prefix, name, parent); \ + if (result < 0) \ + goto error; \ +} while (0) + + +static +int i2400mu_debugfs_add(struct i2400mu *i2400mu) +{ + int result; + struct device *dev = &i2400mu->usb_iface->dev; + struct dentry *dentry = i2400mu->i2400m.wimax_dev.debugfs_dentry; + struct dentry *fd; + + dentry = debugfs_create_dir("i2400m-usb", dentry); + result = PTR_ERR(dentry); + if (IS_ERR(dentry)) { + if (result == -ENODEV) + result = 0; /* No debugfs support */ + goto error; + } + i2400mu->debugfs_dentry = dentry; + __debugfs_register("dl_", usb, dentry); + __debugfs_register("dl_", fw, dentry); + __debugfs_register("dl_", notif, dentry); + __debugfs_register("dl_", rx, dentry); + __debugfs_register("dl_", tx, dentry); + + /* Don't touch these if you don't know what you are doing */ + fd = debugfs_create_u8("rx_size_auto_shrink", 0600, dentry, + &i2400mu->rx_size_auto_shrink); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "rx_size_auto_shrink: %d\n", result); + goto error; + } + + fd = debugfs_create_size_t("rx_size", 0600, dentry, + &i2400mu->rx_size); + result = PTR_ERR(fd); + if (IS_ERR(fd) && result != -ENODEV) { + dev_err(dev, "Can't create debugfs entry " + "rx_size: %d\n", result); + goto error; + } + + return 0; + +error: + debugfs_remove_recursive(i2400mu->debugfs_dentry); + return result; +} + + +/* + * Probe a i2400m interface and register it + * + * @iface: USB interface to link to + * @id: USB class/subclass/protocol id + * @returns: 0 if ok, < 0 errno code on error. + * + * Alloc a net device, initialize the bus-specific details and then + * calls the bus-generic initialization routine. That will register + * the wimax and netdev devices, upload the firmware [using + * _bus_bm_*()], call _bus_dev_start() to finalize the setup of the + * communication with the device and then will start to talk to it to + * finnish setting it up. + */ +static +int i2400mu_probe(struct usb_interface *iface, + const struct usb_device_id *id) +{ + int result; + struct net_device *net_dev; + struct device *dev = &iface->dev; + struct i2400m *i2400m; + struct i2400mu *i2400mu; + struct usb_device *usb_dev = interface_to_usbdev(iface); + + if (usb_dev->speed != USB_SPEED_HIGH) + dev_err(dev, "device not connected as high speed\n"); + + /* Allocate instance [calls i2400m_netdev_setup() on it]. */ + result = -ENOMEM; + net_dev = alloc_netdev(sizeof(*i2400mu), "wmx%d", + i2400mu_netdev_setup); + if (net_dev == NULL) { + dev_err(dev, "no memory for network device instance\n"); + goto error_alloc_netdev; + } + SET_NETDEV_DEV(net_dev, dev); + i2400m = net_dev_to_i2400m(net_dev); + i2400mu = container_of(i2400m, struct i2400mu, i2400m); + i2400m->wimax_dev.net_dev = net_dev; + i2400mu->usb_dev = usb_get_dev(usb_dev); + i2400mu->usb_iface = iface; + usb_set_intfdata(iface, i2400mu); + + i2400m->bus_tx_block_size = I2400MU_BLK_SIZE; + i2400m->bus_pl_size_max = I2400MU_PL_SIZE_MAX; + i2400m->bus_dev_start = i2400mu_bus_dev_start; + i2400m->bus_dev_stop = i2400mu_bus_dev_stop; + i2400m->bus_tx_kick = i2400mu_bus_tx_kick; + i2400m->bus_reset = i2400mu_bus_reset; + i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send; + i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack; + i2400m->bus_fw_name = I2400MU_FW_FILE_NAME; + i2400m->bus_bm_mac_addr_impaired = 0; + + iface->needs_remote_wakeup = 1; /* autosuspend (15s delay) */ + device_init_wakeup(dev, 1); + usb_autopm_enable(i2400mu->usb_iface); + usb_dev->autosuspend_delay = 15 * HZ; + usb_dev->autosuspend_disabled = 0; + + result = i2400m_setup(i2400m, I2400M_BRI_MAC_REINIT); + if (result < 0) { + dev_err(dev, "cannot setup device: %d\n", result); + goto error_setup; + } + result = i2400mu_debugfs_add(i2400mu); + if (result < 0) { + dev_err(dev, "Can't register i2400mu's debugfs: %d\n", result); + goto error_debugfs_add; + } + return 0; + +error_debugfs_add: + i2400m_release(i2400m); +error_setup: + usb_set_intfdata(iface, NULL); + usb_put_dev(i2400mu->usb_dev); + free_netdev(net_dev); +error_alloc_netdev: + return result; +} + + +/* + * Disconect a i2400m from the system. + * + * i2400m_stop() has been called before, so al the rx and tx contexts + * have been taken down already. Make sure the queue is stopped, + * unregister netdev and i2400m, free and kill. + */ +static +void i2400mu_disconnect(struct usb_interface *iface) +{ + struct i2400mu *i2400mu = usb_get_intfdata(iface); + struct i2400m *i2400m = &i2400mu->i2400m; + struct net_device *net_dev = i2400m->wimax_dev.net_dev; + struct device *dev = &iface->dev; + + d_fnstart(3, dev, "(iface %p i2400m %p)\n", iface, i2400m); + + debugfs_remove_recursive(i2400mu->debugfs_dentry); + i2400m_release(i2400m); + usb_set_intfdata(iface, NULL); + usb_put_dev(i2400mu->usb_dev); + free_netdev(net_dev); + d_fnend(3, dev, "(iface %p i2400m %p) = void\n", iface, i2400m); +} + + +/* + * Get the device ready for USB port or system standby and hibernation + * + * USB port and system standby are handled the same. + * + * When the system hibernates, the USB device is powered down and then + * up, so we don't really have to do much here, as it will be seen as + * a reconnect. Still for simplicity we consider this case the same as + * suspend, so that the device has a chance to do notify the base + * station (if connected). + * + * So at the end, the three cases require common handling. + * + * If at the time of this call the device's firmware is not loaded, + * nothing has to be done. + * + * If the firmware is loaded, we need to: + * + * - tell the device to go into host interface power save mode, wait + * for it to ack + * + * This is quite more interesting than it is; we need to execute a + * command, but this time, we don't want the code in usb-{tx,rx}.c + * to call the usb_autopm_get/put_interface() barriers as it'd + * deadlock, so we need to decrement i2400mu->do_autopm, that acts + * as a poor man's semaphore. Ugly, but it works. + * + * As well, the device might refuse going to sleep for whichever + * reason. In this case we just fail. For system suspend/hibernate, + * we *can't* fail. We look at usb_dev->auto_pm to see if the + * suspend call comes from the USB stack or from the system and act + * in consequence. + * + * - stop the notification endpoint polling + */ +static +int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg) +{ + int result = 0; + struct device *dev = &iface->dev; + struct i2400mu *i2400mu = usb_get_intfdata(iface); + struct usb_device *usb_dev = i2400mu->usb_dev; + struct i2400m *i2400m = &i2400mu->i2400m; + + d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event); + if (i2400m->updown == 0) + goto no_firmware; + d_printf(1, dev, "fw up, requesting standby\n"); + atomic_dec(&i2400mu->do_autopm); + result = i2400m_cmd_enter_powersave(i2400m); + atomic_inc(&i2400mu->do_autopm); + if (result < 0 && usb_dev->auto_pm == 0) { + /* System suspend, can't fail */ + dev_err(dev, "failed to suspend, will reset on resume\n"); + result = 0; + } + if (result < 0) + goto error_enter_powersave; + i2400mu_notification_release(i2400mu); + d_printf(1, dev, "fw up, got standby\n"); +error_enter_powersave: +no_firmware: + d_fnend(3, dev, "(iface %p pm_msg %u) = %d\n", + iface, pm_msg.event, result); + return result; +} + + +static +int i2400mu_resume(struct usb_interface *iface) +{ + int ret = 0; + struct device *dev = &iface->dev; + struct i2400mu *i2400mu = usb_get_intfdata(iface); + struct i2400m *i2400m = &i2400mu->i2400m; + + d_fnstart(3, dev, "(iface %p)\n", iface); + if (i2400m->updown == 0) { + d_printf(1, dev, "fw was down, no resume neeed\n"); + goto out; + } + d_printf(1, dev, "fw was up, resuming\n"); + i2400mu_notification_setup(i2400mu); + /* USB has flow control, so we don't need to give it time to + * come back; otherwise, we'd use something like a get-state + * command... */ +out: + d_fnend(3, dev, "(iface %p) = %d\n", iface, ret); + return ret; +} + + +static +struct usb_device_id i2400mu_id_table[] = { + { USB_DEVICE(0x8086, 0x0181) }, + { USB_DEVICE(0x8086, 0x1403) }, + { USB_DEVICE(0x8086, 0x1405) }, + { USB_DEVICE(0x8086, 0x0180) }, + { USB_DEVICE(0x8086, 0x0182) }, + { USB_DEVICE(0x8086, 0x1406) }, + { USB_DEVICE(0x8086, 0x1403) }, + { }, +}; +MODULE_DEVICE_TABLE(usb, i2400mu_id_table); + + +static +struct usb_driver i2400mu_driver = { + .name = KBUILD_MODNAME, + .suspend = i2400mu_suspend, + .resume = i2400mu_resume, + .probe = i2400mu_probe, + .disconnect = i2400mu_disconnect, + .id_table = i2400mu_id_table, + .supports_autosuspend = 1, +}; + +static +int __init i2400mu_driver_init(void) +{ + return usb_register(&i2400mu_driver); +} +module_init(i2400mu_driver_init); + + +static +void __exit i2400mu_driver_exit(void) +{ + flush_scheduled_work(); /* for the stuff we schedule from sysfs.c */ + usb_deregister(&i2400mu_driver); +} +module_exit(i2400mu_driver_exit); + +MODULE_AUTHOR("Intel Corporation "); +MODULE_DESCRIPTION("Intel 2400M WiMAX networking for USB"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(I2400MU_FW_FILE_NAME); -- cgit From 795038107b0078ee5ad3ad33327fe1c3520f6bf2 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:52 -0800 Subject: i2400m/USB: firmware upload backend This implements the backends for the generic driver (i2400m) to be able to load firmware to the USB device. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/usb-fw.c | 340 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 drivers/net/wimax/i2400m/usb-fw.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c new file mode 100644 index 00000000000..5ad287c228b --- /dev/null +++ b/drivers/net/wimax/i2400m/usb-fw.c @@ -0,0 +1,340 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Firmware uploader's USB specifics + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * Inaky Perez-Gonzalez + * - Initial implementation + * + * Inaky Perez-Gonzalez + * - bus generic/specific split + * + * THE PROCEDURE + * + * See fw.c for the generic description of this procedure. + * + * This file implements only the USB specifics. It boils down to how + * to send a command and waiting for an acknowledgement from the + * device. + * + * This code (and process) is single threaded. It assumes it is the + * only thread poking around (guaranteed by fw.c). + * + * COMMAND EXECUTION + * + * A write URB is posted with the buffer to the bulk output endpoint. + * + * ACK RECEPTION + * + * We just post a URB to the notification endpoint and wait for + * data. We repeat until we get all the data we expect (as indicated + * by the call from the bus generic code). + * + * The data is not read from the bulk in endpoint for boot mode. + * + * ROADMAP + * + * i2400mu_bus_bm_cmd_send + * i2400m_bm_cmd_prepare... + * i2400mu_tx_bulk_out + * + * i2400mu_bus_bm_wait_for_ack + * i2400m_notif_submit + */ +#include +#include "i2400m-usb.h" + + +#define D_SUBMODULE fw +#include "usb-debug-levels.h" + + +/* + * Synchronous write to the device + * + * Takes care of updating EDC counts and thus, handle device errors. + */ +static +ssize_t i2400mu_tx_bulk_out(struct i2400mu *i2400mu, void *buf, size_t buf_size) +{ + int result; + struct device *dev = &i2400mu->usb_iface->dev; + int len; + struct usb_endpoint_descriptor *epd; + int pipe, do_autopm = 1; + + result = usb_autopm_get_interface(i2400mu->usb_iface); + if (result < 0) { + dev_err(dev, "BM-CMD: can't get autopm: %d\n", result); + do_autopm = 0; + } + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_OUT); + pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); +retry: + result = usb_bulk_msg(i2400mu->usb_dev, pipe, buf, buf_size, &len, HZ); + switch (result) { + case 0: + if (len != buf_size) { + dev_err(dev, "BM-CMD: short write (%u B vs %zu " + "expected)\n", len, buf_size); + result = -EIO; + break; + } + result = len; + break; + case -EINVAL: /* while removing driver */ + case -ENODEV: /* dev disconnect ... */ + case -ENOENT: /* just ignore it */ + case -ESHUTDOWN: /* and exit */ + case -ECONNRESET: + result = -ESHUTDOWN; + break; + case -ETIMEDOUT: /* bah... */ + break; + default: /* any other? */ + if (edc_inc(&i2400mu->urb_edc, + EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { + dev_err(dev, "BM-CMD: maximum errors in " + "URB exceeded; resetting device\n"); + usb_queue_reset_device(i2400mu->usb_iface); + result = -ENODEV; + break; + } + dev_err(dev, "BM-CMD: URB error %d, retrying\n", + result); + goto retry; + } + result = len; + if (do_autopm) + usb_autopm_put_interface(i2400mu->usb_iface); + return result; +} + + +/* + * Send a boot-mode command over the bulk-out pipe + * + * Command can be a raw command, which requires no preparation (and + * which might not even be following the command format). Checks that + * the right amount of data was transfered. + * + * To satisfy USB requirements (no onstack, vmalloc or in data segment + * buffers), we copy the command to i2400m->bm_cmd_buf and send it from + * there. + * + * @flags: pass thru from i2400m_bm_cmd() + * @return: cmd_size if ok, < 0 errno code on error. + */ +ssize_t i2400mu_bus_bm_cmd_send(struct i2400m *i2400m, + const struct i2400m_bootrom_header *_cmd, + size_t cmd_size, int flags) +{ + ssize_t result; + struct device *dev = i2400m_dev(i2400m); + struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); + int opcode = _cmd == NULL ? -1 : i2400m_brh_get_opcode(_cmd); + struct i2400m_bootrom_header *cmd; + size_t cmd_size_a = ALIGN(cmd_size, 16); /* USB restriction */ + + d_fnstart(8, dev, "(i2400m %p cmd %p size %zu)\n", + i2400m, _cmd, cmd_size); + result = -E2BIG; + if (cmd_size > I2400M_BM_CMD_BUF_SIZE) + goto error_too_big; + memcpy(i2400m->bm_cmd_buf, _cmd, cmd_size); + cmd = i2400m->bm_cmd_buf; + if (cmd_size_a > cmd_size) /* Zero pad space */ + memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size); + if ((flags & I2400M_BM_CMD_RAW) == 0) { + if (WARN_ON(i2400m_brh_get_response_required(cmd) == 0)) + dev_warn(dev, "SW BUG: response_required == 0\n"); + i2400m_bm_cmd_prepare(cmd); + } + result = i2400mu_tx_bulk_out(i2400mu, i2400m->bm_cmd_buf, cmd_size); + if (result < 0) { + dev_err(dev, "boot-mode cmd %d: cannot send: %zd\n", + opcode, result); + goto error_cmd_send; + } + if (result != cmd_size) { /* all was transferred? */ + dev_err(dev, "boot-mode cmd %d: incomplete transfer " + "(%zu vs %zu submitted)\n", opcode, result, cmd_size); + result = -EIO; + goto error_cmd_size; + } +error_cmd_size: +error_cmd_send: +error_too_big: + d_fnend(8, dev, "(i2400m %p cmd %p size %zu) = %zd\n", + i2400m, _cmd, cmd_size, result); + return result; +} + + +static +void __i2400mu_bm_notif_cb(struct urb *urb) +{ + complete(urb->context); +} + + +/* + * submit a read to the notification endpoint + * + * @i2400m: device descriptor + * @urb: urb to use + * @completion: completion varible to complete when done + * + * Data is always read to i2400m->bm_ack_buf + */ +static +int i2400mu_notif_submit(struct i2400mu *i2400mu, struct urb *urb, + struct completion *completion) +{ + struct i2400m *i2400m = &i2400mu->i2400m; + struct usb_endpoint_descriptor *epd; + int pipe; + + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_NOTIFICATION); + pipe = usb_rcvintpipe(i2400mu->usb_dev, epd->bEndpointAddress); + usb_fill_int_urb(urb, i2400mu->usb_dev, pipe, + i2400m->bm_ack_buf, I2400M_BM_ACK_BUF_SIZE, + __i2400mu_bm_notif_cb, completion, + epd->bInterval); + return usb_submit_urb(urb, GFP_KERNEL); +} + + +/* + * Read an ack from the notification endpoint + * + * @i2400m: + * @_ack: pointer to where to store the read data + * @ack_size: how many bytes we should read + * + * Returns: < 0 errno code on error; otherwise, amount of received bytes. + * + * Submits a notification read, appends the read data to the given ack + * buffer and then repeats (until @ack_size bytes have been + * received). + */ +ssize_t i2400mu_bus_bm_wait_for_ack(struct i2400m *i2400m, + struct i2400m_bootrom_header *_ack, + size_t ack_size) +{ + ssize_t result = -ENOMEM; + struct device *dev = i2400m_dev(i2400m); + struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); + struct urb notif_urb; + void *ack = _ack; + size_t offset, len; + long val; + int do_autopm = 1; + DECLARE_COMPLETION_ONSTACK(notif_completion); + + d_fnstart(8, dev, "(i2400m %p ack %p size %zu)\n", + i2400m, ack, ack_size); + BUG_ON(_ack == i2400m->bm_ack_buf); + result = usb_autopm_get_interface(i2400mu->usb_iface); + if (result < 0) { + dev_err(dev, "BM-ACK: can't get autopm: %d\n", (int) result); + do_autopm = 0; + } + usb_init_urb(¬if_urb); /* ready notifications */ + usb_get_urb(¬if_urb); + offset = 0; + while (offset < ack_size) { + init_completion(¬if_completion); + result = i2400mu_notif_submit(i2400mu, ¬if_urb, + ¬if_completion); + if (result < 0) + goto error_notif_urb_submit; + val = wait_for_completion_interruptible_timeout( + ¬if_completion, HZ); + if (val == 0) { + result = -ETIMEDOUT; + usb_kill_urb(¬if_urb); /* Timedout */ + goto error_notif_wait; + } + if (val == -ERESTARTSYS) { + result = -EINTR; /* Interrupted */ + usb_kill_urb(¬if_urb); + goto error_notif_wait; + } + result = notif_urb.status; /* How was the ack? */ + switch (result) { + case 0: + break; + case -EINVAL: /* while removing driver */ + case -ENODEV: /* dev disconnect ... */ + case -ENOENT: /* just ignore it */ + case -ESHUTDOWN: /* and exit */ + case -ECONNRESET: + result = -ESHUTDOWN; + goto error_dev_gone; + default: /* any other? */ + usb_kill_urb(¬if_urb); /* Timedout */ + if (edc_inc(&i2400mu->urb_edc, + EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) + goto error_exceeded; + dev_err(dev, "BM-ACK: URB error %d, " + "retrying\n", notif_urb.status); + continue; /* retry */ + } + if (notif_urb.actual_length == 0) { + d_printf(6, dev, "ZLP received, retrying\n"); + continue; + } + /* Got data, append it to the buffer */ + len = min(ack_size - offset, (size_t) notif_urb.actual_length); + memcpy(ack + offset, i2400m->bm_ack_buf, len); + offset += len; + } + result = offset; +error_notif_urb_submit: +error_notif_wait: +error_dev_gone: +out: + if (do_autopm) + usb_autopm_put_interface(i2400mu->usb_iface); + d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %zd\n", + i2400m, ack, ack_size, result); + return result; + +error_exceeded: + dev_err(dev, "bm: maximum errors in notification URB exceeded; " + "resetting device\n"); + usb_queue_reset_device(i2400mu->usb_iface); + goto out; +} -- cgit From a8ebf98f541463107bb9544a1b611981dc2477e7 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:53 -0800 Subject: i2400m/USB: TX and RX path backends Implements the backend so that the generic driver can TX/RX to/from the USB device. TX is implemented with a kthread sitting in a never-ending loop that when kicked by the generic driver's TX code will pull data from the TX FIFO and send it to the device until it drains it. Then it goes back sleep, waiting for another kick. RX is implemented in a similar fashion, but reads are kicked in by the device notifying in the interrupt endpoint that data is ready. Device reset notifications are also sent via the notification endpoint. We need a thread contexts to run USB autopm functions (blocking) and to process the received data (can get to be heavy in processing time). Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/usb-notif.c | 269 ++++++++++++++++++++++ drivers/net/wimax/i2400m/usb-rx.c | 417 +++++++++++++++++++++++++++++++++++ drivers/net/wimax/i2400m/usb-tx.c | 229 +++++++++++++++++++ 3 files changed, 915 insertions(+) create mode 100644 drivers/net/wimax/i2400m/usb-notif.c create mode 100644 drivers/net/wimax/i2400m/usb-rx.c create mode 100644 drivers/net/wimax/i2400m/usb-tx.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c new file mode 100644 index 00000000000..9702c22b249 --- /dev/null +++ b/drivers/net/wimax/i2400m/usb-notif.c @@ -0,0 +1,269 @@ +/* + * Intel Wireless WiMAX Connection 2400m over USB + * Notification handling + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * Inaky Perez-Gonzalez + * - Initial implementation + * + * + * The notification endpoint is active when the device is not in boot + * mode; in here we just read and get notifications; based on those, + * we act to either reinitialize the device after a reboot or to + * submit a RX request. + * + * ROADMAP + * + * i2400mu_usb_notification_setup() + * + * i2400mu_usb_notification_release() + * + * i2400mu_usb_notification_cb() Called when a URB is ready + * i2400mu_notif_grok() + * i2400m_dev_reset_handle() + * i2400mu_rx_kick() + */ +#include +#include "i2400m-usb.h" + + +#define D_SUBMODULE notif +#include "usb-debug-levels.h" + + +static const +__le32 i2400m_ZERO_BARKER[4] = { 0, 0, 0, 0 }; + + +/* + * Process a received notification + * + * In normal operation mode, we can only receive two types of payloads + * on the notification endpoint: + * + * - a reboot barker, we do a bootstrap (the device has reseted). + * + * - a block of zeroes: there is pending data in the IN endpoint + */ +static +int i2400mu_notification_grok(struct i2400mu *i2400mu, const void *buf, + size_t buf_len) +{ + int ret; + struct device *dev = &i2400mu->usb_iface->dev; + struct i2400m *i2400m = &i2400mu->i2400m; + + d_fnstart(4, dev, "(i2400m %p buf %p buf_len %zu)\n", + i2400mu, buf, buf_len); + ret = -EIO; + if (buf_len < sizeof(i2400m_NBOOT_BARKER)) + /* Not a bug, just ignore */ + goto error_bad_size; + if (!memcmp(i2400m_NBOOT_BARKER, buf, sizeof(i2400m_NBOOT_BARKER)) + || !memcmp(i2400m_SBOOT_BARKER, buf, sizeof(i2400m_SBOOT_BARKER))) + ret = i2400m_dev_reset_handle(i2400m); + else if (!memcmp(i2400m_ZERO_BARKER, buf, sizeof(i2400m_ZERO_BARKER))) { + i2400mu_rx_kick(i2400mu); + ret = 0; + } else { /* Unknown or unexpected data in the notif message */ + char prefix[64]; + ret = -EIO; + dev_err(dev, "HW BUG? Unknown/unexpected data in notification " + "message (%zu bytes)\n", buf_len); + snprintf(prefix, sizeof(prefix), "%s %s: ", + dev_driver_string(dev) , dev->bus_id); + if (buf_len > 64) { + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, + 8, 4, buf, 64, 0); + printk(KERN_ERR "%s... (only first 64 bytes " + "dumped)\n", prefix); + } else + print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, + 8, 4, buf, buf_len, 0); + } +error_bad_size: + d_fnend(4, dev, "(i2400m %p buf %p buf_len %zu) = %d\n", + i2400mu, buf, buf_len, ret); + return ret; +} + + +/* + * URB callback for the notification endpoint + * + * @urb: the urb received from the notification endpoint + * + * This function will just process the USB side of the transaction, + * checking everything is fine, pass the processing to + * i2400m_notification_grok() and resubmit the URB. + */ +static +void i2400mu_notification_cb(struct urb *urb) +{ + int ret; + struct i2400mu *i2400mu = urb->context; + struct device *dev = &i2400mu->usb_iface->dev; + + d_fnstart(4, dev, "(urb %p status %d actual_length %d)\n", + urb, urb->status, urb->actual_length); + ret = urb->status; + switch (ret) { + case 0: + ret = i2400mu_notification_grok(i2400mu, urb->transfer_buffer, + urb->actual_length); + if (ret == -EIO && edc_inc(&i2400mu->urb_edc, EDC_MAX_ERRORS, + EDC_ERROR_TIMEFRAME)) + goto error_exceeded; + if (ret == -ENOMEM) /* uff...power cycle? shutdown? */ + goto error_exceeded; + break; + case -EINVAL: /* while removing driver */ + case -ENODEV: /* dev disconnect ... */ + case -ENOENT: /* ditto */ + case -ESHUTDOWN: /* URB killed */ + case -ECONNRESET: /* disconnection */ + goto out; /* Notify around */ + default: /* Some error? */ + if (edc_inc(&i2400mu->urb_edc, + EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) + goto error_exceeded; + dev_err(dev, "notification: URB error %d, retrying\n", + urb->status); + } + usb_mark_last_busy(i2400mu->usb_dev); + ret = usb_submit_urb(i2400mu->notif_urb, GFP_ATOMIC); + switch (ret) { + case 0: + case -EINVAL: /* while removing driver */ + case -ENODEV: /* dev disconnect ... */ + case -ENOENT: /* ditto */ + case -ESHUTDOWN: /* URB killed */ + case -ECONNRESET: /* disconnection */ + break; /* just ignore */ + default: /* Some error? */ + dev_err(dev, "notification: cannot submit URB: %d\n", ret); + goto error_submit; + } + d_fnend(4, dev, "(urb %p status %d actual_length %d) = void\n", + urb, urb->status, urb->actual_length); + return; + +error_exceeded: + dev_err(dev, "maximum errors in notification URB exceeded; " + "resetting device\n"); +error_submit: + usb_queue_reset_device(i2400mu->usb_iface); +out: + d_fnend(4, dev, "(urb %p status %d actual_length %d) = void\n", + urb, urb->status, urb->actual_length); + return; +} + + +/* + * setup the notification endpoint + * + * @i2400m: device descriptor + * + * This procedure prepares the notification urb and handler for receiving + * unsolicited barkers from the device. + */ +int i2400mu_notification_setup(struct i2400mu *i2400mu) +{ + struct device *dev = &i2400mu->usb_iface->dev; + int usb_pipe, ret = 0; + struct usb_endpoint_descriptor *epd; + char *buf; + + d_fnstart(4, dev, "(i2400m %p)\n", i2400mu); + buf = kmalloc(I2400MU_MAX_NOTIFICATION_LEN, GFP_KERNEL | GFP_DMA); + if (buf == NULL) { + dev_err(dev, "notification: buffer allocation failed\n"); + ret = -ENOMEM; + goto error_buf_alloc; + } + + i2400mu->notif_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!i2400mu->notif_urb) { + ret = -ENOMEM; + dev_err(dev, "notification: cannot allocate URB\n"); + goto error_alloc_urb; + } + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_NOTIFICATION); + usb_pipe = usb_rcvintpipe(i2400mu->usb_dev, epd->bEndpointAddress); + usb_fill_int_urb(i2400mu->notif_urb, i2400mu->usb_dev, usb_pipe, + buf, I2400MU_MAX_NOTIFICATION_LEN, + i2400mu_notification_cb, i2400mu, epd->bInterval); + ret = usb_submit_urb(i2400mu->notif_urb, GFP_KERNEL); + if (ret != 0) { + dev_err(dev, "notification: cannot submit URB: %d\n", ret); + goto error_submit; + } + d_fnend(4, dev, "(i2400m %p) = %d\n", i2400mu, ret); + return ret; + +error_submit: + usb_free_urb(i2400mu->notif_urb); +error_alloc_urb: + kfree(buf); +error_buf_alloc: + d_fnend(4, dev, "(i2400m %p) = %d\n", i2400mu, ret); + return ret; +} + + +/* + * Tear down of the notification mechanism + * + * @i2400m: device descriptor + * + * Kill the interrupt endpoint urb, free any allocated resources. + * + * We need to check if we have done it before as for example, + * _suspend() call this; if after a suspend() we get a _disconnect() + * (as the case is when hibernating), nothing bad happens. + */ +void i2400mu_notification_release(struct i2400mu *i2400mu) +{ + struct device *dev = &i2400mu->usb_iface->dev; + + d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu); + if (i2400mu->notif_urb != NULL) { + usb_kill_urb(i2400mu->notif_urb); + kfree(i2400mu->notif_urb->transfer_buffer); + usb_free_urb(i2400mu->notif_urb); + i2400mu->notif_urb = NULL; + } + d_fnend(4, dev, "(i2400mu %p)\n", i2400mu); +} diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c new file mode 100644 index 00000000000..074cc1f8985 --- /dev/null +++ b/drivers/net/wimax/i2400m/usb-rx.c @@ -0,0 +1,417 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * USB RX handling + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * - Initial implementation + * Inaky Perez-Gonzalez + * - Use skb_clone(), break up processing in chunks + * - Split transport/device specific + * - Make buffer size dynamic to exert less memory pressure + * + * + * This handles the RX path on USB. + * + * When a notification is received that says 'there is RX data ready', + * we call i2400mu_rx_kick(); that wakes up the RX kthread, which + * reads a buffer from USB and passes it to i2400m_rx() in the generic + * handling code. The RX buffer has an specific format that is + * described in rx.c. + * + * We use a kernel thread in a loop because: + * + * - we want to be able to call the USB power management get/put + * functions (blocking) before each transaction. + * + * - We might get a lot of notifications and we don't want to submit + * a zillion reads; by serializing, we are throttling. + * + * - RX data processing can get heavy enough so that it is not + * appropiate for doing it in the USB callback; thus we run it in a + * process context. + * + * We provide a read buffer of an arbitrary size (short of a page); if + * the callback reports -EOVERFLOW, it means it was too small, so we + * just double the size and retry (being careful to append, as + * sometimes the device provided some data). Every now and then we + * check if the average packet size is smaller than the current packet + * size and if so, we halve it. At the end, the size of the + * preallocated buffer should be following the average received + * transaction size, adapting dynamically to it. + * + * ROADMAP + * + * i2400mu_rx_kick() Called from notif.c when we get a + * 'data ready' notification + * i2400mu_rxd() Kernel RX daemon + * i2400mu_rx() Receive USB data + * i2400m_rx() Send data to generic i2400m RX handling + * + * i2400mu_rx_setup() called from i2400mu_bus_dev_start() + * + * i2400mu_rx_release() called from i2400mu_bus_dev_stop() + */ +#include +#include +#include "i2400m-usb.h" + + +#define D_SUBMODULE rx +#include "usb-debug-levels.h" + +/* + * Dynamic RX size + * + * We can't let the rx_size be a multiple of 512 bytes (the RX + * endpoint's max packet size). On some USB host controllers (we + * haven't been able to fully characterize which), if the device is + * about to send (for example) X bytes and we only post a buffer to + * receive n*512, it will fail to mark that as babble (so that + * i2400mu_rx() [case -EOVERFLOW] can resize the buffer and get the + * rest). + * + * So on growing or shrinking, if it is a multiple of the + * maxpacketsize, we remove some (instead of incresing some, so in a + * buddy allocator we try to waste less space). + * + * Note we also need a hook for this on i2400mu_rx() -- when we do the + * first read, we are sure we won't hit this spot because + * i240mm->rx_size has been set properly. However, if we have to + * double because of -EOVERFLOW, when we launch the read to get the + * rest of the data, we *have* to make sure that also is not a + * multiple of the max_pkt_size. + */ + +static +size_t i2400mu_rx_size_grow(struct i2400mu *i2400mu) +{ + struct device *dev = &i2400mu->usb_iface->dev; + size_t rx_size; + const size_t max_pkt_size = 512; + + rx_size = 2 * i2400mu->rx_size; + if (rx_size % max_pkt_size == 0) { + rx_size -= 8; + d_printf(1, dev, + "RX: expected size grew to %zu [adjusted -8] " + "from %zu\n", + rx_size, i2400mu->rx_size); + } else + d_printf(1, dev, + "RX: expected size grew to %zu from %zu\n", + rx_size, i2400mu->rx_size); + return rx_size; +} + + +static +void i2400mu_rx_size_maybe_shrink(struct i2400mu *i2400mu) +{ + const size_t max_pkt_size = 512; + struct device *dev = &i2400mu->usb_iface->dev; + + if (unlikely(i2400mu->rx_size_cnt >= 100 + && i2400mu->rx_size_auto_shrink)) { + size_t avg_rx_size = + i2400mu->rx_size_acc / i2400mu->rx_size_cnt; + size_t new_rx_size = i2400mu->rx_size / 2; + if (avg_rx_size < new_rx_size) { + if (new_rx_size % max_pkt_size == 0) { + new_rx_size -= 8; + d_printf(1, dev, + "RX: expected size shrank to %zu " + "[adjusted -8] from %zu\n", + new_rx_size, i2400mu->rx_size); + } else + d_printf(1, dev, + "RX: expected size shrank to %zu " + "from %zu\n", + new_rx_size, i2400mu->rx_size); + i2400mu->rx_size = new_rx_size; + i2400mu->rx_size_cnt = 0; + i2400mu->rx_size_acc = i2400mu->rx_size; + } + } +} + +/* + * Receive a message with payloads from the USB bus into an skb + * + * @i2400mu: USB device descriptor + * @rx_skb: skb where to place the received message + * + * Deals with all the USB-specifics of receiving, dynamically + * increasing the buffer size if so needed. Returns the payload in the + * skb, ready to process. On a zero-length packet, we retry. + * + * On soft USB errors, we retry (until they become too frequent and + * then are promoted to hard); on hard USB errors, we reset the + * device. On other errors (skb realloacation, we just drop it and + * hope for the next invocation to solve it). + * + * Returns: pointer to the skb if ok, ERR_PTR on error. + * NOTE: this function might realloc the skb (if it is too small), + * so always update with the one returned. + * ERR_PTR() is < 0 on error. + */ +static +struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) +{ + int result = 0; + struct device *dev = &i2400mu->usb_iface->dev; + int usb_pipe, read_size, rx_size, do_autopm; + struct usb_endpoint_descriptor *epd; + const size_t max_pkt_size = 512; + + d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu); + do_autopm = atomic_read(&i2400mu->do_autopm); + result = do_autopm ? + usb_autopm_get_interface(i2400mu->usb_iface) : 0; + if (result < 0) { + dev_err(dev, "RX: can't get autopm: %d\n", result); + do_autopm = 0; + } + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_IN); + usb_pipe = usb_rcvbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); +retry: + rx_size = skb_end_pointer(rx_skb) - rx_skb->data - rx_skb->len; + if (unlikely(rx_size % max_pkt_size == 0)) { + rx_size -= 8; + d_printf(1, dev, "RX: rx_size adapted to %d [-8]\n", rx_size); + } + result = usb_bulk_msg( + i2400mu->usb_dev, usb_pipe, rx_skb->data + rx_skb->len, + rx_size, &read_size, HZ); + usb_mark_last_busy(i2400mu->usb_dev); + switch (result) { + case 0: + if (read_size == 0) + goto retry; /* ZLP, just resubmit */ + skb_put(rx_skb, read_size); + break; + case -EINVAL: /* while removing driver */ + case -ENODEV: /* dev disconnect ... */ + case -ENOENT: /* just ignore it */ + case -ESHUTDOWN: + case -ECONNRESET: + break; + case -EOVERFLOW: { /* too small, reallocate */ + struct sk_buff *new_skb; + rx_size = i2400mu_rx_size_grow(i2400mu); + if (rx_size <= (1 << 16)) /* cap it */ + i2400mu->rx_size = rx_size; + else if (printk_ratelimit()) { + dev_err(dev, "BUG? rx_size up to %d\n", rx_size); + result = -EINVAL; + goto out; + } + skb_put(rx_skb, read_size); + new_skb = skb_copy_expand(rx_skb, 0, rx_size - rx_skb->len, + GFP_KERNEL); + if (new_skb == NULL) { + if (printk_ratelimit()) + dev_err(dev, "RX: Can't reallocate skb to %d; " + "RX dropped\n", rx_size); + kfree(rx_skb); + result = 0; + goto out; /* drop it...*/ + } + kfree_skb(rx_skb); + rx_skb = new_skb; + i2400mu->rx_size_cnt = 0; + i2400mu->rx_size_acc = i2400mu->rx_size; + d_printf(1, dev, "RX: size changed to %d, received %d, " + "copied %d, capacity %ld\n", + rx_size, read_size, rx_skb->len, + (long) (skb_end_pointer(new_skb) - new_skb->head)); + goto retry; + } + /* In most cases, it happens due to the hardware scheduling a + * read when there was no data - unfortunately, we have no way + * to tell this timeout from a USB timeout. So we just ignore + * it. */ + case -ETIMEDOUT: + dev_err(dev, "RX: timeout: %d\n", result); + result = 0; + break; + default: /* Any error */ + if (edc_inc(&i2400mu->urb_edc, + EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) + goto error_reset; + dev_err(dev, "RX: error receiving URB: %d, retrying\n", result); + goto retry; + } +out: + if (do_autopm) + usb_autopm_put_interface(i2400mu->usb_iface); + d_fnend(4, dev, "(i2400mu %p) = %p\n", i2400mu, rx_skb); + return rx_skb; + +error_reset: + dev_err(dev, "RX: maximum errors in URB exceeded; " + "resetting device\n"); + usb_queue_reset_device(i2400mu->usb_iface); + rx_skb = ERR_PTR(result); + goto out; +} + + +/* + * Kernel thread for USB reception of data + * + * This thread waits for a kick; once kicked, it will allocate an skb + * and receive a single message to it from USB (using + * i2400mu_rx()). Once received, it is passed to the generic i2400m RX + * code for processing. + * + * When done processing, it runs some dirty statistics to verify if + * the last 100 messages received were smaller than half of the + * current RX buffer size. In that case, the RX buffer size is + * halved. This will helps lowering the pressure on the memory + * allocator. + * + * Hard errors force the thread to exit. + */ +static +int i2400mu_rxd(void *_i2400mu) +{ + int result = 0; + struct i2400mu *i2400mu = _i2400mu; + struct i2400m *i2400m = &i2400mu->i2400m; + struct device *dev = &i2400mu->usb_iface->dev; + struct net_device *net_dev = i2400m->wimax_dev.net_dev; + size_t pending; + int rx_size; + struct sk_buff *rx_skb; + + d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu); + while (1) { + d_printf(2, dev, "TX: waiting for messages\n"); + pending = 0; + wait_event_interruptible( + i2400mu->rx_wq, + (kthread_should_stop() /* check this first! */ + || (pending = atomic_read(&i2400mu->rx_pending_count))) + ); + if (kthread_should_stop()) + break; + if (pending == 0) + continue; + rx_size = i2400mu->rx_size; + d_printf(2, dev, "RX: reading up to %d bytes\n", rx_size); + rx_skb = __netdev_alloc_skb(net_dev, rx_size, GFP_KERNEL); + if (rx_skb == NULL) { + dev_err(dev, "RX: can't allocate skb [%d bytes]\n", + rx_size); + msleep(50); /* give it some time? */ + continue; + } + + /* Receive the message with the payloads */ + rx_skb = i2400mu_rx(i2400mu, rx_skb); + result = PTR_ERR(rx_skb); + if (IS_ERR(rx_skb)) + goto out; + atomic_dec(&i2400mu->rx_pending_count); + if (rx_skb->len == 0) { /* some ignorable condition */ + kfree_skb(rx_skb); + continue; + } + + /* Deliver the message to the generic i2400m code */ + i2400mu->rx_size_cnt++; + i2400mu->rx_size_acc += rx_skb->len; + result = i2400m_rx(i2400m, rx_skb); + if (result == -EIO + && edc_inc(&i2400mu->urb_edc, + EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { + goto error_reset; + } + + /* Maybe adjust RX buffer size */ + i2400mu_rx_size_maybe_shrink(i2400mu); + } + result = 0; +out: + d_fnend(4, dev, "(i2400mu %p) = %d\n", i2400mu, result); + return result; + +error_reset: + dev_err(dev, "RX: maximum errors in received buffer exceeded; " + "resetting device\n"); + usb_queue_reset_device(i2400mu->usb_iface); + goto out; +} + + +/* + * Start reading from the device + * + * @i2400m: device instance + * + * Notify the RX thread that there is data pending. + */ +void i2400mu_rx_kick(struct i2400mu *i2400mu) +{ + struct i2400m *i2400m = &i2400mu->i2400m; + struct device *dev = &i2400mu->usb_iface->dev; + + d_fnstart(3, dev, "(i2400mu %p)\n", i2400m); + atomic_inc(&i2400mu->rx_pending_count); + wake_up_all(&i2400mu->rx_wq); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); +} + + +int i2400mu_rx_setup(struct i2400mu *i2400mu) +{ + int result = 0; + struct i2400m *i2400m = &i2400mu->i2400m; + struct device *dev = &i2400mu->usb_iface->dev; + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + + i2400mu->rx_kthread = kthread_run(i2400mu_rxd, i2400mu, "%s-rx", + wimax_dev->name); + if (IS_ERR(i2400mu->rx_kthread)) { + result = PTR_ERR(i2400mu->rx_kthread); + dev_err(dev, "RX: cannot start thread: %d\n", result); + } + return result; +} + +void i2400mu_rx_release(struct i2400mu *i2400mu) +{ + kthread_stop(i2400mu->rx_kthread); +} + diff --git a/drivers/net/wimax/i2400m/usb-tx.c b/drivers/net/wimax/i2400m/usb-tx.c new file mode 100644 index 00000000000..dfd893356f4 --- /dev/null +++ b/drivers/net/wimax/i2400m/usb-tx.c @@ -0,0 +1,229 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * USB specific TX handling + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * - Initial implementation + * Inaky Perez-Gonzalez + * - Split transport/device specific + * + * + * Takes the TX messages in the i2400m's driver TX FIFO and sends them + * to the device until there are no more. + * + * If we fail sending the message, we just drop it. There isn't much + * we can do at this point. We could also retry, but the USB stack has + * already retried and still failed, so there is not much of a + * point. As well, most of the traffic is network, which has recovery + * methods for dropped packets. + * + * For sending we just obtain a FIFO buffer to send, send it to the + * USB bulk out, tell the TX FIFO code we have sent it; query for + * another one, etc... until done. + * + * We use a thread so we can call usb_autopm_enable() and + * usb_autopm_disable() for each transaction; this way when the device + * goes idle, it will suspend. It also has less overhead than a + * dedicated workqueue, as it is being used for a single task. + * + * ROADMAP + * + * i2400mu_tx_setup() + * i2400mu_tx_release() + * + * i2400mu_bus_tx_kick() - Called by the tx.c code when there + * is new data in the FIFO. + * i2400mu_txd() + * i2400m_tx_msg_get() + * i2400m_tx_msg_sent() + */ +#include "i2400m-usb.h" + + +#define D_SUBMODULE tx +#include "usb-debug-levels.h" + + +/* + * Get the next TX message in the TX FIFO and send it to the device + * + * Note that any iteration consumes a message to be sent, no matter if + * it succeeds or fails (we have no real way to retry or complain). + * + * Return: 0 if ok, < 0 errno code on hard error. + */ +static +int i2400mu_tx(struct i2400mu *i2400mu, struct i2400m_msg_hdr *tx_msg, + size_t tx_msg_size) +{ + int result = 0; + struct i2400m *i2400m = &i2400mu->i2400m; + struct device *dev = &i2400mu->usb_iface->dev; + int usb_pipe, sent_size, do_autopm; + struct usb_endpoint_descriptor *epd; + + d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu); + do_autopm = atomic_read(&i2400mu->do_autopm); + result = do_autopm ? + usb_autopm_get_interface(i2400mu->usb_iface) : 0; + if (result < 0) { + dev_err(dev, "TX: can't get autopm: %d\n", result); + do_autopm = 0; + } + epd = usb_get_epd(i2400mu->usb_iface, I2400MU_EP_BULK_OUT); + usb_pipe = usb_sndbulkpipe(i2400mu->usb_dev, epd->bEndpointAddress); +retry: + result = usb_bulk_msg(i2400mu->usb_dev, usb_pipe, + tx_msg, tx_msg_size, &sent_size, HZ); + usb_mark_last_busy(i2400mu->usb_dev); + switch (result) { + case 0: + if (sent_size != tx_msg_size) { /* Too short? drop it */ + dev_err(dev, "TX: short write (%d B vs %zu " + "expected)\n", sent_size, tx_msg_size); + result = -EIO; + } + break; + case -EINVAL: /* while removing driver */ + case -ENODEV: /* dev disconnect ... */ + case -ENOENT: /* just ignore it */ + case -ESHUTDOWN: /* and exit */ + case -ECONNRESET: + result = -ESHUTDOWN; + break; + default: /* Some error? */ + if (edc_inc(&i2400mu->urb_edc, + EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { + dev_err(dev, "TX: maximum errors in URB " + "exceeded; resetting device\n"); + usb_queue_reset_device(i2400mu->usb_iface); + } else { + dev_err(dev, "TX: cannot send URB; retrying. " + "tx_msg @%zu %zu B [%d sent]: %d\n", + (void *) tx_msg - i2400m->tx_buf, + tx_msg_size, sent_size, result); + goto retry; + } + } + if (do_autopm) + usb_autopm_put_interface(i2400mu->usb_iface); + d_fnend(4, dev, "(i2400mu %p) = result\n", i2400mu); + return result; +} + + +/* + * Get the next TX message in the TX FIFO and send it to the device + * + * Note we exit the loop if i2400mu_tx() fails; that funtion only + * fails on hard error (failing to tx a buffer not being one of them, + * see its doc). + * + * Return: 0 + */ +static +int i2400mu_txd(void *_i2400mu) +{ + int result = 0; + struct i2400mu *i2400mu = _i2400mu; + struct i2400m *i2400m = &i2400mu->i2400m; + struct device *dev = &i2400mu->usb_iface->dev; + struct i2400m_msg_hdr *tx_msg; + size_t tx_msg_size; + + d_fnstart(4, dev, "(i2400mu %p)\n", i2400mu); + + while (1) { + d_printf(2, dev, "TX: waiting for messages\n"); + tx_msg = NULL; + wait_event_interruptible( + i2400mu->tx_wq, + (kthread_should_stop() /* check this first! */ + || (tx_msg = i2400m_tx_msg_get(i2400m, &tx_msg_size))) + ); + if (kthread_should_stop()) + break; + WARN_ON(tx_msg == NULL); /* should not happen...*/ + d_printf(2, dev, "TX: submitting %zu bytes\n", tx_msg_size); + d_dump(5, dev, tx_msg, tx_msg_size); + /* Yeah, we ignore errors ... not much we can do */ + i2400mu_tx(i2400mu, tx_msg, tx_msg_size); + i2400m_tx_msg_sent(i2400m); /* ack it, advance the FIFO */ + if (result < 0) + break; + } + d_fnend(4, dev, "(i2400mu %p) = %d\n", i2400mu, result); + return result; +} + + +/* + * i2400m TX engine notifies us that there is data in the FIFO ready + * for TX + * + * If there is a URB in flight, don't do anything; when it finishes, + * it will see there is data in the FIFO and send it. Else, just + * submit a write. + */ +void i2400mu_bus_tx_kick(struct i2400m *i2400m) +{ + struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); + struct device *dev = &i2400mu->usb_iface->dev; + + d_fnstart(3, dev, "(i2400m %p) = void\n", i2400m); + wake_up_all(&i2400mu->tx_wq); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); +} + + +int i2400mu_tx_setup(struct i2400mu *i2400mu) +{ + int result = 0; + struct i2400m *i2400m = &i2400mu->i2400m; + struct device *dev = &i2400mu->usb_iface->dev; + struct wimax_dev *wimax_dev = &i2400m->wimax_dev; + + i2400mu->tx_kthread = kthread_run(i2400mu_txd, i2400mu, "%s-tx", + wimax_dev->name); + if (IS_ERR(i2400mu->tx_kthread)) { + result = PTR_ERR(i2400mu->tx_kthread); + dev_err(dev, "TX: cannot start thread: %d\n", result); + } + return result; +} + +void i2400mu_tx_release(struct i2400mu *i2400mu) +{ + kthread_stop(i2400mu->tx_kthread); +} -- cgit From 17d559af963995e483a51ec26697034431bcf2b9 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:54 -0800 Subject: i2400m/SDIO: header for the SDIO subdriver This contains the common function declaration and constants for the SDIO driver for the 2400m Wireless WiMAX Connection and it's debug level settings. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/i2400m-sdio.h | 132 +++++++++++++++++++++++++++ drivers/net/wimax/i2400m/sdio-debug-levels.h | 22 +++++ 2 files changed, 154 insertions(+) create mode 100644 drivers/net/wimax/i2400m/i2400m-sdio.h create mode 100644 drivers/net/wimax/i2400m/sdio-debug-levels.h (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h new file mode 100644 index 00000000000..08c2fb73923 --- /dev/null +++ b/drivers/net/wimax/i2400m/i2400m-sdio.h @@ -0,0 +1,132 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * SDIO-specific i2400m driver definitions + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Brian Bian + * Dirk Brandewie + * Inaky Perez-Gonzalez + * Yanir Lubetkin + * - Initial implementation + * + * + * This driver implements the bus-specific part of the i2400m for + * SDIO. Check i2400m.h for a generic driver description. + * + * ARCHITECTURE + * + * This driver sits under the bus-generic i2400m driver, providing the + * connection to the device. + * + * When probed, all the function pointers are setup and then the + * bus-generic code called. The generic driver will then use the + * provided pointers for uploading firmware (i2400ms_bus_bm*() in + * sdio-fw.c) and then setting up the device (i2400ms_dev_*() in + * sdio.c). + * + * Once firmware is uploaded, TX functions (sdio-tx.c) are called when + * data is ready for transmission in the TX fifo; then the SDIO IRQ is + * fired and data is available (sdio-rx.c), it is sent to the generic + * driver for processing with i2400m_rx. + */ + +#ifndef __I2400M_SDIO_H__ +#define __I2400M_SDIO_H__ + +#include "i2400m.h" + +/* Host-Device interface for SDIO */ +enum { + I2400MS_BLK_SIZE = 256, + I2400MS_PL_SIZE_MAX = 0x3E00, + + I2400MS_DATA_ADDR = 0x0, + I2400MS_INTR_STATUS_ADDR = 0x13, + I2400MS_INTR_CLEAR_ADDR = 0x13, + I2400MS_INTR_ENABLE_ADDR = 0x14, + I2400MS_INTR_GET_SIZE_ADDR = 0x2C, + /* The number of ticks to wait for the device to signal that + * it is ready */ + I2400MS_INIT_SLEEP_INTERVAL = 10, +}; + + +/** + * struct i2400ms - descriptor for a SDIO connected i2400m + * + * @i2400m: bus-generic i2400m implementation; has to be first (see + * it's documentation in i2400m.h). + * + * @func: pointer to our SDIO function + * + * @tx_worker: workqueue struct used to TX data when the bus-generic + * code signals packets are pending for transmission to the device. + * + * @tx_workqueue: workqeueue used for data TX; we don't use the + * system's workqueue as that might cause deadlocks with code in + * the bus-generic driver. + */ +struct i2400ms { + struct i2400m i2400m; /* FIRST! See doc */ + struct sdio_func *func; + + struct work_struct tx_worker; + struct workqueue_struct *tx_workqueue; + char tx_wq_name[32]; + + struct dentry *debugfs_dentry; +}; + + +static inline +void i2400ms_init(struct i2400ms *i2400ms) +{ + i2400m_init(&i2400ms->i2400m); +} + + +extern int i2400ms_rx_setup(struct i2400ms *); +extern void i2400ms_rx_release(struct i2400ms *); +extern ssize_t __i2400ms_rx_get_size(struct i2400ms *); + +extern int i2400ms_tx_setup(struct i2400ms *); +extern void i2400ms_tx_release(struct i2400ms *); +extern void i2400ms_bus_tx_kick(struct i2400m *); + +extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *, + const struct i2400m_bootrom_header *, + size_t, int); +extern ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *, + struct i2400m_bootrom_header *, + size_t); +#endif /* #ifndef __I2400M_SDIO_H__ */ diff --git a/drivers/net/wimax/i2400m/sdio-debug-levels.h b/drivers/net/wimax/i2400m/sdio-debug-levels.h new file mode 100644 index 00000000000..c5199874130 --- /dev/null +++ b/drivers/net/wimax/i2400m/sdio-debug-levels.h @@ -0,0 +1,22 @@ +/* + * debug levels control file for the i2400m module's + */ +#ifndef __debug_levels__h__ +#define __debug_levels__h__ + +/* Maximum compile and run time debug level for all submodules */ +#define D_MODULENAME i2400m_sdio +#define D_MASTER CONFIG_WIMAX_I2400M_DEBUG_LEVEL + +#include + +/* List of all the enabled modules */ +enum d_module { + D_SUBMODULE_DECLARE(main), + D_SUBMODULE_DECLARE(tx), + D_SUBMODULE_DECLARE(rx), + D_SUBMODULE_DECLARE(fw) +}; + + +#endif /* #ifndef __debug_levels__h__ */ -- cgit From a0848826bfaf0815ec9654d78c218a40f755ccd4 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:55 -0800 Subject: i2400m/SDIO: probe/disconnect, dev init/shutdown and reset backends Implements probe/disconnect for the SDIO device, as well as main backends for the generic driver to control the SDIO device (bus_dev_start(), bus_dev_stop() and bus_reset()). Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/sdio.c | 511 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 511 insertions(+) create mode 100644 drivers/net/wimax/i2400m/sdio.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c new file mode 100644 index 00000000000..1bfa283bbd8 --- /dev/null +++ b/drivers/net/wimax/i2400m/sdio.c @@ -0,0 +1,511 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Linux driver model glue for the SDIO device, reset & fw upload + * + * + * Copyright (C) 2007-2008 Intel Corporation + * Dirk Brandewie + * Inaky Perez-Gonzalez + * Yanir Lubetkin + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * See i2400m-sdio.h for a general description of this driver. + * + * This file implements driver model glue, and hook ups for the + * generic driver to implement the bus-specific functions (device + * communication setup/tear down, firmware upload and resetting). + * + * ROADMAP + * + * i2400m_probe() + * alloc_netdev() + * i2400ms_netdev_setup() + * i2400ms_init() + * i2400m_netdev_setup() + * i2400ms_enable_function() + * i2400m_setup() + * + * i2400m_remove() + * i2400m_release() + * free_netdev(net_dev) + * + * i2400ms_bus_reset() Called by i2400m->bus_reset + * __i2400ms_reset() + * __i2400ms_send_barker() + * + * i2400ms_bus_dev_start() Called by i2400m_dev_start() [who is + * i2400ms_tx_setup() called by i2400m_setup()] + * i2400ms_rx_setup() + * + * i2400ms_bus_dev_stop() Called by i2400m_dev_stop() [who is + * i2400ms_rx_release() is called by i2400m_release()] + * i2400ms_tx_release() + * + */ + +#include +#include +#include +#include "i2400m-sdio.h" +#include + +#define D_SUBMODULE main +#include "sdio-debug-levels.h" + +/* IOE WiMAX function timeout in seconds */ +static int ioe_timeout = 2; +module_param(ioe_timeout, int, 0); + +/* Our firmware file name */ +#define I2400MS_FW_FILE_NAME "i2400m-fw-sdio-" I2400M_FW_VERSION ".sbcf" + +/* + * Enable the SDIO function + * + * Tries to enable the SDIO function; might fail if it is still not + * ready (in some hardware, the SDIO WiMAX function is only enabled + * when we ask it to explicitly doing). Tries until a timeout is + * reached. + * + * The reverse of this is...sdio_disable_function() + * + * Returns: 0 if the SDIO function was enabled, < 0 errno code on + * error (-ENODEV when it was unable to enable the function). + */ +static +int i2400ms_enable_function(struct sdio_func *func) +{ + u64 timeout; + int err; + struct device *dev = &func->dev; + + d_fnstart(3, dev, "(func %p)\n", func); + /* Setup timeout (FIXME: This needs to read the CIS table to + * get a real timeout) and then wait for the device to signal + * it is ready */ + timeout = get_jiffies_64() + ioe_timeout * HZ; + err = -ENODEV; + while (err != 0 && time_before64(get_jiffies_64(), timeout)) { + sdio_claim_host(func); + err = sdio_enable_func(func); + if (0 == err) { + sdio_release_host(func); + d_printf(2, dev, "SDIO function enabled\n"); + goto function_enabled; + } + d_printf(2, dev, "SDIO function failed to enable: %d\n", err); + sdio_disable_func(func); + sdio_release_host(func); + msleep(I2400MS_INIT_SLEEP_INTERVAL); + } + /* If timed out, device is not there yet -- get -ENODEV so + * the device driver core will retry later on. */ + if (err == -ETIME) { + dev_err(dev, "Can't enable WiMAX function; " + " has the function been enabled?\n"); + err = -ENODEV; + } +function_enabled: + d_fnend(3, dev, "(func %p) = %d\n", func, err); + return err; +} + + +/* + * Setup driver resources needed to communicate with the device + * + * The fw needs some time to settle, and it was just uploaded, + * so give it a break first. I'd prefer to just wait for the device to + * send something, but seems the poking we do to enable SDIO stuff + * interferes with it, so just give it a break before starting... + */ +static +int i2400ms_bus_dev_start(struct i2400m *i2400m) +{ + int result; + struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + msleep(200); + result = i2400ms_rx_setup(i2400ms); + if (result < 0) + goto error_rx_setup; + result = i2400ms_tx_setup(i2400ms); + if (result < 0) + goto error_tx_setup; + d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); + return result; + + i2400ms_tx_release(i2400ms); +error_tx_setup: + i2400ms_rx_release(i2400ms); +error_rx_setup: + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); + return result; +} + + +static +void i2400ms_bus_dev_stop(struct i2400m *i2400m) +{ + struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + + d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + i2400ms_rx_release(i2400ms); + i2400ms_tx_release(i2400ms); + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); +} + + +/* + * Sends a barker buffer to the device + * + * This helper will allocate a kmalloced buffer and use it to transmit + * (then free it). Reason for this is that the SDIO host controller + * expects alignment (unknown exactly which) which the stack won't + * really provide and certain arches/host-controller combinations + * cannot use stack/vmalloc/text areas for DMA transfers. + */ +static +int __i2400ms_send_barker(struct i2400ms *i2400ms, + const __le32 *barker, size_t barker_size) +{ + int ret; + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + void *buffer; + + ret = -ENOMEM; + buffer = kmalloc(I2400MS_BLK_SIZE, GFP_KERNEL); + if (buffer == NULL) + goto error_kzalloc; + + memcpy(buffer, barker, barker_size); + sdio_claim_host(func); + ret = sdio_memcpy_toio(func, 0, buffer, I2400MS_BLK_SIZE); + sdio_release_host(func); + + if (ret < 0) + d_printf(0, dev, "E: barker error: %d\n", ret); + + kfree(buffer); +error_kzalloc: + return ret; +} + + +/* + * Reset a device at different levels (warm, cold or bus) + * + * @i2400ms: device descriptor + * @reset_type: soft, warm or bus reset (I2400M_RT_WARM/SOFT/BUS) + * + * FIXME: not tested -- need to confirm expected effects + * + * Warm and cold resets get an SDIO reset if they fail (unimplemented) + * + * Warm reset: + * + * The device will be fully reset internally, but won't be + * disconnected from the USB bus (so no reenumeration will + * happen). Firmware upload will be neccessary. + * + * The device will send a reboot barker in the notification endpoint + * that will trigger the driver to reinitialize the state + * automatically from notif.c:i2400m_notification_grok() into + * i2400m_dev_bootstrap_delayed(). + * + * Cold and bus (USB) reset: + * + * The device will be fully reset internally, disconnected from the + * USB bus an a reenumeration will happen. Firmware upload will be + * neccessary. Thus, we don't do any locking or struct + * reinitialization, as we are going to be fully disconnected and + * reenumerated. + * + * Note we need to return -ENODEV if a warm reset was requested and we + * had to resort to a bus reset. See i2400m_op_reset(), wimax_reset() + * and wimax_dev->op_reset. + * + * WARNING: no driver state saved/fixed + */ +static +int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) +{ + int result; + struct i2400ms *i2400ms = + container_of(i2400m, struct i2400ms, i2400m); + struct device *dev = i2400m_dev(i2400m); + static const __le32 i2400m_WARM_BOOT_BARKER[4] = { + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER), + }; + static const __le32 i2400m_COLD_BOOT_BARKER[4] = { + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER), + }; + + if (rt == I2400M_RT_WARM) + result = __i2400ms_send_barker(i2400ms, i2400m_WARM_BOOT_BARKER, + sizeof(i2400m_WARM_BOOT_BARKER)); + else if (rt == I2400M_RT_COLD) + result = __i2400ms_send_barker(i2400ms, i2400m_COLD_BOOT_BARKER, + sizeof(i2400m_COLD_BOOT_BARKER)); + else if (rt == I2400M_RT_BUS) { +do_bus_reset: + dev_err(dev, "FIXME: SDIO bus reset not implemented\n"); + result = rt == I2400M_RT_WARM ? -ENODEV : -ENOSYS; + } else + BUG(); + if (result < 0 && rt != I2400M_RT_BUS) { + dev_err(dev, "%s reset failed (%d); trying SDIO reset\n", + rt == I2400M_RT_WARM ? "warm" : "cold", result); + rt = I2400M_RT_BUS; + goto do_bus_reset; + } + return result; +} + + +static +void i2400ms_netdev_setup(struct net_device *net_dev) +{ + struct i2400m *i2400m = net_dev_to_i2400m(net_dev); + struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); + i2400ms_init(i2400ms); + i2400m_netdev_setup(net_dev); +} + + +/* + * Debug levels control; see debug.h + */ +struct d_level D_LEVEL[] = { + D_SUBMODULE_DEFINE(main), + D_SUBMODULE_DEFINE(tx), + D_SUBMODULE_DEFINE(rx), + D_SUBMODULE_DEFINE(fw), +}; +size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); + + +#define __debugfs_register(prefix, name, parent) \ +do { \ + result = d_level_register_debugfs(prefix, name, parent); \ + if (result < 0) \ + goto error; \ +} while (0) + + +static +int i2400ms_debugfs_add(struct i2400ms *i2400ms) +{ + int result; + struct dentry *dentry = i2400ms->i2400m.wimax_dev.debugfs_dentry; + + dentry = debugfs_create_dir("i2400m-usb", dentry); + result = PTR_ERR(dentry); + if (IS_ERR(dentry)) { + if (result == -ENODEV) + result = 0; /* No debugfs support */ + goto error; + } + i2400ms->debugfs_dentry = dentry; + __debugfs_register("dl_", main, dentry); + __debugfs_register("dl_", tx, dentry); + __debugfs_register("dl_", rx, dentry); + __debugfs_register("dl_", fw, dentry); + + return 0; + +error: + debugfs_remove_recursive(i2400ms->debugfs_dentry); + return result; +} + + +/* + * Probe a i2400m interface and register it + * + * @func: SDIO function + * @id: SDIO device ID + * @returns: 0 if ok, < 0 errno code on error. + * + * Alloc a net device, initialize the bus-specific details and then + * calls the bus-generic initialization routine. That will register + * the wimax and netdev devices, upload the firmware [using + * _bus_bm_*()], call _bus_dev_start() to finalize the setup of the + * communication with the device and then will start to talk to it to + * finnish setting it up. + * + * Initialization is tricky; some instances of the hw are packed with + * others in a way that requires a third driver that enables the WiMAX + * function. In those cases, we can't enable the SDIO function and + * we'll return with -ENODEV. When the driver that enables the WiMAX + * function does its thing, it has to do a bus_rescan_devices() on the + * SDIO bus so this driver is called again to enumerate the WiMAX + * function. + */ +static +int i2400ms_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + int result; + struct net_device *net_dev; + struct device *dev = &func->dev; + struct i2400m *i2400m; + struct i2400ms *i2400ms; + + /* Allocate instance [calls i2400m_netdev_setup() on it]. */ + result = -ENOMEM; + net_dev = alloc_netdev(sizeof(*i2400ms), "wmx%d", + i2400ms_netdev_setup); + if (net_dev == NULL) { + dev_err(dev, "no memory for network device instance\n"); + goto error_alloc_netdev; + } + SET_NETDEV_DEV(net_dev, dev); + i2400m = net_dev_to_i2400m(net_dev); + i2400ms = container_of(i2400m, struct i2400ms, i2400m); + i2400m->wimax_dev.net_dev = net_dev; + i2400ms->func = func; + sdio_set_drvdata(func, i2400ms); + + i2400m->bus_tx_block_size = I2400MS_BLK_SIZE; + i2400m->bus_pl_size_max = I2400MS_PL_SIZE_MAX; + i2400m->bus_dev_start = i2400ms_bus_dev_start; + i2400m->bus_dev_stop = i2400ms_bus_dev_stop; + i2400m->bus_tx_kick = i2400ms_bus_tx_kick; + i2400m->bus_reset = i2400ms_bus_reset; + i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send; + i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack; + i2400m->bus_fw_name = I2400MS_FW_FILE_NAME; + i2400m->bus_bm_mac_addr_impaired = 1; + + result = i2400ms_enable_function(i2400ms->func); + if (result < 0) { + dev_err(dev, "Cannot enable SDIO function: %d\n", result); + goto error_func_enable; + } + + sdio_claim_host(func); + result = sdio_set_block_size(func, I2400MS_BLK_SIZE); + if (result < 0) { + dev_err(dev, "Failed to set block size: %d\n", result); + goto error_set_blk_size; + } + sdio_release_host(func); + + result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT); + if (result < 0) { + dev_err(dev, "cannot setup device: %d\n", result); + goto error_setup; + } + + result = i2400ms_debugfs_add(i2400ms); + if (result < 0) { + dev_err(dev, "cannot create SDIO debugfs: %d\n", + result); + goto error_debugfs_add; + } + return 0; + +error_debugfs_add: + i2400m_release(i2400m); +error_setup: + sdio_set_drvdata(func, NULL); + sdio_claim_host(func); +error_set_blk_size: + sdio_disable_func(func); + sdio_release_host(func); +error_func_enable: + free_netdev(net_dev); +error_alloc_netdev: + return result; +} + + +static +void i2400ms_remove(struct sdio_func *func) +{ + struct device *dev = &func->dev; + struct i2400ms *i2400ms = sdio_get_drvdata(func); + struct i2400m *i2400m = &i2400ms->i2400m; + struct net_device *net_dev = i2400m->wimax_dev.net_dev; + + d_fnstart(3, dev, "SDIO func %p\n", func); + debugfs_remove_recursive(i2400ms->debugfs_dentry); + i2400m_release(i2400m); + sdio_set_drvdata(func, NULL); + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + free_netdev(net_dev); + d_fnend(3, dev, "SDIO func %p\n", func); +} + +enum { + I2400MS_INTEL_VID = 0x89, +}; + +static +const struct sdio_device_id i2400ms_sdio_ids[] = { + /* Intel: i2400m WiMAX over SDIO */ + { SDIO_DEVICE(I2400MS_INTEL_VID, 0x1402) }, + { }, /* end: all zeroes */ +}; +MODULE_DEVICE_TABLE(sdio, i2400ms_sdio_ids); + + +static +struct sdio_driver i2400m_sdio_driver = { + .name = KBUILD_MODNAME, + .probe = i2400ms_probe, + .remove = i2400ms_remove, + .id_table = i2400ms_sdio_ids, +}; + + +static +int __init i2400ms_driver_init(void) +{ + return sdio_register_driver(&i2400m_sdio_driver); +} +module_init(i2400ms_driver_init); + + +static +void __exit i2400ms_driver_exit(void) +{ + flush_scheduled_work(); /* for the stuff we schedule */ + sdio_unregister_driver(&i2400m_sdio_driver); +} +module_exit(i2400ms_driver_exit); + + +MODULE_AUTHOR("Intel Corporation "); +MODULE_DESCRIPTION("Intel 2400M WiMAX networking for SDIO"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(I2400MS_FW_FILE_NAME); -- cgit From 020bb6f30b636d563d4268116107d592550ddd0c Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:56 -0800 Subject: i2400m/SDIO: firmware upload backend This implements the backends for the generic driver (i2400m) to be able to load firmware to the SDIO device. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/sdio-fw.c | 224 +++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 drivers/net/wimax/i2400m/sdio-fw.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/sdio-fw.c b/drivers/net/wimax/i2400m/sdio-fw.c new file mode 100644 index 00000000000..3487205d8f5 --- /dev/null +++ b/drivers/net/wimax/i2400m/sdio-fw.c @@ -0,0 +1,224 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * Firmware uploader's SDIO specifics + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Yanir Lubetkin + * Inaky Perez-Gonzalez + * - Initial implementation + * + * Inaky Perez-Gonzalez + * - Bus generic/specific split for USB + * + * Dirk Brandewie + * - Initial implementation for SDIO + * + * Inaky Perez-Gonzalez + * - SDIO rehash for changes in the bus-driver model + * + * THE PROCEDURE + * + * See fw.c for the generic description of this procedure. + * + * This file implements only the SDIO specifics. It boils down to how + * to send a command and waiting for an acknowledgement from the + * device. We do polled reads. + * + * COMMAND EXECUTION + * + * THe generic firmware upload code will call i2400m_bus_bm_cmd_send() + * to send commands. + * + * The SDIO devices expects things in 256 byte blocks, so it will pad + * it, compute the checksum (if needed) and pass it to SDIO. + * + * ACK RECEPTION + * + * This works in polling mode -- the fw loader says when to wait for + * data and for that it calls i2400ms_bus_bm_wait_for_ack(). + * + * This will poll the device for data until it is received. We need to + * receive at least as much bytes as where asked for (although it'll + * always be a multiple of 256 bytes). + */ +#include +#include "i2400m-sdio.h" + + +#define D_SUBMODULE fw +#include "sdio-debug-levels.h" + +/* + * Send a boot-mode command to the SDIO function + * + * We use a bounce buffer (i2400m->bm_cmd_buf) because we need to + * touch the header if the RAW flag is not set. + * + * @flags: pass thru from i2400m_bm_cmd() + * @return: cmd_size if ok, < 0 errno code on error. + * + * Note the command is padded to the SDIO block size for the device. + */ +ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m, + const struct i2400m_bootrom_header *_cmd, + size_t cmd_size, int flags) +{ + ssize_t result; + struct device *dev = i2400m_dev(i2400m); + struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); + int opcode = _cmd == NULL ? -1 : i2400m_brh_get_opcode(_cmd); + struct i2400m_bootrom_header *cmd; + /* SDIO restriction */ + size_t cmd_size_a = ALIGN(cmd_size, I2400MS_BLK_SIZE); + + d_fnstart(5, dev, "(i2400m %p cmd %p size %zu)\n", + i2400m, _cmd, cmd_size); + result = -E2BIG; + if (cmd_size > I2400M_BM_CMD_BUF_SIZE) + goto error_too_big; + + memcpy(i2400m->bm_cmd_buf, _cmd, cmd_size); /* Prep command */ + cmd = i2400m->bm_cmd_buf; + if (cmd_size_a > cmd_size) /* Zero pad space */ + memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size); + if ((flags & I2400M_BM_CMD_RAW) == 0) { + if (WARN_ON(i2400m_brh_get_response_required(cmd) == 0)) + dev_warn(dev, "SW BUG: response_required == 0\n"); + i2400m_bm_cmd_prepare(cmd); + } + d_printf(4, dev, "BM cmd %d: %zu bytes (%zu padded)\n", + opcode, cmd_size, cmd_size_a); + d_dump(5, dev, cmd, cmd_size); + + sdio_claim_host(i2400ms->func); /* Send & check */ + result = sdio_memcpy_toio(i2400ms->func, I2400MS_DATA_ADDR, + i2400m->bm_cmd_buf, cmd_size_a); + sdio_release_host(i2400ms->func); + if (result < 0) { + dev_err(dev, "BM cmd %d: cannot send: %ld\n", + opcode, (long) result); + goto error_cmd_send; + } + result = cmd_size; +error_cmd_send: +error_too_big: + d_fnend(5, dev, "(i2400m %p cmd %p size %zu) = %d\n", + i2400m, _cmd, cmd_size, (int) result); + return result; +} + + +/* + * Read an ack from the device's boot-mode (polling) + * + * @i2400m: + * @_ack: pointer to where to store the read data + * @ack_size: how many bytes we should read + * + * Returns: < 0 errno code on error; otherwise, amount of received bytes. + * + * The ACK for a BM command is always at least sizeof(*ack) bytes, so + * check for that. We don't need to check for device reboots + * + * NOTE: We do an artificial timeout of 1 sec over the SDIO timeout; + * this way we have control over it...there is no way that I know + * of setting an SDIO transaction timeout. + */ +ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m, + struct i2400m_bootrom_header *ack, + size_t ack_size) +{ + int result; + ssize_t rx_size; + u64 timeout; + struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + + BUG_ON(sizeof(*ack) > ack_size); + + d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n", + i2400m, ack, ack_size); + + timeout = get_jiffies_64() + 2 * HZ; + sdio_claim_host(func); + while (1) { + if (time_after64(get_jiffies_64(), timeout)) { + rx_size = -ETIMEDOUT; + dev_err(dev, "timeout waiting for ack data\n"); + goto error_timedout; + } + + /* Find the RX size, check if it fits or not -- it if + * doesn't fit, fail, as we have no way to dispose of + * the extra data. */ + rx_size = __i2400ms_rx_get_size(i2400ms); + if (rx_size < 0) + goto error_rx_get_size; + result = -ENOSPC; /* Check it fits */ + if (rx_size < sizeof(*ack)) { + rx_size = -EIO; + dev_err(dev, "HW BUG? received is too small (%zu vs " + "%zu needed)\n", sizeof(*ack), rx_size); + goto error_too_small; + } + if (rx_size > I2400M_BM_ACK_BUF_SIZE) { + dev_err(dev, "SW BUG? BM_ACK_BUF is too small (%u vs " + "%zu needed)\n", I2400M_BM_ACK_BUF_SIZE, + rx_size); + goto error_too_small; + } + + /* Read it */ + result = sdio_memcpy_fromio(func, i2400m->bm_ack_buf, + I2400MS_DATA_ADDR, rx_size); + if (result == -ETIMEDOUT || result == -ETIME) + continue; + if (result < 0) { + dev_err(dev, "BM SDIO receive (%zu B) failed: %d\n", + rx_size, result); + goto error_read; + } else + break; + } + rx_size = min((ssize_t)ack_size, rx_size); + memcpy(ack, i2400m->bm_ack_buf, rx_size); +error_read: +error_too_small: +error_rx_get_size: +error_timedout: + sdio_release_host(func); + d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %ld\n", + i2400m, ack, ack_size, (long) rx_size); + return rx_size; +} -- cgit From 514ec71f7289c942f801bdbd309428c470bfc071 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Sat, 20 Dec 2008 16:57:57 -0800 Subject: i2400m/SDIO: TX and RX path backends Implements the backend so that the generic driver can TX/RX to/from the SDIO device. For RX, when data is ready the SDIO IRQ is fired and that will allocate an skb, put all the data there and then pass it to the generic driver RX code for processing and delivery. TX, when kicked by the generic driver, will schedule work on a driver-specific workqueue that pulls data from the TX FIFO and sends it to the device until it drains it. Thread contexts are needed as SDIO functions are blocking. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/wimax/i2400m/sdio-rx.c | 255 +++++++++++++++++++++++++++++++++++++ drivers/net/wimax/i2400m/sdio-tx.c | 153 ++++++++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 drivers/net/wimax/i2400m/sdio-rx.c create mode 100644 drivers/net/wimax/i2400m/sdio-tx.c (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c new file mode 100644 index 00000000000..a3008b904f7 --- /dev/null +++ b/drivers/net/wimax/i2400m/sdio-rx.c @@ -0,0 +1,255 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * SDIO RX handling + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Dirk Brandewie + * - Initial implementation + * + * + * This handles the RX path on SDIO. + * + * The SDIO bus driver calls the "irq" routine when data is available. + * This is not a traditional interrupt routine since the SDIO bus + * driver calls us from its irq thread context. Because of this + * sleeping in the SDIO RX IRQ routine is okay. + * + * From there on, we obtain the size of the data that is available, + * allocate an skb, copy it and then pass it to the generic driver's + * RX routine [i2400m_rx()]. + * + * ROADMAP + * + * i2400ms_irq() + * i2400ms_rx() + * __i2400ms_rx_get_size() + * i2400m_rx() + * + * i2400ms_rx_setup() + * + * i2400ms_rx_release() + */ +#include +#include +#include +#include +#include +#include "i2400m-sdio.h" + +#define D_SUBMODULE rx +#include "sdio-debug-levels.h" + + +/* + * Read and return the amount of bytes available for RX + * + * The RX size has to be read like this: byte reads of three + * sequential locations; then glue'em together. + * + * sdio_readl() doesn't work. + */ +ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms) +{ + int ret, cnt, val; + ssize_t rx_size; + unsigned xfer_size_addr; + struct sdio_func *func = i2400ms->func; + struct device *dev = &i2400ms->func->dev; + + d_fnstart(7, dev, "(i2400ms %p)\n", i2400ms); + xfer_size_addr = I2400MS_INTR_GET_SIZE_ADDR; + rx_size = 0; + for (cnt = 0; cnt < 3; cnt++) { + val = sdio_readb(func, xfer_size_addr + cnt, &ret); + if (ret < 0) { + dev_err(dev, "RX: Can't read byte %d of RX size from " + "0x%08x: %d\n", cnt, xfer_size_addr + cnt, ret); + rx_size = ret; + goto error_read; + } + rx_size = rx_size << 8 | (val & 0xff); + } + d_printf(6, dev, "RX: rx_size is %ld\n", (long) rx_size); +error_read: + d_fnend(7, dev, "(i2400ms %p) = %ld\n", i2400ms, (long) rx_size); + return rx_size; +} + + +/* + * Read data from the device (when in normal) + * + * Allocate an SKB of the right size, read the data in and then + * deliver it to the generic layer. + * + * We also check for a reboot barker. That means the device died and + * we have to reboot it. + */ +static +void i2400ms_rx(struct i2400ms *i2400ms) +{ + int ret; + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + struct i2400m *i2400m = &i2400ms->i2400m; + struct sk_buff *skb; + ssize_t rx_size; + + d_fnstart(7, dev, "(i2400ms %p)\n", i2400ms); + rx_size = __i2400ms_rx_get_size(i2400ms); + if (rx_size < 0) { + ret = rx_size; + goto error_get_size; + } + ret = -ENOMEM; + skb = alloc_skb(rx_size, GFP_ATOMIC); + if (NULL == skb) { + dev_err(dev, "RX: unable to alloc skb\n"); + goto error_alloc_skb; + } + + ret = sdio_memcpy_fromio(func, skb->data, + I2400MS_DATA_ADDR, rx_size); + if (ret < 0) { + dev_err(dev, "RX: SDIO data read failed: %d\n", ret); + goto error_memcpy_fromio; + } + /* Check if device has reset */ + if (!memcmp(skb->data, i2400m_NBOOT_BARKER, + sizeof(i2400m_NBOOT_BARKER)) + || !memcmp(skb->data, i2400m_SBOOT_BARKER, + sizeof(i2400m_SBOOT_BARKER))) { + ret = i2400m_dev_reset_handle(i2400m); + kfree_skb(skb); + } else { + skb_put(skb, rx_size); + i2400m_rx(i2400m, skb); + } + d_fnend(7, dev, "(i2400ms %p) = void\n", i2400ms); + return; + +error_memcpy_fromio: + kfree_skb(skb); +error_alloc_skb: +error_get_size: + d_fnend(7, dev, "(i2400ms %p) = %d\n", i2400ms, ret); + return; +} + + +/* + * Process an interrupt from the SDIO card + * + * FIXME: need to process other events that are not just ready-to-read + * + * Checks there is data ready and then proceeds to read it. + */ +static +void i2400ms_irq(struct sdio_func *func) +{ + int ret; + struct i2400ms *i2400ms = sdio_get_drvdata(func); + struct i2400m *i2400m = &i2400ms->i2400m; + struct device *dev = &func->dev; + int val; + + d_fnstart(6, dev, "(i2400ms %p)\n", i2400ms); + val = sdio_readb(func, I2400MS_INTR_STATUS_ADDR, &ret); + if (ret < 0) { + dev_err(dev, "RX: Can't read interrupt status: %d\n", ret); + goto error_no_irq; + } + if (!val) { + dev_err(dev, "RX: BUG? got IRQ but no interrupt ready?\n"); + goto error_no_irq; + } + sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret); + if (WARN_ON(i2400m->boot_mode != 0)) + dev_err(dev, "RX: SW BUG? boot mode and IRQ is up?\n"); + else + i2400ms_rx(i2400ms); +error_no_irq: + d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms); + return; +} + + +/* + * Setup SDIO RX + * + * Hooks up the IRQ handler and then enables IRQs. + */ +int i2400ms_rx_setup(struct i2400ms *i2400ms) +{ + int result; + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + + d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); + sdio_claim_host(func); + result = sdio_claim_irq(func, i2400ms_irq); + if (result < 0) { + dev_err(dev, "Cannot claim IRQ: %d\n", result); + goto error_irq_claim; + } + result = 0; + sdio_writeb(func, 1, I2400MS_INTR_ENABLE_ADDR, &result); + if (result < 0) { + sdio_release_irq(func); + dev_err(dev, "Failed to enable interrupts %d\n", result); + } +error_irq_claim: + sdio_release_host(func); + d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result); + return result; +} + + +/* + * Tear down SDIO RX + * + * Disables IRQs in the device and removes the IRQ handler. + */ +void i2400ms_rx_release(struct i2400ms *i2400ms) +{ + int result; + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + + d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); + sdio_claim_host(func); + sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result); + sdio_release_irq(func); + sdio_release_host(func); + d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result); +} diff --git a/drivers/net/wimax/i2400m/sdio-tx.c b/drivers/net/wimax/i2400m/sdio-tx.c new file mode 100644 index 00000000000..5105a5ebc44 --- /dev/null +++ b/drivers/net/wimax/i2400m/sdio-tx.c @@ -0,0 +1,153 @@ +/* + * Intel Wireless WiMAX Connection 2400m + * SDIO TX transaction backends + * + * + * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Intel Corporation + * Dirk Brandewie + * - Initial implementation + * + * + * Takes the TX messages in the i2400m's driver TX FIFO and sends them + * to the device until there are no more. + * + * If we fail sending the message, we just drop it. There isn't much + * we can do at this point. Most of the traffic is network, which has + * recovery methods for dropped packets. + * + * The SDIO functions are not atomic, so we can't run from the context + * where i2400m->bus_tx_kick() [i2400ms_bus_tx_kick()] is being called + * (some times atomic). Thus, the actual TX work is deferred to a + * workqueue. + * + * ROADMAP + * + * i2400ms_bus_tx_kick() + * i2400ms_tx_submit() [through workqueue] + * + * i2400m_tx_setup() + * + * i2400m_tx_release() + */ +#include +#include "i2400m-sdio.h" + +#define D_SUBMODULE tx +#include "sdio-debug-levels.h" + + +/* + * Pull TX transations from the TX FIFO and send them to the device + * until there are no more. + */ +static +void i2400ms_tx_submit(struct work_struct *ws) +{ + int result; + struct i2400ms *i2400ms = container_of(ws, struct i2400ms, tx_worker); + struct i2400m *i2400m = &i2400ms->i2400m; + struct sdio_func *func = i2400ms->func; + struct device *dev = &func->dev; + struct i2400m_msg_hdr *tx_msg; + size_t tx_msg_size; + + d_fnstart(4, dev, "(i2400ms %p, i2400m %p)\n", i2400ms, i2400ms); + + while (NULL != (tx_msg = i2400m_tx_msg_get(i2400m, &tx_msg_size))) { + d_printf(2, dev, "TX: submitting %zu bytes\n", tx_msg_size); + d_dump(5, dev, tx_msg, tx_msg_size); + + sdio_claim_host(func); + result = sdio_memcpy_toio(func, 0, tx_msg, tx_msg_size); + sdio_release_host(func); + + i2400m_tx_msg_sent(i2400m); + + if (result < 0) { + dev_err(dev, "TX: cannot submit TX; tx_msg @%zu %zu B:" + " %d\n", (void *) tx_msg - i2400m->tx_buf, + tx_msg_size, result); + } + + d_printf(2, dev, "TX: %zub submitted\n", tx_msg_size); + } + + d_fnend(4, dev, "(i2400ms %p) = void\n", i2400ms); +} + + +/* + * The generic driver notifies us that there is data ready for TX + * + * Schedule a run of i2400ms_tx_submit() to handle it. + */ +void i2400ms_bus_tx_kick(struct i2400m *i2400m) +{ + struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); + struct device *dev = &i2400ms->func->dev; + + d_fnstart(3, dev, "(i2400m %p) = void\n", i2400m); + + /* schedule tx work, this is because tx may block, therefore + * it has to run in a thread context. + */ + queue_work(i2400ms->tx_workqueue, &i2400ms->tx_worker); + + d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); +} + +int i2400ms_tx_setup(struct i2400ms *i2400ms) +{ + int result; + struct device *dev = &i2400ms->func->dev; + struct i2400m *i2400m = &i2400ms->i2400m; + + d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); + + INIT_WORK(&i2400ms->tx_worker, i2400ms_tx_submit); + snprintf(i2400ms->tx_wq_name, sizeof(i2400ms->tx_wq_name), + "%s-tx", i2400m->wimax_dev.name); + i2400ms->tx_workqueue = + create_singlethread_workqueue(i2400ms->tx_wq_name); + if (NULL == i2400ms->tx_workqueue) { + dev_err(dev, "TX: failed to create workqueue\n"); + result = -ENOMEM; + } else + result = 0; + d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result); + return result; +} + +void i2400ms_tx_release(struct i2400ms *i2400ms) +{ + destroy_workqueue(i2400ms->tx_workqueue); +} -- cgit From 143ee2d5557c0598a97f3089eb29e8226e0e8cee Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Tue, 23 Dec 2008 16:18:48 -0800 Subject: i2400m: Makefile and Kconfig Integrate the i2400m driver into the kernel's build and Kconfig. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/net/Kconfig | 2 ++ drivers/net/Makefile | 1 + drivers/net/wimax/Kconfig | 17 ++++++++++++++ drivers/net/wimax/Makefile | 5 ++++ drivers/net/wimax/i2400m/Kconfig | 49 +++++++++++++++++++++++++++++++++++++++ drivers/net/wimax/i2400m/Makefile | 29 +++++++++++++++++++++++ 6 files changed, 103 insertions(+) create mode 100644 drivers/net/wimax/Kconfig create mode 100644 drivers/net/wimax/Makefile create mode 100644 drivers/net/wimax/i2400m/Kconfig create mode 100644 drivers/net/wimax/i2400m/Makefile (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9a18270c108..97ea7c60e00 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2614,6 +2614,8 @@ source "drivers/net/tokenring/Kconfig" source "drivers/net/wireless/Kconfig" +source "drivers/net/wimax/Kconfig" + source "drivers/net/usb/Kconfig" source "drivers/net/pcmcia/Kconfig" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e5c34b46421..a3c5c002f22 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -263,3 +263,4 @@ obj-$(CONFIG_NIU) += niu.o obj-$(CONFIG_VIRTIO_NET) += virtio_net.o obj-$(CONFIG_SFC) += sfc/ +obj-$(CONFIG_WIMAX) += wimax/ diff --git a/drivers/net/wimax/Kconfig b/drivers/net/wimax/Kconfig new file mode 100644 index 00000000000..565018ec1e3 --- /dev/null +++ b/drivers/net/wimax/Kconfig @@ -0,0 +1,17 @@ +# +# WiMAX LAN device drivers configuration +# + + +comment "Enable WiMAX (Networking options) to see the WiMAX drivers" + depends on WIMAX = n + +if WIMAX + +menu "WiMAX Wireless Broadband devices" + +source "drivers/net/wimax/i2400m/Kconfig" + +endmenu + +endif diff --git a/drivers/net/wimax/Makefile b/drivers/net/wimax/Makefile new file mode 100644 index 00000000000..992bc02bc01 --- /dev/null +++ b/drivers/net/wimax/Makefile @@ -0,0 +1,5 @@ + +obj-$(CONFIG_WIMAX_I2400M) += i2400m/ + +# (from Sam Ravnborg) force kbuild to create built-in.o +obj- := dummy.o diff --git a/drivers/net/wimax/i2400m/Kconfig b/drivers/net/wimax/i2400m/Kconfig new file mode 100644 index 00000000000..d623b3d99a4 --- /dev/null +++ b/drivers/net/wimax/i2400m/Kconfig @@ -0,0 +1,49 @@ + +config WIMAX_I2400M + tristate + depends on WIMAX + select FW_LOADER + +comment "Enable USB support to see WiMAX USB drivers" + depends on USB = n + +comment "Enable MMC support to see WiMAX SDIO drivers" + depends on MMC = n + +config WIMAX_I2400M_USB + tristate "Intel Wireless WiMAX Connection 2400 over USB (including 5x50)" + depends on WIMAX && USB + select WIMAX_I2400M + help + Select if you have a device based on the Intel WiMAX + Connection 2400 over USB (like any of the Intel Wireless + WiMAX/WiFi Link 5x50 series). + + If unsure, it is safe to select M (module). + +config WIMAX_I2400M_SDIO + tristate "Intel Wireless WiMAX Connection 2400 over SDIO" + depends on WIMAX && MMC + select WIMAX_I2400M + help + Select if you have a device based on the Intel WiMAX + Connection 2400 over SDIO. + + If unsure, it is safe to select M (module). + +config WIMAX_I2400M_DEBUG_LEVEL + int "WiMAX i2400m debug level" + depends on WIMAX_I2400M + default 8 + help + + Select the maximum debug verbosity level to be compiled into + the WiMAX i2400m driver code. + + By default, this is disabled at runtime and can be + selectively enabled at runtime for different parts of the + code using the sysfs debug-levels file. + + If set at zero, this will compile out all the debug code. + + It is recommended that it is left at 8. diff --git a/drivers/net/wimax/i2400m/Makefile b/drivers/net/wimax/i2400m/Makefile new file mode 100644 index 00000000000..1696e936cf5 --- /dev/null +++ b/drivers/net/wimax/i2400m/Makefile @@ -0,0 +1,29 @@ + +obj-$(CONFIG_WIMAX_I2400M) += i2400m.o +obj-$(CONFIG_WIMAX_I2400M_USB) += i2400m-usb.o +obj-$(CONFIG_WIMAX_I2400M_SDIO) += i2400m-sdio.o + +i2400m-y := \ + control.o \ + driver.o \ + fw.o \ + op-rfkill.o \ + netdev.o \ + tx.o \ + rx.o + +i2400m-$(CONFIG_DEBUG_FS) += debugfs.o + +i2400m-usb-y := \ + usb-fw.o \ + usb-notif.o \ + usb-tx.o \ + usb-rx.o \ + usb.o + + +i2400m-sdio-y := \ + sdio.o \ + sdio-tx.o \ + sdio-fw.o \ + sdio-rx.o -- cgit From e8de1481fd7126ee9e93d6889da6f00c05e1e019 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 22 Oct 2008 19:55:31 -0700 Subject: resource: allow MMIO exclusivity for device drivers Device drivers that use pci_request_regions() (and similar APIs) have a reasonable expectation that they are the only ones accessing their device. As part of the e1000e hunt, we were afraid that some userland (X or some bootsplash stuff) was mapping the MMIO region that the driver thought it had exclusively via /dev/mem or via various sysfs resource mappings. This patch adds the option for device drivers to cause their reserved regions to the "banned from /dev/mem use" list, so now both kernel memory and device-exclusive MMIO regions are banned. NOTE: This is only active when CONFIG_STRICT_DEVMEM is set. In addition to the config option, a kernel parameter iomem=relaxed is provided for the cases where developers want to diagnose, in the field, drivers issues from userspace. Reviewed-by: Matthew Wilcox Signed-off-by: Arjan van de Ven Signed-off-by: Jesse Barnes --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index d4639facd1b..91817d0afca 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4807,7 +4807,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } } - err = pci_request_selected_regions(pdev, + err = pci_request_selected_regions_exclusive(pdev, pci_select_bars(pdev, IORESOURCE_MEM), e1000e_driver_name); if (err) -- cgit From ef1bba28bfe68ef3c0488feeaabd3e8bc523130c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 23 Dec 2008 03:09:53 +0000 Subject: net: sfc: Use pci_clear_master() to disable bus mastering pci_disable_device() disables many features, like MSI-X, which we never reenable in efx_reset(). Further, calls to pci_enable_device() and pci_disable_device() must be matched since the nesting count was introduced, so switch to using pci_clear_master() instead. Signed-off-by: Ben Hutchings Signed-off-by: Jesse Barnes --- drivers/net/sfc/falcon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 6884dc8c1f8..5b9f2d9cc4e 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1403,9 +1403,9 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) } /* Disable both devices */ - pci_disable_device(efx->pci_dev); + pci_clear_master(efx->pci_dev); if (FALCON_IS_DUAL_FUNC(efx)) - pci_disable_device(nic_data->pci_dev2); + pci_clear_master(nic_data->pci_dev2); falcon_disable_interrupts(efx); if (++n_int_errors < FALCON_MAX_INT_ERRORS) { -- cgit From 9ac32e1bc0518b01b47dd34a733dce8634a38ed3 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 12:59:17 -0800 Subject: firmware: convert e100 driver to request_firmware() Thanks to David Woodhouse for help. Signed-off-by: Jaswinder Singh Rajput Signed-off-by: David S. Miller --- drivers/net/e100.c | 299 +++++++++++++++++------------------------------------ 1 file changed, 97 insertions(+), 202 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 134b2d60b47..86bb876fb12 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -161,6 +161,7 @@ #include #include #include +#include #include @@ -174,10 +175,17 @@ #define E100_WATCHDOG_PERIOD (2 * HZ) #define E100_NAPI_WEIGHT 16 +#define FIRMWARE_D101M "e100/d101m_ucode.bin" +#define FIRMWARE_D101S "e100/d101s_ucode.bin" +#define FIRMWARE_D102E "e100/d102e_ucode.bin" + MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +MODULE_FIRMWARE(FIRMWARE_D101M); +MODULE_FIRMWARE(FIRMWARE_D101S); +MODULE_FIRMWARE(FIRMWARE_D102E); static int debug = 3; static int eeprom_bad_csum_allow = 0; @@ -1049,178 +1057,6 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); } -/********************************************************/ -/* Micro code for 8086:1229 Rev 8 */ -/********************************************************/ - -/* Parameter values for the D101M B-step */ -#define D101M_CPUSAVER_TIMER_DWORD 78 -#define D101M_CPUSAVER_BUNDLE_DWORD 65 -#define D101M_CPUSAVER_MIN_SIZE_DWORD 126 - -#define D101M_B_RCVBUNDLE_UCODE \ -{\ -0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \ -0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \ -0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \ -0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \ -0x00380438, 0x00000000, 0x00140000, 0x00380555, \ -0x00308000, 0x00100662, 0x00100561, 0x000E0408, \ -0x00134861, 0x000C0002, 0x00103093, 0x00308000, \ -0x00100624, 0x00100561, 0x000E0408, 0x00100861, \ -0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \ -0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \ -0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \ -0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \ -0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \ -0x00041000, 0x00010004, 0x00130826, 0x000C0006, \ -0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00080600, 0x00101B10, 0x00050004, 0x00100826, \ -0x00101210, 0x00380C34, 0x00000000, 0x00000000, \ -0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \ -0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \ -0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \ -0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \ -0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \ -0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \ -0x00130826, 0x000C0001, 0x00220559, 0x00101313, \ -0x00380559, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00130831, 0x0010090B, 0x00124813, \ -0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \ -0x003806A8, 0x00000000, 0x00000000, 0x00000000, \ -} - -/********************************************************/ -/* Micro code for 8086:1229 Rev 9 */ -/********************************************************/ - -/* Parameter values for the D101S */ -#define D101S_CPUSAVER_TIMER_DWORD 78 -#define D101S_CPUSAVER_BUNDLE_DWORD 67 -#define D101S_CPUSAVER_MIN_SIZE_DWORD 128 - -#define D101S_RCVBUNDLE_UCODE \ -{\ -0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \ -0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \ -0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \ -0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \ -0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \ -0x00308000, 0x00100610, 0x00100561, 0x000E0408, \ -0x00134861, 0x000C0002, 0x00103093, 0x00308000, \ -0x00100624, 0x00100561, 0x000E0408, 0x00100861, \ -0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \ -0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \ -0x003A047E, 0x00044010, 0x00380819, 0x00000000, \ -0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \ -0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \ -0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \ -0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \ -0x00101313, 0x00380700, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00080600, 0x00101B10, 0x00050004, 0x00100826, \ -0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \ -0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \ -0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \ -0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \ -0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \ -0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \ -0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \ -0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \ -0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00130831, \ -0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \ -0x00041000, 0x00010004, 0x00380700 \ -} - -/********************************************************/ -/* Micro code for the 8086:1229 Rev F/10 */ -/********************************************************/ - -/* Parameter values for the D102 E-step */ -#define D102_E_CPUSAVER_TIMER_DWORD 42 -#define D102_E_CPUSAVER_BUNDLE_DWORD 54 -#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46 - -#define D102_E_RCVBUNDLE_UCODE \ -{\ -0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \ -0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \ -0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \ -0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \ -0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \ -0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \ -0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \ -0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \ -0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -0x00000000, 0x00000000, 0x00000000, 0x00000000, \ -} - -static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) -{ -/* *INDENT-OFF* */ - static struct { - u32 ucode[UCODE_SIZE + 1]; - u8 mac; - u8 timer_dword; - u8 bundle_dword; - u8 min_size_dword; - } ucode_opts[] = { - { D101M_B_RCVBUNDLE_UCODE, - mac_82559_D101M, - D101M_CPUSAVER_TIMER_DWORD, - D101M_CPUSAVER_BUNDLE_DWORD, - D101M_CPUSAVER_MIN_SIZE_DWORD }, - { D101S_RCVBUNDLE_UCODE, - mac_82559_D101S, - D101S_CPUSAVER_TIMER_DWORD, - D101S_CPUSAVER_BUNDLE_DWORD, - D101S_CPUSAVER_MIN_SIZE_DWORD }, - { D102_E_RCVBUNDLE_UCODE, - mac_82551_F, - D102_E_CPUSAVER_TIMER_DWORD, - D102_E_CPUSAVER_BUNDLE_DWORD, - D102_E_CPUSAVER_MIN_SIZE_DWORD }, - { D102_E_RCVBUNDLE_UCODE, - mac_82551_10, - D102_E_CPUSAVER_TIMER_DWORD, - D102_E_CPUSAVER_BUNDLE_DWORD, - D102_E_CPUSAVER_MIN_SIZE_DWORD }, - { {0}, 0, 0, 0, 0} - }, *opts; -/* *INDENT-ON* */ - /************************************************************************* * CPUSaver parameters * @@ -1280,42 +1116,101 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb #define BUNDLEMAX (u16)6 #define INTDELAY (u16)1536 /* 0x600 */ +/* Initialize firmware */ +static const struct firmware *e100_request_firmware(struct nic *nic) +{ + const char *fw_name; + const struct firmware *fw; + u8 timer, bundle, min_size; + int err; + /* do not load u-code for ICH devices */ if (nic->flags & ich) - goto noloaducode; + return NULL; /* Search for ucode match against h/w revision */ - for (opts = ucode_opts; opts->mac; opts++) { - int i; - u32 *ucode = opts->ucode; - if (nic->mac != opts->mac) - continue; - - /* Insert user-tunable settings */ - ucode[opts->timer_dword] &= 0xFFFF0000; - ucode[opts->timer_dword] |= INTDELAY; - ucode[opts->bundle_dword] &= 0xFFFF0000; - ucode[opts->bundle_dword] |= BUNDLEMAX; - ucode[opts->min_size_dword] &= 0xFFFF0000; - ucode[opts->min_size_dword] |= (BUNDLESMALL) ? 0xFFFF : 0xFF80; - - for (i = 0; i < UCODE_SIZE; i++) - cb->u.ucode[i] = cpu_to_le32(ucode[i]); - cb->command = cpu_to_le16(cb_ucode | cb_el); - return; - } - -noloaducode: - cb->command = cpu_to_le16(cb_nop | cb_el); -} - -static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb, - void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)) -{ + if (nic->mac == mac_82559_D101M) + fw_name = FIRMWARE_D101M; + else if (nic->mac == mac_82559_D101S) + fw_name = FIRMWARE_D101S; + else if (nic->mac == mac_82551_F || nic->mac == mac_82551_10) + fw_name = FIRMWARE_D102E; + else /* No ucode on other devices */ + return NULL; + + err = request_firmware(&fw, fw_name, &nic->pdev->dev); + if (err) { + DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n", + fw_name, err); + return ERR_PTR(err); + } + /* Firmware should be precisely UCODE_SIZE (words) plus three bytes + indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */ + if (fw->size != UCODE_SIZE * 4 + 3) { + DPRINTK(PROBE, ERR, "Firmware \"%s\" has wrong size %zu\n", + fw_name, fw->size); + release_firmware(fw); + return ERR_PTR(-EINVAL); + } + + /* Read timer, bundle and min_size from end of firmware blob */ + timer = fw->data[UCODE_SIZE * 4]; + bundle = fw->data[UCODE_SIZE * 4 + 1]; + min_size = fw->data[UCODE_SIZE * 4 + 2]; + + if (timer >= UCODE_SIZE || bundle >= UCODE_SIZE || + min_size >= UCODE_SIZE) { + DPRINTK(PROBE, ERR, + "\"%s\" has bogus offset values (0x%x,0x%x,0x%x)\n", + fw_name, timer, bundle, min_size); + release_firmware(fw); + return ERR_PTR(-EINVAL); + } + /* OK, firmware is validated and ready to use... */ + return fw; +} + +static void e100_setup_ucode(struct nic *nic, struct cb *cb, + struct sk_buff *skb) +{ + const struct firmware *fw = (void *)skb; + u8 timer, bundle, min_size; + + /* It's not a real skb; we just abused the fact that e100_exec_cb + will pass it through to here... */ + cb->skb = NULL; + + /* firmware is stored as little endian already */ + memcpy(cb->u.ucode, fw->data, UCODE_SIZE * 4); + + /* Read timer, bundle and min_size from end of firmware blob */ + timer = fw->data[UCODE_SIZE * 4]; + bundle = fw->data[UCODE_SIZE * 4 + 1]; + min_size = fw->data[UCODE_SIZE * 4 + 2]; + + /* Insert user-tunable settings in cb->u.ucode */ + cb->u.ucode[timer] &= cpu_to_le32(0xFFFF0000); + cb->u.ucode[timer] |= cpu_to_le32(INTDELAY); + cb->u.ucode[bundle] &= cpu_to_le32(0xFFFF0000); + cb->u.ucode[bundle] |= cpu_to_le32(BUNDLEMAX); + cb->u.ucode[min_size] &= cpu_to_le32(0xFFFF0000); + cb->u.ucode[min_size] |= cpu_to_le32((BUNDLESMALL) ? 0xFFFF : 0xFF80); + + cb->command = cpu_to_le16(cb_ucode | cb_el); +} + +static inline int e100_load_ucode_wait(struct nic *nic) +{ + const struct firmware *fw; int err = 0, counter = 50; struct cb *cb = nic->cb_to_clean; - if ((err = e100_exec_cb(nic, NULL, e100_setup_ucode))) + fw = e100_request_firmware(nic); + /* If it's NULL, then no ucode is required */ + if (!fw || IS_ERR(fw)) + return PTR_ERR(fw); + + if ((err = e100_exec_cb(nic, (void *)fw, e100_setup_ucode))) DPRINTK(PROBE,ERR, "ucode cmd failed with error %d\n", err); /* must restart cuc */ @@ -1435,7 +1330,7 @@ static int e100_hw_init(struct nic *nic) return err; if ((err = e100_exec_cmd(nic, ruc_load_base, 0))) return err; - if ((err = e100_exec_cb_wait(nic, NULL, e100_setup_ucode))) + if ((err = e100_load_ucode_wait(nic))) return err; if ((err = e100_exec_cb(nic, NULL, e100_configure))) return err; -- cgit From 43a67304a3e882ec297e08159f8698be59a235fe Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:22:19 -0800 Subject: appletalk: convert ipddp to net_device_ops Use internal element in network device for stats as well. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/appletalk/ipddp.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index 9a0be9b2eaa..da64ba88d7f 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -48,12 +48,18 @@ static int ipddp_mode = IPDDP_DECAP; /* Index to functions, as function prototypes. */ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *ipddp_get_stats(struct net_device *dev); static int ipddp_create(struct ipddp_route *new_rt); static int ipddp_delete(struct ipddp_route *rt); static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt); static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static const struct net_device_ops ipddp_netdev_ops = { + .ndo_start_xmit = ipddp_xmit, + .ndo_do_ioctl = ipddp_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; static struct net_device * __init ipddp_init(void) { @@ -61,7 +67,7 @@ static struct net_device * __init ipddp_init(void) struct net_device *dev; int err; - dev = alloc_etherdev(sizeof(struct net_device_stats)); + dev = alloc_etherdev(0); if (!dev) return ERR_PTR(-ENOMEM); @@ -71,9 +77,7 @@ static struct net_device * __init ipddp_init(void) printk(version); /* Initalize the device structure. */ - dev->hard_start_xmit = ipddp_xmit; - dev->get_stats = ipddp_get_stats; - dev->do_ioctl = ipddp_ioctl; + dev->netdev_ops = &ipddp_netdev_ops; dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ dev->mtu = 585; @@ -103,13 +107,6 @@ static struct net_device * __init ipddp_init(void) return dev; } -/* - * Get the current statistics. This may be called with the card open or closed. - */ -static struct net_device_stats *ipddp_get_stats(struct net_device *dev) -{ - return netdev_priv(dev); -} /* * Transmit LLAP/ELAP frame using aarp_send_ddp. @@ -170,8 +167,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ - ((struct net_device_stats *) netdev_priv(dev))->tx_packets++; - ((struct net_device_stats *) netdev_priv(dev))->tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0) dev_kfree_skb(skb); -- cgit From 83d6f0352cc47b41d42cc1d6fb31bc8d9753b772 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:25:41 -0800 Subject: cassini: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/cassini.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 321f43d9f0e..840b3d1a22f 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -4977,6 +4977,22 @@ static void __devinit cas_program_bridge(struct pci_dev *cas_pdev) pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xff); } +static const struct net_device_ops cas_netdev_ops = { + .ndo_open = cas_open, + .ndo_stop = cas_close, + .ndo_start_xmit = cas_start_xmit, + .ndo_get_stats = cas_get_stats, + .ndo_set_multicast_list = cas_set_multicast, + .ndo_do_ioctl = cas_ioctl, + .ndo_tx_timeout = cas_tx_timeout, + .ndo_change_mtu = cas_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = cas_netpoll, +#endif +}; + static int __devinit cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -5166,21 +5182,12 @@ static int __devinit cas_init_one(struct pci_dev *pdev, for (i = 0; i < N_RX_FLOWS; i++) skb_queue_head_init(&cp->rx_flows[i]); - dev->open = cas_open; - dev->stop = cas_close; - dev->hard_start_xmit = cas_start_xmit; - dev->get_stats = cas_get_stats; - dev->set_multicast_list = cas_set_multicast; - dev->do_ioctl = cas_ioctl; + dev->netdev_ops = &cas_netdev_ops; dev->ethtool_ops = &cas_ethtool_ops; - dev->tx_timeout = cas_tx_timeout; dev->watchdog_timeo = CAS_TX_TIMEOUT; - dev->change_mtu = cas_change_mtu; + #ifdef USE_NAPI netif_napi_add(dev, &cp->napi, cas_poll, 64); -#endif -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = cas_netpoll; #endif dev->irq = pdev->irq; dev->dma = 0; -- cgit From 04fb5f735e70a27f7dd06a5e349c003fd5d4bfa2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:26:14 -0800 Subject: ipg: update to net_device_ops Signed-off-by: Stephen Hemminger Acked-by: Pekka Enberg Signed-off-by: David S. Miller --- drivers/net/ipg.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 7b6d435a846..360aa5e35fd 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -2210,6 +2210,19 @@ static void __devexit ipg_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +static const struct net_device_ops ipg_netdev_ops = { + .ndo_open = ipg_nic_open, + .ndo_stop = ipg_nic_stop, + .ndo_start_xmit = ipg_nic_hard_start_xmit, + .ndo_get_stats = ipg_nic_get_stats, + .ndo_set_multicast_list = ipg_nic_set_multicast_list, + .ndo_do_ioctl = ipg_ioctl, + .ndo_tx_timeout = ipg_tx_timeout, + .ndo_change_mtu = ipg_nic_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit ipg_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -2258,15 +2271,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev, /* Declare IPG NIC functions for Ethernet device methods. */ - dev->open = &ipg_nic_open; - dev->stop = &ipg_nic_stop; - dev->hard_start_xmit = &ipg_nic_hard_start_xmit; - dev->get_stats = &ipg_nic_get_stats; - dev->set_multicast_list = &ipg_nic_set_multicast_list; - dev->do_ioctl = ipg_ioctl; - dev->tx_timeout = ipg_tx_timeout; - dev->change_mtu = &ipg_nic_change_mtu; - + dev->netdev_ops = &ipg_netdev_ops; SET_NETDEV_DEV(dev, &pdev->dev); SET_ETHTOOL_OPS(dev, &ipg_ethtool_ops); -- cgit From ed8cf436caccb7f464135b0a9eba0e7624299826 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:26:48 -0800 Subject: plip: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/plip.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 0c46d603b8f..0be0f0b164f 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -265,6 +265,13 @@ static const struct header_ops plip_header_ops = { .cache = plip_hard_header_cache, }; +static const struct net_device_ops plip_netdev_ops = { + .ndo_open = plip_open, + .ndo_stop = plip_close, + .ndo_start_xmit = plip_tx_packet, + .ndo_do_ioctl = plip_ioctl, +}; + /* Entry point of PLIP driver. Probe the hardware, and register/initialize the driver. @@ -280,15 +287,11 @@ plip_init_netdev(struct net_device *dev) struct net_local *nl = netdev_priv(dev); /* Then, override parts of it */ - dev->hard_start_xmit = plip_tx_packet; - dev->open = plip_open; - dev->stop = plip_close; - dev->do_ioctl = plip_ioctl; - dev->tx_queue_len = 10; dev->flags = IFF_POINTOPOINT|IFF_NOARP; memset(dev->dev_addr, 0xfc, ETH_ALEN); + dev->netdev_ops = &plip_netdev_ops; dev->header_ops = &plip_header_ops; -- cgit From 391c5e6e1822810900c33165442af8053a8ae054 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:27:15 -0800 Subject: tlan: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tlan.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 85ef8b74455..68b967b585a 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -831,6 +831,21 @@ static void TLan_Poll(struct net_device *dev) } #endif +static const struct net_device_ops TLan_netdev_ops = { + .ndo_open = TLan_Open, + .ndo_stop = TLan_Close, + .ndo_start_xmit = TLan_StartTx, + .ndo_tx_timeout = TLan_tx_timeout, + .ndo_get_stats = TLan_GetStats, + .ndo_set_multicast_list = TLan_SetMulticastList, + .ndo_do_ioctl = TLan_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = TLan_Poll, +#endif +}; @@ -892,16 +907,7 @@ static int TLan_Init( struct net_device *dev ) netif_carrier_off(dev); /* Device methods */ - dev->open = &TLan_Open; - dev->hard_start_xmit = &TLan_StartTx; - dev->stop = &TLan_Close; - dev->get_stats = &TLan_GetStats; - dev->set_multicast_list = &TLan_SetMulticastList; - dev->do_ioctl = &TLan_ioctl; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = &TLan_Poll; -#endif - dev->tx_timeout = &TLan_tx_timeout; + dev->netdev_ops = &TLan_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; return 0; -- cgit From 805524cbcf8d756ec1969b6e16b945103cd4c94e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:27:39 -0800 Subject: epic100: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/epic100.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index f9b37c80dda..a539bc3163c 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -308,7 +308,18 @@ static int epic_close(struct net_device *dev); static struct net_device_stats *epic_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); - +static const struct net_device_ops epic_netdev_ops = { + .ndo_open = epic_open, + .ndo_stop = epic_close, + .ndo_start_xmit = epic_start_xmit, + .ndo_tx_timeout = epic_tx_timeout, + .ndo_get_stats = epic_get_stats, + .ndo_set_multicast_list = set_rx_mode, + .ndo_do_ioctl = netdev_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; static int __devinit epic_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -483,15 +494,9 @@ static int __devinit epic_init_one (struct pci_dev *pdev, dev->if_port = ep->default_port = option; /* The Epic-specific entries in the device structure. */ - dev->open = &epic_open; - dev->hard_start_xmit = &epic_start_xmit; - dev->stop = &epic_close; - dev->get_stats = &epic_get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &netdev_ioctl; + dev->netdev_ops = &epic_netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT; - dev->tx_timeout = &epic_tx_timeout; netif_napi_add(dev, &ep->napi, epic_poll, 64); ret = register_netdev(dev); -- cgit From 2f89d12e98c9248ce967f4c6a86b06dbbcf013cd Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:28:35 -0800 Subject: sunhme: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sunhme.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index b22d3355fb4..7a72a3112f0 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2607,6 +2607,18 @@ static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev) } #endif /* CONFIG_PCI */ +static const struct net_device_ops hme_netdev_ops = { + .ndo_open = happy_meal_open, + .ndo_stop = happy_meal_close, + .ndo_start_xmit = happy_meal_start_xmit, + .ndo_tx_timeout = happy_meal_tx_timeout, + .ndo_get_stats = happy_meal_get_stats, + .ndo_set_multicast_list = happy_meal_set_multicast, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + #ifdef CONFIG_SBUS static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) { @@ -2750,12 +2762,7 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) init_timer(&hp->happy_timer); hp->dev = dev; - dev->open = &happy_meal_open; - dev->stop = &happy_meal_close; - dev->hard_start_xmit = &happy_meal_start_xmit; - dev->get_stats = &happy_meal_get_stats; - dev->set_multicast_list = &happy_meal_set_multicast; - dev->tx_timeout = &happy_meal_tx_timeout; + dev->netdev_ops = &hme_netdev_ops; dev->watchdog_timeo = 5*HZ; dev->ethtool_ops = &hme_ethtool_ops; @@ -3076,12 +3083,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, init_timer(&hp->happy_timer); hp->dev = dev; - dev->open = &happy_meal_open; - dev->stop = &happy_meal_close; - dev->hard_start_xmit = &happy_meal_start_xmit; - dev->get_stats = &happy_meal_get_stats; - dev->set_multicast_list = &happy_meal_set_multicast; - dev->tx_timeout = &happy_meal_tx_timeout; + dev->netdev_ops = &hme_netdev_ops; dev->watchdog_timeo = 5*HZ; dev->ethtool_ops = &hme_ethtool_ops; dev->irq = pdev->irq; -- cgit From d9a811d5fd9ff6c5fec17dea559a6ea697ae207e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:28:54 -0800 Subject: sungem: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sungem.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 8a746041248..86c765d83de 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2989,6 +2989,19 @@ static void gem_remove_one(struct pci_dev *pdev) } } +static const struct net_device_ops gem_netdev_ops = { + .ndo_open = gem_open, + .ndo_stop = gem_close, + .ndo_start_xmit = gem_start_xmit, + .ndo_get_stats = gem_get_stats, + .ndo_set_multicast_list = gem_set_multicast, + .ndo_do_ioctl = gem_ioctl, + .ndo_tx_timeout = gem_tx_timeout, + .ndo_change_mtu = gem_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -3142,17 +3155,10 @@ static int __devinit gem_init_one(struct pci_dev *pdev, if (gem_get_device_address(gp)) goto err_out_free_consistent; - dev->open = gem_open; - dev->stop = gem_close; - dev->hard_start_xmit = gem_start_xmit; - dev->get_stats = gem_get_stats; - dev->set_multicast_list = gem_set_multicast; - dev->do_ioctl = gem_ioctl; + dev->netdev_ops = &gem_netdev_ops; netif_napi_add(dev, &gp->napi, gem_poll, 64); dev->ethtool_ops = &gem_ethtool_ops; - dev->tx_timeout = gem_tx_timeout; dev->watchdog_timeo = 5 * HZ; - dev->change_mtu = gem_change_mtu; dev->irq = pdev->irq; dev->dma = 0; dev->set_mac_address = gem_set_mac_address; -- cgit From 3bc124dd02007290782a154ed3d12847489aae77 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:29:16 -0800 Subject: pcnet32: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/pcnet32.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 044b7b07f5f..c1bef953bf0 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1568,6 +1568,22 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent) return err; } +static const struct net_device_ops pcnet32_netdev_ops = { + .ndo_open = pcnet32_open, + .ndo_stop = pcnet32_close, + .ndo_start_xmit = pcnet32_start_xmit, + .ndo_tx_timeout = pcnet32_tx_timeout, + .ndo_get_stats = pcnet32_get_stats, + .ndo_set_multicast_list = pcnet32_set_multicast_list, + .ndo_do_ioctl = pcnet32_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = pcnet32_poll_controller, +#endif +}; + /* pcnet32_probe1 * Called from both pcnet32_probe_vlbus and pcnet_probe_pci. * pdev will be NULL when called from pcnet32_probe_vlbus. @@ -1934,20 +1950,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) lp->watchdog_timer.function = (void *)&pcnet32_watchdog; /* The PCNET32-specific entries in the device structure. */ - dev->open = &pcnet32_open; - dev->hard_start_xmit = &pcnet32_start_xmit; - dev->stop = &pcnet32_close; - dev->get_stats = &pcnet32_get_stats; - dev->set_multicast_list = &pcnet32_set_multicast_list; - dev->do_ioctl = &pcnet32_ioctl; + dev->netdev_ops = &pcnet32_netdev_ops; dev->ethtool_ops = &pcnet32_ethtool_ops; - dev->tx_timeout = pcnet32_tx_timeout; dev->watchdog_timeo = (5 * HZ); -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = pcnet32_poll_controller; -#endif - /* Fill in the generic fields of the device structure. */ if (register_netdev(dev)) goto err_free_ring; -- cgit From 8bdd5553660bd07d7904af967893f8d487cc6c44 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:29:46 -0800 Subject: typhoon: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/typhoon.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 0009f4e3443..3af9a9516cc 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -2296,6 +2296,19 @@ out: return mode; } +static const struct net_device_ops typhoon_netdev_ops = { + .ndo_open = typhoon_open, + .ndo_stop = typhoon_close, + .ndo_start_xmit = typhoon_start_tx, + .ndo_set_multicast_list = typhoon_set_rx_mode, + .ndo_tx_timeout = typhoon_tx_timeout, + .ndo_get_stats = typhoon_get_stats, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = typhoon_set_mac_address, + .ndo_change_mtu = eth_change_mtu, + .ndo_vlan_rx_register = typhoon_vlan_rx_register, +}; + static int __devinit typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -2495,16 +2508,9 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } /* The chip-specific entries in the device structure. */ - dev->open = typhoon_open; - dev->hard_start_xmit = typhoon_start_tx; - dev->stop = typhoon_close; - dev->set_multicast_list = typhoon_set_rx_mode; - dev->tx_timeout = typhoon_tx_timeout; + dev->netdev_ops = &typhoon_netdev_ops; netif_napi_add(dev, &tp->napi, typhoon_poll, 16); dev->watchdog_timeo = TX_TIMEOUT; - dev->get_stats = typhoon_get_stats; - dev->set_mac_address = typhoon_set_mac_address; - dev->vlan_rx_register = typhoon_vlan_rx_register; SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops); -- cgit From 1f5ec79b8ec357516fbe14904a47f619bb3b543d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:30:09 -0800 Subject: enc28j60: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/enc28j60.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index cefe1d98f93..fc6cc038c7b 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -1531,6 +1531,17 @@ static int enc28j60_chipset_init(struct net_device *dev) return enc28j60_hw_init(priv); } +static const struct net_device_ops enc28j60_netdev_ops = { + .ndo_open = enc28j60_net_open, + .ndo_stop = enc28j60_net_close, + .ndo_start_xmit = enc28j60_send_packet, + .ndo_set_multicast_list = enc28j60_set_multicast_list, + .ndo_set_mac_address = enc28j60_set_mac_address, + .ndo_tx_timeout = enc28j60_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit enc28j60_probe(struct spi_device *spi) { struct net_device *dev; @@ -1585,12 +1596,7 @@ static int __devinit enc28j60_probe(struct spi_device *spi) dev->if_port = IF_PORT_10BASET; dev->irq = spi->irq; - dev->open = enc28j60_net_open; - dev->stop = enc28j60_net_close; - dev->hard_start_xmit = enc28j60_send_packet; - dev->set_multicast_list = &enc28j60_set_multicast_list; - dev->set_mac_address = enc28j60_set_mac_address; - dev->tx_timeout = &enc28j60_tx_timeout; + dev->netdev_ops = &enc28j60_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops); -- cgit From b8aa76a2bd9782e1a45e96602812910d5cfe7b52 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:34:36 -0800 Subject: de600: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/de600.c | 14 +++++++++++--- drivers/net/de620.c | 17 ++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/de600.c b/drivers/net/de600.c index 970f820ba81..de63f1d41d3 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -378,6 +378,16 @@ static void de600_rx_intr(struct net_device *dev) */ } +static const struct net_device_ops de600_netdev_ops = { + .ndo_open = de600_open, + .ndo_stop = de600_close, + .ndo_start_xmit = de600_start_xmit, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + + static struct net_device * __init de600_probe(void) { int i; @@ -439,9 +449,7 @@ static struct net_device * __init de600_probe(void) printk(", Ethernet Address: %pM\n", dev->dev_addr); - dev->open = de600_open; - dev->stop = de600_close; - dev->hard_start_xmit = &de600_start_xmit; + dev->netdev_ops = &de600_netdev_ops; dev->flags&=~IFF_MULTICAST; diff --git a/drivers/net/de620.c b/drivers/net/de620.c index bdfa8940338..d52f34cc952 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -784,6 +784,17 @@ static int adapter_init(struct net_device *dev) return 0; /* all ok */ } +static const struct net_device_ops de620_netdev_ops = { + .ndo_open = de620_open, + .ndo_stop = de620_close, + .ndo_start_xmit = de620_start_xmit, + .ndo_tx_timeout = de620_timeout, + .ndo_set_multicast_list = de620_set_multicast_list, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + /****************************************************************************** * * Only start-up code below @@ -861,12 +872,8 @@ struct net_device * __init de620_probe(int unit) else printk(" UTP)\n"); - dev->open = de620_open; - dev->stop = de620_close; - dev->hard_start_xmit = de620_start_xmit; - dev->tx_timeout = de620_timeout; + dev->netdev_ops = &de620_netdev_ops; dev->watchdog_timeo = HZ*2; - dev->set_multicast_list = de620_set_multicast_list; /* base_addr and irq are already set, see above! */ -- cgit From 97488c5b2d5b2121da3bc386558488598fb0ce23 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:35:41 -0800 Subject: sis190: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sis190.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 83cc3c5f794..a9732686134 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1782,6 +1782,21 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); } +static const struct net_device_ops sis190_netdev_ops = { + .ndo_open = sis190_open, + .ndo_stop = sis190_close, + .ndo_do_ioctl = sis190_ioctl, + .ndo_start_xmit = sis190_start_xmit, + .ndo_tx_timeout = sis190_tx_timeout, + .ndo_set_multicast_list = sis190_set_rx_mode, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = sis190_netpoll, +#endif +}; + static int __devinit sis190_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1815,19 +1830,12 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, INIT_WORK(&tp->phy_task, sis190_phy_task); - dev->open = sis190_open; - dev->stop = sis190_close; - dev->do_ioctl = sis190_ioctl; - dev->tx_timeout = sis190_tx_timeout; - dev->watchdog_timeo = SIS190_TX_TIMEOUT; - dev->hard_start_xmit = sis190_start_xmit; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = sis190_netpoll; -#endif - dev->set_multicast_list = sis190_set_rx_mode; + dev->netdev_ops = &sis190_netdev_ops; + SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops); dev->irq = pdev->irq; dev->base_addr = (unsigned long) 0xdead; + dev->watchdog_timeo = SIS190_TX_TIMEOUT; spin_lock_init(&tp->lock); -- cgit From a7d1de25dc2e823c741cf1ae86a59379ca5a6804 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:36:07 -0800 Subject: ns83820: fix net_device_ops support The vlan_rx_register fuction is now in net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ns83820.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 46b0772489e..42021aca1dd 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1957,6 +1957,9 @@ static const struct net_device_ops netdev_ops = { .ndo_set_multicast_list = ns83820_set_multicast, .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = ns83820_tx_timeout, +#ifdef NS83820_VLAN_ACCEL_SUPPORT + .ndo_vlan_rx_register = ns83820_vlan_rx_register, +#endif }; static int __devinit ns83820_init_one(struct pci_dev *pci_dev, @@ -2216,7 +2219,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, #ifdef NS83820_VLAN_ACCEL_SUPPORT /* We also support hardware vlan acceleration */ ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - ndev->vlan_rx_register = ns83820_vlan_rx_register; #endif if (using_dac) { -- cgit From d49d19c962c5f409a7dc771f185afd22cdb49edf Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:56:54 -0800 Subject: sb1000: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sb1000.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c index be3025310e9..fc0e38bddee 100644 --- a/drivers/net/sb1000.c +++ b/drivers/net/sb1000.c @@ -134,6 +134,16 @@ static const struct pnp_device_id sb1000_pnp_ids[] = { }; MODULE_DEVICE_TABLE(pnp, sb1000_pnp_ids); +static const struct net_device_ops sb1000_netdev_ops = { + .ndo_open = sb1000_open, + .ndo_start_xmit = sb1000_start_xmit, + .ndo_do_ioctl = sb1000_dev_ioctl, + .ndo_stop = sb1000_close, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id) { @@ -192,11 +202,7 @@ sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id) if (sb1000_debug > 0) printk(KERN_NOTICE "%s", version); - /* The SB1000-specific entries in the device structure. */ - dev->open = sb1000_open; - dev->do_ioctl = sb1000_dev_ioctl; - dev->hard_start_xmit = sb1000_start_xmit; - dev->stop = sb1000_close; + dev->netdev_ops = &sb1000_netdev_ops; /* hardware address is 0:0:serial_number */ dev->dev_addr[2] = serial_number >> 24 & 0xff; -- cgit From 2b7d0c7039e9fd1bd64ba3ef2676f06b068eba34 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:57:19 -0800 Subject: natsemi: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/natsemi.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 478edb92bca..c5dec54251b 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -779,6 +779,22 @@ static void __devinit natsemi_init_media (struct net_device *dev) } +static const struct net_device_ops natsemi_netdev_ops = { + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_start_xmit = start_tx, + .ndo_get_stats = get_stats, + .ndo_set_multicast_list = set_rx_mode, + .ndo_change_mtu = natsemi_change_mtu, + .ndo_do_ioctl = netdev_ioctl, + .ndo_tx_timeout = ns_tx_timeout, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = natsemi_poll_controller, +#endif +}; + static int __devinit natsemi_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -911,20 +927,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, if (find_cnt < MAX_UNITS && full_duplex[find_cnt]) np->full_duplex = 1; - /* The chip-specific entries in the device structure. */ - dev->open = &netdev_open; - dev->hard_start_xmit = &start_tx; - dev->stop = &netdev_close; - dev->get_stats = &get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->change_mtu = &natsemi_change_mtu; - dev->do_ioctl = &netdev_ioctl; - dev->tx_timeout = &ns_tx_timeout; + dev->netdev_ops = &natsemi_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = &natsemi_poll_controller; -#endif SET_ETHTOOL_OPS(dev, ðtool_ops); if (mtu) -- cgit From e287157f15f3ab9cda4cfe334fee41c7b758966f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:57:47 -0800 Subject: fealnx: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/fealnx.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 31ab1ff623f..daf7272c335 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -467,6 +467,18 @@ static void stop_nic_rxtx(void __iomem *ioaddr, long crvalue) } } +static const struct net_device_ops netdev_ops = { + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_start_xmit = start_tx, + .ndo_get_stats = get_stats, + .ndo_set_multicast_list = set_rx_mode, + .ndo_do_ioctl = mii_ioctl, + .ndo_tx_timeout = fealnx_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; static int __devinit fealnx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -649,15 +661,8 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, np->mii.force_media = 1; } - /* The chip-specific entries in the device structure. */ - dev->open = &netdev_open; - dev->hard_start_xmit = &start_tx; - dev->stop = &netdev_close; - dev->get_stats = &get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &mii_ioctl; + dev->netdev_ops = &netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; - dev->tx_timeout = &fealnx_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; err = register_netdev(dev); -- cgit From 4fc8006e003a9bcb09015179e1cfc42420d88872 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:58:17 -0800 Subject: starfire: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/starfire.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 57fb1f71c47..da3a76b18ef 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -648,6 +648,24 @@ static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) #endif /* VLAN_SUPPORT */ +static const struct net_device_ops netdev_ops = { + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_start_xmit = start_tx, + .ndo_tx_timeout = tx_timeout, + .ndo_get_stats = get_stats, + .ndo_set_multicast_list = &set_rx_mode, + .ndo_do_ioctl = netdev_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef VLAN_SUPPORT + .ndo_vlan_rx_register = netdev_vlan_rx_register, + .ndo_vlan_rx_add_vid = netdev_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = netdev_vlan_rx_kill_vid, +#endif +}; + static int __devinit starfire_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -710,11 +728,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, if (enable_hw_cksum) dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; #endif /* ZEROCOPY */ + #ifdef VLAN_SUPPORT dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - dev->vlan_rx_register = netdev_vlan_rx_register; - dev->vlan_rx_add_vid = netdev_vlan_rx_add_vid; - dev->vlan_rx_kill_vid = netdev_vlan_rx_kill_vid; #endif /* VLAN_RX_KILL_VID */ #ifdef ADDR_64BITS dev->features |= NETIF_F_HIGHDMA; @@ -810,18 +826,12 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, } } - /* The chip-specific entries in the device structure. */ - dev->open = &netdev_open; - dev->hard_start_xmit = &start_tx; - dev->tx_timeout = tx_timeout; + dev->netdev_ops = &netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; - netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work); - dev->stop = &netdev_close; - dev->get_stats = &get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &netdev_ioctl; SET_ETHTOOL_OPS(dev, ðtool_ops); + netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work); + if (mtu) dev->mtu = mtu; -- cgit From 633a277e2a06b4cc10b1373380b09613c702523c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:58:43 -0800 Subject: sundance: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sundance.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 698893b9200..feaf0e0577d 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -449,6 +449,19 @@ static void sundance_reset(struct net_device *dev, unsigned long reset_cmd) } } +static const struct net_device_ops netdev_ops = { + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_start_xmit = start_tx, + .ndo_get_stats = get_stats, + .ndo_set_multicast_list = set_rx_mode, + .ndo_do_ioctl = netdev_ioctl, + .ndo_tx_timeout = tx_timeout, + .ndo_change_mtu = change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit sundance_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -530,16 +543,10 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, np->mii_if.reg_num_mask = 0x1f; /* The chip-specific entries in the device structure. */ - dev->open = &netdev_open; - dev->hard_start_xmit = &start_tx; - dev->stop = &netdev_close; - dev->get_stats = &get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &netdev_ioctl; + dev->netdev_ops = &netdev_ops; SET_ETHTOOL_OPS(dev, ðtool_ops); - dev->tx_timeout = &tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - dev->change_mtu = &change_mtu; + pci_set_drvdata(pdev, dev); i = register_netdev(dev); -- cgit From f4266cf34d7b903e2e11b317f2e548a2acc4cd4e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:59:15 -0800 Subject: tulip: convert devices to new API Convert to net_device_ops and internal net_device_stats Signed-off-by: Stephen Hemminger Acked-by: Grant Grundler Signed-off-by: David S. Miller --- drivers/net/tulip/tulip_core.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index ff84babb3ff..bee75fa87a9 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1225,6 +1225,22 @@ static int tulip_uli_dm_quirk(struct pci_dev *pdev) return 0; } +static const struct net_device_ops tulip_netdev_ops = { + .ndo_open = tulip_open, + .ndo_start_xmit = tulip_start_xmit, + .ndo_tx_timeout = tulip_tx_timeout, + .ndo_stop = tulip_close, + .ndo_get_stats = tulip_get_stats, + .ndo_do_ioctl = private_ioctl, + .ndo_set_multicast_list = set_rx_mode, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = poll_tulip, +#endif +}; + static int __devinit tulip_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1601,19 +1617,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, } /* The Tulip-specific entries in the device structure. */ - dev->open = tulip_open; - dev->hard_start_xmit = tulip_start_xmit; - dev->tx_timeout = tulip_tx_timeout; + dev->netdev_ops = &tulip_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; #ifdef CONFIG_TULIP_NAPI netif_napi_add(dev, &tp->napi, tulip_poll, 16); -#endif - dev->stop = tulip_close; - dev->get_stats = tulip_get_stats; - dev->do_ioctl = private_ioctl; - dev->set_multicast_list = set_rx_mode; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = &poll_tulip; #endif SET_ETHTOOL_OPS(dev, &ops); -- cgit From 90d8743d03593520ceb5e8fd8cf3b86072518f83 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 17:59:47 -0800 Subject: de2104x: convert to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tulip/de2104x.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 5166be930a5..d5d53b633cf 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -1922,6 +1922,18 @@ bad_srom: goto fill_defaults; } +static const struct net_device_ops de_netdev_ops = { + .ndo_open = de_open, + .ndo_stop = de_close, + .ndo_set_multicast_list = de_set_rx_mode, + .ndo_start_xmit = de_start_xmit, + .ndo_get_stats = de_get_stats, + .ndo_tx_timeout = de_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit de_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1944,14 +1956,9 @@ static int __devinit de_init_one (struct pci_dev *pdev, if (!dev) return -ENOMEM; + dev->netdev_ops = &de_netdev_ops; SET_NETDEV_DEV(dev, &pdev->dev); - dev->open = de_open; - dev->stop = de_close; - dev->set_multicast_list = de_set_rx_mode; - dev->hard_start_xmit = de_start_xmit; - dev->get_stats = de_get_stats; dev->ethtool_ops = &de_ethtool_ops; - dev->tx_timeout = de_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; de = netdev_priv(dev); -- cgit From 0b9a5b05b23587c81e2985bc89f6f1a502c1991e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:00:31 -0800 Subject: de4x5: convert to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tulip/de4x5.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 67bfd6f4336..6418f74415d 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1077,6 +1077,18 @@ static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = { mdelay(2); /* Wait for 2ms */\ } +static const struct net_device_ops de4x5_netdev_ops = { + .ndo_open = de4x5_open, + .ndo_stop = de4x5_close, + .ndo_start_xmit = de4x5_queue_pkt, + .ndo_get_stats = de4x5_get_stats, + .ndo_set_multicast_list = set_multicast_list, + .ndo_do_ioctl = de4x5_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address= eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) @@ -1258,13 +1270,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) /* The DE4X5-specific entries in the device structure. */ SET_NETDEV_DEV(dev, gendev); - dev->open = &de4x5_open; - dev->hard_start_xmit = &de4x5_queue_pkt; - dev->stop = &de4x5_close; - dev->get_stats = &de4x5_get_stats; - dev->set_multicast_list = &set_multicast_list; - dev->do_ioctl = &de4x5_ioctl; - + dev->netdev_ops = &de4x5_netdev_ops; dev->mem_start = 0; /* Fill in the generic fields of the device structure. */ -- cgit From 1034c9f69ae7b61d408836e60c6a2b5afc6e48bc Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:00:55 -0800 Subject: xircom: convert devices to new API Convert to net_device_ops and internal net_device_stats Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tulip/xircom_cb.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index 13c8703ecb9..c2ca9f40e40 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -104,10 +104,8 @@ struct xircom_private { */ spinlock_t lock; - struct pci_dev *pdev; struct net_device *dev; - struct net_device_stats stats; }; @@ -119,7 +117,6 @@ static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev); static int xircom_open(struct net_device *dev); static int xircom_close(struct net_device *dev); static void xircom_up(struct xircom_private *card); -static struct net_device_stats *xircom_get_stats(struct net_device *dev); #ifdef CONFIG_NET_POLL_CONTROLLER static void xircom_poll_controller(struct net_device *dev); #endif @@ -194,6 +191,18 @@ static const struct ethtool_ops netdev_ethtool_ops = { .get_drvinfo = netdev_get_drvinfo, }; +static const struct net_device_ops netdev_ops = { + .ndo_open = xircom_open, + .ndo_stop = xircom_close, + .ndo_start_xmit = xircom_start_xmit, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = xircom_poll_controller, +#endif +}; + /* xircom_probe is the code that gets called on device insertion. it sets up the hardware and registers the device to the networklayer. @@ -266,13 +275,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ read_mac_address(private); setup_descriptors(private); - dev->open = &xircom_open; - dev->hard_start_xmit = &xircom_start_xmit; - dev->stop = &xircom_close; - dev->get_stats = &xircom_get_stats; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = &xircom_poll_controller; -#endif + dev->netdev_ops = &netdev_ops; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); pci_set_drvdata(pdev, dev); @@ -497,14 +500,6 @@ static int xircom_close(struct net_device *dev) } - -static struct net_device_stats *xircom_get_stats(struct net_device *dev) -{ - struct xircom_private *card = netdev_priv(dev); - return &card->stats; -} - - #ifdef CONFIG_NET_POLL_CONTROLLER static void xircom_poll_controller(struct net_device *dev) { @@ -1193,7 +1188,7 @@ static void investigate_read_descriptor(struct net_device *dev,struct xircom_pri skb = dev_alloc_skb(pkt_len + 2); if (skb == NULL) { - card->stats.rx_dropped++; + dev->stats.rx_dropped++; goto out; } skb_reserve(skb, 2); @@ -1201,8 +1196,8 @@ static void investigate_read_descriptor(struct net_device *dev,struct xircom_pri skb_put(skb, pkt_len); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - card->stats.rx_packets++; - card->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; out: /* give the buffer back to the card */ @@ -1232,16 +1227,16 @@ static void investigate_write_descriptor(struct net_device *dev, struct xircom_p #endif if (status > 0) { /* bit 31 is 0 when done */ if (card->tx_skb[descnr]!=NULL) { - card->stats.tx_bytes += card->tx_skb[descnr]->len; + dev->stats.tx_bytes += card->tx_skb[descnr]->len; dev_kfree_skb_irq(card->tx_skb[descnr]); } card->tx_skb[descnr] = NULL; /* Bit 8 in the status field is 1 if there was a collision */ if (status&(1<<8)) - card->stats.collisions++; + dev->stats.collisions++; card->tx_buffer[4*descnr] = 0; /* descriptor is free again */ netif_wake_queue (dev); - card->stats.tx_packets++; + dev->stats.tx_packets++; } leave("investigate_write_descriptor"); -- cgit From 2765df58986ac4382b70bf31be70a64a7a9eaf4c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:01:20 -0800 Subject: dmfe: convert to new API Convert to internal net_device-stats and net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tulip/dmfe.c | 62 +++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 28a5c51b43a..2e5c99941f3 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -257,9 +257,6 @@ struct dmfe_board_info { u8 wol_mode; /* user WOL settings */ struct timer_list timer; - /* System defined statistic counter */ - struct net_device_stats stats; - /* Driver defined statistic counter */ unsigned long tx_fifo_underrun; unsigned long tx_loss_carrier; @@ -316,7 +313,6 @@ static u8 SF_mode; /* Special Function: 1:VLAN, 2:RX Flow Control static int dmfe_open(struct DEVICE *); static int dmfe_start_xmit(struct sk_buff *, struct DEVICE *); static int dmfe_stop(struct DEVICE *); -static struct net_device_stats * dmfe_get_stats(struct DEVICE *); static void dmfe_set_filter_mode(struct DEVICE *); static const struct ethtool_ops netdev_ethtool_ops; static u16 read_srom_word(long ,int); @@ -351,6 +347,19 @@ static void dmfe_set_phyxcer(struct dmfe_board_info *); /* DM910X network board routine ---------------------------- */ +static const struct net_device_ops netdev_ops = { + .ndo_open = dmfe_open, + .ndo_stop = dmfe_stop, + .ndo_start_xmit = dmfe_start_xmit, + .ndo_set_multicast_list = dmfe_set_filter_mode, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = poll_dmfe, +#endif +}; + /* * Search DM910X board ,allocate space and register it */ @@ -442,14 +451,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, dev->base_addr = db->ioaddr; dev->irq = pdev->irq; pci_set_drvdata(pdev, dev); - dev->open = &dmfe_open; - dev->hard_start_xmit = &dmfe_start_xmit; - dev->stop = &dmfe_stop; - dev->get_stats = &dmfe_get_stats; - dev->set_multicast_list = &dmfe_set_filter_mode; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = &poll_dmfe; -#endif + dev->netdev_ops = &netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; netif_carrier_off(dev); spin_lock_init(&db->lock); @@ -867,15 +869,15 @@ static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db) /* A packet sent completed */ db->tx_packet_cnt--; - db->stats.tx_packets++; + dev->stats.tx_packets++; /* Transmit statistic counter */ if ( tdes0 != 0x7fffffff ) { /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */ - db->stats.collisions += (tdes0 >> 3) & 0xf; - db->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; + dev->stats.collisions += (tdes0 >> 3) & 0xf; + dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; if (tdes0 & TDES0_ERR_MASK) { - db->stats.tx_errors++; + dev->stats.tx_errors++; if (tdes0 & 0x0002) { /* UnderRun */ db->tx_fifo_underrun++; @@ -969,13 +971,13 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) if (rdes0 & 0x8000) { /* This is a error packet */ //printk(DRV_NAME ": rdes0: %lx\n", rdes0); - db->stats.rx_errors++; + dev->stats.rx_errors++; if (rdes0 & 1) - db->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (rdes0 & 2) - db->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (rdes0 & 0x80) - db->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } if ( !(rdes0 & 0x8000) || @@ -1008,8 +1010,8 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - db->stats.rx_packets++; - db->stats.rx_bytes += rxlen; + dev->stats.rx_packets++; + dev->stats.rx_bytes += rxlen; } } else { /* Reuse SKB buffer when the packet is error */ @@ -1024,20 +1026,6 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) db->rx_ready_ptr = rxptr; } - -/* - * Get statistics from driver. - */ - -static struct net_device_stats * dmfe_get_stats(struct DEVICE *dev) -{ - struct dmfe_board_info *db = netdev_priv(dev); - - DMFE_DBUG(0, "dmfe_get_stats", 0); - return &db->stats; -} - - /* * Set DM910X multicast address */ @@ -1161,7 +1149,7 @@ static void dmfe_timer(unsigned long data) /* Operating Mode Check */ if ( (db->dm910x_chk_mode & 0x1) && - (db->stats.rx_packets > MAX_CHECK_PACKET) ) + (dev->stats.rx_packets > MAX_CHECK_PACKET) ) db->dm910x_chk_mode = 0x4; /* Dynamic reset DM910X : system error or transmit time-out */ -- cgit From dfefe02bfd865c18eeaebc07ff1cd50120c40c20 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:01:40 -0800 Subject: uli526x: convert devices to new API Convert to net_device_ops and internal net_device_stats Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tulip/uli526x.c | 63 +++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 36 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 00cbc5251dc..030e02e6302 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -168,9 +168,6 @@ struct uli526x_board_info { u8 wait_reset; /* Hardware failed, need to reset */ struct timer_list timer; - /* System defined statistic counter */ - struct net_device_stats stats; - /* Driver defined statistic counter */ unsigned long tx_fifo_underrun; unsigned long tx_loss_carrier; @@ -220,7 +217,6 @@ static int mode = 8; static int uli526x_open(struct net_device *); static int uli526x_start_xmit(struct sk_buff *, struct net_device *); static int uli526x_stop(struct net_device *); -static struct net_device_stats * uli526x_get_stats(struct net_device *); static void uli526x_set_filter_mode(struct net_device *); static const struct ethtool_ops netdev_ethtool_ops; static u16 read_srom_word(long, int); @@ -251,6 +247,19 @@ static void uli526x_set_phyxcer(struct uli526x_board_info *); /* ULI526X network board routine ---------------------------- */ +static const struct net_device_ops netdev_ops = { + .ndo_open = uli526x_open, + .ndo_stop = uli526x_stop, + .ndo_start_xmit = uli526x_start_xmit, + .ndo_set_multicast_list = uli526x_set_filter_mode, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = uli526x_poll, +#endif +}; + /* * Search ULI526X board, allocate space and register it */ @@ -335,15 +344,9 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev, pci_set_drvdata(pdev, dev); /* Register some necessary functions */ - dev->open = &uli526x_open; - dev->hard_start_xmit = &uli526x_start_xmit; - dev->stop = &uli526x_stop; - dev->get_stats = &uli526x_get_stats; - dev->set_multicast_list = &uli526x_set_filter_mode; + dev->netdev_ops = &netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = &uli526x_poll; -#endif + spin_lock_init(&db->lock); @@ -733,7 +736,8 @@ static void uli526x_poll(struct net_device *dev) * Free TX resource after TX complete */ -static void uli526x_free_tx_pkt(struct net_device *dev, struct uli526x_board_info * db) +static void uli526x_free_tx_pkt(struct net_device *dev, + struct uli526x_board_info * db) { struct tx_desc *txptr; u32 tdes0; @@ -747,15 +751,15 @@ static void uli526x_free_tx_pkt(struct net_device *dev, struct uli526x_board_inf /* A packet sent completed */ db->tx_packet_cnt--; - db->stats.tx_packets++; + dev->stats.tx_packets++; /* Transmit statistic counter */ if ( tdes0 != 0x7fffffff ) { /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */ - db->stats.collisions += (tdes0 >> 3) & 0xf; - db->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; + dev->stats.collisions += (tdes0 >> 3) & 0xf; + dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; if (tdes0 & TDES0_ERR_MASK) { - db->stats.tx_errors++; + dev->stats.tx_errors++; if (tdes0 & 0x0002) { /* UnderRun */ db->tx_fifo_underrun++; if ( !(db->cr6_data & CR6_SFT) ) { @@ -825,13 +829,13 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info if (rdes0 & 0x8000) { /* This is a error packet */ //printk(DRV_NAME ": rdes0: %lx\n", rdes0); - db->stats.rx_errors++; + dev->stats.rx_errors++; if (rdes0 & 1) - db->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (rdes0 & 2) - db->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (rdes0 & 0x80) - db->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } if ( !(rdes0 & 0x8000) || @@ -854,8 +858,8 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - db->stats.rx_packets++; - db->stats.rx_bytes += rxlen; + dev->stats.rx_packets++; + dev->stats.rx_bytes += rxlen; } else { /* Reuse SKB buffer when the packet is error */ @@ -871,19 +875,6 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info } -/* - * Get statistics from driver. - */ - -static struct net_device_stats * uli526x_get_stats(struct net_device *dev) -{ - struct uli526x_board_info *db = netdev_priv(dev); - - ULI526X_DBUG(0, "uli526x_get_stats", 0); - return &db->stats; -} - - /* * Set ULI526X multicast address */ -- cgit From 2a97e6b735416054dcc1b3cf7f4d358f43b45c6e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:02:26 -0800 Subject: windbond: convert devices to new API Convert to net_device_ops and internal net_device_stats Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tulip/winbond-840.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 022d99af864..f467bf87817 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -343,7 +343,18 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static const struct ethtool_ops netdev_ethtool_ops; static int netdev_close(struct net_device *dev); - +static const struct net_device_ops netdev_ops = { + .ndo_open = netdev_open, + .ndo_stop = netdev_close, + .ndo_start_xmit = start_tx, + .ndo_get_stats = get_stats, + .ndo_set_multicast_list = set_rx_mode, + .ndo_do_ioctl = netdev_ioctl, + .ndo_tx_timeout = tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; static int __devinit w840_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -420,14 +431,8 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, np->mii_if.force_media = 1; /* The chip-specific entries in the device structure. */ - dev->open = &netdev_open; - dev->hard_start_xmit = &start_tx; - dev->stop = &netdev_close; - dev->get_stats = &get_stats; - dev->set_multicast_list = &set_rx_mode; - dev->do_ioctl = &netdev_ioctl; + dev->netdev_ops = &netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; - dev->tx_timeout = &tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; i = register_netdev(dev); @@ -1555,7 +1560,7 @@ static void __devexit w840_remove1 (struct pci_dev *pdev) * rtnl_lock, & netif_device_detach after the rtnl_unlock. * - get_stats: * spin_lock_irq(np->lock), doesn't touch hw if not present - * - hard_start_xmit: + * - start_xmit: * synchronize_irq + netif_tx_disable; * - tx_timeout: * netif_device_detach + netif_tx_disable; -- cgit From b1da683d17972fc851c46331a5efa801bddf9273 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:09:36 -0800 Subject: slip: convert to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/slip.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8e1c0baf695..5c61d5fad90 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -603,7 +603,6 @@ static int sl_init(struct net_device *dev) dev->mtu = sl->mtu; dev->type = ARPHRD_SLIP + sl->mode; #ifdef SL_CHECK_TRANSMIT - dev->tx_timeout = sl_tx_timeout; dev->watchdog_timeo = 20*HZ; #endif return 0; @@ -617,19 +616,26 @@ static void sl_uninit(struct net_device *dev) sl_free_bufs(sl); } +static const struct net_device_ops sl_netdev_ops = { + .ndo_init = sl_init, + .ndo_uninit = sl_uninit, + .ndo_open = sl_open, + .ndo_stop = sl_close, + .ndo_start_xmit = sl_xmit, + .ndo_get_stats = sl_get_stats, + .ndo_change_mtu = sl_change_mtu, + .ndo_tx_timeout = sl_tx_timeout, +#ifdef CONFIG_SLIP_SMART + .ndo_do_ioctl = sl_ioctl, +#endif +}; + + static void sl_setup(struct net_device *dev) { - dev->init = sl_init; - dev->uninit = sl_uninit; - dev->open = sl_open; + dev->netdev_ops = &sl_netdev_ops; dev->destructor = free_netdev; - dev->stop = sl_close; - dev->get_stats = sl_get_stats; - dev->change_mtu = sl_change_mtu; - dev->hard_start_xmit = sl_xmit; -#ifdef CONFIG_SLIP_SMART - dev->do_ioctl = sl_ioctl; -#endif + dev->hard_header_len = 0; dev->addr_len = 0; dev->tx_queue_len = 10; -- cgit From 887e53d2d131fe0740326f66f1b417671fdfcf9a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:09:58 -0800 Subject: amd8111e: convert to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/amd8111e.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 187ac6eb6e9..7709992bb6b 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1813,6 +1813,25 @@ static void __devinit amd8111e_probe_ext_phy(struct net_device* dev) lp->ext_phy_addr = 1; } +static const struct net_device_ops amd8111e_netdev_ops = { + .ndo_open = amd8111e_open, + .ndo_stop = amd8111e_close, + .ndo_start_xmit = amd8111e_start_xmit, + .ndo_tx_timeout = amd8111e_tx_timeout, + .ndo_get_stats = amd8111e_get_stats, + .ndo_set_multicast_list = amd8111e_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = amd8111e_set_mac_address, + .ndo_do_ioctl = amd8111e_ioctl, + .ndo_change_mtu = amd8111e_change_mtu, +#if AMD8111E_VLAN_TAG_USED + .ndo_vlan_rx_register = amd8111e_vlan_rx_register, +#endif +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = amd8111e_poll, +#endif +}; + static int __devinit amd8111e_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1872,7 +1891,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, #if AMD8111E_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX ; - dev->vlan_rx_register =amd8111e_vlan_rx_register; #endif lp = netdev_priv(dev); @@ -1901,27 +1919,16 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, if(dynamic_ipg[card_idx++]) lp->options |= OPTION_DYN_IPG_ENABLE; + /* Initialize driver entry points */ - dev->open = amd8111e_open; - dev->hard_start_xmit = amd8111e_start_xmit; - dev->stop = amd8111e_close; - dev->get_stats = amd8111e_get_stats; - dev->set_multicast_list = amd8111e_set_multicast_list; - dev->set_mac_address = amd8111e_set_mac_address; - dev->do_ioctl = amd8111e_ioctl; - dev->change_mtu = amd8111e_change_mtu; + dev->netdev_ops = &amd8111e_netdev_ops; SET_ETHTOOL_OPS(dev, &ops); dev->irq =pdev->irq; - dev->tx_timeout = amd8111e_tx_timeout; dev->watchdog_timeo = AMD8111E_TX_TIMEOUT; netif_napi_add(dev, &lp->napi, amd8111e_rx_poll, 32); -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = amd8111e_poll; -#endif #if AMD8111E_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->vlan_rx_register =amd8111e_vlan_rx_register; #endif /* Probe the external PHY */ amd8111e_probe_ext_phy(dev); -- cgit From 3a1a27fa46f6c3ce39fe02b73df6d8d4648d1679 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:10:24 -0800 Subject: atp: convert to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/atp.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atp.c b/drivers/net/atp.c index ea493ce2398..4317b3edb3d 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -204,8 +204,7 @@ static irqreturn_t atp_interrupt(int irq, void *dev_id); static void net_rx(struct net_device *dev); static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode); static int net_close(struct net_device *dev); -static void set_rx_mode_8002(struct net_device *dev); -static void set_rx_mode_8012(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); static void tx_timeout(struct net_device *dev); @@ -242,6 +241,17 @@ static int __init atp_init(void) return -ENODEV; } +static const struct net_device_ops atp_netdev_ops = { + .ndo_open = net_open, + .ndo_stop = net_close, + .ndo_start_xmit = atp_send_packet, + .ndo_set_multicast_list = set_rx_mode, + .ndo_tx_timeout = tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __init atp_probe1(long ioaddr) { struct net_device *dev = NULL; @@ -342,12 +352,7 @@ static int __init atp_probe1(long ioaddr) if (dev->mem_end & 0xf) net_debug = dev->mem_end & 7; - dev->open = net_open; - dev->stop = net_close; - dev->hard_start_xmit = atp_send_packet; - dev->set_multicast_list = - lp->chip_type == RTL8002 ? &set_rx_mode_8002 : &set_rx_mode_8012; - dev->tx_timeout = tx_timeout; + dev->netdev_ops = &atp_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; res = register_netdev(dev); @@ -903,6 +908,17 @@ static void set_rx_mode_8012(struct net_device *dev) write_reg(ioaddr, CMR2, CMR2_IRQOUT); /* Switch back to page 0 */ } +static void set_rx_mode(struct net_device *dev) +{ + struct net_local *lp = netdev_priv(dev); + + if (lp->chip_type == RTL8002) + return set_rx_mode_8002(dev); + else + return set_rx_mode_8012(dev); +} + + static int __init atp_init_module(void) { if (debug) /* Emit version even if no cards detected. */ printk(KERN_INFO "%s", version); -- cgit From 403413e50d6fc88dada28bf41262a3d0e3627827 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:10:49 -0800 Subject: b44: convert to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/b44.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 0e7470a201f..6926ebedfdc 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2108,6 +2108,22 @@ static int __devinit b44_get_invariants(struct b44 *bp) return err; } +static const struct net_device_ops b44_netdev_ops = { + .ndo_open = b44_open, + .ndo_stop = b44_close, + .ndo_start_xmit = b44_start_xmit, + .ndo_get_stats = b44_get_stats, + .ndo_set_multicast_list = b44_set_rx_mode, + .ndo_set_mac_address = b44_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = b44_ioctl, + .ndo_tx_timeout = b44_tx_timeout, + .ndo_change_mtu = b44_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = b44_poll_controller, +#endif +}; + static int __devinit b44_init_one(struct ssb_device *sdev, const struct ssb_device_id *ent) { @@ -2145,20 +2161,9 @@ static int __devinit b44_init_one(struct ssb_device *sdev, bp->rx_pending = B44_DEF_RX_RING_PENDING; bp->tx_pending = B44_DEF_TX_RING_PENDING; - dev->open = b44_open; - dev->stop = b44_close; - dev->hard_start_xmit = b44_start_xmit; - dev->get_stats = b44_get_stats; - dev->set_multicast_list = b44_set_rx_mode; - dev->set_mac_address = b44_set_mac_addr; - dev->do_ioctl = b44_ioctl; - dev->tx_timeout = b44_tx_timeout; + dev->netdev_ops = &b44_netdev_ops; netif_napi_add(dev, &bp->napi, b44_poll, 64); dev->watchdog_timeo = B44_TX_TIMEOUT; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = b44_poll_controller; -#endif - dev->change_mtu = b44_change_mtu; dev->irq = sdev->irq; SET_ETHTOOL_OPS(dev, &b44_ethtool_ops); -- cgit From d9d6f46b42294754f8d4ed743124ae8bb8e01fba Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 7 Jan 2009 18:13:49 -0800 Subject: hp100: update to net_device_ops Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hp100.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index ebe7651fcb8..ad8be7e7829 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -425,6 +425,28 @@ struct net_device * __init hp100_probe(int unit) } #endif /* !MODULE && CONFIG_ISA */ +static const struct net_device_ops hp100_bm_netdev_ops = { + .ndo_open = hp100_open, + .ndo_stop = hp100_close, + .ndo_start_xmit = hp100_start_xmit_bm, + .ndo_get_stats = hp100_get_stats, + .ndo_set_multicast_list = hp100_set_multicast_list, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +static const struct net_device_ops hp100_netdev_ops = { + .ndo_open = hp100_open, + .ndo_stop = hp100_close, + .ndo_start_xmit = hp100_start_xmit, + .ndo_get_stats = hp100_get_stats, + .ndo_set_multicast_list = hp100_set_multicast_list, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit hp100_probe1(struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev) { @@ -657,16 +679,10 @@ static int __devinit hp100_probe1(struct net_device *dev, int ioaddr, lp->virt_memory_size = virt_memory_size; lp->rx_ratio = hp100_rx_ratio; /* can be conf'd with insmod */ - dev->open = hp100_open; - dev->stop = hp100_close; - if (lp->mode == 1) /* busmaster */ - dev->hard_start_xmit = hp100_start_xmit_bm; + dev->netdev_ops = &hp100_bm_netdev_ops; else - dev->hard_start_xmit = hp100_start_xmit; - - dev->get_stats = hp100_get_stats; - dev->set_multicast_list = &hp100_set_multicast_list; + dev->netdev_ops = &hp100_netdev_ops; /* Ask the card for which IRQ line it is configured */ if (bus == HP100_BUS_PCI) { -- cgit From 73ac36ea14fd18ea3dc057e41b16ff31a3c0bd5a Mon Sep 17 00:00:00 2001 From: Coly Li Date: Wed, 7 Jan 2009 18:09:16 -0800 Subject: fix similar typos to successfull When I review ocfs2 code, find there are 2 typos to "successfull". After doing grep "successfull " in kernel tree, 22 typos found totally -- great minds always think alike :) This patch fixes all the similar typos. Thanks for Randy's ack and comments. Signed-off-by: Coly Li Acked-by: Randy Dunlap Acked-by: Roland Dreier Cc: Jeremy Kerr Cc: Jeff Garzik Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Theodore Ts'o Cc: Mark Fasheh Cc: Vlad Yasevich Cc: Sridhar Samudrala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/wireless/ath5k/dma.c | 2 +- drivers/net/wireless/zd1211rw/zd_mac.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath5k/dma.c index 7e2b1a67e5d..b65b4feb2d2 100644 --- a/drivers/net/wireless/ath5k/dma.c +++ b/drivers/net/wireless/ath5k/dma.c @@ -594,7 +594,7 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) * XXX: BMISS interrupts may occur after association. * I found this on 5210 code but it needs testing. If this is * true we should disable them before assoc and re-enable them - * after a successfull assoc + some jiffies. + * after a successful assoc + some jiffies. interrupt_mask &= ~AR5K_INT_BMISS; */ } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 9caa96a1358..a611ad85798 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -287,7 +287,7 @@ static void zd_op_stop(struct ieee80211_hw *hw) * @skb - a sk-buffer * @flags: extra flags to set in the TX status info * @ackssi: ACK signal strength - * @success - True for successfull transmission of the frame + * @success - True for successful transmission of the frame * * This information calls ieee80211_tx_status_irqsafe() if required by the * control information. It copies the control information into the status -- cgit From 4b9f8ec6e5e98779e8b3806a5f58267378ef57eb Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 6 Jan 2009 18:52:58 +0000 Subject: dm9601: tell HW about random generated mac address Otherwise unicast RX will only work in promisc mode. Signed-off-by: Peter Korsgaard Signed-off-by: Wu Fengguang Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 49a30bde7a8..63e97a38708 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -397,6 +397,11 @@ static void dm9601_set_multicast(struct net_device *net) dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl); } +static void __dm9601_set_mac_address(struct usbnet *dev) +{ + dm_write_async(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr); +} + static int dm9601_set_mac_address(struct net_device *net, void *p) { struct sockaddr *addr = p; @@ -406,7 +411,7 @@ static int dm9601_set_mac_address(struct net_device *net, void *p) return -EINVAL; memcpy(net->dev_addr, addr->sa_data, net->addr_len); - dm_write_async(dev, DM_PHY_ADDR, net->addr_len, net->dev_addr); + __dm9601_set_mac_address(dev); return 0; } @@ -450,6 +455,8 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) */ if (is_valid_ether_addr(mac)) memcpy(dev->net->dev_addr, mac, ETH_ALEN); + else + __dm9601_set_mac_address(dev); /* power up phy */ dm_write_reg(dev, DM_GPR_CTRL, 1); -- cgit From f52deb0e8408515ecf58c330c93fa99b8cb53cb4 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Thu, 8 Jan 2009 10:47:01 -0800 Subject: dm9601: warn on invalid mac address Add warnings on invalid mac address to help disclose/debug problems. Signed-off-by: Wu Fengguang Acked-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 63e97a38708..5b67bbf1987 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -407,8 +407,11 @@ static int dm9601_set_mac_address(struct net_device *net, void *p) struct sockaddr *addr = p; struct usbnet *dev = netdev_priv(net); - if (!is_valid_ether_addr(addr->sa_data)) + if (!is_valid_ether_addr(addr->sa_data)) { + dev_err(&net->dev, "not setting invalid mac address %pM\n", + addr->sa_data); return -EINVAL; + } memcpy(net->dev_addr, addr->sa_data, net->addr_len); __dm9601_set_mac_address(dev); @@ -455,8 +458,12 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) */ if (is_valid_ether_addr(mac)) memcpy(dev->net->dev_addr, mac, ETH_ALEN); - else + else { + printk(KERN_WARNING + "dm9601: No valid MAC address in EEPROM, using %pM\n", + dev->net->dev_addr); __dm9601_set_mac_address(dev); + } /* power up phy */ dm_write_reg(dev, DM_GPR_CTRL, 1); -- cgit From 33a2a2b4c7076fc3ff1ee77d2376723dd12df44d Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Thu, 8 Jan 2009 10:52:26 -0800 Subject: netdev: bfin_mac: enable bfin_mac net dev driver for BF51x Signed-off-by: Sonic Zhang Signed-off-by: Bryan Wu Signed-off-by: David S. Miller --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9a18270c108..6b1eb43d063 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -830,7 +830,7 @@ config ULTRA32 config BFIN_MAC tristate "Blackfin on-chip MAC support" - depends on NET_ETHERNET && (BF526 || BF527 || BF536 || BF537) + depends on NET_ETHERNET && (BF516 || BF518 || BF526 || BF527 || BF536 || BF537) select CRC32 select MII select PHYLIB -- cgit From 41efea5a34caa76c11e56458db21eb259d5c6384 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Thu, 8 Jan 2009 10:57:15 -0800 Subject: mlx4_en: Consider inline packets on completion Was trying to unmap work queue entries that had inline packets, so naturally weren't mapped. Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_tx.c | 59 ++++++++++++++++++++++++++-------------------- drivers/net/mlx4/mlx4_en.h | 1 + 2 files changed, 34 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index ff4d75205c2..4afd5993e31 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -203,19 +203,21 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, /* Optimize the common case when there are no wraparounds */ if (likely((void *) tx_desc + tx_info->nr_txbb * TXBB_SIZE <= end)) { - if (tx_info->linear) { - pci_unmap_single(mdev->pdev, - (dma_addr_t) be64_to_cpu(data->addr), + if (!tx_info->inl) { + if (tx_info->linear) { + pci_unmap_single(mdev->pdev, + (dma_addr_t) be64_to_cpu(data->addr), be32_to_cpu(data->byte_count), PCI_DMA_TODEVICE); - ++data; - } + ++data; + } - for (i = 0; i < frags; i++) { - frag = &skb_shinfo(skb)->frags[i]; - pci_unmap_page(mdev->pdev, - (dma_addr_t) be64_to_cpu(data[i].addr), - frag->size, PCI_DMA_TODEVICE); + for (i = 0; i < frags; i++) { + frag = &skb_shinfo(skb)->frags[i]; + pci_unmap_page(mdev->pdev, + (dma_addr_t) be64_to_cpu(data[i].addr), + frag->size, PCI_DMA_TODEVICE); + } } /* Stamp the freed descriptor */ for (i = 0; i < tx_info->nr_txbb * TXBB_SIZE; i += STAMP_STRIDE) { @@ -224,27 +226,29 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, } } else { - if ((void *) data >= end) { - data = (struct mlx4_wqe_data_seg *) - (ring->buf + ((void *) data - end)); - } + if (!tx_info->inl) { + if ((void *) data >= end) { + data = (struct mlx4_wqe_data_seg *) + (ring->buf + ((void *) data - end)); + } - if (tx_info->linear) { - pci_unmap_single(mdev->pdev, - (dma_addr_t) be64_to_cpu(data->addr), + if (tx_info->linear) { + pci_unmap_single(mdev->pdev, + (dma_addr_t) be64_to_cpu(data->addr), be32_to_cpu(data->byte_count), PCI_DMA_TODEVICE); - ++data; - } + ++data; + } - for (i = 0; i < frags; i++) { - /* Check for wraparound before unmapping */ - if ((void *) data >= end) - data = (struct mlx4_wqe_data_seg *) ring->buf; - frag = &skb_shinfo(skb)->frags[i]; - pci_unmap_page(mdev->pdev, + for (i = 0; i < frags; i++) { + /* Check for wraparound before unmapping */ + if ((void *) data >= end) + data = (struct mlx4_wqe_data_seg *) ring->buf; + frag = &skb_shinfo(skb)->frags[i]; + pci_unmap_page(mdev->pdev, (dma_addr_t) be64_to_cpu(data->addr), frag->size, PCI_DMA_TODEVICE); + } } /* Stamp the freed descriptor */ for (i = 0; i < tx_info->nr_txbb * TXBB_SIZE; i += STAMP_STRIDE) { @@ -790,8 +794,11 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) wmb(); data->byte_count = cpu_to_be32(skb_headlen(skb) - lso_header_size); } - } else + tx_info->inl = 0; + } else { build_inline_wqe(tx_desc, skb, real_size, &vlan_tag, tx_ind, fragptr); + tx_info->inl = 1; + } ring->prod += nr_txbb; diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 2e96c7b2180..08bf321a9e6 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -202,6 +202,7 @@ struct mlx4_en_tx_info { u32 nr_txbb; u8 linear; u8 data_offset; + u8 inl; }; -- cgit From bd531e36b8aa223aded15493d0a93930e1de51c6 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Thu, 8 Jan 2009 10:57:37 -0800 Subject: mlx4_en: Returning real Max in get_ringparam Signed-off-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/mlx4/en_params.c | 6 ++++-- drivers/net/mlx4/mlx4_en.h | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/en_params.c b/drivers/net/mlx4/en_params.c index cfeef0f1bac..c1bd040b9e0 100644 --- a/drivers/net/mlx4/en_params.c +++ b/drivers/net/mlx4/en_params.c @@ -399,8 +399,10 @@ static int mlx4_en_set_ringparam(struct net_device *dev, rx_size = roundup_pow_of_two(param->rx_pending); rx_size = max_t(u32, rx_size, MLX4_EN_MIN_RX_SIZE); + rx_size = min_t(u32, rx_size, MLX4_EN_MAX_RX_SIZE); tx_size = roundup_pow_of_two(param->tx_pending); tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE); + tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE); if (rx_size == priv->prof->rx_ring_size && tx_size == priv->prof->tx_ring_size) @@ -440,8 +442,8 @@ static void mlx4_en_get_ringparam(struct net_device *dev, struct mlx4_en_dev *mdev = priv->mdev; memset(param, 0, sizeof(*param)); - param->rx_max_pending = mdev->dev->caps.max_rq_sg; - param->tx_max_pending = mdev->dev->caps.max_sq_sg; + param->rx_max_pending = MLX4_EN_MAX_RX_SIZE; + param->tx_max_pending = MLX4_EN_MAX_TX_SIZE; param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size; param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size; } diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 08bf321a9e6..e9af32d41ca 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -115,6 +115,10 @@ enum { }; #define MLX4_EN_MAX_RX_FRAGS 4 +/* Maximum ring sizes */ +#define MLX4_EN_MAX_TX_SIZE 8192 +#define MLX4_EN_MAX_RX_SIZE 8192 + /* Minimum ring size for our page-allocation sceme to work */ #define MLX4_EN_MIN_RX_SIZE (MLX4_EN_ALLOC_SIZE / SMP_CACHE_BYTES) #define MLX4_EN_MIN_TX_SIZE (4096 / TXBB_SIZE) -- cgit From a1d8f6015e0fab61cc27204560d54a442181be54 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 8 Jan 2009 10:58:38 -0800 Subject: gianfar: Fixup use of BUS_ID_SIZE Commit b31a1d8b41513b96e9c7ec2f68c5734cef0b26a4 ("gianfar: Convert gianfar to an of_platform_driver") went back to using BUS_ID_SIZE instead of sizeof() as per the larger patch series that will remove "char bus_id[20]" from struct device. Signed-off-by: Kumar Gala Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 7fcc3af3f86..1b8deca8b9f 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -238,8 +238,8 @@ static int gfar_of_init(struct net_device *dev) goto err_out; } - snprintf(priv->phy_bus_id, BUS_ID_SIZE, PHY_ID_FMT, "0", - fixed_link[0]); + snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), + PHY_ID_FMT, "0", fixed_link[0]); } else { phy = of_find_node_by_phandle(*ph); @@ -256,7 +256,7 @@ static int gfar_of_init(struct net_device *dev) of_node_put(mdio); gfar_mdio_bus_name(bus_name, mdio); - snprintf(priv->phy_bus_id, BUS_ID_SIZE, "%s:%02x", + snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x", bus_name, *id); } -- cgit From 9a48ce84004eb61940850c7066af5d222a5f81c9 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 8 Jan 2009 11:00:52 -0800 Subject: r6040: make printks consistent with DRV_NAME This patch fixes some printks which were not prefixed with DRV_NAME, useful when having multiple cards/drivers on the system. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 53bbddfc8c9..92b14c87135 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -200,7 +200,7 @@ struct r6040_private { static char version[] __devinitdata = KERN_INFO DRV_NAME ": RDC R6040 NAPI net driver," - "version "DRV_VERSION " (" DRV_RELDATE ")\n"; + "version "DRV_VERSION " (" DRV_RELDATE ")"; static int phy_table[] = { PHY1_ADDR, PHY2_ADDR }; @@ -330,7 +330,7 @@ static int r6040_alloc_rxbufs(struct net_device *dev) do { skb = netdev_alloc_skb(dev, MAX_BUF_SIZE); if (!skb) { - printk(KERN_ERR "%s: failed to alloc skb for rx\n", dev->name); + printk(KERN_ERR DRV_NAME "%s: failed to alloc skb for rx\n", dev->name); rc = -ENOMEM; goto err_exit; } @@ -1077,20 +1077,20 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, /* this should always be supported */ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (err) { - printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" + printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses" "not supported by the card\n"); goto err_out; } err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); if (err) { - printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" + printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses" "not supported by the card\n"); goto err_out; } /* IO Size check */ if (pci_resource_len(pdev, 0) < io_size) { - printk(KERN_ERR DRV_NAME "Insufficient PCI resources, aborting\n"); + printk(KERN_ERR DRV_NAME ": Insufficient PCI resources, aborting\n"); err = -EIO; goto err_out; } @@ -1100,7 +1100,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct r6040_private)); if (!dev) { - printk(KERN_ERR DRV_NAME "Failed to allocate etherdev\n"); + printk(KERN_ERR DRV_NAME ": Failed to allocate etherdev\n"); err = -ENOMEM; goto err_out; } @@ -1116,7 +1116,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, ioaddr = pci_iomap(pdev, bar, io_size); if (!ioaddr) { - printk(KERN_ERR "ioremap failed for device %s\n", + printk(KERN_ERR DRV_NAME ": ioremap failed for device %s\n", pci_name(pdev)); err = -EIO; goto err_out_free_res; -- cgit From 84314bf92265bccea601ed75ec93944e1a36dd81 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 8 Jan 2009 11:01:58 -0800 Subject: r6040: check PHY status when bringing interface up This patch makes the driver properly initialize the PHY status if not correctly set by the bootloader/BIOS. It prevents some boards to bring up the link on boot. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 92b14c87135..7ac6fede6e6 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -1121,6 +1121,10 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, err = -EIO; goto err_out_free_res; } + /* If PHY status change register is still set to zero it means the + * bootloader didn't initialize it */ + if (ioread16(ioaddr + PHY_CC) == 0) + iowrite16(0x9f07, ioaddr + PHY_CC); /* Init system & device */ lp->base = ioaddr; -- cgit From 1d2b1a76d39433ba9eb065bb31d3594cb491e617 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 8 Jan 2009 11:02:30 -0800 Subject: r6040: warn about MAC address being unset Some bootloader/BIOSes do not set the MAC address, warn about that. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 7ac6fede6e6..3354cceb75d 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -1141,6 +1141,11 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, adrp[1] = ioread16(ioaddr + MID_0M); adrp[2] = ioread16(ioaddr + MID_0H); + /* Some bootloader/BIOSes do not initialize + * MAC address, warn about that */ + if (!(adrp[0] || adrp[1] || adrp[2])) + printk(KERN_WARNING DRV_NAME ": MAC address not initialized\n"); + /* Link new device into r6040_root_dev */ lp->pdev = pdev; lp->dev = dev; -- cgit From b8c31da64165b8566fc6e1c9c826f76e7b98ff02 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 8 Jan 2009 11:03:57 -0800 Subject: r6040: bump release number to 0.20 This patch bumps release number to 0.20 and 07Jan2009. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 3354cceb75d..cf3a082bc89 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -49,8 +49,8 @@ #include #define DRV_NAME "r6040" -#define DRV_VERSION "0.19" -#define DRV_RELDATE "18Dec2008" +#define DRV_VERSION "0.20" +#define DRV_RELDATE "07Jan2009" /* PHY CHIP Address */ #define PHY1_ADDR 1 /* For MAC1 */ -- cgit From 9fd7a1d92b4462acaa460bb0f58b12ede6ffe6b9 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Thu, 8 Jan 2009 11:08:25 -0800 Subject: i2400m/usb: wrap USB power saving in #ifdef CONFIG_PM Current code was assuming PM was always enabled, which is not correct. Code which accesses members in the struct usb_device that are dependant on CONFIG_PM must be protected the same. Reported by Randy Dunlap from a build error in the linux-next tree on 07/01/2009. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/usb.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index 6d4b65fd9c1..c6d93465c7e 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -397,11 +397,13 @@ int i2400mu_probe(struct usb_interface *iface, i2400m->bus_fw_name = I2400MU_FW_FILE_NAME; i2400m->bus_bm_mac_addr_impaired = 0; +#ifdef CONFIG_PM iface->needs_remote_wakeup = 1; /* autosuspend (15s delay) */ device_init_wakeup(dev, 1); usb_autopm_enable(i2400mu->usb_iface); usb_dev->autosuspend_delay = 15 * HZ; usb_dev->autosuspend_disabled = 0; +#endif result = i2400m_setup(i2400m, I2400M_BRI_MAC_REINIT); if (result < 0) { @@ -493,7 +495,9 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg) int result = 0; struct device *dev = &iface->dev; struct i2400mu *i2400mu = usb_get_intfdata(iface); +#ifdef CONFIG_PM struct usb_device *usb_dev = i2400mu->usb_dev; +#endif struct i2400m *i2400m = &i2400mu->i2400m; d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event); @@ -503,11 +507,13 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg) atomic_dec(&i2400mu->do_autopm); result = i2400m_cmd_enter_powersave(i2400m); atomic_inc(&i2400mu->do_autopm); +#ifdef CONFIG_PM if (result < 0 && usb_dev->auto_pm == 0) { /* System suspend, can't fail */ dev_err(dev, "failed to suspend, will reset on resume\n"); result = 0; } +#endif if (result < 0) goto error_enter_powersave; i2400mu_notification_release(i2400mu); -- cgit From 283a21d3e16e9709012cc8b0839ec474d8888a5d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 8 Jan 2009 11:17:13 -0800 Subject: pcnet32: round off carrier watch timer The link check watchdog timer on this driver fires every two seconds, but since not aligned it causes extra wakeups. It is more important on this driver than most because it is the hardware that is emulated by default when using network interfaces on VMware. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/pcnet32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index c1bef953bf0..665a4286da3 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -2282,7 +2282,7 @@ static int pcnet32_open(struct net_device *dev) if (lp->chip_version >= PCNET32_79C970A) { /* Print the link status and start the watchdog */ pcnet32_check_media(dev, 1); - mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); + mod_timer(&lp->watchdog_timer, PCNET32_WATCHDOG_TIMEOUT); } i = 0; @@ -2917,7 +2917,7 @@ static void pcnet32_watchdog(struct net_device *dev) pcnet32_check_media(dev, 0); spin_unlock_irqrestore(&lp->lock, flags); - mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); + mod_timer(&lp->watchdog_timer, round_jiffies(PCNET32_WATCHDOG_TIMEOUT)); } static int pcnet32_pm_suspend(struct pci_dev *pdev, pm_message_t state) -- cgit From 321ea8b2d37e1e09e65415c421403b40d7d81c1c Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 8 Jan 2009 11:20:22 -0800 Subject: net: switch kaweth driver to netdevops This converts the kaweth ethernet USB driver to netdevops. Signed-off-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/kaweth.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 3073ca25a0b..7cb10a0a531 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -251,7 +251,6 @@ struct kaweth_device struct net_device_stats stats; }; - /**************************************************************** * kaweth_control ****************************************************************/ @@ -975,6 +974,17 @@ static int kaweth_resume(struct usb_interface *intf) /**************************************************************** * kaweth_probe ****************************************************************/ + + +static const struct net_device_ops kaweth_netdev_ops = { + .ndo_open = kaweth_open, + .ndo_stop = kaweth_close, + .ndo_start_xmit = kaweth_start_xmit, + .ndo_tx_timeout = kaweth_tx_timeout, + .ndo_set_multicast_list = kaweth_set_rx_mode, + .ndo_get_stats = kaweth_netdev_stats, +}; + static int kaweth_probe( struct usb_interface *intf, const struct usb_device_id *id /* from id_table */ @@ -1147,22 +1157,13 @@ err_fw: memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr, sizeof(kaweth->configuration.hw_addr)); - netdev->open = kaweth_open; - netdev->stop = kaweth_close; - + netdev->netdev_ops = &kaweth_netdev_ops; netdev->watchdog_timeo = KAWETH_TX_TIMEOUT; - netdev->tx_timeout = kaweth_tx_timeout; - - netdev->hard_start_xmit = kaweth_start_xmit; - netdev->set_multicast_list = kaweth_set_rx_mode; - netdev->get_stats = kaweth_netdev_stats; netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size); SET_ETHTOOL_OPS(netdev, &ops); /* kaweth is zeroed as part of alloc_netdev */ - INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl); - usb_set_intfdata(intf, kaweth); #if 0 -- cgit From 9f4c95835654f6169469af8a1de91454f7a65ac1 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 8 Jan 2009 11:21:43 -0800 Subject: bnx2x: Prevent eeprom set when driver is down Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ef8103b3523..4be05847f86 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -8243,6 +8243,9 @@ static int bnx2x_set_eeprom(struct net_device *dev, 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, -- cgit From 8cb89571bd66fec6a71d8a2b1de2262722dfbb8d Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 8 Jan 2009 11:22:25 -0800 Subject: net: convert pegasus driver to net_device_ops This converts the pegasus driver to use of the new net_device_ops structure Signed-off-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/pegasus.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index d9241f1c080..a8228d87c8c 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -93,6 +93,7 @@ module_param (msg_level, int, 0); MODULE_PARM_DESC (msg_level, "Override default message level"); MODULE_DEVICE_TABLE(usb, pegasus_ids); +static const struct net_device_ops pegasus_netdev_ops; static int update_eth_regs_async(pegasus_t *); /* Aargh!!! I _really_ hate such tweaks */ @@ -1360,14 +1361,10 @@ static int pegasus_probe(struct usb_interface *intf, pegasus->intf = intf; pegasus->usb = dev; pegasus->net = net; - net->open = pegasus_open; - net->stop = pegasus_close; + + net->watchdog_timeo = PEGASUS_TX_TIMEOUT; - net->tx_timeout = pegasus_tx_timeout; - net->do_ioctl = pegasus_ioctl; - net->hard_start_xmit = pegasus_start_xmit; - net->set_multicast_list = pegasus_set_multicast; - net->get_stats = pegasus_netdev_stats; + net->netdev_ops = &pegasus_netdev_ops; SET_ETHTOOL_OPS(net, &ops); pegasus->mii.dev = net; pegasus->mii.mdio_read = mdio_read; @@ -1482,6 +1479,16 @@ static int pegasus_resume (struct usb_interface *intf) return 0; } +static const struct net_device_ops pegasus_netdev_ops = { + .ndo_open = pegasus_open, + .ndo_stop = pegasus_close, + .ndo_do_ioctl = pegasus_ioctl, + .ndo_start_xmit = pegasus_start_xmit, + .ndo_set_multicast_list = pegasus_set_multicast, + .ndo_get_stats = pegasus_netdev_stats, + .ndo_tx_timeout = pegasus_tx_timeout, +}; + static struct usb_driver pegasus_driver = { .name = driver_name, .probe = pegasus_probe, -- cgit From 70cb92539cd1b8e1dec935a68fc154ea0db3a177 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 9 Jan 2009 13:14:07 -0800 Subject: mlx4_core: Fix warning from min() Recent cpumask changes changed num_possible_cpus() from returning an int to returning an unsigned int. This means that doing min(num_possible_cpus(), ) now produces a warning like drivers/net/mlx4/main.c: In function 'mlx4_enable_msi_x': drivers/net/mlx4/main.c:915: warning: comparison of distinct pointer types lacks a cast Fix this by using min_t(int, ...). Signed-off-by: Roland Dreier --- drivers/net/mlx4/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 710c79e7a2d..6ef2490d5c3 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -912,8 +912,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) int i; if (msi_x) { - nreq = min(dev->caps.num_eqs - dev->caps.reserved_eqs, - num_possible_cpus() + 1); + nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, + num_possible_cpus() + 1); entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); if (!entries) goto no_msi; -- cgit From 216c32d4407ea6951d6832773fdb3de058e12c62 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 8 Jan 2009 16:42:08 -0800 Subject: irda: fix incomplete conversation to internal stats Fix for commit af0490810c (irda: convert to internal stats) Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/irda/au1k_ir.c | 2 +- drivers/net/irda/donauboe.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 75a1d0a86de..941164076a2 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -594,7 +594,7 @@ static int au1k_irda_rx(struct net_device *dev) update_rx_stats(dev, flags, count); skb=alloc_skb(count+1,GFP_ATOMIC); if (skb == NULL) { - aup->stats.rx_dropped++; + aup->netdev->stats.rx_dropped++; continue; } skb_reserve(skb, 1); diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 687c2d53d4d..6f3e7f71658 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -1194,13 +1194,13 @@ toshoboe_interrupt (int irq, void *dev_id) txp = txpc; txpc++; txpc %= TX_SLOTS; - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS) self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX; } - self->stats.tx_packets--; + self->netdev->stats.tx_packets--; #else - self->stats.tx_packets++; + self->netdev->stats.tx_packets++; #endif toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX); } @@ -1280,7 +1280,7 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<'); skb_put (skb, len); skb_copy_to_linear_data(skb, self->rx_bufs[self->rxs], len); - self->stats.rx_packets++; + self->netdev->stats.rx_packets++; skb->dev = self->netdev; skb_reset_mac_header(skb); skb->protocol = htons (ETH_P_IRDA); -- cgit From 58854c6b411e9e9f46b39bd7092022f639c41904 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 9 Jan 2009 23:19:26 -0800 Subject: r6040: fix ifconfig down and freeing of tx/rx descriptors This patch fixes warnings and such traces that appear when doing an ifconfig down on the interface: WARNING: at arch/x86/kernel/pci-dma.c:376 dma_free_coherent+0x40/0x7d() Modules linked in: Signed-off-by: Joe Chou Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index cf3a082bc89..b59837e8075 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -457,22 +457,12 @@ static void r6040_down(struct net_device *dev) iowrite16(adrp[0], ioaddr + MID_0L); iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[2], ioaddr + MID_0H); - free_irq(dev->irq, dev); - - /* Free RX buffer */ - r6040_free_rxbufs(dev); - - /* Free TX buffer */ - r6040_free_txbufs(dev); - - /* Free Descriptor memory */ - pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); - pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); } static int r6040_close(struct net_device *dev) { struct r6040_private *lp = netdev_priv(dev); + struct pci_dev *pdev = lp->pdev; /* deleted timer */ del_timer_sync(&lp->timer); @@ -481,8 +471,28 @@ static int r6040_close(struct net_device *dev) napi_disable(&lp->napi); netif_stop_queue(dev); r6040_down(dev); + + free_irq(dev->irq, dev); + + /* Free RX buffer */ + r6040_free_rxbufs(dev); + + /* Free TX buffer */ + r6040_free_txbufs(dev); + spin_unlock_irq(&lp->lock); + /* Free Descriptor memory */ + if (lp->rx_ring) { + pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); + lp->rx_ring = 0; + } + + if (lp->tx_ring) { + pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); + lp->tx_ring = 0; + } + return 0; } -- cgit From 9f1136182f732f6e847fc43bd88b579739d5c211 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 8 Jan 2009 15:04:45 +0000 Subject: r6040: generate random ethernet MAC address when not initialized This patch makes the ethernet driver assign a random ethernet MAC address when the bootloader does not set it. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index b59837e8075..8b5d50927eb 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -1153,8 +1153,10 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, /* Some bootloader/BIOSes do not initialize * MAC address, warn about that */ - if (!(adrp[0] || adrp[1] || adrp[2])) - printk(KERN_WARNING DRV_NAME ": MAC address not initialized\n"); + if (!(adrp[0] || adrp[1] || adrp[2])) { + printk(KERN_WARNING DRV_NAME ": MAC address not initialized, generating random\n"); + random_ether_addr(dev->dev_addr); + } /* Link new device into r6040_root_dev */ lp->pdev = pdev; -- cgit From 68334115eecc2502426657a1449dd04b3572ae0d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 8 Jan 2009 15:04:50 +0000 Subject: r6040: no longer mark r6040 as being experimental We do not depend on EXPERIMENTAL and the driver is not experimental, so remove this warning. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 65afda4a62d..9fe8cb7d43a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1600,7 +1600,7 @@ config 8139_OLD_RX_RESET old RX-reset behavior. If unsure, say N. config R6040 - tristate "RDC R6040 Fast Ethernet Adapter support (EXPERIMENTAL)" + tristate "RDC R6040 Fast Ethernet Adapter support" depends on NET_PCI && PCI select CRC32 select MII -- cgit From e56e356b21c285663712dc39aa9e4303072cbaba Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 8 Jan 2009 15:04:57 +0000 Subject: r6040: bump release to 0.21 Bump version to 0.21 and release date to 09Jan2009. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 8b5d50927eb..454e7dea0bc 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -49,8 +49,8 @@ #include #define DRV_NAME "r6040" -#define DRV_VERSION "0.20" -#define DRV_RELDATE "07Jan2009" +#define DRV_VERSION "0.21" +#define DRV_RELDATE "09Jan2009" /* PHY CHIP Address */ #define PHY1_ADDR 1 /* For MAC1 */ -- cgit From eefacf3b4f8a688aeaddd2f7c46ac5ffceb92472 Mon Sep 17 00:00:00 2001 From: David Graham Date: Thu, 8 Jan 2009 16:03:29 +0000 Subject: e1000e: Add process name to WARN message when detecting Mutex contention Adds process name of the current mutex holder to the WARN message output when the e1000e driver attempts to acquire the nvm_mutex and finds that it is already being held. With this patch the WARN message indicates both the process name of the current mutex holder and the process name of the attempted acquisition, which together will help to identify the contending codepaths. Signed-off-by: David Graham Acked-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/ich8lan.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index f2a5963b5a9..e415e81ecd3 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -390,7 +390,8 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) } static DEFINE_MUTEX(nvm_mutex); -static pid_t nvm_owner = -1; +static pid_t nvm_owner_pid = -1; +static char nvm_owner_name[TASK_COMM_LEN] = ""; /** * e1000_acquire_swflag_ich8lan - Acquire software control flag @@ -408,11 +409,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) might_sleep(); if (!mutex_trylock(&nvm_mutex)) { - WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n", - nvm_owner); + WARN(1, KERN_ERR "e1000e mutex contention. Owned by process " + "%s (pid %d), required by process %s (pid %d)\n", + nvm_owner_name, nvm_owner_pid, + current->comm, current->pid); + mutex_lock(&nvm_mutex); } - nvm_owner = current->pid; + nvm_owner_pid = current->pid; + strncpy(nvm_owner_name, current->comm, TASK_COMM_LEN); while (timeout) { extcnf_ctrl = er32(EXTCNF_CTRL); @@ -430,7 +435,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); - nvm_owner = -1; + nvm_owner_pid = -1; + strcpy(nvm_owner_name, ""); mutex_unlock(&nvm_mutex); return -E1000_ERR_CONFIG; } @@ -454,7 +460,8 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); - nvm_owner = -1; + nvm_owner_pid = -1; + strcpy(nvm_owner_name, ""); mutex_unlock(&nvm_mutex); } -- cgit From 4ca857958c129781b46870ec1d2d13c50aafb8c5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 9 Jan 2009 02:39:57 +0000 Subject: b44: fix misalignment and wasted space in rx handling Broadcom 4400 puts a header of configurable size (apparently needs to be at least 28 bytes) in front of received packets. When handling this, the previous code accidentally added the offset 30 *twice* for the software and once for the hardware, thereby cancelling out the IP alignment effect of the 30 byte padding and wasting an additional 30 bytes of memory per packet. This patch fixes this problem and improves routing throughput by about 30% on MIPS, where unaligned access is expensive. Signed-off-by: Felix Fietkau Signed-off-by: David S. Miller --- drivers/net/b44.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 6926ebedfdc..5ae131c147f 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -73,8 +73,8 @@ (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP)) #define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1)) -#define RX_PKT_OFFSET 30 -#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET + 64) +#define RX_PKT_OFFSET (RX_HEADER_LEN + 2) +#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET) /* minimum number of free TX descriptors required to wake up TX process */ #define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) @@ -682,7 +682,6 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) } rh = (struct rx_header *) skb->data; - skb_reserve(skb, RX_PKT_OFFSET); rh->len = 0; rh->flags = 0; @@ -693,13 +692,13 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) if (src_map != NULL) src_map->skb = NULL; - ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET)); + ctrl = (DESC_CTRL_LEN & RX_PKT_BUF_SZ); if (dest_idx == (B44_RX_RING_SIZE - 1)) ctrl |= DESC_CTRL_EOT; dp = &bp->rx_ring[dest_idx]; dp->ctrl = cpu_to_le32(ctrl); - dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset); + dp->addr = cpu_to_le32((u32) mapping + bp->dma_offset); if (bp->flags & B44_FLAG_RX_RING_HACK) b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma, @@ -809,8 +808,8 @@ static int b44_rx(struct b44 *bp, int budget) ssb_dma_unmap_single(bp->sdev, map, skb_size, DMA_FROM_DEVICE); /* Leave out rx_header */ - skb_put(skb, len + RX_PKT_OFFSET); - skb_pull(skb, RX_PKT_OFFSET); + skb_put(skb, len + RX_PKT_OFFSET); + skb_pull(skb, RX_PKT_OFFSET); } else { struct sk_buff *copy_skb; -- cgit From c224969e636ea027e7ce474b48e84922e62ca1d6 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Fri, 9 Jan 2009 03:14:47 +0000 Subject: qlge: Naming interrupt vectors Name interrupt vectors according to the new naming standard, by Robert Olsson and DaveM. The qlge driver were very close to the new standard, thus the change is kind of trivial. Signed-off-by: Jesper Dangaard Brouer Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index f4c016012f1..b7e40add958 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2746,14 +2746,14 @@ static void ql_resolve_queues_to_irqs(struct ql_adapter *qdev) * Outbound queue is for outbound completions only. */ intr_context->handler = qlge_msix_tx_isr; - sprintf(intr_context->name, "%s-txq-%d", + sprintf(intr_context->name, "%s-tx-%d", qdev->ndev->name, i); } else { /* * Inbound queues handle unicast frames only. */ intr_context->handler = qlge_msix_rx_isr; - sprintf(intr_context->name, "%s-rxq-%d", + sprintf(intr_context->name, "%s-rx-%d", qdev->ndev->name, i); } } -- cgit From c17931c52ec6b1af710185986e10c344039edeb7 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Fri, 9 Jan 2009 03:53:17 +0000 Subject: 3c59x: Use device_set_wakeup_enable Since dev->power.should_wakeup bit is used by the PCI core to decide whether the device should wake up the system from sleep states, set this bit by calling device_set_wakeup_enable(). This restores proper WOL for the 3c59x driver. Reported-and-tested-by: Graeme Wilford Reported-by: Gunnar Degnbol Signed-off-by: Steffen Klassert Signed-off-by: David S. Miller --- drivers/net/3c59x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 665e7fdf27a..cdbbb6226fc 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -3109,6 +3109,8 @@ static void acpi_set_WOL(struct net_device *dev) struct vortex_private *vp = netdev_priv(dev); void __iomem *ioaddr = vp->ioaddr; + device_set_wakeup_enable(vp->gendev, vp->enable_wol); + if (vp->enable_wol) { /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */ EL3WINDOW(7); -- cgit From 0397a2648434a65d73564216c4f96945c192ad4a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 9 Jan 2009 10:23:09 +0000 Subject: drivers/net/hamradio/6pack.c: move a dereference below a NULL test In each case, if the NULL test is necessary, then the dereference should be moved below the NULL test. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ type T; expression E; identifier i,fld; statement S; @@ - T i = E->fld; + T i; ... when != E when != i if (E == NULL) S + i = E->fld; // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/hamradio/6pack.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 50f1e172ee8..2d4089894ec 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -717,11 +717,12 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct sixpack *sp = sp_get(tty); - struct net_device *dev = sp->dev; + struct net_device *dev; unsigned int tmp, err; if (!sp) return -ENXIO; + dev = sp->dev; switch(cmd) { case SIOCGIFNAME: -- cgit From 43baa5bb26298e8e268056c58900098ce8454548 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 9 Jan 2009 10:23:10 +0000 Subject: drivers/net/wireless/libertas: move a dereference below a NULL test In each case, if the NULL test is necessary, then the dereference should be moved below the NULL test. I have also taken advantage of the availability of the value of priv->dev in the subsequent calls to netif_stop_queue and netif_carrier_off. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ type T; expression E; identifier i,fld; statement S; @@ - T i = E->fld; + T i; ... when != E when != i if (E == NULL) S + i = E->fld; // Signed-off-by: Julia Lawall Acked-by: Dan Williams Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/wireless/libertas/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 3dba8367944..4e0007d2003 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1369,7 +1369,7 @@ EXPORT_SYMBOL_GPL(lbs_start_card); void lbs_stop_card(struct lbs_private *priv) { - struct net_device *dev = priv->dev; + struct net_device *dev; struct cmd_ctrl_node *cmdnode; unsigned long flags; @@ -1377,9 +1377,10 @@ void lbs_stop_card(struct lbs_private *priv) if (!priv) goto out; + dev = priv->dev; - netif_stop_queue(priv->dev); - netif_carrier_off(priv->dev); + netif_stop_queue(dev); + netif_carrier_off(dev); lbs_debugfs_remove_one(priv); if (priv->mesh_tlv) { -- cgit From 0faac9f75fa4260d67fed5a67bb2f16dbe2e93c8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 9 Jan 2009 10:23:11 +0000 Subject: netdev: gianfar: add MII ioctl handler This is the same kind of wrapper that can also be found in many other network device drivers. Tested with a freescale MPC8349E host CPU: Toggled the interface LEDs on a DP83865 PHY. Signed-off-by: Clifford Wolf Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1b8deca8b9f..efcbeb6c867 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -296,6 +296,20 @@ err_out: return err; } +/* Ioctl MII Interface */ +static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct gfar_private *priv = netdev_priv(dev); + + if (!netif_running(dev)) + return -EINVAL; + + if (!priv->phydev) + return -ENODEV; + + return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd); +} + /* Set up the ethernet device structure, private data, * and anything else we need before we start */ static int gfar_probe(struct of_device *ofdev, @@ -366,6 +380,7 @@ static int gfar_probe(struct of_device *ofdev, dev->set_multicast_list = gfar_set_multi; dev->ethtool_ops = &gfar_ethtool_ops; + dev->do_ioctl = gfar_ioctl; if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { priv->rx_csum_enable = 1; -- cgit From fe96aaa14f553f0eb7af0e3502563a5400c65257 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 9 Jan 2009 11:13:14 +0000 Subject: netdev: add missing set_mac_address hook Many drivers lost the ability to set ethernet address accidently during the net_device_ops conversion. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/3c503.c | 1 + drivers/net/8139cp.c | 2 ++ drivers/net/8139too.c | 2 +- drivers/net/8390.c | 1 + drivers/net/8390p.c | 1 + drivers/net/arm/etherh.c | 1 + drivers/net/e2100.c | 1 + drivers/net/enic/enic_main.c | 1 + drivers/net/hamachi.c | 1 + drivers/net/hp-plus.c | 1 + drivers/net/hydra.c | 1 + drivers/net/mac8390.c | 1 + drivers/net/ne-h8300.c | 1 + drivers/net/ne2k-pci.c | 1 + drivers/net/ns83820.c | 1 + drivers/net/r6040.c | 1 + drivers/net/sc92031.c | 1 + drivers/net/sis900.c | 1 + drivers/net/smc-mca.c | 1 + drivers/net/smc-ultra.c | 1 + drivers/net/smsc911x.c | 1 + drivers/net/smsc9420.c | 1 + drivers/net/via-rhine.c | 1 + drivers/net/via-velocity.c | 1 + drivers/net/wd.c | 1 + drivers/net/yellowfin.c | 1 + drivers/net/zorro8390.c | 1 + 27 files changed, 28 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index c092c392922..5b91a85fe10 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -177,6 +177,7 @@ static const struct net_device_ops el2_netdev_ops = { .ndo_get_stats = eip_get_stats, .ndo_set_multicast_list = eip_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = eip_poll, diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index dd7ac8290ae..4e19ae3ce6b 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -1821,6 +1821,7 @@ static const struct net_device_ops cp_netdev_ops = { .ndo_open = cp_open, .ndo_stop = cp_close, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_set_multicast_list = cp_set_rx_mode, .ndo_get_stats = cp_get_stats, .ndo_do_ioctl = cp_ioctl, @@ -1832,6 +1833,7 @@ static const struct net_device_ops cp_netdev_ops = { #ifdef BROKEN .ndo_change_mtu = cp_change_mtu, #endif + #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = cp_poll_controller, #endif diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index fe370f80579..a5b24202d56 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -917,6 +917,7 @@ static const struct net_device_ops rtl8139_netdev_ops = { .ndo_stop = rtl8139_close, .ndo_get_stats = rtl8139_get_stats, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_start_xmit = rtl8139_start_xmit, .ndo_set_multicast_list = rtl8139_set_rx_mode, .ndo_do_ioctl = netdev_ioctl, @@ -924,7 +925,6 @@ static const struct net_device_ops rtl8139_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = rtl8139_poll_controller, #endif - }; static int __devinit rtl8139_init_one (struct pci_dev *pdev, diff --git a/drivers/net/8390.c b/drivers/net/8390.c index fbe609a51e0..ec3e22e6306 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -63,6 +63,7 @@ const struct net_device_ops ei_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c index ee70b358a81..da863c91d1d 100644 --- a/drivers/net/8390p.c +++ b/drivers/net/8390p.c @@ -68,6 +68,7 @@ const struct net_device_ops eip_netdev_ops = { .ndo_get_stats = eip_get_stats, .ndo_set_multicast_list = eip_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = eip_poll, diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 6278606d104..745ac188bab 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -646,6 +646,7 @@ static const struct net_device_ops etherh_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_addr = eth_set_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index 20eb05cddb8..b07ba1924de 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -169,6 +169,7 @@ static const struct net_device_ops e21_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index d039e16f276..7d60551d538 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1599,6 +1599,7 @@ static const struct net_device_ops enic_netdev_ops = { .ndo_start_xmit = enic_hard_start_xmit, .ndo_get_stats = enic_get_stats, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_set_multicast_list = enic_set_multicast_list, .ndo_change_mtu = enic_change_mtu, .ndo_vlan_rx_register = enic_vlan_rx_register, diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 32200227c92..7e8b3c59a7d 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -576,6 +576,7 @@ static const struct net_device_ops hamachi_netdev_ops = { .ndo_set_multicast_list = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_tx_timeout = hamachi_tx_timeout, .ndo_do_ioctl = netdev_ioctl, }; diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index b507dbc16e6..5e070f44663 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -166,6 +166,7 @@ static const struct net_device_ops hpp_netdev_ops = { .ndo_get_stats = eip_get_stats, .ndo_set_multicast_list = eip_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = eip_poll, diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index 9cb38a8d438..8ac0930c183 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -103,6 +103,7 @@ static const struct net_device_ops hydra_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c index 57716e22660..8e884869a05 100644 --- a/drivers/net/mac8390.c +++ b/drivers/net/mac8390.c @@ -486,6 +486,7 @@ static const struct net_device_ops mac8390_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c index b5723917104..7bd6662d5b0 100644 --- a/drivers/net/ne-h8300.c +++ b/drivers/net/ne-h8300.c @@ -202,6 +202,7 @@ static const struct net_device_ops ne_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index 62f20ba211c..f090d3b9ec9 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -208,6 +208,7 @@ static const struct net_device_ops ne2k_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 42021aca1dd..e80294d8cc1 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1956,6 +1956,7 @@ static const struct net_device_ops netdev_ops = { .ndo_change_mtu = ns83820_change_mtu, .ndo_set_multicast_list = ns83820_set_multicast, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_tx_timeout = ns83820_tx_timeout, #ifdef NS83820_VLAN_ACCEL_SUPPORT .ndo_vlan_rx_register = ns83820_vlan_rx_register, diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 454e7dea0bc..72fd9e97c19 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -1059,6 +1059,7 @@ static const struct net_device_ops r6040_netdev_ops = { .ndo_set_multicast_list = r6040_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_do_ioctl = r6040_ioctl, .ndo_tx_timeout = r6040_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 42fd3127660..8b75bef4a84 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c @@ -1408,6 +1408,7 @@ static const struct net_device_ops sc92031_netdev_ops = { .ndo_set_multicast_list = sc92031_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_tx_timeout = sc92031_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = sc92031_poll_controller, diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 4acd41a093a..6cbefcae9ac 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -389,6 +389,7 @@ static const struct net_device_ops sis900_netdev_ops = { .ndo_set_multicast_list = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_do_ioctl = mii_ioctl, .ndo_tx_timeout = sis900_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index 404b80e5ba1..8d36d40649e 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -192,6 +192,7 @@ static const struct net_device_ops ultramca_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index b3866089a20..2033fee3143 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -196,6 +196,7 @@ static const struct net_device_ops ultra_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index dc3f1108884..020c5830c37 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1740,6 +1740,7 @@ static const struct net_device_ops smsc911x_netdev_ops = { .ndo_set_multicast_list = smsc911x_set_multicast_list, .ndo_do_ioctl = smsc911x_do_ioctl, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = smsc911x_poll_controller, #endif diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 27e017d9696..c14a4c6452c 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -1551,6 +1551,7 @@ static const struct net_device_ops smsc9420_netdev_ops = { .ndo_set_multicast_list = smsc9420_set_multicast_list, .ndo_do_ioctl = smsc9420_do_ioctl, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = smsc9420_poll_controller, #endif /* CONFIG_NET_POLL_CONTROLLER */ diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index ac07cc6e3cb..3b8e6325427 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -622,6 +622,7 @@ static const struct net_device_ops rhine_netdev_ops = { .ndo_get_stats = rhine_get_stats, .ndo_set_multicast_list = rhine_set_rx_mode, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = rhine_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 58e25d090ae..a75f91dc315 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -855,6 +855,7 @@ static const struct net_device_ops velocity_netdev_ops = { .ndo_start_xmit = velocity_xmit, .ndo_get_stats = velocity_get_stats, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_set_multicast_list = velocity_set_multi, .ndo_change_mtu = velocity_change_mtu, .ndo_do_ioctl = velocity_ioctl, diff --git a/drivers/net/wd.c b/drivers/net/wd.c index 3c1edda08d3..d8322d2d1e2 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -155,6 +155,7 @@ static const struct net_device_ops wd_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index cf971292277..2f1645dcb8c 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -362,6 +362,7 @@ static const struct net_device_ops netdev_ops = { .ndo_set_multicast_list = set_rx_mode, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_do_ioctl = netdev_ioctl, .ndo_tx_timeout = yellowfin_tx_timeout, }; diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c index affd904deaf..37c84e3b8be 100644 --- a/drivers/net/zorro8390.c +++ b/drivers/net/zorro8390.c @@ -147,6 +147,7 @@ static const struct net_device_ops zorro8390_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, -- cgit From 52255bbe3551e481b7af423406ca229a13990b1c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 9 Jan 2009 10:45:37 +0000 Subject: netdev: missing validate_address hooks Some devices were converted incorrectly and are missing the validate address hooks. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/acenic.c | 1 + drivers/net/arm/ks8695net.c | 1 + drivers/net/mlx4/en_netdev.c | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 5b396ff6c83..9589d620639 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -460,6 +460,7 @@ static const struct net_device_ops ace_netdev_ops = { .ndo_get_stats = ace_get_stats, .ndo_start_xmit = ace_start_xmit, .ndo_set_multicast_list = ace_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = ace_set_mac_addr, .ndo_change_mtu = ace_change_mtu, #if ACENIC_DO_VLAN diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 9ad22d1b00f..1cf2f949c0b 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -1357,6 +1357,7 @@ static const struct net_device_ops ks8695_netdev_ops = { .ndo_start_xmit = ks8695_start_xmit, .ndo_tx_timeout = ks8695_timeout, .ndo_set_mac_address = ks8695_set_mac, + .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = ks8695_set_multicast, }; diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 15bb38d9930..9f6644a4403 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -952,6 +952,7 @@ static const struct net_device_ops mlx4_netdev_ops = { .ndo_get_stats = mlx4_en_get_stats, .ndo_set_multicast_list = mlx4_en_set_multicast, .ndo_set_mac_address = mlx4_en_set_mac, + .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = mlx4_en_change_mtu, .ndo_tx_timeout = mlx4_en_tx_timeout, .ndo_vlan_rx_register = mlx4_en_vlan_rx_register, -- cgit From 001eb84bbf7205f8cc541a75364a6a0892b5d0a2 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Fri, 9 Jan 2009 11:03:44 +0000 Subject: forcedeth: xmit lock fix This patch fixes a potential race condition between xmit thread and xmit completion thread. The calculation of empty tx descriptors is not performed under the lock. This could cause it to set the stop flag while the completion thread finishes all tx's. This will result in the tx queue in stopped state and no one to wake it up. Signed-off-by: Ayaz Abdulla Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 5b68dc20168..6905ec9467d 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2096,14 +2096,15 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); } + spin_lock_irqsave(&np->lock, flags); empty_slots = nv_get_empty_tx_slots(np); if (unlikely(empty_slots <= entries)) { - spin_lock_irqsave(&np->lock, flags); netif_stop_queue(dev); np->tx_stop = 1; spin_unlock_irqrestore(&np->lock, flags); return NETDEV_TX_BUSY; } + spin_unlock_irqrestore(&np->lock, flags); start_tx = put_tx = np->put_tx.orig; @@ -2214,14 +2215,15 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); } + spin_lock_irqsave(&np->lock, flags); empty_slots = nv_get_empty_tx_slots(np); if (unlikely(empty_slots <= entries)) { - spin_lock_irqsave(&np->lock, flags); netif_stop_queue(dev); np->tx_stop = 1; spin_unlock_irqrestore(&np->lock, flags); return NETDEV_TX_BUSY; } + spin_unlock_irqrestore(&np->lock, flags); start_tx = put_tx = np->put_tx.ex; start_tx_ctx = np->put_tx_ctx; -- cgit From f1405d32e392f2f5f80f4687fe186305de300bf6 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Fri, 9 Jan 2009 11:03:54 +0000 Subject: forcedeth: version bump and copyright This patch bumps up the version number and adds current year to copyright. Signed-off-by: Ayaz Abdulla Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 6905ec9467d..37a6e956f0b 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -13,7 +13,7 @@ * Copyright (C) 2004 Andrew de Quincey (wol support) * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane * IRQ rate fixes, bigendian fixes, cleanups, verification) - * Copyright (c) 2004,2005,2006,2007,2008 NVIDIA Corporation + * Copyright (c) 2004,2005,2006,2007,2008,2009 NVIDIA 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 @@ -39,7 +39,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.61" +#define FORCEDETH_VERSION "0.62" #define DRV_NAME "forcedeth" #include -- cgit From ba7cd3ba97f81564be3e4a4ee8ee17726aa853d7 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Fri, 9 Jan 2009 11:31:49 +0000 Subject: qlge: Get rid of volatile usage for shadow register. Putting back ql_read_sh_reg() function and using rmb() instead of volatile. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 22 ++++++++++++++++++++-- drivers/net/qlge/qlge_dbg.c | 14 ++++++++------ drivers/net/qlge/qlge_main.c | 12 ++++++------ 3 files changed, 34 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 459663a4023..4cb3647bb1b 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -1145,7 +1145,7 @@ struct tx_ring { struct wqicb wqicb; /* structure used to inform chip of new queue */ void *wq_base; /* pci_alloc:virtual addr for tx */ dma_addr_t wq_base_dma; /* pci_alloc:dma addr for tx */ - u32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */ + __le32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */ dma_addr_t cnsmr_idx_sh_reg_dma; /* dma-shadow copy of consumer */ u32 wq_size; /* size in bytes of queue area */ u32 wq_len; /* number of entries in queue */ @@ -1181,7 +1181,7 @@ struct rx_ring { u32 cq_size; u32 cq_len; u16 cq_id; - volatile __le32 *prod_idx_sh_reg; /* Shadowed producer register. */ + __le32 *prod_idx_sh_reg; /* Shadowed producer register. */ dma_addr_t prod_idx_sh_reg_dma; void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */ u32 cnsmr_idx; /* current sw idx */ @@ -1459,6 +1459,24 @@ static inline void ql_write_db_reg(u32 val, void __iomem *addr) mmiowb(); } +/* + * Shadow Registers: + * Outbound queues have a consumer index that is maintained by the chip. + * Inbound queues have a producer index that is maintained by the chip. + * For lower overhead, these registers are "shadowed" to host memory + * which allows the device driver to track the queue progress without + * PCI reads. When an entry is placed on an inbound queue, the chip will + * update the relevant index register and then copy the value to the + * shadow register in host memory. + */ +static inline u32 ql_read_sh_reg(__le32 *addr) +{ + u32 reg; + reg = le32_to_cpu(*addr); + rmb(); + return reg; +} + extern char qlge_driver_name[]; extern const char qlge_driver_version[]; extern const struct ethtool_ops qlge_ethtool_ops; diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c index 3f5e02d2e4a..e705ea5b975 100644 --- a/drivers/net/qlge/qlge_dbg.c +++ b/drivers/net/qlge/qlge_dbg.c @@ -455,10 +455,11 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring) printk(KERN_ERR PFX "tx_ring->base = %p.\n", tx_ring->wq_base); printk(KERN_ERR PFX "tx_ring->base_dma = 0x%llx.\n", (unsigned long long) tx_ring->wq_base_dma); - printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg = %p.\n", - tx_ring->cnsmr_idx_sh_reg); - printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg_dma = 0x%llx.\n", - (unsigned long long) tx_ring->cnsmr_idx_sh_reg_dma); + printk(KERN_ERR PFX + "tx_ring->cnsmr_idx_sh_reg, addr = 0x%p, value = %d.\n", + tx_ring->cnsmr_idx_sh_reg, + tx_ring->cnsmr_idx_sh_reg + ? ql_read_sh_reg(tx_ring->cnsmr_idx_sh_reg) : 0); printk(KERN_ERR PFX "tx_ring->size = %d.\n", tx_ring->wq_size); printk(KERN_ERR PFX "tx_ring->len = %d.\n", tx_ring->wq_len); printk(KERN_ERR PFX "tx_ring->prod_idx_db_reg = %p.\n", @@ -558,9 +559,10 @@ void ql_dump_rx_ring(struct rx_ring *rx_ring) printk(KERN_ERR PFX "rx_ring->cq_size = %d.\n", rx_ring->cq_size); printk(KERN_ERR PFX "rx_ring->cq_len = %d.\n", rx_ring->cq_len); printk(KERN_ERR PFX - "rx_ring->prod_idx_sh_reg, addr = %p, value = %d.\n", + "rx_ring->prod_idx_sh_reg, addr = 0x%p, value = %d.\n", rx_ring->prod_idx_sh_reg, - rx_ring->prod_idx_sh_reg ? *(rx_ring->prod_idx_sh_reg) : 0); + rx_ring->prod_idx_sh_reg + ? ql_read_sh_reg(rx_ring->prod_idx_sh_reg) : 0); printk(KERN_ERR PFX "rx_ring->prod_idx_sh_reg_dma = %llx.\n", (unsigned long long) rx_ring->prod_idx_sh_reg_dma); printk(KERN_ERR PFX "rx_ring->cnsmr_idx_db_reg = %p.\n", diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index b7e40add958..78df7d11cef 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1545,7 +1545,7 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) { struct ql_adapter *qdev = rx_ring->qdev; - u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); + u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); struct ob_mac_iocb_rsp *net_rsp = NULL; int count = 0; @@ -1571,7 +1571,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) } count++; ql_update_cq(rx_ring); - prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); + prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); } ql_write_cq_idx(rx_ring); if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) { @@ -1591,7 +1591,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) { struct ql_adapter *qdev = rx_ring->qdev; - u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); + u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); struct ql_net_rsp_iocb *net_rsp; int count = 0; @@ -1624,7 +1624,7 @@ static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) } count++; ql_update_cq(rx_ring); - prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); + prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); if (count == budget) break; } @@ -1787,7 +1787,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) * Check the default queue and wake handler if active. */ rx_ring = &qdev->rx_ring[0]; - if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { + if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n"); ql_disable_completion_interrupt(qdev, intr_context->intr); queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue, @@ -1801,7 +1801,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) */ for (i = 1; i < qdev->rx_ring_count; i++) { rx_ring = &qdev->rx_ring[i]; - if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != + if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[%d].\n", i); -- cgit From 97345524392dcbe0157ce2a9d9a589e2022b1c15 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Fri, 9 Jan 2009 11:31:50 +0000 Subject: qlge: Get rid of split addresses in hardware control blocks. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 24 ++++++++-------------- drivers/net/qlge/qlge_dbg.c | 48 +++++++++++++++----------------------------- drivers/net/qlge/qlge_main.c | 26 ++++++++---------------- 3 files changed, 32 insertions(+), 66 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 4cb3647bb1b..96970023226 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -961,8 +961,7 @@ struct ib_mac_iocb_rsp { #define IB_MAC_IOCB_RSP_DS 0x40 /* data is in small buffer */ #define IB_MAC_IOCB_RSP_DL 0x80 /* data is in large buffer */ __le32 data_len; /* */ - __le32 data_addr_lo; /* */ - __le32 data_addr_hi; /* */ + __le64 data_addr; /* */ __le32 rss; /* */ __le16 vlan_id; /* 12 bits */ #define IB_MAC_IOCB_RSP_C 0x1000 /* VLAN CFI bit */ @@ -976,8 +975,7 @@ struct ib_mac_iocb_rsp { #define IB_MAC_IOCB_RSP_HS 0x40 #define IB_MAC_IOCB_RSP_HL 0x80 __le32 hdr_len; /* */ - __le32 hdr_addr_lo; /* */ - __le32 hdr_addr_hi; /* */ + __le64 hdr_addr; /* */ } __attribute((packed)); struct ib_ae_iocb_rsp { @@ -1042,10 +1040,8 @@ struct wqicb { __le16 cq_id_rss; #define Q_CQ_ID_RSS_RV 0x8000 __le16 rid; - __le32 addr_lo; - __le32 addr_hi; - __le32 cnsmr_idx_addr_lo; - __le32 cnsmr_idx_addr_hi; + __le64 addr; + __le64 cnsmr_idx_addr; } __attribute((packed)); /* @@ -1070,18 +1066,14 @@ struct cqicb { #define LEN_CPP_64 0x0002 #define LEN_CPP_128 0x0003 __le16 rid; - __le32 addr_lo; - __le32 addr_hi; - __le32 prod_idx_addr_lo; - __le32 prod_idx_addr_hi; + __le64 addr; + __le64 prod_idx_addr; __le16 pkt_delay; __le16 irq_delay; - __le32 lbq_addr_lo; - __le32 lbq_addr_hi; + __le64 lbq_addr; __le16 lbq_buf_size; __le16 lbq_len; /* entry count */ - __le32 sbq_addr_lo; - __le32 sbq_addr_hi; + __le64 sbq_addr; __le16 sbq_buf_size; __le16 sbq_len; /* entry count */ } __attribute((packed)); diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c index e705ea5b975..379b895ed6e 100644 --- a/drivers/net/qlge/qlge_dbg.c +++ b/drivers/net/qlge/qlge_dbg.c @@ -435,14 +435,10 @@ void ql_dump_wqicb(struct wqicb *wqicb) printk(KERN_ERR PFX "wqicb->cq_id_rss = %d.\n", le16_to_cpu(wqicb->cq_id_rss)); printk(KERN_ERR PFX "wqicb->rid = 0x%x.\n", le16_to_cpu(wqicb->rid)); - printk(KERN_ERR PFX "wqicb->wq_addr_lo = 0x%.08x.\n", - le32_to_cpu(wqicb->addr_lo)); - printk(KERN_ERR PFX "wqicb->wq_addr_hi = 0x%.08x.\n", - le32_to_cpu(wqicb->addr_hi)); - printk(KERN_ERR PFX "wqicb->wq_cnsmr_idx_addr_lo = 0x%.08x.\n", - le32_to_cpu(wqicb->cnsmr_idx_addr_lo)); - printk(KERN_ERR PFX "wqicb->wq_cnsmr_idx_addr_hi = 0x%.08x.\n", - le32_to_cpu(wqicb->cnsmr_idx_addr_hi)); + printk(KERN_ERR PFX "wqicb->wq_addr = 0x%llx.\n", + (unsigned long long) le64_to_cpu(wqicb->addr)); + printk(KERN_ERR PFX "wqicb->wq_cnsmr_idx_addr = 0x%llx.\n", + (unsigned long long) le64_to_cpu(wqicb->cnsmr_idx_addr)); } void ql_dump_tx_ring(struct tx_ring *tx_ring) @@ -511,30 +507,22 @@ void ql_dump_cqicb(struct cqicb *cqicb) printk(KERN_ERR PFX "cqicb->msix_vect = %d.\n", cqicb->msix_vect); printk(KERN_ERR PFX "cqicb->flags = %x.\n", cqicb->flags); printk(KERN_ERR PFX "cqicb->len = %d.\n", le16_to_cpu(cqicb->len)); - printk(KERN_ERR PFX "cqicb->addr_lo = %x.\n", - le32_to_cpu(cqicb->addr_lo)); - printk(KERN_ERR PFX "cqicb->addr_hi = %x.\n", - le32_to_cpu(cqicb->addr_hi)); - printk(KERN_ERR PFX "cqicb->prod_idx_addr_lo = %x.\n", - le32_to_cpu(cqicb->prod_idx_addr_lo)); - printk(KERN_ERR PFX "cqicb->prod_idx_addr_hi = %x.\n", - le32_to_cpu(cqicb->prod_idx_addr_hi)); + printk(KERN_ERR PFX "cqicb->addr = 0x%llx.\n", + (unsigned long long) le64_to_cpu(cqicb->addr)); + printk(KERN_ERR PFX "cqicb->prod_idx_addr = 0x%llx.\n", + (unsigned long long) le64_to_cpu(cqicb->prod_idx_addr)); printk(KERN_ERR PFX "cqicb->pkt_delay = 0x%.04x.\n", le16_to_cpu(cqicb->pkt_delay)); printk(KERN_ERR PFX "cqicb->irq_delay = 0x%.04x.\n", le16_to_cpu(cqicb->irq_delay)); - printk(KERN_ERR PFX "cqicb->lbq_addr_lo = %x.\n", - le32_to_cpu(cqicb->lbq_addr_lo)); - printk(KERN_ERR PFX "cqicb->lbq_addr_hi = %x.\n", - le32_to_cpu(cqicb->lbq_addr_hi)); + printk(KERN_ERR PFX "cqicb->lbq_addr = 0x%llx.\n", + (unsigned long long) le64_to_cpu(cqicb->lbq_addr)); printk(KERN_ERR PFX "cqicb->lbq_buf_size = 0x%.04x.\n", le16_to_cpu(cqicb->lbq_buf_size)); printk(KERN_ERR PFX "cqicb->lbq_len = 0x%.04x.\n", le16_to_cpu(cqicb->lbq_len)); - printk(KERN_ERR PFX "cqicb->sbq_addr_lo = %x.\n", - le32_to_cpu(cqicb->sbq_addr_lo)); - printk(KERN_ERR PFX "cqicb->sbq_addr_hi = %x.\n", - le32_to_cpu(cqicb->sbq_addr_hi)); + printk(KERN_ERR PFX "cqicb->sbq_addr = 0x%llx.\n", + (unsigned long long) le64_to_cpu(cqicb->sbq_addr)); printk(KERN_ERR PFX "cqicb->sbq_buf_size = 0x%.04x.\n", le16_to_cpu(cqicb->sbq_buf_size)); printk(KERN_ERR PFX "cqicb->sbq_len = 0x%.04x.\n", @@ -811,10 +799,8 @@ void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp) printk(KERN_ERR PFX "data_len = %d\n", le32_to_cpu(ib_mac_rsp->data_len)); - printk(KERN_ERR PFX "data_addr_hi = 0x%x\n", - le32_to_cpu(ib_mac_rsp->data_addr_hi)); - printk(KERN_ERR PFX "data_addr_lo = 0x%x\n", - le32_to_cpu(ib_mac_rsp->data_addr_lo)); + printk(KERN_ERR PFX "data_addr = 0x%llx\n", + (unsigned long long) le64_to_cpu(ib_mac_rsp->data_addr)); if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_RSS_MASK) printk(KERN_ERR PFX "rss = %x\n", le32_to_cpu(ib_mac_rsp->rss)); @@ -830,10 +816,8 @@ void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp) if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) { printk(KERN_ERR PFX "hdr length = %d.\n", le32_to_cpu(ib_mac_rsp->hdr_len)); - printk(KERN_ERR PFX "hdr addr_hi = 0x%x.\n", - le32_to_cpu(ib_mac_rsp->hdr_addr_hi)); - printk(KERN_ERR PFX "hdr addr_lo = 0x%x.\n", - le32_to_cpu(ib_mac_rsp->hdr_addr_lo)); + printk(KERN_ERR PFX "hdr addr = 0x%llx.\n", + (unsigned long long) le64_to_cpu(ib_mac_rsp->hdr_addr)); } } #endif diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 78df7d11cef..33bbdcefe0a 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2467,12 +2467,9 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) bq_len = (rx_ring->cq_len == 65536) ? 0 : (u16) rx_ring->cq_len; cqicb->len = cpu_to_le16(bq_len | LEN_V | LEN_CPP_CONT); - cqicb->addr_lo = cpu_to_le32(rx_ring->cq_base_dma); - cqicb->addr_hi = cpu_to_le32((u64) rx_ring->cq_base_dma >> 32); + cqicb->addr = cpu_to_le64(rx_ring->cq_base_dma); - cqicb->prod_idx_addr_lo = cpu_to_le32(rx_ring->prod_idx_sh_reg_dma); - cqicb->prod_idx_addr_hi = - cpu_to_le32((u64) rx_ring->prod_idx_sh_reg_dma >> 32); + cqicb->prod_idx_addr = cpu_to_le64(rx_ring->prod_idx_sh_reg_dma); /* * Set up the control block load flags. @@ -2483,10 +2480,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->lbq_len) { cqicb->flags |= FLAGS_LL; /* Load lbq values */ *((u64 *) rx_ring->lbq_base_indirect) = rx_ring->lbq_base_dma; - cqicb->lbq_addr_lo = - cpu_to_le32(rx_ring->lbq_base_indirect_dma); - cqicb->lbq_addr_hi = - cpu_to_le32((u64) rx_ring->lbq_base_indirect_dma >> 32); + cqicb->lbq_addr = + cpu_to_le64(rx_ring->lbq_base_indirect_dma); bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 : (u16) rx_ring->lbq_buf_size; cqicb->lbq_buf_size = cpu_to_le16(bq_len); @@ -2501,10 +2496,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->sbq_len) { cqicb->flags |= FLAGS_LS; /* Load sbq values */ *((u64 *) rx_ring->sbq_base_indirect) = rx_ring->sbq_base_dma; - cqicb->sbq_addr_lo = - cpu_to_le32(rx_ring->sbq_base_indirect_dma); - cqicb->sbq_addr_hi = - cpu_to_le32((u64) rx_ring->sbq_base_indirect_dma >> 32); + cqicb->sbq_addr = + cpu_to_le64(rx_ring->sbq_base_indirect_dma); cqicb->sbq_buf_size = cpu_to_le16(((rx_ring->sbq_buf_size / 2) + 8) & 0xfffffff8); bq_len = (rx_ring->sbq_len == 65536) ? 0 : @@ -2611,12 +2604,9 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring) Q_FLAGS_LB | Q_FLAGS_LI | Q_FLAGS_LO); wqicb->cq_id_rss = cpu_to_le16(tx_ring->cq_id); wqicb->rid = 0; - wqicb->addr_lo = cpu_to_le32(tx_ring->wq_base_dma); - wqicb->addr_hi = cpu_to_le32((u64) tx_ring->wq_base_dma >> 32); + wqicb->addr = cpu_to_le64(tx_ring->wq_base_dma); - wqicb->cnsmr_idx_addr_lo = cpu_to_le32(tx_ring->cnsmr_idx_sh_reg_dma); - wqicb->cnsmr_idx_addr_hi = - cpu_to_le32((u64) tx_ring->cnsmr_idx_sh_reg_dma >> 32); + wqicb->cnsmr_idx_addr = cpu_to_le64(tx_ring->cnsmr_idx_sh_reg_dma); ql_init_tx_ring(qdev, tx_ring); -- cgit From 697cdc46801d1106a25d27a8225cb925f0a7f5aa Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Fri, 9 Jan 2009 11:31:51 +0000 Subject: qlge: Remove support for device ID 8000. Support for dev id 8000 is pushed out until 2.6.30. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 3 +-- drivers/net/qlge/qlge_main.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 96970023226..a5095343eb1 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -28,8 +28,7 @@ } while (0) #define QLGE_VENDOR_ID 0x1077 -#define QLGE_DEVICE_ID1 0x8012 -#define QLGE_DEVICE_ID 0x8000 +#define QLGE_DEVICE_ID 0x8012 #define MAX_RX_RINGS 128 #define MAX_TX_RINGS 128 diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 33bbdcefe0a..9931cf7b6ad 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -76,7 +76,6 @@ MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy."); static struct pci_device_id qlge_pci_tbl[] __devinitdata = { {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID)}, - {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID1)}, /* required last entry */ {0,} }; -- cgit From 0857e9d73feea0125280dcd431cee84f6cb3b4e2 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Fri, 9 Jan 2009 11:31:52 +0000 Subject: qlge: Fix schedule while atomic issue. There is no need to sleep while waiting for the hardware semaphore to become available. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 9931cf7b6ad..543a4135ae0 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -126,12 +126,12 @@ static int ql_sem_trylock(struct ql_adapter *qdev, u32 sem_mask) int ql_sem_spinlock(struct ql_adapter *qdev, u32 sem_mask) { - unsigned int seconds = 3; + unsigned int wait_count = 30; do { if (!ql_sem_trylock(qdev, sem_mask)) return 0; - ssleep(1); - } while (--seconds); + udelay(100); + } while (--wait_count); return -ETIMEDOUT; } -- cgit From 683d46a9798c382220ef282b37f8210b5276cb3a Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Fri, 9 Jan 2009 11:31:53 +0000 Subject: qlge: Remove dynamic alloc of rx ring control blocks. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 12 ++++++++---- drivers/net/qlge/qlge_main.c | 31 ++----------------------------- 2 files changed, 10 insertions(+), 33 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index a5095343eb1..c1dadadfab1 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -30,8 +30,9 @@ #define QLGE_VENDOR_ID 0x1077 #define QLGE_DEVICE_ID 0x8012 -#define MAX_RX_RINGS 128 -#define MAX_TX_RINGS 128 +#define MAX_CPUS 8 +#define MAX_TX_RINGS MAX_CPUS +#define MAX_RX_RINGS ((MAX_CPUS * 2) + 1) #define NUM_TX_RING_ENTRIES 256 #define NUM_RX_RING_ENTRIES 256 @@ -44,6 +45,7 @@ #define MAX_SPLIT_SIZE 1023 #define QLGE_SB_PAD 32 +#define MAX_CQ 128 #define DFLT_COALESCE_WAIT 100 /* 100 usec wait for coalescing */ #define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */ #define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2) @@ -1393,9 +1395,11 @@ struct ql_adapter { int rx_ring_count; int ring_mem_size; void *ring_mem; - struct rx_ring *rx_ring; + + struct rx_ring rx_ring[MAX_RX_RINGS]; + struct tx_ring tx_ring[MAX_TX_RINGS]; + int rx_csum; - struct tx_ring *tx_ring; u32 default_rx_queue; u16 rx_coalesce_usecs; /* cqicb->int_delay */ diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 543a4135ae0..45421c8b601 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2355,28 +2355,6 @@ static void ql_tx_ring_clean(struct ql_adapter *qdev) } } -static void ql_free_ring_cb(struct ql_adapter *qdev) -{ - kfree(qdev->ring_mem); -} - -static int ql_alloc_ring_cb(struct ql_adapter *qdev) -{ - /* Allocate space for tx/rx ring control blocks. */ - qdev->ring_mem_size = - (qdev->tx_ring_count * sizeof(struct tx_ring)) + - (qdev->rx_ring_count * sizeof(struct rx_ring)); - qdev->ring_mem = kmalloc(qdev->ring_mem_size, GFP_KERNEL); - if (qdev->ring_mem == NULL) { - return -ENOMEM; - } else { - qdev->rx_ring = qdev->ring_mem; - qdev->tx_ring = qdev->ring_mem + - (qdev->rx_ring_count * sizeof(struct rx_ring)); - } - return 0; -} - static void ql_free_mem_resources(struct ql_adapter *qdev) { int i; @@ -3236,7 +3214,6 @@ static int qlge_close(struct net_device *ndev) msleep(1); ql_adapter_down(qdev); ql_release_adapter_resources(qdev); - ql_free_ring_cb(qdev); return 0; } @@ -3262,8 +3239,8 @@ static int ql_configure_rings(struct ql_adapter *qdev) * This limitation can be removed when requested. */ - if (cpu_cnt > 8) - cpu_cnt = 8; + if (cpu_cnt > MAX_CPUS) + cpu_cnt = MAX_CPUS; /* * rx_ring[0] is always the default queue. @@ -3283,9 +3260,6 @@ static int ql_configure_rings(struct ql_adapter *qdev) */ qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1; - if (ql_alloc_ring_cb(qdev)) - return -ENOMEM; - for (i = 0; i < qdev->tx_ring_count; i++) { tx_ring = &qdev->tx_ring[i]; memset((void *)tx_ring, 0, sizeof(tx_ring)); @@ -3382,7 +3356,6 @@ static int qlge_open(struct net_device *ndev) error_up: ql_release_adapter_resources(qdev); - ql_free_ring_cb(qdev); return err; } -- cgit From a7ee2f73f3ce90d73736de1cf432339c35a3faf2 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Fri, 9 Jan 2009 22:40:06 -0800 Subject: forcedeth: remove mgmt unit for mcp79 chipset This patch removes the feature flag for mgmt unit as it is not used for this chipset. Signed-off-by: Ayaz Abdulla Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 37a6e956f0b..e06782a60bd 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -6169,19 +6169,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36), - .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_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, + .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_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37), - .driver_data = DEV_NEED_TIMERIRQ|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_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, + .driver_data = DEV_NEED_TIMERIRQ|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_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38), - .driver_data = DEV_NEED_TIMERIRQ|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_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, + .driver_data = DEV_NEED_TIMERIRQ|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_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39), - .driver_data = DEV_NEED_TIMERIRQ|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_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, + .driver_data = DEV_NEED_TIMERIRQ|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_LIMIT|DEV_HAS_GEAR_MODE, }, {0,}, }; -- cgit From eb10a781824ca63c4e484c4642a19b3370980792 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Sun, 11 Jan 2009 00:09:04 -0800 Subject: forcedeth: napi schedule lock fix This patch fixes a potential race condition between scheduling napi and completing napi poll. The call to netif_rx_schedule should be under protection of the lock (as is the completion), otherwise, interrupts could be masked off. Signed-off-by: Ayaz Abdulla Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index e06782a60bd..5b910cf6374 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3405,10 +3405,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data) #ifdef CONFIG_FORCEDETH_NAPI if (events & NVREG_IRQ_RX_ALL) { + spin_lock(&np->lock); netif_rx_schedule(&np->napi); /* Disable furthur receive irq's */ - spin_lock(&np->lock); np->irqmask &= ~NVREG_IRQ_RX_ALL; if (np->msi_flags & NV_MSI_X_ENABLED) @@ -3522,10 +3522,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) #ifdef CONFIG_FORCEDETH_NAPI if (events & NVREG_IRQ_RX_ALL) { + spin_lock(&np->lock); netif_rx_schedule(&np->napi); /* Disable furthur receive irq's */ - spin_lock(&np->lock); np->irqmask &= ~NVREG_IRQ_RX_ALL; if (np->msi_flags & NV_MSI_X_ENABLED) -- cgit From 702403af28ef647b090b49bb61abebb45150ce7f Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Sun, 11 Jan 2009 00:14:27 -0800 Subject: smsc911x: fix smsc911x_reg_read compiler warning if this code path is ever hit, the platform_data struct isn't properly configured with a bus width flag so the device won't work (hence the BUG()). This patch adds a dummy return statement to eliminate this compiler warning: drivers/net/smsc911x.c: In function 'smsc911x_reg_read': drivers/net/smsc911x.c:148: warning: control reaches end of non-void function Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 020c5830c37..fd3d2a7a1a2 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -144,6 +144,7 @@ static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) } BUG(); + return 0; } static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, -- cgit From 08168f7164fed494852361ab900358cd7a6b95d6 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Sun, 11 Jan 2009 00:14:52 -0800 Subject: smsc911x: register irq with device name, not driver name This change lets "cat /proc/interrupts" show the name of the ethernet device (e.g. eth0) rather than the driver name (smsc911x). Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index fd3d2a7a1a2..f513bdf1c88 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1969,7 +1969,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF); retval = request_irq(dev->irq, smsc911x_irqhandler, IRQF_DISABLED, - SMSC_CHIPNAME, dev); + dev->name, dev); if (retval) { SMSC_WARNING(PROBE, "Unable to claim requested irq: %d", dev->irq); -- cgit From 2a7e637de51ded7b0b56b927f45915eadb6734bb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 11 Jan 2009 00:18:13 -0800 Subject: sfc: SFT9001: Fix condition for LNPGA power-off Only the SFX7101 requires software power control. This was incorrectly being applied to the SFT9001 rev A as well. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/tenxpress.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index b9768760fae..9ecb77da954 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -636,10 +636,11 @@ static void tenxpress_phy_fini(struct efx_nic *efx) { int reg; - if (efx->phy_type == PHY_TYPE_SFT9001B) { + if (efx->phy_type == PHY_TYPE_SFT9001B) device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_short_reach); - } else { + + if (efx->phy_type == PHY_TYPE_SFX7101) { /* Power down the LNPGA */ reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, -- cgit From 47fd23fe8efeea3af4593a8424419df48724eb25 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Sun, 11 Jan 2009 00:19:36 -0800 Subject: cxgb3: Keep LRO off if disabled when interface is down I have a system with a Chelsio adapter (driven by cxgb3) whose ports are part of a Linux bridge. Recently I updated the kernel and discovered that things stopped working because cxgb3 was doing LRO on packets that were passed into the bridge code for forwarding. (Incidentally, this problem manifested itself in a strange way that made debugging a bit interesting -- for some reason, the skb_warn_if_lro() check in bridge didn't trigger and these LROed packets were forwarded out a forcedeth interface, and caused the forcedeth transmit path to get stuck) This is because cxgb3 has no way of keeping state for the LRO flag until the interface is brought up, so if the bridging code disables LRO while the interface is down, then cxgb3_up() will just reenable LRO, and on my Debian system at least, the init scripts add interfaces to a bridge before bringing the interfaces up. Fix this by keeping track of each interface's LRO state in cxgb3 so that when bridge disables LRO, it stays disabled in cxgb3_up() when the interface is brought up. I did this by changing the rx_csum_offload flag into a pair of bit flags; the effect of this on the rx_eth() fast path is miniscule enough that it should be fine (eg on x86, a cmpb instruction becomes a testb instruction). Signed-off-by: Roland Dreier Signed-off-by: David S. Miller --- drivers/net/cxgb3/adapter.h | 7 ++++++- drivers/net/cxgb3/cxgb3_main.c | 22 ++++++++++++++-------- drivers/net/cxgb3/sge.c | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 5b346f9eaa8..a89d8cc5120 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -50,12 +50,17 @@ struct vlan_group; struct adapter; struct sge_qset; +enum { /* rx_offload flags */ + T3_RX_CSUM = 1 << 0, + T3_LRO = 1 << 1, +}; + struct port_info { struct adapter *adapter; struct vlan_group *vlan_grp; struct sge_qset *qs; u8 port_id; - u8 rx_csum_offload; + u8 rx_offload; u8 nqsets; u8 first_qset; struct cphy phy; diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 2847f947499..0089746b8d0 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -546,7 +546,7 @@ static int setup_sge_qsets(struct adapter *adap) pi->qs = &adap->sge.qs[pi->first_qset]; for (j = pi->first_qset; j < pi->first_qset + pi->nqsets; ++j, ++qset_idx) { - set_qset_lro(dev, qset_idx, pi->rx_csum_offload); + set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO); err = t3_sge_alloc_qset(adap, qset_idx, 1, (adap->flags & USING_MSIX) ? qset_idx + 1 : irq_idx, @@ -1657,17 +1657,19 @@ static u32 get_rx_csum(struct net_device *dev) { struct port_info *p = netdev_priv(dev); - return p->rx_csum_offload; + return p->rx_offload & T3_RX_CSUM; } static int set_rx_csum(struct net_device *dev, u32 data) { struct port_info *p = netdev_priv(dev); - p->rx_csum_offload = data; - if (!data) { + if (data) { + p->rx_offload |= T3_RX_CSUM; + } else { int i; + p->rx_offload &= ~(T3_RX_CSUM | T3_LRO); for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) set_qset_lro(dev, i, 0); } @@ -1830,15 +1832,18 @@ static int cxgb3_set_flags(struct net_device *dev, u32 data) int i; if (data & ETH_FLAG_LRO) { - if (!pi->rx_csum_offload) + if (!(pi->rx_offload & T3_RX_CSUM)) return -EINVAL; + pi->rx_offload |= T3_LRO; for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++) set_qset_lro(dev, i, 1); - } else + } else { + pi->rx_offload &= ~T3_LRO; for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++) set_qset_lro(dev, i, 0); + } return 0; } @@ -1926,7 +1931,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) pi = adap2pinfo(adapter, i); if (t.qset_idx >= pi->first_qset && t.qset_idx < pi->first_qset + pi->nqsets && - !pi->rx_csum_offload) + !(pi->rx_offload & T3_RX_CSUM)) return -EINVAL; } @@ -2946,7 +2951,7 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->port[i] = netdev; pi = netdev_priv(netdev); pi->adapter = adapter; - pi->rx_csum_offload = 1; + pi->rx_offload = T3_RX_CSUM | T3_LRO; pi->port_id = i; netif_carrier_off(netdev); netif_tx_stop_all_queues(netdev); @@ -2955,6 +2960,7 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->mem_end = mmio_start + mmio_len - 1; netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; netdev->features |= NETIF_F_LLTX; + netdev->features |= NETIF_F_LRO; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 6c641a88947..14f9fb3e879 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -1932,7 +1932,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, skb_pull(skb, sizeof(*p) + pad); skb->protocol = eth_type_trans(skb, adap->port[p->iff]); pi = netdev_priv(skb->dev); - if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) && + if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid && p->csum == htons(0xffff) && !p->fragment) { qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; skb->ip_summed = CHECKSUM_UNNECESSARY; -- cgit From 3bc53427e4f323d4f33f70477fc32c1c2ae7fb5d Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Sun, 11 Jan 2009 00:25:21 -0800 Subject: ucc_geth: use correct UCCE macros The UCC Event Register (UCCE) already has unambigous macro definitions in qe.h, so we should not be defining our own in the UCC Ethernet driver. Removed unused local variable 'dev' from ucc_geth_poll(), which fixes a warning caused by commit 908a7a16b852ffd618a9127be8d62432182d81b4 ("net: Remove unused netdev arg from some NAPI interfaces."). Replaced in_be/out_be pairs with setbits32 or clrbits32, where applicable. Signed-off-by: Timur Tabi Signed-off-by: David S. Miller --- drivers/net/ucc_geth.c | 128 +++++++++++++++++-------------------------------- drivers/net/ucc_geth.h | 114 ++++++++++--------------------------------- 2 files changed, 68 insertions(+), 174 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 7d5a1303e30..11441225bf4 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -442,40 +442,30 @@ static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) { struct ucc_fast_private *uccf; struct ucc_geth __iomem *ug_regs; - u32 maccfg2, uccm; uccf = ugeth->uccf; ug_regs = ugeth->ug_regs; /* Enable interrupts for magic packet detection */ - uccm = in_be32(uccf->p_uccm); - uccm |= UCCE_MPD; - out_be32(uccf->p_uccm, uccm); + setbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD); /* Enable magic packet detection */ - maccfg2 = in_be32(&ug_regs->maccfg2); - maccfg2 |= MACCFG2_MPE; - out_be32(&ug_regs->maccfg2, maccfg2); + setbits32(&ug_regs->maccfg2, MACCFG2_MPE); } static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) { struct ucc_fast_private *uccf; struct ucc_geth __iomem *ug_regs; - u32 maccfg2, uccm; uccf = ugeth->uccf; ug_regs = ugeth->ug_regs; /* Disable interrupts for magic packet detection */ - uccm = in_be32(uccf->p_uccm); - uccm &= ~UCCE_MPD; - out_be32(uccf->p_uccm, uccm); + clrbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD); /* Disable magic packet detection */ - maccfg2 = in_be32(&ug_regs->maccfg2); - maccfg2 &= ~MACCFG2_MPE; - out_be32(&ug_regs->maccfg2, maccfg2); + clrbits32(&ug_regs->maccfg2, MACCFG2_MPE); } #endif /* MAGIC_PACKET */ @@ -585,7 +575,8 @@ static void get_statistics(struct ucc_geth_private *ugeth, /* Hardware only if user handed pointer and driver actually gathers hardware statistics */ - if (hardware_statistics && (in_be32(&uf_regs->upsmr) & UPSMR_HSE)) { + if (hardware_statistics && + (in_be32(&uf_regs->upsmr) & UCC_GETH_UPSMR_HSE)) { hardware_statistics->tx64 = in_be32(&ug_regs->tx64); hardware_statistics->tx127 = in_be32(&ug_regs->tx127); hardware_statistics->tx255 = in_be32(&ug_regs->tx255); @@ -1181,9 +1172,7 @@ int init_flow_control_params(u32 automatic_flow_control_mode, out_be32(uempr_register, value); /* Set UPSMR register */ - value = in_be32(upsmr_register); - value |= automatic_flow_control_mode; - out_be32(upsmr_register, value); + setbits32(upsmr_register, automatic_flow_control_mode); value = in_be32(maccfg1_register); if (rx_flow_control_enable) @@ -1200,14 +1189,11 @@ static int init_hw_statistics_gathering_mode(int enable_hardware_statistics, u32 __iomem *upsmr_register, u16 __iomem *uescr_register) { - u32 upsmr_value = 0; u16 uescr_value = 0; + /* Enable hardware statistics gathering if requested */ - if (enable_hardware_statistics) { - upsmr_value = in_be32(upsmr_register); - upsmr_value |= UPSMR_HSE; - out_be32(upsmr_register, upsmr_value); - } + if (enable_hardware_statistics) + setbits32(upsmr_register, UCC_GETH_UPSMR_HSE); /* Clear hardware statistics counters */ uescr_value = in_be16(uescr_register); @@ -1233,23 +1219,17 @@ static int init_firmware_statistics_gathering_mode(int { /* Note: this function does not check if */ /* the parameters it receives are NULL */ - u16 temoder_value; - u32 remoder_value; if (enable_tx_firmware_statistics) { out_be32(tx_rmon_base_ptr, tx_firmware_statistics_structure_address); - temoder_value = in_be16(temoder_register); - temoder_value |= TEMODER_TX_RMON_STATISTICS_ENABLE; - out_be16(temoder_register, temoder_value); + setbits16(temoder_register, TEMODER_TX_RMON_STATISTICS_ENABLE); } if (enable_rx_firmware_statistics) { out_be32(rx_rmon_base_ptr, rx_firmware_statistics_structure_address); - remoder_value = in_be32(remoder_register); - remoder_value |= REMODER_RX_RMON_STATISTICS_ENABLE; - out_be32(remoder_register, remoder_value); + setbits32(remoder_register, REMODER_RX_RMON_STATISTICS_ENABLE); } return 0; @@ -1316,15 +1296,12 @@ static int init_check_frame_length_mode(int length_check, static int init_preamble_length(u8 preamble_length, u32 __iomem *maccfg2_register) { - u32 value = 0; - if ((preamble_length < 3) || (preamble_length > 7)) return -EINVAL; - value = in_be32(maccfg2_register); - value &= ~MACCFG2_PREL_MASK; - value |= (preamble_length << MACCFG2_PREL_SHIFT); - out_be32(maccfg2_register, value); + clrsetbits_be32(maccfg2_register, MACCFG2_PREL_MASK, + preamble_length << MACCFG2_PREL_SHIFT); + return 0; } @@ -1337,19 +1314,19 @@ static int init_rx_parameters(int reject_broadcast, value = in_be32(upsmr_register); if (reject_broadcast) - value |= UPSMR_BRO; + value |= UCC_GETH_UPSMR_BRO; else - value &= ~UPSMR_BRO; + value &= ~UCC_GETH_UPSMR_BRO; if (receive_short_frames) - value |= UPSMR_RSH; + value |= UCC_GETH_UPSMR_RSH; else - value &= ~UPSMR_RSH; + value &= ~UCC_GETH_UPSMR_RSH; if (promiscuous) - value |= UPSMR_PRO; + value |= UCC_GETH_UPSMR_PRO; else - value &= ~UPSMR_PRO; + value &= ~UCC_GETH_UPSMR_PRO; out_be32(upsmr_register, value); @@ -1410,26 +1387,27 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) /* Set UPSMR */ upsmr = in_be32(&uf_regs->upsmr); - upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM); + upsmr &= ~(UCC_GETH_UPSMR_RPM | UCC_GETH_UPSMR_R10M | + UCC_GETH_UPSMR_TBIM | UCC_GETH_UPSMR_RMM); if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) || (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) || (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) || (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) || (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) || (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { - upsmr |= UPSMR_RPM; + upsmr |= UCC_GETH_UPSMR_RPM; switch (ugeth->max_speed) { case SPEED_10: - upsmr |= UPSMR_R10M; + upsmr |= UCC_GETH_UPSMR_R10M; /* FALLTHROUGH */ case SPEED_100: if (ugeth->phy_interface != PHY_INTERFACE_MODE_RTBI) - upsmr |= UPSMR_RMM; + upsmr |= UCC_GETH_UPSMR_RMM; } } if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) || (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { - upsmr |= UPSMR_TBIM; + upsmr |= UCC_GETH_UPSMR_TBIM; } out_be32(&uf_regs->upsmr, upsmr); @@ -1517,9 +1495,9 @@ static void adjust_link(struct net_device *dev) (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) || (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { if (phydev->speed == SPEED_10) - upsmr |= UPSMR_R10M; + upsmr |= UCC_GETH_UPSMR_R10M; else - upsmr &= ~(UPSMR_R10M); + upsmr &= ~UCC_GETH_UPSMR_R10M; } break; default: @@ -1602,10 +1580,8 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) uccf = ugeth->uccf; /* Mask GRACEFUL STOP TX interrupt bit and clear it */ - temp = in_be32(uccf->p_uccm); - temp &= ~UCCE_GRA; - out_be32(uccf->p_uccm, temp); - out_be32(uccf->p_ucce, UCCE_GRA); /* clear by writing 1 */ + clrbits32(uccf->p_uccm, UCC_GETH_UCCE_GRA); + out_be32(uccf->p_ucce, UCC_GETH_UCCE_GRA); /* clear by writing 1 */ /* Issue host command */ cecr_subblock = @@ -1617,7 +1593,7 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) do { msleep(10); temp = in_be32(uccf->p_ucce); - } while (!(temp & UCCE_GRA) && --i); + } while (!(temp & UCC_GETH_UCCE_GRA) && --i); uccf->stopped_tx = 1; @@ -1975,12 +1951,9 @@ static void ucc_geth_set_multi(struct net_device *dev) uf_regs = ugeth->uccf->uf_regs; if (dev->flags & IFF_PROMISC) { - - out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr) | UPSMR_PRO); - + setbits32(&uf_regs->upsmr, UCC_GETH_UPSMR_PRO); } else { - - out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr)&~UPSMR_PRO); + clrbits32(&uf_regs->upsmr, UCC_GETH_UPSMR_PRO); p_82xx_addr_filt = (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth-> @@ -2020,7 +1993,6 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) { struct ucc_geth __iomem *ug_regs = ugeth->ug_regs; struct phy_device *phydev = ugeth->phydev; - u32 tempval; ugeth_vdbg("%s: IN", __func__); @@ -2037,9 +2009,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) out_be32(ugeth->uccf->p_ucce, 0xffffffff); /* Disable Rx and Tx */ - tempval = in_be32(&ug_regs->maccfg1); - tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); - out_be32(&ug_regs->maccfg1, tempval); + clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); ucc_geth_memclean(ugeth); } @@ -2153,10 +2123,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) /* Generate uccm_mask for receive */ uf_info->uccm_mask = ug_info->eventRegMask & UCCE_OTHER;/* Errors */ for (i = 0; i < ug_info->numQueuesRx; i++) - uf_info->uccm_mask |= (UCCE_RXBF_SINGLE_MASK << i); + uf_info->uccm_mask |= (UCC_GETH_UCCE_RXF0 << i); for (i = 0; i < ug_info->numQueuesTx; i++) - uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i); + uf_info->uccm_mask |= (UCC_GETH_UCCE_TXB0 << i); /* Initialize the general fast UCC block. */ if (ucc_fast_init(uf_info, &ugeth->uccf)) { if (netif_msg_probe(ugeth)) @@ -2185,7 +2155,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) struct ucc_geth __iomem *ug_regs; int ret_val = -EINVAL; u32 remoder = UCC_GETH_REMODER_INIT; - u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; + u32 init_enet_pram_offset, cecr_subblock, command; u32 ifstat, i, j, size, l2qt, l3qt, length; u16 temoder = UCC_GETH_TEMODER_INIT; u16 test; @@ -2281,10 +2251,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) &uf_regs->upsmr, &ug_regs->uempr, &ug_regs->maccfg1); - maccfg1 = in_be32(&ug_regs->maccfg1); - maccfg1 |= MACCFG1_ENABLE_RX; - maccfg1 |= MACCFG1_ENABLE_TX; - out_be32(&ug_regs->maccfg1, maccfg1); + setbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); /* Set IPGIFG */ /* For more details see the hardware spec. */ @@ -3274,7 +3241,6 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) static int ucc_geth_poll(struct napi_struct *napi, int budget) { struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi); - struct net_device *dev = ugeth->dev; struct ucc_geth_info *ug_info; int howmany, i; @@ -3285,14 +3251,8 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget) howmany += ucc_geth_rx(ugeth, i, budget - howmany); if (howmany < budget) { - struct ucc_fast_private *uccf; - u32 uccm; - netif_rx_complete(napi); - uccf = ugeth->uccf; - uccm = in_be32(uccf->p_uccm); - uccm |= UCCE_RX_EVENTS; - out_be32(uccf->p_uccm, uccm); + setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS); } return howmany; @@ -3332,7 +3292,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) /* Tx event processing */ if (ucce & UCCE_TX_EVENTS) { spin_lock(&ugeth->lock); - tx_mask = UCCE_TXBF_SINGLE_MASK; + tx_mask = UCC_GETH_UCCE_TXB0; for (i = 0; i < ug_info->numQueuesTx; i++) { if (ucce & tx_mask) ucc_geth_tx(dev, i); @@ -3344,12 +3304,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) /* Errors and other events */ if (ucce & UCCE_OTHER) { - if (ucce & UCCE_BSY) { + if (ucce & UCC_GETH_UCCE_BSY) dev->stats.rx_errors++; - } - if (ucce & UCCE_TXE) { + if (ucce & UCC_GETH_UCCE_TXE) dev->stats.tx_errors++; - } } return IRQ_HANDLED; diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index d74d2f7cb73..8f699cb773e 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -162,92 +162,27 @@ struct ucc_geth { boundary */ /* UCC GETH Event Register */ -#define UCCE_MPD 0x80000000 /* Magic packet - detection */ -#define UCCE_SCAR 0x40000000 -#define UCCE_GRA 0x20000000 /* Tx graceful - stop - complete */ -#define UCCE_CBPR 0x10000000 -#define UCCE_BSY 0x08000000 -#define UCCE_RXC 0x04000000 -#define UCCE_TXC 0x02000000 -#define UCCE_TXE 0x01000000 -#define UCCE_TXB7 0x00800000 -#define UCCE_TXB6 0x00400000 -#define UCCE_TXB5 0x00200000 -#define UCCE_TXB4 0x00100000 -#define UCCE_TXB3 0x00080000 -#define UCCE_TXB2 0x00040000 -#define UCCE_TXB1 0x00020000 -#define UCCE_TXB0 0x00010000 -#define UCCE_RXB7 0x00008000 -#define UCCE_RXB6 0x00004000 -#define UCCE_RXB5 0x00002000 -#define UCCE_RXB4 0x00001000 -#define UCCE_RXB3 0x00000800 -#define UCCE_RXB2 0x00000400 -#define UCCE_RXB1 0x00000200 -#define UCCE_RXB0 0x00000100 -#define UCCE_RXF7 0x00000080 -#define UCCE_RXF6 0x00000040 -#define UCCE_RXF5 0x00000020 -#define UCCE_RXF4 0x00000010 -#define UCCE_RXF3 0x00000008 -#define UCCE_RXF2 0x00000004 -#define UCCE_RXF1 0x00000002 -#define UCCE_RXF0 0x00000001 - -#define UCCE_RXBF_SINGLE_MASK (UCCE_RXF0) -#define UCCE_TXBF_SINGLE_MASK (UCCE_TXB0) - -#define UCCE_TXB (UCCE_TXB7 | UCCE_TXB6 | UCCE_TXB5 | UCCE_TXB4 |\ - UCCE_TXB3 | UCCE_TXB2 | UCCE_TXB1 | UCCE_TXB0) -#define UCCE_RXB (UCCE_RXB7 | UCCE_RXB6 | UCCE_RXB5 | UCCE_RXB4 |\ - UCCE_RXB3 | UCCE_RXB2 | UCCE_RXB1 | UCCE_RXB0) -#define UCCE_RXF (UCCE_RXF7 | UCCE_RXF6 | UCCE_RXF5 | UCCE_RXF4 |\ - UCCE_RXF3 | UCCE_RXF2 | UCCE_RXF1 | UCCE_RXF0) -#define UCCE_OTHER (UCCE_SCAR | UCCE_GRA | UCCE_CBPR | UCCE_BSY |\ - UCCE_RXC | UCCE_TXC | UCCE_TXE) - -#define UCCE_RX_EVENTS (UCCE_RXF | UCCE_BSY) -#define UCCE_TX_EVENTS (UCCE_TXB | UCCE_TXE) - -/* UCC GETH UPSMR (Protocol Specific Mode Register) */ -#define UPSMR_ECM 0x04000000 /* Enable CAM - Miss or - Enable - Filtering - Miss */ -#define UPSMR_HSE 0x02000000 /* Hardware - Statistics - Enable */ -#define UPSMR_PRO 0x00400000 /* Promiscuous*/ -#define UPSMR_CAP 0x00200000 /* CAM polarity - */ -#define UPSMR_RSH 0x00100000 /* Receive - Short Frames - */ -#define UPSMR_RPM 0x00080000 /* Reduced Pin - Mode - interfaces */ -#define UPSMR_R10M 0x00040000 /* RGMII/RMII - 10 Mode */ -#define UPSMR_RLPB 0x00020000 /* RMII - Loopback - Mode */ -#define UPSMR_TBIM 0x00010000 /* Ten-bit - Interface - Mode */ -#define UPSMR_RMM 0x00001000 /* RMII/RGMII - Mode */ -#define UPSMR_CAM 0x00000400 /* CAM Address - Matching */ -#define UPSMR_BRO 0x00000200 /* Broadcast - Address */ -#define UPSMR_RES1 0x00002000 /* Reserved - feild - must - be 1 */ +#define UCCE_TXB (UCC_GETH_UCCE_TXB7 | UCC_GETH_UCCE_TXB6 | \ + UCC_GETH_UCCE_TXB5 | UCC_GETH_UCCE_TXB4 | \ + UCC_GETH_UCCE_TXB3 | UCC_GETH_UCCE_TXB2 | \ + UCC_GETH_UCCE_TXB1 | UCC_GETH_UCCE_TXB0) + +#define UCCE_RXB (UCC_GETH_UCCE_RXB7 | UCC_GETH_UCCE_RXB6 | \ + UCC_GETH_UCCE_RXB5 | UCC_GETH_UCCE_RXB4 | \ + UCC_GETH_UCCE_RXB3 | UCC_GETH_UCCE_RXB2 | \ + UCC_GETH_UCCE_RXB1 | UCC_GETH_UCCE_RXB0) + +#define UCCE_RXF (UCC_GETH_UCCE_RXF7 | UCC_GETH_UCCE_RXF6 | \ + UCC_GETH_UCCE_RXF5 | UCC_GETH_UCCE_RXF4 | \ + UCC_GETH_UCCE_RXF3 | UCC_GETH_UCCE_RXF2 | \ + UCC_GETH_UCCE_RXF1 | UCC_GETH_UCCE_RXF0) + +#define UCCE_OTHER (UCC_GETH_UCCE_SCAR | UCC_GETH_UCCE_GRA | \ + UCC_GETH_UCCE_CBPR | UCC_GETH_UCCE_BSY | \ + UCC_GETH_UCCE_RXC | UCC_GETH_UCCE_TXC | UCC_GETH_UCCE_TXE) + +#define UCCE_RX_EVENTS (UCCE_RXF | UCC_GETH_UCCE_BSY) +#define UCCE_TX_EVENTS (UCCE_TXB | UCC_GETH_UCCE_TXE) /* UCC GETH MACCFG1 (MAC Configuration 1 Register) */ #define MACCFG1_FLOW_RX 0x00000020 /* Flow Control @@ -945,9 +880,10 @@ struct ucc_geth_hardware_statistics { #define UCC_GETH_REMODER_INIT 0 /* bits that must be set */ #define UCC_GETH_TEMODER_INIT 0xC000 /* bits that must */ -#define UCC_GETH_UPSMR_INIT (UPSMR_RES1) /* Start value - for this - register */ + +/* Initial value for UPSMR */ +#define UCC_GETH_UPSMR_INIT UCC_GETH_UPSMR_RES1 + #define UCC_GETH_MACCFG1_INIT 0 #define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1) -- cgit From 8476a6571005f9440adda08ca4d6c69c7f4db30b Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Tue, 30 Dec 2008 22:49:28 +0100 Subject: Wireless: Fix Kconfig fact error Raytheon cards use 2.4 GHz, not 2.4 MHz. See http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Linux.Wireless.drivers.html#Raylink Signed-off-by: Erik Ekman Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index ea543fcf268..e4f9f747de8 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -111,7 +111,7 @@ config WLAN_80211 lets you choose drivers. config PCMCIA_RAYCS - tristate "Aviator/Raytheon 2.4MHz wireless support" + tristate "Aviator/Raytheon 2.4GHz wireless support" depends on PCMCIA && WLAN_80211 select WIRELESS_EXT ---help--- -- cgit From d1b29405bd3590bc97c4d3ff2c9139ca55e56ccd Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Fri, 2 Jan 2009 08:05:27 +0000 Subject: rt2x00: Fix radio LED type check Since "rt2x00: Fix LED state handling", rt2x00leds_led_radio wrongly checks that the LED type is LED_TYPE_ASSOC. This patch makes it check for LED_TYPE_RADIO once again. Signed-off-by: Andrew Price Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00leds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index 68f4e0fc35b..a0cd35b6beb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c @@ -97,7 +97,7 @@ void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled) { - if (rt2x00dev->led_radio.type == LED_TYPE_ASSOC) + if (rt2x00dev->led_radio.type == LED_TYPE_RADIO) rt2x00led_led_simple(&rt2x00dev->led_radio, enabled); } -- cgit From 51fb80fefe736db1182551fec6528d1ef095b0ea Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 3 Jan 2009 12:45:12 -0600 Subject: p54usb: Fix to prevent SKB memory allocation errors with 4K page size On x86_64 architecture with 4K page size and SLUB debugging enabled, stress testing on p54usb has resulted in skb allocation failures of O(1) and extreme page fragmentation. Reducing rx_mtu fixes this problem by reducing the size of all receive skb allocations to be of O(0). This change does not impact performance in any way. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 82354b974a0..06c64744df2 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -138,6 +138,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) u8 *fw_version = NULL; size_t len; int i; + int maxlen; if (priv->rx_start) return 0; @@ -195,6 +196,16 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) else priv->rx_mtu = (size_t) 0x620 - priv->tx_hdr_len; + maxlen = priv->tx_hdr_len + /* USB devices */ + sizeof(struct p54_rx_data) + + 4 + /* rx alignment */ + IEEE80211_MAX_FRAG_THRESHOLD; + if (priv->rx_mtu > maxlen && PAGE_SIZE == 4096) { + printk(KERN_INFO "p54: rx_mtu reduced from %d " + "to %d\n", priv->rx_mtu, + maxlen); + priv->rx_mtu = maxlen; + } break; } case BR_CODE_EXPOSED_IF: -- cgit From 3be36ae223271f9c2cfbe7406846c8fdcd2f50c3 Mon Sep 17 00:00:00 2001 From: Stefan Lippers-Hollmann Date: Sun, 4 Jan 2009 01:10:49 +0100 Subject: rt2x00: add USB ID for the Linksys WUSB200. add USB ID for the Linksys WUSB200 Wireless-G Business USB Adapter to rt73usb. Signed-off-by: Stefan Lippers-Hollmann Cc: stable Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index d638a8a5937..96a8d69f879 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2321,6 +2321,7 @@ static struct usb_device_id rt73usb_device_table[] = { /* Linksys */ { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, /* MSI */ { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, -- cgit From 3ea96463156123cbfd09ac412012a87fef068830 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 4 Jan 2009 17:33:25 +0100 Subject: rt2x00: Fix TX short preamble detection The short preamble mode was not correctly detected during TX, rt2x00 used the rate->hw_value_short field but mac80211 is not using this field that way. Instead the flag IEEE80211_TX_RC_USE_SHORT_PREAMBLE should be used to determine if the frame should be send out using short preamble or not. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 8 +++----- drivers/net/wireless/rt2x00/rt2x00lib.h | 11 ----------- drivers/net/wireless/rt2x00/rt2x00queue.c | 2 +- 3 files changed, 4 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 6d92542fcf0..87c0f2c8307 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -807,13 +807,11 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry, { entry->flags = 0; entry->bitrate = rate->bitrate; - entry->hw_value = rt2x00_create_rate_hw_value(index, 0); - entry->hw_value_short = entry->hw_value; + entry->hw_value =index; + entry->hw_value_short = index; - if (rate->flags & DEV_RATE_SHORT_PREAMBLE) { + if (rate->flags & DEV_RATE_SHORT_PREAMBLE) entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; - entry->hw_value_short |= rt2x00_create_rate_hw_value(index, 1); - } } static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 03024327767..86cd26fbf76 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -52,22 +52,11 @@ struct rt2x00_rate { extern const struct rt2x00_rate rt2x00_supported_rates[12]; -static inline u16 rt2x00_create_rate_hw_value(const u16 index, - const u16 short_preamble) -{ - return (short_preamble << 8) | (index & 0xff); -} - static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) { return &rt2x00_supported_rates[hw_value & 0xff]; } -static inline int rt2x00_get_rate_preamble(const u16 hw_value) -{ - return (hw_value & 0xff00); -} - /* * Radio control handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index eaec6bd93ed..746a8f36b93 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -313,7 +313,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, * When preamble is enabled we should set the * preamble bit for the signal. */ - if (rt2x00_get_rate_preamble(rate->hw_value)) + if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) txdesc->signal |= 0x08; } } -- cgit From 878e6a432f85690a2c0d88d96f177e54ff1d4a57 Mon Sep 17 00:00:00 2001 From: Michiel Date: Sun, 4 Jan 2009 17:22:28 -0600 Subject: p54usb: Add USB ID for Thomson Speedtouch 121g Add the USB ID for Thomson Speedtouch 121g to p54usb. Signed-off-by: Michiel Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index c44a200059d..8f5c063b854 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -56,6 +56,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ -- cgit From 176ddc7dcfe3fd93778f52abf9a947d92932f19e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 5 Jan 2009 13:51:24 +0200 Subject: ath9k: Enforce module build if rfkill is a module CONFIG_ATH9K=y results in build issues if CONFIG_RFKILL=m since ath9k does not depend on rfkill in kconfig (i.e., CONFIG_RFKILL is used to select whether to enable rfkill in ath9k), but uses its functions if rfkill is enabled. Enforce ath9k to be build as a module if CONFIG_RFKILL=m to avoid this invalid configuration. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig index c43bd321f97..90a8dd87378 100644 --- a/drivers/net/wireless/ath9k/Kconfig +++ b/drivers/net/wireless/ath9k/Kconfig @@ -1,6 +1,7 @@ config ATH9K tristate "Atheros 802.11n wireless cards support" depends on PCI && MAC80211 && WLAN_80211 + depends on RFKILL || RFKILL=n select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS -- cgit From 20953ad68ee522f6420b63c200ac9b23f96d937a Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Wed, 7 Jan 2009 00:23:55 +0000 Subject: orinoco: take the driver lock in the rx tasklet Fix the warning reproduced below. We add to rx_list in interrupt context and remove elements in tasklet context. While removing elements we need to prevent the interrupt modifying the list. Note that "orinoco: Process bulk of receive interrupt in a tasklet" did not preserve locking semantics on what is now orinoco_rx. This patch reinstates the locking semantics and ensures it covers rx_list as well. This leads to additional cleanup required in free_orinocodev. [89479.105038] WARNING: at lib/list_debug.c:30 __list_add+0x8f/0xa0() [89479.105058] list_add corruption. prev->next should be next (dddb3568), but was cbc28978. (prev=dddb3568). [89479.106002] Pid: 15746, comm: X Not tainted 2.6.28-1avb #26 [89479.106020] Call Trace: [89479.106062] [] warn_slowpath+0x60/0x80 [89479.106104] [] ? native_sched_clock+0x20/0x70 [89479.106194] [] ? lock_release_holdtime+0x35/0x200 [89479.106218] [] ? __slab_alloc+0x550/0x560 [89479.106254] [] ? _spin_unlock+0x1d/0x20 [89479.106270] [] ? __slab_alloc+0x550/0x560 [89479.106302] [] ? delay_tsc+0x17/0x24 [89479.106319] [] ? __const_udelay+0x21/0x30 [89479.106376] [] ? hermes_bap_seek+0x112/0x1e0 [hermes] [89479.106396] [] ? trace_hardirqs_off+0xb/0x10 [89479.106418] [] ? __kmalloc_track_caller+0xb7/0x110 [89479.106448] [] ? dev_alloc_skb+0x1c/0x30 [89479.106465] [] ? dev_alloc_skb+0x1c/0x30 [89479.106482] [] __list_add+0x8f/0xa0 [89479.106551] [] orinoco_interrupt+0xcae/0x16c0 [orinoco] [89479.106574] [] ? tick_dev_program_event+0x33/0xb0 [89479.106594] [] ? native_sched_clock+0x20/0x70 [89479.106613] [] ? lock_release_holdtime+0x35/0x200 [89479.106662] [] ? trace_hardirqs_off+0xb/0x10 [89479.106892] [] ? usb_hcd_irq+0x97/0xa0 [usbcore] [89479.106926] [] handle_IRQ_event+0x29/0x60 [89479.106947] [] handle_level_irq+0x69/0xe0 [89479.106963] [] ? handle_level_irq+0x0/0xe0 [89479.106977] [] ? tcp_v4_rcv+0x633/0x6e0 [89479.107025] [] ? common_interrupt+0x28/0x30 [89479.107057] [] ? sk_run_filter+0x320/0x7a0 [89479.107078] [] ? list_del+0x21/0x90 [89479.107106] [] ? orinoco_rx_isr_tasklet+0x2ce/0x480 [orinoco] [89479.107131] [] ? __lock_acquire+0x160/0x1650 [89479.107151] [] ? native_sched_clock+0x20/0x70 [89479.107169] [] ? lock_release_holdtime+0x35/0x200 [89479.107200] [] ? irq_enter+0xa/0x60 [89479.107217] [] ? do_IRQ+0xd2/0x130 [89479.107518] [] ? restore_nocheck_notrace+0x0/0xe [89479.107542] [] ? __do_softirq+0x0/0x110 [89479.107561] [] ? trace_hardirqs_on_caller+0x74/0x140 [89479.107583] [] ? trace_hardirqs_on_thunk+0xc/0x10 [89479.107602] [] ? tasklet_action+0x27/0x90 [89479.107620] [] ? trace_hardirqs_on_caller+0x74/0x140 [89479.107638] [] ? tasklet_action+0x43/0x90 [89479.107655] [] ? __do_softirq+0x6f/0x110 [89479.107674] [] ? __do_softirq+0x0/0x110 [89479.107685] [] ? handle_level_irq+0x0/0xe0 [89479.107715] [] ? irq_exit+0x5d/0x80 [89479.107732] [] ? do_IRQ+0xd2/0x130 [89479.107747] [] ? sysenter_exit+0xf/0x16 [89479.107765] [] ? trace_hardirqs_on_caller+0xfd/0x140 [89479.107782] [] ? common_interrupt+0x28/0x30 [89479.107797] ---[ end trace a1fc0a52df4a729d ]--- Reported-by: Andrey Borzenkov Signed-off-by: David Kilroy Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c index bc84e2792f8..c3bb85e0251 100644 --- a/drivers/net/wireless/orinoco/orinoco.c +++ b/drivers/net/wireless/orinoco/orinoco.c @@ -1610,6 +1610,16 @@ static void orinoco_rx_isr_tasklet(unsigned long data) struct orinoco_rx_data *rx_data, *temp; struct hermes_rx_descriptor *desc; struct sk_buff *skb; + unsigned long flags; + + /* orinoco_rx requires the driver lock, and we also need to + * protect priv->rx_list, so just hold the lock over the + * lot. + * + * If orinoco_lock fails, we've unplugged the card. In this + * case just abort. */ + if (orinoco_lock(priv, &flags) != 0) + return; /* extract desc and skb from queue */ list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) { @@ -1622,6 +1632,8 @@ static void orinoco_rx_isr_tasklet(unsigned long data) kfree(desc); } + + orinoco_unlock(priv, &flags); } /********************************************************************/ @@ -3645,12 +3657,22 @@ struct net_device void free_orinocodev(struct net_device *dev) { struct orinoco_private *priv = netdev_priv(dev); + struct orinoco_rx_data *rx_data, *temp; - /* No need to empty priv->rx_list: if the tasklet is scheduled - * when we call tasklet_kill it will run one final time, - * emptying the list */ + /* If the tasklet is scheduled when we call tasklet_kill it + * will run one final time. However the tasklet will only + * drain priv->rx_list if the hw is still available. */ tasklet_kill(&priv->rx_tasklet); + /* Explicitly drain priv->rx_list */ + list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) { + list_del(&rx_data->list); + + dev_kfree_skb(rx_data->skb); + kfree(rx_data->desc); + kfree(rx_data); + } + unregister_pm_notifier(&priv->pm_notifier); orinoco_uncache_fw(priv); -- cgit From 86060f0d691f5ee1b4ef4efe770b683e54ac438d Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 7 Jan 2009 14:25:29 +0530 Subject: ath9k: Fix chainmask handling bug The chainmasks have to be updated before setting the channel, since the HW reset routine uses them to set the appropriate registers. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 191eec50dc7..727f067aca4 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -2164,13 +2164,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) conf->ht.channel_type); } + ath_update_chainmask(sc, conf->ht.enabled); + if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); mutex_unlock(&sc->mutex); return -EINVAL; } - - ath_update_chainmask(sc, conf->ht.enabled); } if (changed & IEEE80211_CONF_CHANGE_POWER) -- cgit From d732129b25b972c208c9705759c8c64f63a21800 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 8 Jan 2009 10:20:00 -0800 Subject: iwlwifi: Fix get_cmd_string() for REPLY_3945_RX 0x1b is a 3945 specific command, we should print it too when debugging. Signed-off-by: Samuel Ortiz Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 01a2169cece..8c71ad4f88c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -51,6 +51,7 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_REMOVE_STA); IWL_CMD(REPLY_REMOVE_ALL_STA); IWL_CMD(REPLY_WEPKEY); + IWL_CMD(REPLY_3945_RX); IWL_CMD(REPLY_TX); IWL_CMD(REPLY_RATE_SCALE); IWL_CMD(REPLY_LEDS_CMD); -- cgit From 706ea9b66935e341b063d860c9c8f279b37b5578 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 9 Jan 2009 12:31:48 -0500 Subject: orinoco_cs: add ID for ARtem Onair Comcard 11 Reported by Michael Jarosch Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco_cs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index f127602670e..0b32215d3f5 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -435,6 +435,7 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ + PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ -- cgit From c1d34c1dad76be6d515ef33e24eb92f10547b08b Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 20 Dec 2008 02:21:37 +0100 Subject: p54: crypto offload fixes This patch fixes two small flaws: - restore the original TKIP IV if we altered it. - reserve & initialize ICV with zeros. This is actually only necessary for some obsolete p54usb firmwares. But we don't know yet, if all devices are compatible with the new revisions. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 06c64744df2..37294a657f8 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -809,6 +809,16 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) info->flags |= IEEE80211_TX_STAT_TX_FILTERED; info->status.ack_signal = p54_rssi_to_dbm(dev, (int)payload->ack_rssi); + + if (entry_data->key_type == P54_CRYPTO_TKIPMICHAEL) { + u8 *iv = (u8 *)(entry_data->align + pad + + entry_data->crypt_offset); + + /* Restore the original TKIP IV. */ + iv[2] = iv[0]; + iv[0] = iv[1]; + iv[1] = (iv[0] | 0x20) & 0x7f; /* WEPSeed - 8.3.2.2 */ + } skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); ieee80211_tx_status_irqsafe(dev, entry); goto out; @@ -1394,7 +1404,6 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) hdr->tries = ridx; txhdr->rts_rate_idx = 0; if (info->control.hw_key) { - crypt_offset += info->control.hw_key->iv_len; txhdr->key_type = p54_convert_algo(info->control.hw_key->alg); txhdr->key_len = min((u8)16, info->control.hw_key->keylen); memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len); @@ -1408,6 +1417,8 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) } /* reserve some space for ICV */ len += info->control.hw_key->icv_len; + memset(skb_put(skb, info->control.hw_key->icv_len), 0, + info->control.hw_key->icv_len); } else { txhdr->key_type = 0; txhdr->key_len = 0; -- cgit From 00627f229c9807e4cb825a7ce36b886e2adf2229 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 20 Dec 2008 02:21:56 +0100 Subject: p54usb: fix random traffic stalls (LM87) All LM87 firmwares need a explicit termination "packet", in oder to finish the pending transfer properly. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 8f5c063b854..6a6a72f6f82 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -285,6 +285,7 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb) usb_fill_bulk_urb(data_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), skb->data, skb->len, p54u_tx_cb, skb); + data_urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(data_urb, &priv->submitted); if (usb_submit_urb(data_urb, GFP_ATOMIC)) { -- cgit From d15cfc3ac77388f1d588c57743d5f26b15eba9a8 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 20 Dec 2008 11:00:23 +0100 Subject: rt2x00: Fix segementation fault The queue_end() macro points to 1 position after the queue, which means that if we want to know if queue is at the end of the queue we should first increment the position and then check if it is a valid entry. This fixes a segmentation fault which only occurs when the device has enough endpoints to provide a dedicated endpoint for all TX queues (which likely won't happen for rt2500usb and rt73usb, but will happen for rt2800usb). Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 83df312ac56..0b29d767a25 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -434,11 +434,11 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev) if (usb_endpoint_is_bulk_in(ep_desc)) { rt2x00usb_assign_endpoint(rt2x00dev->rx, ep_desc); - } else if (usb_endpoint_is_bulk_out(ep_desc)) { + } else if (usb_endpoint_is_bulk_out(ep_desc) && + (queue != queue_end(rt2x00dev))) { rt2x00usb_assign_endpoint(queue, ep_desc); + queue = queue_next(queue); - if (queue != queue_end(rt2x00dev)) - queue = queue_next(queue); tx_ep_desc = ep_desc; } } -- cgit From 1061787967db03975dc02030d6815811f4eb9231 Mon Sep 17 00:00:00 2001 From: Daniel Wu Date: Sat, 20 Dec 2008 10:53:29 -0800 Subject: iwlwifi: Fix typo in iwl-commands.h for CCK rate bit range. My first (minor) patch, hopefully this is correct. Fix a typo in iwl-commands.h for CCK rates which needs 7 bits and not 4. Signed-off-by: Daniel Wu Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 52966ffbef6..ba997204c8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -255,7 +255,7 @@ struct iwl_cmd_header { * 0x3) 54 Mbps * * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): - * 3-0: 10) 1 Mbps + * 6-0: 10) 1 Mbps * 20) 2 Mbps * 55) 5.5 Mbps * 110) 11 Mbps -- cgit From b55eae3349ff5d6d088c7ab0151260d5e3dbd26d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 21 Dec 2008 15:40:33 -0600 Subject: rtl8180: Fix to add STA mode To be compatible with mac80211 following "mac80211: only create default STA interface if supported", rtl8180 needs to set NL80211_IFTYPE_STATION in interface_modes. Signed-off-by: Larry Finger Reported-by: Fabio Rossi Tested-by: Piter PUNK Acked-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8180_dev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 5f887fb137a..387c133ec0f 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -897,6 +897,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SIGNAL_UNSPEC; + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); dev->queues = 1; dev->max_signal = 65; -- cgit From f3d340c1d536fd3e5a104c99ac9c3f8694270d72 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 21 Dec 2008 23:19:17 +0100 Subject: Fix rt2500usb HW crypto: TKIP rt2500usb doesn't strip the IV/ICV data from received frames, so we don't need to set the RX_FLAG_IV_STRIPPED flag. We do need to set the RX_FLAG_MMIC_STRIPPED flag for all encryption types since the MMIC has been removed from the frame. After this patch TKIP Hardware crypto works for rt2500usb. WEP and AES are still failing. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 30028e2422f..065f111f01f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -376,11 +376,11 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, /* * The driver does not support the IV/EIV generation - * in hardware. However it doesn't support the IV/EIV - * inside the ieee80211 frame either, but requires it - * to be provided seperately for the descriptor. - * rt2x00lib will cut the IV/EIV data out of all frames - * given to us by mac80211, but we must tell mac80211 + * in hardware. However it demands the data to be provided + * both seperately as well as inside the frame. + * We already provided the CONFIG_CRYPTO_COPY_IV to rt2x00lib + * to ensure rt2x00lib will not strip the data from the + * frame after the copy, now we must tell mac80211 * to generate the IV/EIV data. */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -1334,14 +1334,7 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, /* ICV is located at the end of frame */ - /* - * Hardware has stripped IV/EIV data from 802.11 frame during - * decryption. It has provided the data seperately but rt2x00lib - * should decide if it should be reinserted. - */ - rxdesc->flags |= RX_FLAG_IV_STRIPPED; - if (rxdesc->cipher != CIPHER_TKIP) - rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; + rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) rxdesc->flags |= RX_FLAG_DECRYPTED; else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) -- cgit From d3a1db1c67735063921d9186145fc86164cf9781 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Mon, 22 Dec 2008 16:31:58 +0530 Subject: ath9k: Fix incorrect sequence numbering for unaggregated QoS Frame. This patch fixes an issue with the sequence numbers of unaggregated QoS frames, because of which the frames are handled in a different order at the AP and resulted in MLME REPLAYFAILURE. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/xmit.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 3bfc3b90f25..1ea9428c0cd 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -264,25 +264,22 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, } /* Get seqno */ - - if (ieee80211_is_data(fc) && !is_pae(skb)) { - /* For HT capable stations, we save tidno for later use. - * We also override seqno set by upper layer with the one - * in tx aggregation state. - * - * If fragmentation is on, the sequence number is - * not overridden, since it has been - * incremented by the fragmentation routine. - * - * FIXME: check if the fragmentation threshold exceeds - * IEEE80211 max. - */ - tid = ATH_AN_2_TID(an, bf->bf_tidno); - hdr->seq_ctrl = cpu_to_le16(tid->seq_next << - IEEE80211_SEQ_SEQ_SHIFT); - bf->bf_seqno = tid->seq_next; - INCR(tid->seq_next, IEEE80211_SEQ_MAX); - } + /* For HT capable stations, we save tidno for later use. + * We also override seqno set by upper layer with the one + * in tx aggregation state. + * + * If fragmentation is on, the sequence number is + * not overridden, since it has been + * incremented by the fragmentation routine. + * + * FIXME: check if the fragmentation threshold exceeds + * IEEE80211 max. + */ + tid = ATH_AN_2_TID(an, bf->bf_tidno); + hdr->seq_ctrl = cpu_to_le16(tid->seq_next << + IEEE80211_SEQ_SEQ_SHIFT); + bf->bf_seqno = tid->seq_next; + INCR(tid->seq_next, IEEE80211_SEQ_MAX); } static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, @@ -1718,11 +1715,10 @@ static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, /* Assign seqno, tidno */ - if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR)) + if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) assign_aggr_tid_seqno(skb, bf); /* DMA setup */ - bf->bf_mpdu = skb; bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, -- cgit From 157ec8768457e8177d281ae099fb1c321c9a16d7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 22 Dec 2008 16:45:54 +0200 Subject: ath9k: Revert fix to TX status reporting for retries and MCS index This patch reverts "ath9k: Fix TX status reporting for retries and MCS index" because that change ended up breaking ath9k rate control. While the MCS index reporting to mac80211 was indeed fixed by the patch, it did not take into account that the ath9k rate control algorithm was updating private tables based on this index and the index comes through the rate control API call, i.e., based on mac80211 TX status call. In addition, it looks like the "fix" to remove +1 from TX status 'count' field was not correct based on ieee80211_tx_status() implementation that counts the total of count values, but starting from -1, not 0. The TX status reporting for frames using MCS needs to be fixed somehow, but it does not look like there is any easy fix for the ath9k rate control algorithm, so the best option now seems to be to revert the change and bring it back once the rate control code is cleaned up to handle this better. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/xmit.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 1ea9428c0cd..c92f0c6e4ad 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -126,15 +126,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, tx_info->flags |= IEEE80211_TX_STAT_ACK; } - tx_info->status.rates[0].count = tx_status->retries; - if (tx_info->status.rates[0].flags & IEEE80211_TX_RC_MCS) { - /* Change idx from internal table index to MCS index */ - int idx = tx_info->status.rates[0].idx; - struct ath_rate_table *rate_table = sc->cur_rate_table; - if (idx >= 0 && idx < rate_table->rate_cnt) - tx_info->status.rates[0].idx = - rate_table->info[idx].ratecode & 0x7f; - } + tx_info->status.rates[0].count = tx_status->retries + 1; hdrlen = ieee80211_get_hdrlen_from_skb(skb); padsize = hdrlen & 3; -- cgit From 4fb7404e0eaf574c00d01d2b1ce2615229b350cd Mon Sep 17 00:00:00 2001 From: Steve Brown Date: Tue, 23 Dec 2008 07:57:05 -0500 Subject: ath5k: Correct usage of AR5K_CFG_ADHOC This corrects usage of AR5K_CFG_ADHOC introduced in "ath5k: Update PCU code". Also, the name of the indicator is changed to AR5K_CFG_IBSS to more accurately reflect its function. This change restores beaconing in AP and mesh modes. Signed-off-by: Steve Brown Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/pcu.c | 4 ++-- drivers/net/wireless/ath5k/reg.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c index 0cac05c6a9c..75eb9f43c74 100644 --- a/drivers/net/wireless/ath5k/pcu.c +++ b/drivers/net/wireless/ath5k/pcu.c @@ -65,7 +65,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah) if (ah->ah_version == AR5K_AR5210) pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; else - AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_ADHOC); + AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); break; case NL80211_IFTYPE_AP: @@ -75,7 +75,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah) if (ah->ah_version == AR5K_AR5210) pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; else - AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_ADHOC); + AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); break; case NL80211_IFTYPE_STATION: diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index 91aaeaf8819..9189ab13286 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h @@ -73,7 +73,7 @@ #define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */ #define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer */ #define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register access */ -#define AR5K_CFG_ADHOC 0x00000020 /* AP/Adhoc indication [5211+] */ +#define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */ #define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */ #define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */ #define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (Disable dynamic clock) */ -- cgit From 124b68e755c2ef9342d5d477142c499fd7901360 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 26 Dec 2008 19:09:45 +0100 Subject: p54: fix WARN_ON at line 2247 of net/mac80211/rx.c This patch hopefully fixes a mac80211<->p54 interaction problem, which was described by Larry Finger (ref: http://marc.info/?l=linux-wireless&m=123009889327707 ) I guess the warning was triggered by pending frames in the receive queue, while we're doing a band change 5GHz. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 37294a657f8..cba89ed0f57 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -586,6 +586,7 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) u16 freq = le16_to_cpu(hdr->freq); size_t header_len = sizeof(*hdr); u32 tsf32; + u8 rate = hdr->rate & 0xf; /* * If the device is in a unspecified state we have to @@ -614,8 +615,11 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) rx_status.qual = (100 * hdr->rssi) / 127; if (hdr->rate & 0x10) rx_status.flag |= RX_FLAG_SHORTPRE; - rx_status.rate_idx = (dev->conf.channel->band == IEEE80211_BAND_2GHZ ? - hdr->rate : (hdr->rate - 4)) & 0xf; + if (dev->conf.channel->band == IEEE80211_BAND_5GHZ) + rx_status.rate_idx = (rate < 4) ? 0 : rate - 4; + else + rx_status.rate_idx = rate; + rx_status.freq = freq; rx_status.band = dev->conf.channel->band; rx_status.antenna = hdr->antenna; -- cgit From d6e2be988d5146d1faa8df895cd8b32106d987bd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Jan 2009 23:11:26 -0600 Subject: rtl8187: Fix module so that rmmod/insmod does not error Due to misunderstanding of the returned values allowed for the tx callback of mac80211, rtl8187 was using skb's that had been freed. This problem was triggered when the module was sujected to a rmmod/insmod cycle. After that was fixed, the modules would not work after the rmmod/insmod cycle until the USB device was reset. Signed-off-by: Johannes Berg Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 00ce3ef39ab..6ad6bac3770 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -213,7 +213,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { kfree_skb(skb); - return -ENOMEM; + return NETDEV_TX_OK; } flags = skb->len; @@ -281,7 +281,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) } usb_free_urb(urb); - return rc; + return NETDEV_TX_OK; } static void rtl8187_rx_cb(struct urb *urb) @@ -1471,6 +1471,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) ieee80211_unregister_hw(dev); priv = dev->priv; + usb_reset_device(priv->udev); usb_put_dev(interface_to_usbdev(intf)); ieee80211_free_hw(dev); } -- cgit From 71ef99c8b79ab07e1c79794085481464f9870d62 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 5 Jan 2009 20:46:34 -0500 Subject: ath5k: fix return values from ath5k_tx Should return NETDEV_TX_{OK,BUSY} instead of 0,-1 (this doesn't change any current functionality). Changes-licensed-under: 3-Clause-BSD Reported-by: Johannes Berg Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 4af2607deec..8ef87356e08 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -2644,7 +2644,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (skb_headroom(skb) < padsize) { ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough" " headroom to pad %d\n", hdrlen, padsize); - return -1; + return NETDEV_TX_BUSY; } skb_push(skb, padsize); memmove(skb->data, skb->data+padsize, hdrlen); @@ -2655,7 +2655,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); spin_unlock_irqrestore(&sc->txbuflock, flags); ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); - return -1; + return NETDEV_TX_BUSY; } bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); list_del(&bf->list); @@ -2673,10 +2673,10 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) sc->txbuf_len++; spin_unlock_irqrestore(&sc->txbuflock, flags); dev_kfree_skb_any(skb); - return 0; + return NETDEV_TX_OK; } - return 0; + return NETDEV_TX_OK; } static int -- cgit From f1dd2b23badfe8a28910a78be24452c627c4b6f2 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 3 Jan 2009 16:27:14 +0100 Subject: rt2x00: Fix rt2500usb HW crypto: WEP 128 & AES The TXD_W0_CIPHER field is a 1-bit field. It only acts as boolean value to indicate if the frame must be encrypted or not. The way rt2x00_set_field32() worked it would grab the least signifcant bit from txdesc->cipher and use that as value. Because of that WEP 64 and TKIP worked since they had odd-numbered values, while WEP 128 and AES were even numbers and didn't work. Correctly booleanize the txdecs->cipher value to allow the hardware to encrypt the outgoing data. After this we can enable HW crypto by default again. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 065f111f01f..af6b5847be5 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -38,7 +38,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 1; +static int modparam_nohwcrypt = 0; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -1181,7 +1181,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); - rt2x00_set_field32(&word, TXD_W0_CIPHER, txdesc->cipher); + rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); rt2x00_desc_write(txd, 0, word); } -- cgit From 51e99158d261a5ec5772ca89b935c3daa270b07c Mon Sep 17 00:00:00 2001 From: Andrey Yurovsky Date: Mon, 5 Jan 2009 14:37:31 -0800 Subject: libertas_tf: return NETDEV_TX_OK in TX op The TX op should return NETDEV_TX_OK or NETDEV_TX_BUSY. Signed-off-by: Andrey Yurovsky Signed-off-by: John W. Linville --- drivers/net/wireless/libertas_tf/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index d1fc305de5f..e7289e2e7f1 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -206,7 +206,7 @@ static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * there are no buffered multicast frames to send */ ieee80211_stop_queues(priv->hw); - return 0; + return NETDEV_TX_OK; } static void lbtf_tx_work(struct work_struct *work) -- cgit From fe333321e2a71f706b794d55b6a3dcb5ab240f65 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 6 Jan 2009 14:26:03 +0000 Subject: powerpc: Change u64/s64 to a long long integer type Convert arch/powerpc/ over to long long based u64: -#ifdef __powerpc64__ -# include -#else -# include -#endif +#include This will avoid reoccuring spurious warnings in core kernel code that comes when people test on their own hardware. (i.e. x86 in ~98% of the cases) This is what x86 uses and it generally helps keep 64-bit code 32-bit clean too. [Adjusted to not impact user mode (from paulus) - sfr] Signed-off-by: Ingo Molnar Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- drivers/net/pasemi_mac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 5b7a574ce57..d0349e7d73e 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -712,7 +712,7 @@ static inline void pasemi_mac_rx_error(const struct pasemi_mac *mac, rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); ccmdsta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno)); - printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n", + printk(KERN_ERR "pasemi_mac: rx error. macrx %016llx, rx status %llx\n", macrx, *chan->status); printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n", @@ -730,8 +730,8 @@ static inline void pasemi_mac_tx_error(const struct pasemi_mac *mac, cmdsta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno)); - printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\ - "tx status 0x%016lx\n", mactx, *chan->status); + printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016llx, "\ + "tx status 0x%016llx\n", mactx, *chan->status); printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta); } -- cgit From a1c5a8932bbb75b550deb156d890027827fc9d6e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:40:06 +0000 Subject: powerpc: Cleanup from l64 to ll64 change: drivers/net These are powerpc specific drivers. Signed-off-by: Stephen Rothwell Acked-by: David S. Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/net/ehea/ehea_main.c | 8 ++++---- drivers/net/ehea/ehea_qmr.c | 18 +++++++++--------- drivers/net/ibmveth.c | 16 ++++++++-------- drivers/net/iseries_veth.c | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index e3131ea629c..dfe92264e82 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -132,7 +132,7 @@ void ehea_dump(void *adr, int len, char *msg) int x; unsigned char *deb = adr; for (x = 0; x < len; x += 16) { - printk(DRV_NAME " %s adr=%p ofs=%04x %016lx %016lx\n", msg, + printk(DRV_NAME " %s adr=%p ofs=%04x %016llx %016llx\n", msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); deb += 16; } @@ -883,7 +883,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) while (eqe) { qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - ehea_error("QP aff_err: entry=0x%lx, token=0x%x", + ehea_error("QP aff_err: entry=0x%llx, token=0x%x", eqe->entry, qp_token); qp = port->port_res[qp_token].qp; @@ -1159,7 +1159,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) netif_stop_queue(port->netdev); break; default: - ehea_error("unknown event code %x, eqe=0x%lX", ec, eqe); + ehea_error("unknown event code %x, eqe=0x%llX", ec, eqe); break; } } @@ -1971,7 +1971,7 @@ static void ehea_set_multicast_list(struct net_device *dev) } if (dev->mc_count > port->adapter->max_mc_mac) { - ehea_info("Mcast registration limit reached (0x%lx). " + ehea_info("Mcast registration limit reached (0x%llx). " "Use ALLMULTI!", port->adapter->max_mc_mac); goto out; diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 225c692b5d9..49d766ebbcf 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -168,7 +168,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, cq->fw_handle, rpage, 1); if (hret < H_SUCCESS) { ehea_error("register_rpage_cq failed ehea_cq=%p " - "hret=%lx counter=%i act_pages=%i", + "hret=%llx counter=%i act_pages=%i", cq, hret, counter, cq->attr.nr_pages); goto out_kill_hwq; } @@ -178,13 +178,13 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, if ((hret != H_SUCCESS) || (vpage)) { ehea_error("registration of pages not " - "complete hret=%lx\n", hret); + "complete hret=%llx\n", hret); goto out_kill_hwq; } } else { if (hret != H_PAGE_REGISTERED) { ehea_error("CQ: registration of page failed " - "hret=%lx\n", hret); + "hret=%llx\n", hret); goto out_kill_hwq; } } @@ -986,15 +986,15 @@ void print_error_data(u64 *data) length = EHEA_PAGESIZE; if (type == 0x8) /* Queue Pair */ - ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " - "port=%lX", resource, data[6], data[12], data[22]); + ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " + "port=%llX", resource, data[6], data[12], data[22]); if (type == 0x4) /* Completion Queue */ - ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource, + ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, data[6]); if (type == 0x3) /* Event Queue */ - ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource, + ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, data[6]); ehea_dump(data, length, "error data"); @@ -1016,11 +1016,11 @@ void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle) rblock); if (ret == H_R_STATE) - ehea_error("No error data is available: %lX.", res_handle); + ehea_error("No error data is available: %llX.", res_handle); else if (ret == H_SUCCESS) print_error_data(rblock); else - ehea_error("Error data could not be fetched: %lX", res_handle); + ehea_error("Error data could not be fetched: %llX", res_handle); kfree(rblock); } diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index ca3bb9f7321..dfa6348ac1d 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -602,7 +602,7 @@ static int ibmveth_open(struct net_device *netdev) if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); - ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n", + ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n", adapter->buffer_list_dma, adapter->filter_list_dma, rxq_desc.desc, @@ -1378,13 +1378,13 @@ static int ibmveth_show(struct seq_file *seq, void *v) seq_printf(seq, "Firmware MAC: %pM\n", firmware_mac); seq_printf(seq, "\nAdapter Statistics:\n"); - seq_printf(seq, " TX: vio_map_single failres: %ld\n", adapter->tx_map_failed); - seq_printf(seq, " send failures: %ld\n", adapter->tx_send_failed); - seq_printf(seq, " RX: replenish task cycles: %ld\n", adapter->replenish_task_cycles); - seq_printf(seq, " alloc_skb_failures: %ld\n", adapter->replenish_no_mem); - seq_printf(seq, " add buffer failures: %ld\n", adapter->replenish_add_buff_failure); - seq_printf(seq, " invalid buffers: %ld\n", adapter->rx_invalid_buffer); - seq_printf(seq, " no buffers: %ld\n", adapter->rx_no_buffer); + seq_printf(seq, " TX: vio_map_single failres: %lld\n", adapter->tx_map_failed); + seq_printf(seq, " send failures: %lld\n", adapter->tx_send_failed); + seq_printf(seq, " RX: replenish task cycles: %lld\n", adapter->replenish_task_cycles); + seq_printf(seq, " alloc_skb_failures: %lld\n", adapter->replenish_no_mem); + seq_printf(seq, " add buffer failures: %lld\n", adapter->replenish_add_buff_failure); + seq_printf(seq, " invalid buffers: %lld\n", adapter->rx_invalid_buffer); + seq_printf(seq, " no buffers: %lld\n", adapter->rx_no_buffer); return 0; } diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index c7457f97259..cb793c2bade 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -429,7 +429,7 @@ SIMPLE_PORT_ATTR(promiscuous); SIMPLE_PORT_ATTR(num_mcast); CUSTOM_PORT_ATTR(lpar_map, "0x%X\n", port->lpar_map); CUSTOM_PORT_ATTR(stopped_map, "0x%X\n", port->stopped_map); -CUSTOM_PORT_ATTR(mac_addr, "0x%lX\n", port->mac_addr); +CUSTOM_PORT_ATTR(mac_addr, "0x%llX\n", port->mac_addr); #define GET_PORT_ATTR(_name) (&veth_port_attr_##_name.attr) static struct attribute *veth_port_default_attrs[] = { -- cgit From d9736749f581abd80c2831244e2659e2e833b0e3 Mon Sep 17 00:00:00 2001 From: Krzysztof HaÅ‚asa Date: Mon, 12 Jan 2009 16:31:54 -0800 Subject: WAN: Fix NAPI interface in IXP4xx HSS driver. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof HaÅ‚asa Signed-off-by: David S. Miller --- drivers/net/wan/ixp4xx_hss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 2dc241689d3..0dbd85b0162 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -622,7 +622,7 @@ static void hss_hdlc_rx_irq(void *pdev) printk(KERN_DEBUG "%s: hss_hdlc_rx_irq\n", dev->name); #endif qmgr_disable_irq(queue_ids[port->id].rx); - netif_rx_schedule(dev, &port->napi); + netif_rx_schedule(&port->napi); } static int hss_hdlc_poll(struct napi_struct *napi, int budget) @@ -651,7 +651,7 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget) printk(KERN_DEBUG "%s: hss_hdlc_poll" " netif_rx_complete\n", dev->name); #endif - netif_rx_complete(dev, napi); + netif_rx_complete(napi); qmgr_enable_irq(rxq); if (!qmgr_stat_empty(rxq) && netif_rx_reschedule(napi)) { @@ -1069,7 +1069,7 @@ static int hss_hdlc_open(struct net_device *dev) hss_start_hdlc(port); /* we may already have RX data, enables IRQ */ - netif_rx_schedule(dev, &port->napi); + netif_rx_schedule(&port->napi); return 0; err_unlock: -- cgit From b74f62c1e736ea01c660355526dd54132d241ca9 Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Mon, 12 Jan 2009 21:56:49 -0800 Subject: hso: driver fix for big endian machines. Filip Aben says this fix is neccessary for big endian machines. Signed-off-by: Denis Joseph Barrow Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index c4918b86ed1..d17dc5214c9 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1792,8 +1792,8 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, /* initialize */ ctrl_req->wValue = 0; - ctrl_req->wIndex = hso_port_to_mux(port); - ctrl_req->wLength = size; + ctrl_req->wIndex = cpu_to_le16(hso_port_to_mux(port)); + ctrl_req->wLength = cpu_to_le16(size); if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) { /* Reading command */ -- cgit From a6d0b91ae5dd01263530c96f9b29001cb1ed58b0 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 12 Jan 2009 21:57:34 -0800 Subject: gianfar: Fix soft lockup with multi-interrupt TSECs This patch fixes following bug: BUG: soft lockup - CPU#0 stuck for 61s! [S03mountvirtfs-:922] Modules linked in: NIP: c006505c LR: c00675f0 CTR: c0020438 REGS: c7a1db90 TRAP: 0901 Not tainted (2.6.28-rc8-01311-g8c7396a) MSR: 00009032 CR: 28248442 XER: 20000000 TASK = c7a288a0[922] 'S03mountvirtfs-' THREAD: c7a1c000 GPR00: 00009032 c7a1dc40 c7a288a0 00000024 c79a1840 00000000 00000300 00000020 GPR08: c035f97c 00000000 00004008 c04d5210 00000000 NIP [c006505c] handle_IRQ_event+0x34/0xb0 LR [c00675f0] handle_level_irq+0xa8/0x144 Call Trace: [c7a1dc40] [c00204d8] ipic_mask_irq+0xa0/0xb4 (unreliable) [c7a1dc60] [c00675f0] handle_level_irq+0xa8/0x144 [c7a1dc80] [c00067f8] do_IRQ+0x78/0x108 [c7a1dc90] [c0014d7c] ret_from_except+0x0/0x14 --- Exception: 501 at gfar_schedule_cleanup+0x54/0x7c LR = gfar_transmit+0x14/0x28 [c7a1dd50] [c0352a3c] _spin_unlock_irqrestore+0x18/0x30 (unreliable) [c7a1dd60] [c01f49a8] gfar_transmit+0x14/0x28 [c7a1dd70] [c0065084] handle_IRQ_event+0x5c/0xb0 [c7a1dd90] [c00675f0] handle_level_irq+0xa8/0x144 [c7a1ddb0] [c00067f8] do_IRQ+0x78/0x108 [c7a1ddc0] [c0014d7c] ret_from_except+0x0/0x14 --- Exception: 501 at up_read+0x10/0x48 LR = do_page_fault+0x2b0/0x3e0 [c7a1de80] [c7a177e8] 0xc7a177e8 (unreliable) [c7a1de90] [c0017964] do_page_fault+0x2b0/0x3e0 [c7a1df40] [c0014b14] handle_page_fault+0xc/0x80 --- Exception: 301 at 0xfe98b7c LR = 0xfe989c0 Instruction dump: 7c0802a6 bf810010 7c9f2378 7c7c1b78 90010024 80040004 70090020 40820010 7c0000a6 60008000 7c000124 3bc00000 <3ba00000> 48000010 83ff0014 2f9f0000 The bug introduced by commit 8c7396aebb68994c0519e438eecdf4d5fa9c7844 ("gianfar: Merge Tx and Rx interrupt for scheduling clean up ring"). The commit merged TX and RX interrupt code into a single routine that schedules NAPI, but no locks were introduced. This causes irq races, so when irqs are enabled and netif_rx_schedule_prep() returns 0, nobody disable the interrupts again. This leads to interrupt storm and finally to the lockup. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index efcbeb6c867..ea530673236 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1622,10 +1622,18 @@ static int gfar_clean_tx_ring(struct net_device *dev) static void gfar_schedule_cleanup(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&priv->txlock, flags); + spin_lock(&priv->rxlock); + if (netif_rx_schedule_prep(&priv->napi)) { gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED); __netif_rx_schedule(&priv->napi); } + + spin_unlock(&priv->rxlock); + spin_unlock_irqrestore(&priv->txlock, flags); } /* Interrupt Handler for Transmit complete */ -- cgit From 859975764fa61e927e7a69f46a55a4ba415785dd Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 12 Jan 2009 22:11:56 -0800 Subject: net: ppp_generic - fix regressions caused by IDR conversion The commits: 7a95d267fb62cd6b80ef73be0592bbbe1dbd5df7 ("net: ppp_generic - use idr technique instead of cardmaps") ab5024ab23b78c86a0a1425defcdde48710fe449 ("net: ppp_generic - use DEFINE_IDR for static initialization") introduced usage of IDR functionality but broke userspace side. Before this commits it was possible to allocate new ppp interface with specified number. Now it fails with EINVAL. Fix it by trying to allocate interface with specified unit number and return EEXIST if fail which allow pppd to ask us to allocate new unit number. And fix messages on memory allocation fails - add details that it's PPP module who is complaining. Signed-off-by: Cyrill Gorcunov Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 06b448285eb..7b2728b8f1b 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -250,6 +250,7 @@ static int ppp_connect_channel(struct channel *pch, int unit); static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); static int unit_get(struct idr *p, void *ptr); +static int unit_set(struct idr *p, void *ptr, int n); static void unit_put(struct idr *p, int n); static void *unit_find(struct idr *p, int n); @@ -2432,11 +2433,18 @@ ppp_create_interface(int unit, int *retp) } else { if (unit_find(&ppp_units_idr, unit)) goto out2; /* unit already exists */ - else { - /* darn, someone is cheating us? */ - *retp = -EINVAL; + /* + * if caller need a specified unit number + * lets try to satisfy him, otherwise -- + * he should better ask us for new unit number + * + * NOTE: yes I know that returning EEXIST it's not + * fair but at least pppd will ask us to allocate + * new unit in this case so user is happy :) + */ + unit = unit_set(&ppp_units_idr, ppp, unit); + if (unit < 0) goto out2; - } } /* Initialize the new ppp unit */ @@ -2677,14 +2685,37 @@ static void __exit ppp_cleanup(void) * by holding all_ppp_mutex */ +/* associate pointer with specified number */ +static int unit_set(struct idr *p, void *ptr, int n) +{ + int unit, err; + +again: + if (!idr_pre_get(p, GFP_KERNEL)) { + printk(KERN_ERR "PPP: No free memory for idr\n"); + return -ENOMEM; + } + + err = idr_get_new_above(p, ptr, n, &unit); + if (err == -EAGAIN) + goto again; + + if (unit != n) { + idr_remove(p, unit); + return -EINVAL; + } + + return unit; +} + /* get new free unit number and associate pointer with it */ static int unit_get(struct idr *p, void *ptr) { int unit, err; again: - if (idr_pre_get(p, GFP_KERNEL) == 0) { - printk(KERN_ERR "Out of memory expanding drawable idr\n"); + if (!idr_pre_get(p, GFP_KERNEL)) { + printk(KERN_ERR "PPP: No free memory for idr\n"); return -ENOMEM; } -- cgit From 922d8a0b6d82fb40ffb561576e3800c3784ff43d Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:40:20 -0500 Subject: b43: fix "‘gmode’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/b43/main.c: In function ‘b43_op_config’: drivers/net/wireless/b43/main.c:3264: warning: ‘gmode’ may be used uninitialized Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7b31a327b24..c788bad1066 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3261,7 +3261,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) struct b43_wldev *down_dev; struct b43_wldev *d; int err; - bool gmode; + bool uninitialized_var(gmode); int prev_status; /* Find a device and PHY which supports the band. */ -- cgit From 08cb7e01678b0a8d95d76aa0a395f2d7390f7ee1 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:43:18 -0500 Subject: b43legacy: fix "‘up_dev’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/b43legacy/main.c: In function ‘b43legacy_op_dev_config’: drivers/net/wireless/b43legacy/main.c:2468: warning: ‘up_dev’ may be used uninitialized in this function Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c1324e31d2f..fb996c27a19 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2465,7 +2465,7 @@ static void b43legacy_put_phy_into_reset(struct b43legacy_wldev *dev) static int b43legacy_switch_phymode(struct b43legacy_wl *wl, unsigned int new_mode) { - struct b43legacy_wldev *up_dev; + struct b43legacy_wldev *uninitialized_var(up_dev); struct b43legacy_wldev *down_dev; int err; bool gmode = 0; -- cgit From 25a4cceaa44a7f73c8f92e6177812347500a0b15 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:44:52 -0500 Subject: iwl3945: fix "‘power_idx’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/iwlwifi/iwl-3945.c: In function ‘iwl3945_txpower_set_from_eeprom’: drivers/net/wireless/iwlwifi/iwl-3945.c:2222: warning: ‘power_idx’ may be used uninitialized in this function Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8fdb34222c0..45cfa1cf194 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2219,7 +2219,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv) /* set tx power value for all OFDM rates */ for (rate_index = 0; rate_index < IWL_OFDM_RATES; rate_index++) { - s32 power_idx; + s32 uninitialized_var(power_idx); int rc; /* use channel group's clip-power table, -- cgit From 26d1597c9a4532eec74f9651c4c96483cb8892fe Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:46:39 -0500 Subject: p54: fix "‘ret’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/p54/p54common.c: In function ‘p54_config’: drivers/net/wireless/p54/p54common.c:1853: warning: ‘ret’ may be used uninitialized in this function Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index cba89ed0f57..c6a370fa9bc 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1850,7 +1850,7 @@ static void p54_remove_interface(struct ieee80211_hw *dev, static int p54_config(struct ieee80211_hw *dev, u32 changed) { - int ret; + int ret = 0; struct p54_common *priv = dev->priv; struct ieee80211_conf *conf = &dev->conf; -- cgit From 483a2b3a3182abcb7fcea986d7ea13e793bb00b1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Jan 2009 14:35:15 -0800 Subject: ARM etherh: Fix build failure. Reported by Russell King: drivers/net/arm/etherh.c:649: error: unknown field 'ndo_set_mac_addr' specified in initializer Signed-off-by: David S. Miller --- drivers/net/arm/etherh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 745ac188bab..d15d8b79d8e 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -646,7 +646,7 @@ static const struct net_device_ops etherh_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_addr = eth_set_mac_addr, + .ndo_set_mac_address = eth_set_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, -- cgit From f0d44ae310bc8eb0b6694e257015d8b24e1a357c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 14 Jan 2009 14:38:02 -0800 Subject: phylib: Fix Freescale TBI PHY detection Freescale on-chip TBI PHYs reports PHY ID as 0x0, but as of commit 3ee82383f0098a2e13acc8cf1be8e47512f41e5a Author: Giulio Benetti Date: Thu Nov 13 21:53:13 2008 +0000 phy: fix phy address bug PHYID returns 0xffff and not 0xffffffff when not found and in some case(at91sam9263) 0x0. Maybe this patch could be useful. phy_device.c treats PHY ID == 0x0 as bogus IDs, and that results in gianfar driver failure to see the TBI PHYs. This code snippet triggers: if (!priv->tbiphy) { printk(KERN_WARNING "SGMII mode requires that the device " "tree specify a tbi-handle\n"); return; } Although tbi-handle is specified in the device tree. Btw, technically PHY ID == 0x0 is a valid ID (if we ever see a PHY manufactured by Xerox :-). Signed-off-by: Anton Vorontsov Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index e35460165bf..0a06e4fd37d 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -231,15 +231,6 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr) if ((phy_id & 0x1fffffff) == 0x1fffffff) return NULL; - /* - * Broken hardware is sometimes missing the pull-up resistor on the - * MDIO line, which results in reads to non-existent devices returning - * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent - * device as well. - */ - if (phy_id == 0) - return NULL; - dev = phy_device_create(bus, addr, phy_id); return dev; -- cgit From d7e094d4212bc72f5575e54edfef1349e0c4cdb5 Mon Sep 17 00:00:00 2001 From: Mike Ditto Date: Wed, 14 Jan 2009 20:43:43 -0800 Subject: powerpc/fs_enet: Add missing irq free in error path. If something goes wrong attaching to phy driver, we weren't freeing the IRQ. Signed-off-by: Mike Ditto Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 4e6a9195fe5..ce900e54d8d 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -795,6 +795,7 @@ static int fs_enet_open(struct net_device *dev) err = fs_init_phy(dev); if (err) { + free_irq(fep->interrupt, dev); if (fep->fpi->use_napi) napi_disable(&fep->napi); return err; -- cgit From d1d5e6b1cead3df6f722d1d458874bd7f93da8d6 Mon Sep 17 00:00:00 2001 From: Daniele Venzano Date: Wed, 14 Jan 2009 20:46:24 -0800 Subject: sis900: generate fake MAC address if the hardware doesn't have one The attached patch modifies the sis900 driver when the MAC address read from the hardware is invalid. As suggested, the patch now generates a random address so that the user can go on and use the hardware. In any case a message is also shown to warn on the unexpected condition. This seems to happen with newer HW implementation of the sis900 chipset, since this never came up before. Patch is against vanilla 2.6.28 (but the driver doesn't change so often, so it will probably apply to older/newer versions too). See bugzilla ID 10201 and 11649 and ignore the previous patch. Signed-off-by: Daniele Venzano Signed-off-by: David S. Miller --- drivers/net/sis900.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 6cbefcae9ac..be4465bc0a6 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -509,10 +509,10 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, else ret = sis900_get_mac_addr(pci_dev, net_dev); - if (ret == 0) { - printk(KERN_WARNING "%s: Cannot read MAC address.\n", dev_name); - ret = -ENODEV; - goto err_unmap_rx; + if (!ret || !is_valid_ether_addr(net_dev->dev_addr)) { + random_ether_addr(net_dev->dev_addr); + printk(KERN_WARNING "%s: Unreadable or invalid MAC address," + "using random generated one\n", dev_name); } /* 630ET : set the mii access mode as software-mode */ -- cgit From 2edbb454428729f450f7a0aabbf95ac62b46b78a Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:47:30 -0800 Subject: netxen: fix endianness in firmware commands o Set restricted (little endian) data types in firmware command requests and responses. o Remove unnecessary conversion to LE when writing registers. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 98 ++++++++++++++++++------------------ drivers/net/netxen/netxen_nic_ctx.c | 50 ++++++++---------- drivers/net/netxen/netxen_nic_hw.c | 42 +++++++++------- drivers/net/netxen/netxen_nic_init.c | 2 +- 4 files changed, 95 insertions(+), 97 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index f8e601c51da..31311cc66d1 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -995,31 +995,31 @@ struct netxen_recv_context { */ typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u32 ring_size; /* Ring entries */ - u16 msi_index; - u16 rsvd; /* Padding */ + __le64 host_phys_addr; /* Ring base addr */ + __le32 ring_size; /* Ring entries */ + __le16 msi_index; + __le16 rsvd; /* Padding */ } nx_hostrq_sds_ring_t; typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u64 buff_size; /* Packet buffer size */ - u32 ring_size; /* Ring entries */ - u32 ring_kind; /* Class of ring */ + __le64 host_phys_addr; /* Ring base addr */ + __le64 buff_size; /* Packet buffer size */ + __le32 ring_size; /* Ring entries */ + __le32 ring_kind; /* Class of ring */ } nx_hostrq_rds_ring_t; typedef struct { - u64 host_rsp_dma_addr; /* Response dma'd here */ - u32 capabilities[4]; /* Flag bit vector */ - u32 host_int_crb_mode; /* Interrupt crb usage */ - u32 host_rds_crb_mode; /* RDS crb usage */ + __le64 host_rsp_dma_addr; /* Response dma'd here */ + __le32 capabilities[4]; /* Flag bit vector */ + __le32 host_int_crb_mode; /* Interrupt crb usage */ + __le32 host_rds_crb_mode; /* RDS crb usage */ /* These ring offsets are relative to data[0] below */ - u32 rds_ring_offset; /* Offset to RDS config */ - u32 sds_ring_offset; /* Offset to SDS config */ - u16 num_rds_rings; /* Count of RDS rings */ - u16 num_sds_rings; /* Count of SDS rings */ - u16 rsvd1; /* Padding */ - u16 rsvd2; /* Padding */ + __le32 rds_ring_offset; /* Offset to RDS config */ + __le32 sds_ring_offset; /* Offset to SDS config */ + __le16 num_rds_rings; /* Count of RDS rings */ + __le16 num_sds_rings; /* Count of SDS rings */ + __le16 rsvd1; /* Padding */ + __le16 rsvd2; /* Padding */ u8 reserved[128]; /* reserve space for future expansion*/ /* MUST BE 64-bit aligned. The following is packed: @@ -1029,24 +1029,24 @@ typedef struct { } nx_hostrq_rx_ctx_t; typedef struct { - u32 host_producer_crb; /* Crb to use */ - u32 rsvd1; /* Padding */ + __le32 host_producer_crb; /* Crb to use */ + __le32 rsvd1; /* Padding */ } nx_cardrsp_rds_ring_t; typedef struct { - u32 host_consumer_crb; /* Crb to use */ - u32 interrupt_crb; /* Crb to use */ + __le32 host_consumer_crb; /* Crb to use */ + __le32 interrupt_crb; /* Crb to use */ } nx_cardrsp_sds_ring_t; typedef struct { /* These ring offsets are relative to data[0] below */ - u32 rds_ring_offset; /* Offset to RDS config */ - u32 sds_ring_offset; /* Offset to SDS config */ - u32 host_ctx_state; /* Starting State */ - u32 num_fn_per_port; /* How many PCI fn share the port */ - u16 num_rds_rings; /* Count of RDS rings */ - u16 num_sds_rings; /* Count of SDS rings */ - u16 context_id; /* Handle for context */ + __le32 rds_ring_offset; /* Offset to RDS config */ + __le32 sds_ring_offset; /* Offset to SDS config */ + __le32 host_ctx_state; /* Starting State */ + __le32 num_fn_per_port; /* How many PCI fn share the port */ + __le16 num_rds_rings; /* Count of RDS rings */ + __le16 num_sds_rings; /* Count of SDS rings */ + __le16 context_id; /* Handle for context */ u8 phys_port; /* Physical id of port */ u8 virt_port; /* Virtual/Logical id of port */ u8 reserved[128]; /* save space for future expansion */ @@ -1072,34 +1072,34 @@ typedef struct { */ typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u32 ring_size; /* Ring entries */ - u32 rsvd; /* Padding */ + __le64 host_phys_addr; /* Ring base addr */ + __le32 ring_size; /* Ring entries */ + __le32 rsvd; /* Padding */ } nx_hostrq_cds_ring_t; typedef struct { - u64 host_rsp_dma_addr; /* Response dma'd here */ - u64 cmd_cons_dma_addr; /* */ - u64 dummy_dma_addr; /* */ - u32 capabilities[4]; /* Flag bit vector */ - u32 host_int_crb_mode; /* Interrupt crb usage */ - u32 rsvd1; /* Padding */ - u16 rsvd2; /* Padding */ - u16 interrupt_ctl; - u16 msi_index; - u16 rsvd3; /* Padding */ + __le64 host_rsp_dma_addr; /* Response dma'd here */ + __le64 cmd_cons_dma_addr; /* */ + __le64 dummy_dma_addr; /* */ + __le32 capabilities[4]; /* Flag bit vector */ + __le32 host_int_crb_mode; /* Interrupt crb usage */ + __le32 rsvd1; /* Padding */ + __le16 rsvd2; /* Padding */ + __le16 interrupt_ctl; + __le16 msi_index; + __le16 rsvd3; /* Padding */ nx_hostrq_cds_ring_t cds_ring; /* Desc of cds ring */ u8 reserved[128]; /* future expansion */ } nx_hostrq_tx_ctx_t; typedef struct { - u32 host_producer_crb; /* Crb to use */ - u32 interrupt_crb; /* Crb to use */ + __le32 host_producer_crb; /* Crb to use */ + __le32 interrupt_crb; /* Crb to use */ } nx_cardrsp_cds_ring_t; typedef struct { - u32 host_ctx_state; /* Starting state */ - u16 context_id; /* Handle for context */ + __le32 host_ctx_state; /* Starting state */ + __le16 context_id; /* Handle for context */ u8 phys_port; /* Physical id of port */ u8 virt_port; /* Virtual/Logical id of port */ nx_cardrsp_cds_ring_t cds_ring; /* Card cds settings */ @@ -1202,9 +1202,9 @@ enum { #define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */ typedef struct { - u64 qhdr; - u64 req_hdr; - u64 words[6]; + __le64 qhdr; + __le64 req_hdr; + __le64 words[6]; } nx_nic_req_t; typedef struct { diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 64b51643c62..746bdb47041 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -76,7 +76,7 @@ netxen_api_unlock(struct netxen_adapter *adapter) static u32 netxen_poll_rsp(struct netxen_adapter *adapter) { - u32 raw_rsp, rsp = NX_CDRP_RSP_OK; + u32 rsp = NX_CDRP_RSP_OK; int timeout = 0; do { @@ -86,10 +86,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter) if (++timeout > NX_OS_CRB_RETRY_COUNT) return NX_CDRP_RSP_TIMEOUT; - netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, - &raw_rsp); - - rsp = le32_to_cpu(raw_rsp); + netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp); } while (!NX_CDRP_IS_RSP(rsp)); return rsp; @@ -109,20 +106,16 @@ netxen_issue_cmd(struct netxen_adapter *adapter, if (netxen_api_lock(adapter)) return NX_RCODE_TIMEOUT; - netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, - cpu_to_le32(signature)); + netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature); - netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, - cpu_to_le32(arg1)); + netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1); - netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, - cpu_to_le32(arg2)); + netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2); - netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, - cpu_to_le32(arg3)); + netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3); netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET, - cpu_to_le32(NX_CDRP_FORM_CMD(cmd))); + NX_CDRP_FORM_CMD(cmd)); rsp = netxen_poll_rsp(adapter); @@ -133,7 +126,6 @@ netxen_issue_cmd(struct netxen_adapter *adapter, rcode = NX_RCODE_TIMEOUT; } else if (rsp == NX_CDRP_RSP_FAIL) { netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode); - rcode = le32_to_cpu(rcode); printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); @@ -183,7 +175,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) int i, nrds_rings, nsds_rings; size_t rq_size, rsp_size; - u32 cap, reg; + u32 cap, reg, val; int err; @@ -225,11 +217,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) prq->num_rds_rings = cpu_to_le16(nrds_rings); prq->num_sds_rings = cpu_to_le16(nsds_rings); - prq->rds_ring_offset = 0; - prq->sds_ring_offset = prq->rds_ring_offset + + prq->rds_ring_offset = cpu_to_le32(0); + + val = le32_to_cpu(prq->rds_ring_offset) + (sizeof(nx_hostrq_rds_ring_t) * nrds_rings); + prq->sds_ring_offset = cpu_to_le32(val); - prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + prq->rds_ring_offset); + prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + + le32_to_cpu(prq->rds_ring_offset)); for (i = 0; i < nrds_rings; i++) { @@ -241,17 +236,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size); } - prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + prq->sds_ring_offset); + prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + + le32_to_cpu(prq->sds_ring_offset)); prq_sds[0].host_phys_addr = cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count); /* only one msix vector for now */ - prq_sds[0].msi_index = cpu_to_le32(0); - - /* now byteswap offsets */ - prq->rds_ring_offset = cpu_to_le32(prq->rds_ring_offset); - prq->sds_ring_offset = cpu_to_le32(prq->sds_ring_offset); + prq_sds[0].msi_index = cpu_to_le16(0); phys_addr = hostrq_phys_addr; err = netxen_issue_cmd(adapter, @@ -269,9 +261,9 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) prsp_rds = ((nx_cardrsp_rds_ring_t *) - &prsp->data[prsp->rds_ring_offset]); + &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]); - for (i = 0; i < le32_to_cpu(prsp->num_rds_rings); i++) { + for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) { rds_ring = &recv_ctx->rds_rings[i]; reg = le32_to_cpu(prsp_rds[i].host_producer_crb); @@ -279,7 +271,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) } prsp_sds = ((nx_cardrsp_sds_ring_t *) - &prsp->data[prsp->sds_ring_offset]); + &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]); reg = le32_to_cpu(prsp_sds[0].host_consumer_crb); recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200); @@ -288,7 +280,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); recv_ctx->context_id = le16_to_cpu(prsp->context_id); - recv_ctx->virt_port = le16_to_cpu(prsp->virt_port); + recv_ctx->virt_port = prsp->virt_port; out_free_rsp: pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index aa6e603bfcb..e8a0eed0078 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -539,16 +539,19 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev, { struct netxen_adapter *adapter = netdev_priv(dev); nx_nic_req_t req; - nx_mac_req_t mac_req; + nx_mac_req_t *mac_req; + u64 word; int rv; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_NIC_REQUEST << 23); - req.req_hdr |= NX_MAC_EVENT; - req.req_hdr |= ((u64)adapter->portnum << 16); - mac_req.op = op; - memcpy(&mac_req.mac_addr, addr, 6); - req.words[0] = cpu_to_le64(*(u64 *)&mac_req); + req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); + + word = NX_MAC_EVENT | ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); + + mac_req = (nx_mac_req_t *)&req.words[0]; + mac_req->op = op; + memcpy(mac_req->mac_addr, addr, 6); rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); if (rv != 0) { @@ -612,12 +615,16 @@ send_fw_cmd: int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { nx_nic_req_t req; + u64 word; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_HOST_REQUEST << 23); - req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE; - req.req_hdr |= ((u64)adapter->portnum << 16); + req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); + + word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE | + ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); + req.words[0] = cpu_to_le64(mode); return netxen_send_cmd_descs(adapter, @@ -632,13 +639,15 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) int netxen_config_intr_coalesce(struct netxen_adapter *adapter) { nx_nic_req_t req; + u64 word; int rv; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_NIC_REQUEST << 23); - req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE; - req.req_hdr |= ((u64)adapter->portnum << 16); + req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); + + word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal)); @@ -772,13 +781,10 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4); adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4); - mac_hi = cpu_to_le32(mac_hi); - mac_lo = cpu_to_le32(mac_lo); - if (pci_func & 1) - *mac = ((mac_lo >> 16) | ((u64)mac_hi << 16)); + *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16)); else - *mac = ((mac_lo) | ((u64)mac_hi << 32)); + *mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32)); return 0; } diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index d924468e506..c0e06a65317 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1277,7 +1277,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, dev_kfree_skb_any(skb); for (i = 0; i < nr_frags; i++) { - index = frag_desc->frag_handles[i]; + index = le16_to_cpu(frag_desc->frag_handles[i]); skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum); if (skb) -- cgit From 391587c3447d99b842a647f8e701895c9eea050b Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:48:11 -0800 Subject: netxen: fix ipv6 offload and tx cleanup o fix the ip/tcp hdr offset in tx descriptors for ipv6. o cleanup xmit function, move the tso checks into separate function, this reduces unnecessary endian conversions back and forth. o optimize macros to initialize tx descriptors. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 43 +++++---------- drivers/net/netxen/netxen_nic_hw.c | 4 -- drivers/net/netxen/netxen_nic_main.c | 101 ++++++++++++++++------------------- 3 files changed, 57 insertions(+), 91 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 31311cc66d1..acb2ac971ca 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -308,27 +308,16 @@ struct netxen_ring_ctx { #define netxen_set_cmd_desc_ctxid(cmd_desc, var) \ ((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0)) -#define netxen_set_cmd_desc_flags(cmd_desc, val) \ - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ - ~cpu_to_le16(0x7f)) | cpu_to_le16((val) & 0x7f) -#define netxen_set_cmd_desc_opcode(cmd_desc, val) \ - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ - ~cpu_to_le16((u16)0x3f << 7)) | cpu_to_le16(((val) & 0x3f) << 7) - -#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ - (cmd_desc)->num_of_buffers_total_length = \ - ((cmd_desc)->num_of_buffers_total_length & \ - ~cpu_to_le32(0xff)) | cpu_to_le32((val) & 0xff) -#define netxen_set_cmd_desc_totallength(cmd_desc, val) \ - (cmd_desc)->num_of_buffers_total_length = \ - ((cmd_desc)->num_of_buffers_total_length & \ - ~cpu_to_le32((u32)0xffffff << 8)) | \ - cpu_to_le32(((val) & 0xffffff) << 8) - -#define netxen_get_cmd_desc_opcode(cmd_desc) \ - ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003f) -#define netxen_get_cmd_desc_totallength(cmd_desc) \ - ((le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) & 0xffffff) +#define netxen_set_tx_port(_desc, _port) \ + (_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0) + +#define netxen_set_tx_flags_opcode(_desc, _flags, _opcode) \ + (_desc)->flags_opcode = \ + cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7)) + +#define netxen_set_tx_frags_len(_desc, _frags, _len) \ + (_desc)->num_of_buffers_total_length = \ + cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8)) struct cmd_desc_type0 { u8 tcp_hdr_offset; /* For LSO only */ @@ -757,7 +746,7 @@ extern char netxen_nic_driver_name[]; */ struct netxen_skb_frag { u64 dma; - u32 length; + ulong length; }; #define _netxen_set_bits(config_word, start, bits, val) {\ @@ -783,13 +772,7 @@ struct netxen_skb_frag { struct netxen_cmd_buffer { struct sk_buff *skb; struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1]; - u32 total_length; - u32 mss; - u16 port; - u8 cmd; - u8 frag_count; - unsigned long time_stamp; - u32 state; + u32 frag_count; }; /* In rx_buffer, we do not need multiple fragments as is a single buffer */ @@ -1486,8 +1469,6 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter); void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); int netxen_init_firmware(struct netxen_adapter *adapter); -void netxen_tso_check(struct netxen_adapter *adapter, - struct cmd_desc_type0 *desc, struct sk_buff *skb); void netxen_nic_clear_stats(struct netxen_adapter *adapter); void netxen_watchdog_task(struct work_struct *work); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index e8a0eed0078..98d0bcda5f4 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -508,12 +508,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, cmd_desc = &cmd_desc_arr[i]; pbuf = &adapter->cmd_buf_arr[producer]; - pbuf->mss = 0; - pbuf->total_length = 0; pbuf->skb = NULL; - pbuf->cmd = 0; pbuf->frag_count = 0; - pbuf->port = 0; /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */ memcpy(&adapter->ahw.cmd_desc_head[producer], diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index ba01524b553..cb391238180 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -39,6 +39,7 @@ #include "netxen_nic_phan_reg.h" #include +#include #include MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); @@ -1137,29 +1138,46 @@ static int netxen_nic_close(struct net_device *netdev) return 0; } -void netxen_tso_check(struct netxen_adapter *adapter, +static bool netxen_tso_check(struct net_device *netdev, struct cmd_desc_type0 *desc, struct sk_buff *skb) { - if (desc->mss) { - desc->total_hdr_length = (sizeof(struct ethhdr) + - ip_hdrlen(skb) + tcp_hdrlen(skb)); + bool tso = false; + u8 opcode = TX_ETHER_PKT; - if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) && - (skb->protocol == htons(ETH_P_IPV6))) - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6); - else - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); + if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && + skb_shinfo(skb)->gso_size > 0) { + + desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + desc->total_hdr_length = + skb_transport_offset(skb) + tcp_hdrlen(skb); + + opcode = (skb->protocol == htons(ETH_P_IPV6)) ? + TX_TCP_LSO6 : TX_TCP_LSO; + tso = true; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); - else if (ip_hdr(skb)->protocol == IPPROTO_UDP) - netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); - else - return; + u8 l4proto; + + if (skb->protocol == htons(ETH_P_IP)) { + l4proto = ip_hdr(skb)->protocol; + + if (l4proto == IPPROTO_TCP) + opcode = TX_TCP_PKT; + else if(l4proto == IPPROTO_UDP) + opcode = TX_UDP_PKT; + } else if (skb->protocol == htons(ETH_P_IPV6)) { + l4proto = ipv6_hdr(skb)->nexthdr; + + if (l4proto == IPPROTO_TCP) + opcode = TX_TCPV6_PKT; + else if(l4proto == IPPROTO_UDP) + opcode = TX_UDPV6_PKT; + } } desc->tcp_hdr_offset = skb_transport_offset(skb); desc->ip_hdr_offset = skb_network_offset(skb); + netxen_set_tx_flags_opcode(desc, 0, opcode); + return tso; } static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) @@ -1167,33 +1185,20 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_hardware_context *hw = &adapter->ahw; unsigned int first_seg_len = skb->len - skb->data_len; + struct netxen_cmd_buffer *pbuf; struct netxen_skb_frag *buffrag; - unsigned int i; + struct cmd_desc_type0 *hwdesc; + int i, k; u32 producer, consumer; - u32 saved_producer = 0; - struct cmd_desc_type0 *hwdesc; - int k; - struct netxen_cmd_buffer *pbuf = NULL; - int frag_count; - int no_of_desc; + int frag_count, no_of_desc; u32 num_txd = adapter->max_tx_desc_count; + bool is_tso = false; frag_count = skb_shinfo(skb)->nr_frags + 1; /* There 4 fragments per descriptor */ no_of_desc = (frag_count + 3) >> 2; - if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) { - if (skb_shinfo(skb)->gso_size > 0) { - - no_of_desc++; - if ((ip_hdrlen(skb) + tcp_hdrlen(skb) + - sizeof(struct ethhdr)) > - (sizeof(struct cmd_desc_type0) - 2)) { - no_of_desc++; - } - } - } producer = adapter->cmd_producer; smp_mb(); @@ -1205,34 +1210,22 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } /* Copy the descriptors into the hardware */ - saved_producer = producer; hwdesc = &hw->cmd_desc_head[producer]; memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; - if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && - skb_shinfo(skb)->gso_size > 0) { - pbuf->mss = skb_shinfo(skb)->gso_size; - hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - } else { - pbuf->mss = 0; - hwdesc->mss = 0; - } - pbuf->total_length = skb->len; + + is_tso = netxen_tso_check(netdev, hwdesc, skb); + pbuf->skb = skb; - pbuf->cmd = TX_ETHER_PKT; pbuf->frag_count = frag_count; - pbuf->port = adapter->portnum; buffrag = &pbuf->frag_array[0]; buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); buffrag->length = first_seg_len; - netxen_set_cmd_desc_totallength(hwdesc, skb->len); - netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); - netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); + netxen_set_tx_frags_len(hwdesc, frag_count, skb->len); + netxen_set_tx_port(hwdesc, adapter->portnum); - netxen_set_cmd_desc_port(hwdesc, adapter->portnum); - netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum); hwdesc->buffer1_length = cpu_to_le16(first_seg_len); hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); @@ -1285,16 +1278,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } producer = get_next_index(producer, num_txd); - /* might change opcode to TX_TCP_LSO */ - netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); - /* For LSO, we need to copy the MAC/IP/TCP headers into * the descriptor ring */ - if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer]) - == TX_TCP_LSO) { + if (is_tso) { int hdr_len, first_hdr_len, more_hdr; - hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length; + hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) { first_hdr_len = sizeof(struct cmd_desc_type0) - 2; more_hdr = 1; -- cgit From c7860a2aec571ea95d3ad19b8d9775b27828baac Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:48:32 -0800 Subject: netxen: fix link speed reporting for some boards o Read negotiated link speed when link state changes. o Fix link speed reporting for hybrid nic boards, which have both 1Gbps and 10Gbps ports. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 3 ++- drivers/net/netxen/netxen_nic_ethtool.c | 31 +++++++++++++++++++++++-------- drivers/net/netxen/netxen_nic_hw.c | 28 ++++++++++++++++++++-------- drivers/net/netxen/netxen_nic_main.c | 14 +++++++++++++- 4 files changed, 58 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index acb2ac971ca..a674a23f72b 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -499,7 +499,8 @@ typedef enum { NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a, NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b, NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031, - NETXEN_BRDTYPE_P3_10G_XFP = 0x0032 + NETXEN_BRDTYPE_P3_10G_XFP = 0x0032, + NETXEN_BRDTYPE_P3_10G_TP = 0x0080 } netxen_brdtype_t; diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index e45ce295172..c0bd40fcf70 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -136,11 +136,9 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->port = PORT_TP; - if (netif_running(dev)) { - ecmd->speed = adapter->link_speed; - ecmd->duplex = adapter->link_duplex; - ecmd->autoneg = adapter->link_autoneg; - } + ecmd->speed = adapter->link_speed; + ecmd->duplex = adapter->link_duplex; + ecmd->autoneg = adapter->link_autoneg; } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { u32 val; @@ -171,7 +169,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } else return -EIO; - ecmd->phy_address = adapter->portnum; + ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; switch ((netxen_brdtype_t) boardinfo->board_type) { @@ -180,13 +178,13 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: - case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; case NETXEN_BRDTYPE_P2_SB31_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4_LP: + case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; @@ -204,16 +202,33 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; - case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: case NETXEN_BRDTYPE_P3_10G_SFP_CT: case NETXEN_BRDTYPE_P3_10G_SFP_QT: + ecmd->advertising |= ADVERTISED_TP; + ecmd->supported |= SUPPORTED_TP; + case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; + case NETXEN_BRDTYPE_P3_10G_TP: + if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { + ecmd->autoneg = AUTONEG_DISABLE; + ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); + ecmd->advertising |= + (ADVERTISED_FIBRE | ADVERTISED_TP); + ecmd->port = PORT_FIBRE; + } else { + ecmd->autoneg = AUTONEG_ENABLE; + ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); + ecmd->advertising |= + (ADVERTISED_TP | ADVERTISED_Autoneg); + ecmd->port = PORT_TP; + } + break; default: printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 98d0bcda5f4..4276f7f8223 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -2036,7 +2036,13 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) rv = -1; } - DPRINTK(INFO, "Discovered board type:0x%x ", boardinfo->board_type); + if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) { + u32 gpio = netxen_nic_reg_read(adapter, + NETXEN_ROMUSB_GLB_PAD_GPIO_I); + if ((gpio & 0x8000) == 0) + boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP; + } + switch ((netxen_brdtype_t) boardinfo->board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: adapter->ahw.board_type = NETXEN_NIC_GBE; @@ -2055,7 +2061,6 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) case NETXEN_BRDTYPE_P3_10G_SFP_QT: case NETXEN_BRDTYPE_P3_10G_XFP: case NETXEN_BRDTYPE_P3_10000_BASE_T: - adapter->ahw.board_type = NETXEN_NIC_XGBE; break; case NETXEN_BRDTYPE_P1_BD: @@ -2065,9 +2070,12 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: - adapter->ahw.board_type = NETXEN_NIC_GBE; break; + case NETXEN_BRDTYPE_P3_10G_TP: + adapter->ahw.board_type = (adapter->portnum < 2) ? + NETXEN_NIC_XGBE : NETXEN_NIC_GBE; + break; default: printk("%s: Unknown(%x)\n", netxen_nic_driver_name, boardinfo->board_type); @@ -2112,12 +2120,16 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) { __u32 status; __u32 autoneg; - __u32 mode; __u32 port_mode; - netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); - if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ + if (!netif_carrier_ok(adapter->netdev)) { + adapter->link_speed = 0; + adapter->link_duplex = -1; + adapter->link_autoneg = AUTONEG_ENABLE; + return; + } + if (adapter->ahw.board_type == NETXEN_NIC_GBE) { adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &port_mode, 4); if (port_mode == NETXEN_PORT_MODE_802_3_AP) { @@ -2143,7 +2155,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) adapter->link_speed = SPEED_1000; break; default: - adapter->link_speed = -1; + adapter->link_speed = 0; break; } switch (netxen_get_phy_duplex(status)) { @@ -2166,7 +2178,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) goto link_down; } else { link_down: - adapter->link_speed = -1; + adapter->link_speed = 0; adapter->link_duplex = -1; } } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cb391238180..2c6ce6ffde0 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -243,7 +243,7 @@ static void netxen_check_options(struct netxen_adapter *adapter) case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: adapter->msix_supported = !!use_msi_x; - adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; break; case NETXEN_BRDTYPE_P2_SB35_4G: @@ -252,6 +252,14 @@ static void netxen_check_options(struct netxen_adapter *adapter) adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; break; + case NETXEN_BRDTYPE_P3_10G_TP: + adapter->msix_supported = !!use_msi_x; + if (adapter->ahw.board_type == NETXEN_NIC_XGBE) + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; + else + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; + break; + default: adapter->msix_supported = 0; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; @@ -1396,6 +1404,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) netif_carrier_off(netdev); netif_stop_queue(netdev); } + + netxen_nic_set_link_parameters(adapter); } else if (!adapter->ahw.linkup && linkup) { printk(KERN_INFO "%s: %s NIC Link is up\n", netxen_nic_driver_name, netdev->name); @@ -1404,6 +1414,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) netif_carrier_on(netdev); netif_wake_queue(netdev); } + + netxen_nic_set_link_parameters(adapter); } } -- cgit From 27c915a4d843b90eb4065298969578d15e5e6ab0 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:49:00 -0800 Subject: netxen: firmware init fix o Fix order or rom register writes. o Reduce udelays when writing rom registers. This cuts the firmware init time by 40%. o Do not reset core/memory clocks when reinitializing driver. Firmware willl handle this when initialized. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_hw.c | 6 ++--- drivers/net/netxen/netxen_nic_init.c | 35 ++++++++++++++++----------- drivers/net/netxen/netxen_nic_main.c | 47 +++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 37 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 4276f7f8223..511db2ac57c 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -939,7 +939,7 @@ int netxen_load_firmware(struct netxen_adapter *adapter) { int i; u32 data, size = 0; - u32 flashaddr = NETXEN_BOOTLD_START, memaddr = NETXEN_BOOTLD_START; + u32 flashaddr = NETXEN_BOOTLD_START; size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4; @@ -951,10 +951,8 @@ int netxen_load_firmware(struct netxen_adapter *adapter) if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) return -EIO; - adapter->pci_mem_write(adapter, memaddr, &data, 4); + adapter->pci_mem_write(adapter, flashaddr, &data, 4); flashaddr += 4; - memaddr += 4; - cond_resched(); } msleep(1); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index c0e06a65317..a3203644b48 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -439,6 +439,8 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter) long timeout = 0; long done = 0; + cond_resched(); + while (done == 0) { done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS); done &= 2; @@ -533,12 +535,9 @@ static int do_rom_fast_write(struct netxen_adapter *adapter, int addr, static int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { - cond_resched(); - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); - udelay(100); /* prevent bursting on CRB */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); if (netxen_wait_rom_done(adapter)) { printk("Error waiting for rom done\n"); @@ -546,7 +545,7 @@ static int do_rom_fast_read(struct netxen_adapter *adapter, } /* reset abyte_cnt and dummy_byte_cnt */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); - udelay(100); /* prevent bursting on CRB */ + udelay(10); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); @@ -884,14 +883,16 @@ int netxen_flash_unlock(struct netxen_adapter *adapter) int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) { int addr, val; - int i, init_delay = 0; + int i, n, init_delay = 0; struct crb_addr_pair *buf; - unsigned offset, n; + unsigned offset; u32 off; /* resetall */ + rom_lock(adapter); netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); + netxen_rom_unlock(adapter); if (verbose) { if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) @@ -910,7 +911,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { if (netxen_rom_fast_read(adapter, 0, &n) != 0 || - (n != 0xcafecafeUL) || + (n != 0xcafecafe) || netxen_rom_fast_read(adapter, 4, &n) != 0) { printk(KERN_ERR "%s: ERROR Reading crb_init area: " "n: %08x\n", netxen_nic_driver_name, n); @@ -975,6 +976,14 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) /* do not reset PCI */ if (off == (ROMUSB_GLB + 0xbc)) continue; + if (off == (ROMUSB_GLB + 0xa8)) + continue; + if (off == (ROMUSB_GLB + 0xc8)) /* core clock */ + continue; + if (off == (ROMUSB_GLB + 0x24)) /* MN clock */ + continue; + if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ + continue; if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) buf[i].data = 0x1020; /* skip the function enable register */ @@ -992,23 +1001,21 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) continue; } + init_delay = 1; /* After writing this register, HW needs time for CRB */ /* to quiet down (else crb_window returns 0xffffffff) */ if (off == NETXEN_ROMUSB_GLB_SW_RESET) { - init_delay = 1; + init_delay = 1000; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { /* hold xdma in reset also */ buf[i].data = NETXEN_NIC_XDMA_RESET; + buf[i].data = 0x8000ff; } } adapter->hw_write_wx(adapter, off, &buf[i].data, 4); - if (init_delay == 1) { - msleep(1000); - init_delay = 0; - } - msleep(1); + msleep(init_delay); } kfree(buf); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2c6ce6ffde0..cbe2b3e814d 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -280,10 +280,15 @@ static void netxen_check_options(struct netxen_adapter *adapter) static int netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) { - int ret = 0; + u32 val, timeout; if (first_boot == 0x55555555) { /* This is the first boot after power up */ + adapter->pci_write_normalize(adapter, + NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); + + if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) + return 0; /* PCI bus master workaround */ adapter->hw_read_wx(adapter, @@ -303,18 +308,26 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) /* clear the register for future unloads/loads */ adapter->pci_write_normalize(adapter, NETXEN_CAM_RAM(0x1fc), 0); - ret = -1; + return -EIO; } - if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - /* Start P2 boot loader */ - adapter->pci_write_normalize(adapter, - NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); - adapter->pci_write_normalize(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); - } + /* Start P2 boot loader */ + val = adapter->pci_read_normalize(adapter, + NETXEN_ROMUSB_GLB_PEGTUNE_DONE); + adapter->pci_write_normalize(adapter, + NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1); + timeout = 0; + do { + msleep(1); + val = adapter->pci_read_normalize(adapter, + NETXEN_CAM_RAM(0x1fc)); + + if (++timeout > 5000) + return -EIO; + + } while (val == NETXEN_BDINFO_MAGIC); } - return ret; + return 0; } static void netxen_set_port_mode(struct netxen_adapter *adapter) @@ -793,8 +806,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) CRB_CMDPEG_STATE, 0); netxen_pinit_from_rom(adapter, 0); msleep(1); - netxen_load_firmware(adapter); } + netxen_load_firmware(adapter); if (NX_IS_REVISION_P3(revision_id)) netxen_pcie_strap_init(adapter); @@ -810,13 +823,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } - if ((first_boot == 0x55555555) && - (NX_IS_REVISION_P2(revision_id))) { - /* Unlock the HW, prompting the boot sequence */ - adapter->pci_write_normalize(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); - } - err = netxen_initialize_adapter_offload(adapter); if (err) goto err_out_iounmap; @@ -830,7 +836,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); /* Handshake with the card before we register the devices. */ - netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + if (err) + goto err_out_free_offload; } /* first_driver */ @@ -934,6 +942,7 @@ err_out_disable_msi: if (adapter->flags & NETXEN_NIC_MSI_ENABLED) pci_disable_msi(pdev); +err_out_free_offload: if (first_driver) netxen_free_adapter_offload(adapter); -- cgit From 06e9d9f9783860fe4c602ef491f47211804ccc96 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:49:22 -0800 Subject: netxen: cleanup mac list on driver unload This fixes a tiny memory leak when driver is unloaded. The mac address list maintained in netxen_adapter needs to deleted when driver is going down. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 1 + drivers/net/netxen/netxen_nic_hw.c | 13 +++++++++++++ drivers/net/netxen/netxen_nic_main.c | 3 +++ 3 files changed, 17 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index a674a23f72b..6598a34b87d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1478,6 +1478,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter); u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); void netxen_p2_nic_set_multi(struct net_device *netdev); void netxen_p3_nic_set_multi(struct net_device *netdev); +void netxen_p3_free_mac_list(struct netxen_adapter *adapter); int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); int netxen_config_intr_coalesce(struct netxen_adapter *adapter); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 511db2ac57c..e2d2a2fdbe1 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -627,6 +627,19 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) (struct cmd_desc_type0 *)&req, 1); } +void netxen_p3_free_mac_list(struct netxen_adapter *adapter) +{ + nx_mac_list_t *cur, *next; + + cur = adapter->mac_list; + + while (cur) { + next = cur->next; + kfree(cur); + cur = next; + } +} + #define NETXEN_CONFIG_INTR_COALESCE 3 /* diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cbe2b3e814d..9268fd2fbac 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -986,6 +986,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_free_hw_resources(adapter); netxen_release_rx_buffers(adapter); netxen_free_sw_resources(adapter); + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + netxen_p3_free_mac_list(adapter); } if (adapter->portnum == 0) -- cgit From 03e678ee968ae54b79c1580c2935895bd863ad95 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:49:43 -0800 Subject: netxen: hold tx lock while sending firmware commands Some firmware commands like mac address addition/deletion are sent on the transmit ring. So need to hold the tx lock before touching tx producer/consumer indices. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_hw.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index e2d2a2fdbe1..821cff68b3f 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -503,6 +503,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, i = 0; + netif_tx_lock_bh(adapter->netdev); + producer = adapter->cmd_producer; do { cmd_desc = &cmd_desc_arr[i]; @@ -527,6 +529,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); + netif_tx_unlock_bh(adapter->netdev); + return 0; } -- cgit From 6f70340698333f14b1d9c9e913c5de8f66b72c55 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:50:00 -0800 Subject: netxen: handle dma mapping failures o Bail out if pci_map_single() fails while replenishing rx ring. o Drop packet if pci_map_{single,page}() fail in tx. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 1 - drivers/net/netxen/netxen_nic_init.c | 68 +++++++++++++++++------------------- drivers/net/netxen/netxen_nic_main.c | 38 ++++++++++++++++++-- 3 files changed, 67 insertions(+), 40 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 6598a34b87d..c11c568fd7d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -860,7 +860,6 @@ struct nx_host_rds_ring { u32 skb_size; struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */ struct list_head free_list; - int begin_alloc; }; /* diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index a3203644b48..ca7c8d8050c 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -308,7 +308,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) } memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE); INIT_LIST_HEAD(&rds_ring->free_list); - rds_ring->begin_alloc = 0; /* * Now go through all of them, set reference handles * and put them in the queues. @@ -1435,7 +1434,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; int count = 0; - int index = 0; netxen_ctx_msg msg = 0; dma_addr_t dma; struct list_head *head; @@ -1443,7 +1441,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) rds_ring = &recv_ctx->rds_rings[ringid]; producer = rds_ring->producer; - index = rds_ring->begin_alloc; head = &rds_ring->free_list; /* We can start writing rx descriptors into the phantom memory. */ @@ -1451,39 +1448,37 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) skb = dev_alloc_skb(rds_ring->skb_size); if (unlikely(!skb)) { - rds_ring->begin_alloc = index; break; } + if (!adapter->ahw.cut_through) + skb_reserve(skb, 2); + + dma = pci_map_single(pdev, skb->data, + rds_ring->dma_size, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(pdev, dma)) { + dev_kfree_skb_any(skb); + break; + } + + count++; buffer = list_entry(head->next, struct netxen_rx_buffer, list); list_del(&buffer->list); - count++; /* now there should be no failure */ - pdesc = &rds_ring->desc_head[producer]; - - if (!adapter->ahw.cut_through) - skb_reserve(skb, 2); - /* This will be setup when we receive the - * buffer after it has been filled FSL TBD TBD - * skb->dev = netdev; - */ - dma = pci_map_single(pdev, skb->data, rds_ring->dma_size, - PCI_DMA_FROMDEVICE); - pdesc->addr_buffer = cpu_to_le64(dma); buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; buffer->dma = dma; + /* make a rcv descriptor */ + pdesc = &rds_ring->desc_head[producer]; + pdesc->addr_buffer = cpu_to_le64(dma); pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); - DPRINTK(INFO, "done writing descripter\n"); - producer = - get_next_index(producer, rds_ring->max_rx_desc_count); - index = get_next_index(index, rds_ring->max_rx_desc_count); + + producer = get_next_index(producer, rds_ring->max_rx_desc_count); } /* if we did allocate buffers, then write the count to Phantom */ if (count) { - rds_ring->begin_alloc = index; rds_ring->producer = producer; /* Window = 1 */ adapter->pci_write_normalize(adapter, @@ -1522,49 +1517,50 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; int count = 0; - int index = 0; struct list_head *head; + dma_addr_t dma; rds_ring = &recv_ctx->rds_rings[ringid]; producer = rds_ring->producer; - index = rds_ring->begin_alloc; head = &rds_ring->free_list; /* We can start writing rx descriptors into the phantom memory. */ while (!list_empty(head)) { skb = dev_alloc_skb(rds_ring->skb_size); if (unlikely(!skb)) { - rds_ring->begin_alloc = index; break; } + if (!adapter->ahw.cut_through) + skb_reserve(skb, 2); + + dma = pci_map_single(pdev, skb->data, + rds_ring->dma_size, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(pdev, dma)) { + dev_kfree_skb_any(skb); + break; + } + + count++; buffer = list_entry(head->next, struct netxen_rx_buffer, list); list_del(&buffer->list); - count++; /* now there should be no failure */ - pdesc = &rds_ring->desc_head[producer]; - if (!adapter->ahw.cut_through) - skb_reserve(skb, 2); buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; - buffer->dma = pci_map_single(pdev, skb->data, - rds_ring->dma_size, - PCI_DMA_FROMDEVICE); + buffer->dma = dma; /* make a rcv descriptor */ + pdesc = &rds_ring->desc_head[producer]; pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); pdesc->addr_buffer = cpu_to_le64(buffer->dma); - producer = - get_next_index(producer, rds_ring->max_rx_desc_count); - index = get_next_index(index, rds_ring->max_rx_desc_count); - buffer = &rds_ring->rx_buf_arr[index]; + + producer = get_next_index(producer, rds_ring->max_rx_desc_count); } /* if we did allocate buffers, then write the count to Phantom */ if (count) { - rds_ring->begin_alloc = index; rds_ring->producer = producer; /* Window = 1 */ adapter->pci_write_normalize(adapter, diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9268fd2fbac..86867405a36 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1200,6 +1200,24 @@ static bool netxen_tso_check(struct net_device *netdev, return tso; } +static void +netxen_clean_tx_dma_mapping(struct pci_dev *pdev, + struct netxen_cmd_buffer *pbuf, int last) +{ + int k; + struct netxen_skb_frag *buffrag; + + buffrag = &pbuf->frag_array[0]; + pci_unmap_single(pdev, buffrag->dma, + buffrag->length, PCI_DMA_TODEVICE); + + for (k = 1; k < last; k++) { + buffrag = &pbuf->frag_array[k]; + pci_unmap_page(pdev, buffrag->dma, + buffrag->length, PCI_DMA_TODEVICE); + } +} + static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); @@ -1208,6 +1226,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct netxen_cmd_buffer *pbuf; struct netxen_skb_frag *buffrag; struct cmd_desc_type0 *hwdesc; + struct pci_dev *pdev = adapter->pdev; + dma_addr_t temp_dma; int i, k; u32 producer, consumer; @@ -1240,8 +1260,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pbuf->skb = skb; pbuf->frag_count = frag_count; buffrag = &pbuf->frag_array[0]; - buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len, + temp_dma = pci_map_single(pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(pdev, temp_dma)) + goto drop_packet; + + buffrag->dma = temp_dma; buffrag->length = first_seg_len; netxen_set_tx_frags_len(hwdesc, frag_count, skb->len); netxen_set_tx_port(hwdesc, adapter->portnum); @@ -1253,7 +1277,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct skb_frag_struct *frag; int len, temp_len; unsigned long offset; - dma_addr_t temp_dma; /* move to next desc. if there is a need */ if ((i & 0x3) == 0) { @@ -1269,8 +1292,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) offset = frag->page_offset; temp_len = len; - temp_dma = pci_map_page(adapter->pdev, frag->page, offset, + temp_dma = pci_map_page(pdev, frag->page, offset, len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(pdev, temp_dma)) { + netxen_clean_tx_dma_mapping(pdev, pbuf, i); + goto drop_packet; + } buffrag++; buffrag->dma = temp_dma; @@ -1345,6 +1372,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) netdev->trans_start = jiffies; return NETDEV_TX_OK; + +drop_packet: + adapter->stats.txdropped++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } static int netxen_nic_check_temp(struct netxen_adapter *adapter) -- cgit From 2950e952920811be465ec95c6b56f03dc66a05c0 Mon Sep 17 00:00:00 2001 From: Jos-Vicente Gilabert Date: Wed, 14 Jan 2009 20:55:00 -0800 Subject: drivers/net/irda/irda-usb.c: fix buffer overflow Taken from http://bugzilla.kernel.org/show_bug.cgi?id=12397 We're doing an sprintf of an 11-char string into an 11-char buffer. Whoops. It breaks firmware uploading. Reported-by: Jos-Vicente Gilabert Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/irda/irda-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 29118f58a14..3a22dc41b65 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1073,7 +1073,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self) { unsigned int i; int ret; - char stir421x_fw_name[11]; + char stir421x_fw_name[12]; const struct firmware *fw; const unsigned char *fw_version_ptr; /* pointer to version string */ unsigned long fw_version = 0; -- cgit From 937f1ba56b4be37d9e2ad77412f95048662058d2 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 14 Jan 2009 21:05:05 -0800 Subject: net: Add init_dummy_netdev() and fix EMAC driver using it This adds an init_dummy_netdev() function that gets a network device structure (allocation and lifetime entirely under caller's control) and initialize the minimum amount of fields so it can be used to schedule NAPI polls without registering a full blown interface. This is to be used by drivers that need to tie several hardware interfaces to a single NAPI poll scheduler due to HW limitations. It also updates the ibm_newemac driver to use that, this fixing the oops on 2.6.29 due to passing NULL as "dev" to netif_napi_add() Symbol is exported GPL only a I don't think we want binary drivers doing that sort of acrobatics (if we want them at all). Signed-off-by: Benjamin Herrenschmidt Tested-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ibm_newemac/mal.c | 4 +++- drivers/net/ibm_newemac/mal.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index ecf9798987f..2a2fc17b287 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -613,7 +613,9 @@ static int __devinit mal_probe(struct of_device *ofdev, INIT_LIST_HEAD(&mal->list); spin_lock_init(&mal->lock); - netif_napi_add(NULL, &mal->napi, mal_poll, + init_dummy_netdev(&mal->dummy_dev); + + netif_napi_add(&mal->dummy_dev, &mal->napi, mal_poll, CONFIG_IBM_NEW_EMAC_POLL_WEIGHT); /* Load power-on reset defaults */ diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h index 2f0a8736084..9ededfbf072 100644 --- a/drivers/net/ibm_newemac/mal.h +++ b/drivers/net/ibm_newemac/mal.h @@ -214,6 +214,8 @@ struct mal_instance { int index; spinlock_t lock; + struct net_device dummy_dev; + unsigned int features; }; -- cgit From d57bc36e7aba9e3a00d154f5eff80ff596146fc4 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 14 Jan 2009 21:05:55 -0800 Subject: ax88796: start_xmit fix using net_device_ops This patch hooks up the start_xmit/tx_timeout/get_stats callbacks in the ax88796 driver since they no longer are installed by the lib8390 code. Without this patch the function dev_hard_start_xmit() crashes due to a start_xmit callback with the value NULL. While at it, update the ax88796 driver to make use of use of struct net_device_ops. Signed-off-by: Magnus Damm Signed-off-by: David S. Miller --- drivers/net/ax88796.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 337488ec707..a4eb6c40678 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -37,7 +37,10 @@ static int phy_debug = 0; #define __ei_open ax_ei_open #define __ei_close ax_ei_close #define __ei_poll ax_ei_poll +#define __ei_start_xmit ax_ei_start_xmit #define __ei_tx_timeout ax_ei_tx_timeout +#define __ei_get_stats ax_ei_get_stats +#define __ei_set_multicast_list ax_ei_set_multicast_list #define __ei_interrupt ax_ei_interrupt #define ____alloc_ei_netdev ax__alloc_ei_netdev #define __NS8390_init ax_NS8390_init @@ -623,6 +626,23 @@ static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom) } #endif +static const struct net_device_ops ax_netdev_ops = { + .ndo_open = ax_open, + .ndo_stop = ax_close, + .ndo_do_ioctl = ax_ioctl, + + .ndo_start_xmit = ax_ei_start_xmit, + .ndo_tx_timeout = ax_ei_tx_timeout, + .ndo_get_stats = ax_ei_get_stats, + .ndo_set_multicast_list = ax_ei_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ax_ei_poll, +#endif +}; + /* setup code */ static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) @@ -738,9 +758,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) ei_status.get_8390_hdr = &ax_get_8390_hdr; ei_status.priv = 0; - dev->open = ax_open; - dev->stop = ax_close; - dev->do_ioctl = ax_ioctl; + dev->netdev_ops = &ax_netdev_ops; dev->ethtool_ops = &ax_ethtool_ops; ax->msg_enable = NETIF_MSG_LINK; @@ -753,9 +771,6 @@ static int ax_init_dev(struct net_device *dev, int first_init) ax->mii.mdio_write = ax_phy_write; ax->mii.dev = dev; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = ax_ei_poll; -#endif ax_NS8390_init(dev, 0); if (first_init) -- cgit From 1cf167f27ad2720af11ee8aa350009342f909e70 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:22:18 -0800 Subject: bnx2x: Using singlethread work queue Since slow-path events, including link update, are handled in work-queue, a race condition was introduced in the self-test that sometimes caused the link status to fail: the self-test was running under RTNL lock, and if the link-watch was scheduled it stoped the shared work-queue (waiting for the RTNL lock) and so the link update event was not handled until the self-test ended (releasing the RTNL lock) with failure (since the link status was not updated) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 2 +- drivers/net/bnx2x_main.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index fd705d1295a..96a8889afbe 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -811,7 +811,7 @@ struct bnx2x { int pm_cap; int pcie_cap; - struct work_struct sp_task; + struct delayed_work sp_task; struct work_struct reset_task; struct timer_list timer; diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 4be05847f86..cc6ffba7459 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -95,6 +95,7 @@ MODULE_PARM_DESC(debug, "default debug msglevel"); module_param(use_multi, int, 0); MODULE_PARM_DESC(use_multi, "use per-CPU queues"); #endif +static struct workqueue_struct *bnx2x_wq; enum bnx2x_board_type { BCM57710 = 0, @@ -671,7 +672,8 @@ static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) synchronize_irq(bp->pdev->irq); /* make sure sp_task is not running */ - cancel_work_sync(&bp->sp_task); + cancel_delayed_work(&bp->sp_task); + flush_workqueue(bnx2x_wq); } /* fast path */ @@ -1660,7 +1662,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) if (unlikely(status & 0x1)) { - schedule_work(&bp->sp_task); + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); status &= ~0x1; if (!status) @@ -2820,7 +2822,7 @@ static void bnx2x_attn_int(struct bnx2x *bp) static void bnx2x_sp_task(struct work_struct *work) { - struct bnx2x *bp = container_of(work, struct bnx2x, sp_task); + struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work); u16 status; @@ -2875,7 +2877,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) return IRQ_HANDLED; #endif - schedule_work(&bp->sp_task); + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); return IRQ_HANDLED; } @@ -7501,7 +7503,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) mutex_init(&bp->port.phy_mutex); - INIT_WORK(&bp->sp_task, bnx2x_sp_task); + INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); INIT_WORK(&bp->reset_task, bnx2x_reset_task); rc = bnx2x_get_hwinfo(bp); @@ -10519,12 +10521,20 @@ static struct pci_driver bnx2x_pci_driver = { static int __init bnx2x_init(void) { + bnx2x_wq = create_singlethread_workqueue("bnx2x"); + if (bnx2x_wq == NULL) { + printk(KERN_ERR PFX "Cannot create workqueue\n"); + return -ENOMEM; + } + return pci_register_driver(&bnx2x_pci_driver); } static void __exit bnx2x_cleanup(void) { pci_unregister_driver(&bnx2x_pci_driver); + + destroy_workqueue(bnx2x_wq); } module_init(bnx2x_init); -- cgit From 58f4c4cfce5c4715b79621f0a635925c55f855d5 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:23:36 -0800 Subject: bnx2x: Missing memory barriers While working on IA64, it became clear that the following memory barriers are missing Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index cc6ffba7459..f0b2e73b87f 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1357,11 +1357,23 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, 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 tstorm_eth_rx_producers)/4; i++) REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4, ((u32 *)&rx_prods)[i]); + mmiowb(); /* keep prod updates ordered */ + DP(NETIF_MSG_RX_STATUS, "Wrote: bd_prod %u cqe_prod %u sge_prod %u\n", bd_prod, rx_comp_prod, rx_sge_prod); @@ -1582,7 +1594,6 @@ next_cqe: /* Update producers */ bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod, fp->rx_sge_prod); - mmiowb(); /* keep prod updates ordered */ fp->rx_pkt += rx_pkt; fp->rx_calls++; @@ -8729,6 +8740,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) tx_bd->general_data = ((UNICAST_ADDRESS << ETH_TX_BD_ETH_ADDR_TYPE_SHIFT) | 1); + wmb(); + fp->hw_tx_prods->bds_prod = cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1); mb(); /* FW restriction: must not reorder writing nbd and packets */ @@ -8780,7 +8793,6 @@ test_loopback_rx_exit: /* Update producers */ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, fp->rx_sge_prod); - mmiowb(); /* keep prod updates ordered */ test_loopback_exit: bp->link_params.loopback_mode = LOOPBACK_NONE; @@ -9707,6 +9719,15 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) 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->hw_tx_prods->bds_prod = cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd); mb(); /* FW restriction: must not reorder writing nbd and packets */ @@ -9720,6 +9741,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { + /* We want bnx2x_tx_int to "see" the updated tx_bd_prod + if we put Tx into XOFF state. */ + smp_mb(); netif_stop_queue(dev); bp->eth_stats.driver_xoff++; if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) -- cgit From 4f40f2cba244e04c0f385c5ce60498b513b335dd Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:24:17 -0800 Subject: bnx2x: Using system page size for SGE When the page size is not 4KB, the FW must be programmed to work with the right SGE boundaries and fragment list length. To avoid confusion with the BCM_PAGE_SIZE which is set to 4KB for the FW sake, another alias for the system page size was added to explicitly indicate that it is meant for the SGE Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 3 +++ drivers/net/bnx2x_main.c | 32 ++++++++++++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 96a8889afbe..2cd1e427828 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -150,6 +150,9 @@ struct sw_rx_page { #define PAGES_PER_SGE_SHIFT 0 #define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT) +#define SGE_PAGE_SIZE PAGE_SIZE +#define SGE_PAGE_SHIFT PAGE_SHIFT +#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN(addr) #define BCM_RX_ETH_PAYLOAD_ALIGN 64 diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index f0b2e73b87f..75b2624cd60 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -974,7 +974,7 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, return; pci_unmap_page(bp->pdev, pci_unmap_addr(sw_buf, mapping), - BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); __free_pages(page, PAGES_PER_SGE_SHIFT); sw_buf->page = NULL; @@ -1002,7 +1002,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, if (unlikely(page == NULL)) return -ENOMEM; - mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE, + mapping = pci_map_page(bp->pdev, page, 0, SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { __free_pages(page, PAGES_PER_SGE_SHIFT); @@ -1098,9 +1098,9 @@ 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 = BCM_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) - + u16 sge_len = SGE_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) - le16_to_cpu(fp_cqe->len_on_bd)) >> - BCM_PAGE_SHIFT; + SGE_PAGE_SHIFT; u16 last_max, last_elem, first_elem; u16 delta = 0; u16 i; @@ -1205,22 +1205,22 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 cqe_idx) { struct sw_rx_page *rx_pg, old_rx_pg; - struct page *sge; 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 = BCM_PAGE_ALIGN(frag_size) >> BCM_PAGE_SHIFT; + 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)BCM_PAGE_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 > 8*PAGES_PER_SGE) { + if (pages > + min((u32)8, (u32)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", @@ -1236,9 +1236,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* 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)(BCM_PAGE_SIZE*PAGES_PER_SGE)); + frag_len = min(frag_size, (u32)(SGE_PAGE_SIZE*PAGES_PER_SGE)); rx_pg = &fp->rx_page_ring[sge_idx]; - sge = rx_pg->page; old_rx_pg = *rx_pg; /* If we fail to allocate a substitute page, we simply stop @@ -1251,7 +1250,7 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Unmap the page as we r going to pass it to the stack */ pci_unmap_page(bp->pdev, pci_unmap_addr(&old_rx_pg, mapping), - BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); /* Add one frag and update the appropriate fields in the skb */ skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len); @@ -4544,7 +4543,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp) if (bp->flags & TPA_ENABLE_FLAG) { tstorm_client.max_sges_for_packet = - BCM_PAGE_ALIGN(tstorm_client.mtu) >> BCM_PAGE_SHIFT; + SGE_PAGE_ALIGN(tstorm_client.mtu) >> SGE_PAGE_SHIFT; tstorm_client.max_sges_for_packet = ((tstorm_client.max_sges_for_packet + PAGES_PER_SGE - 1) & (~(PAGES_PER_SGE - 1))) >> @@ -4727,10 +4726,11 @@ static void bnx2x_init_internal_func(struct bnx2x *bp) bp->e1hov); } - /* Init CQ ring mapping and aggregation size */ - max_agg_size = min((u32)(bp->rx_buf_size + - 8*BCM_PAGE_SIZE*PAGES_PER_SGE), - (u32)0xffff); + /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */ + max_agg_size = + min((u32)(min((u32)8, (u32)MAX_SKB_FRAGS) * + SGE_PAGE_SIZE * PAGES_PER_SGE), + (u32)0xffff); for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; -- cgit From ad33ea3a8d2ec324dc0f46b6ae404d824d2b349b Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:24:57 -0800 Subject: bnx2x: Missing mask when calculating flow control Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 75b2624cd60..9b1555820f5 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1899,7 +1899,8 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) static void bnx2x_calc_fc_adv(struct bnx2x *bp) { - switch (bp->link_vars.ieee_fc) { + 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); -- cgit From 3c96c68b0c67d11b8519bc38233aec586f0211f4 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:25:31 -0800 Subject: bnx2x: Flow control updated before reporting the link Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 9b1555820f5..4f1ee1f2968 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1970,10 +1970,11 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp) rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); bnx2x_release_phy_lock(bp); + bnx2x_calc_fc_adv(bp); + if (bp->link_vars.link_up) bnx2x_link_report(bp); - bnx2x_calc_fc_adv(bp); return rc; } -- cgit From a5e9a7cfad5fd301ce2b7869bbf386b70aa39e7c Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:26:01 -0800 Subject: bnx2x: Protecting the link change indication Without this lock, in some race conditions the driver missed link change indication Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 4f1ee1f2968..701bcc1260c 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -2234,9 +2234,7 @@ static void bnx2x_link_attn(struct bnx2x *bp) /* Make sure that we are synced with the current statistics */ bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_acquire_phy_lock(bp); bnx2x_link_update(&bp->link_params, &bp->link_vars); - bnx2x_release_phy_lock(bp); if (bp->link_vars.link_up) { @@ -2485,6 +2483,8 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) if (asserted & ATTN_HARD_WIRED_MASK) { if (asserted & ATTN_NIG_FOR_FUNC) { + bnx2x_acquire_phy_lock(bp); + /* save nig interrupt mask */ bp->nig_mask = REG_RD(bp, nig_int_mask_addr); REG_WR(bp, nig_int_mask_addr, 0); @@ -2540,8 +2540,10 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) REG_WR(bp, hc_addr, asserted); /* now set back the mask */ - if (asserted & ATTN_NIG_FOR_FUNC) + if (asserted & ATTN_NIG_FOR_FUNC) { REG_WR(bp, nig_int_mask_addr, bp->nig_mask); + bnx2x_release_phy_lock(bp); + } } static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) -- cgit From 0c6671b0d94f706dfc20cb22d792218ba9814412 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:26:51 -0800 Subject: bnx2x: VLAN tagged packets without VLAN offload Wrong handling of tagged packet if VLAN offload is disabled caused packets to get corrupted Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 12 +++++++----- drivers/net/bnx2x_main.c | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 2cd1e427828..e7fbca7722d 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -20,6 +20,11 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#define BCM_VLAN 1 +#endif + + /* error/debug prints */ #define DRV_MODULE_NAME "bnx2x" @@ -78,11 +83,6 @@ #endif -#ifdef NETIF_F_HW_VLAN_TX -#define BCM_VLAN 1 -#endif - - #define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) #define U64_HI(x) (u32)(((u64)(x)) >> 32) #define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) @@ -804,6 +804,8 @@ struct bnx2x { #define TPA_ENABLE_FLAG 0x80 #define NO_MCP_FLAG 0x100 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) +#define HW_VLAN_TX_FLAG 0x400 +#define HW_VLAN_RX_FLAG 0x800 int func; #define BP_PORT(bp) (bp->func % PORT_MAX) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 701bcc1260c..ca8b25126b2 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -38,9 +38,7 @@ #include #include #include -#ifdef NETIF_F_HW_VLAN_TX - #include -#endif +#include #include #include #include @@ -1283,6 +1281,13 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, 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); @@ -1307,6 +1312,12 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, 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); } @@ -1314,9 +1325,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN)) + if ((bp->vlgrp != NULL) && is_vlan_cqe && + (!is_not_hwaccel_vlan_cqe)) vlan_hwaccel_receive_skb(skb, bp->vlgrp, le16_to_cpu(cqe->fast_path_cqe. vlan_tag)); @@ -1560,7 +1570,7 @@ reuse_rx: } #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && + if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) && (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & PARSING_FLAGS_VLAN)) vlan_hwaccel_receive_skb(skb, bp->vlgrp, @@ -4538,7 +4548,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp) tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; #ifdef BCM_VLAN - if (bp->rx_mode && bp->vlgrp) { + if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) { tstorm_client.config_flags |= TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); @@ -9567,11 +9577,14 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) "sending pkt %u @%p next_idx %u bd %u @%p\n", pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd); - if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) { +#ifdef BCM_VLAN + if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && + (bp->flags & HW_VLAN_TX_FLAG)) { tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; vlan_off += 4; } else +#endif tx_bd->vlan = cpu_to_le16(pkt_prod); if (xmit_type) { @@ -10017,6 +10030,16 @@ static void bnx2x_vlan_rx_register(struct net_device *dev, 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); } @@ -10173,6 +10196,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->features |= NETIF_F_HIGHDMA; #ifdef BCM_VLAN dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); + bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); #endif dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->features |= NETIF_F_TSO6; -- cgit From 68d5948436c2f782ebb5ddf25a6588ee452e8c30 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:27:36 -0800 Subject: bnx2x: Endianness issues Adding missing le_to_cpu and disabling wrong HW endianity flag (the two complete each other) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ca8b25126b2..d2350dd300b 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1438,7 +1438,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) 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, - cqe->fast_path_cqe.rss_hash_result, + 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)); @@ -2821,8 +2821,10 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) static void bnx2x_attn_int(struct bnx2x *bp) { /* read local copy of bits */ - u32 attn_bits = bp->def_status_blk->atten_status_block.attn_bits; - u32 attn_ack = bp->def_status_blk->atten_status_block.attn_bits_ack; + 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 */ @@ -2870,7 +2872,7 @@ static void bnx2x_sp_task(struct work_struct *work) if (status & 0x2) bp->stats_pending = 0; - bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx, + 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); @@ -5161,7 +5163,6 @@ static int bnx2x_init_common(struct bnx2x *bp) 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); - REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 1); /* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */ REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1); -- cgit From a5f67a04d998b0b6e4beb1de8f1247dd93ac1ff4 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:28:13 -0800 Subject: bnx2x: Fixing the doorbell size The size of the doorbell is 4KB, this bug become visible when using more than 8 queues Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index e7fbca7722d..6fcccef4cf3 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -739,7 +739,7 @@ struct bnx2x { struct bnx2x_fastpath fp[MAX_CONTEXT]; void __iomem *regview; void __iomem *doorbells; -#define BNX2X_DB_SIZE (16*2048) +#define BNX2X_DB_SIZE (16*BCM_PAGE_SIZE) struct net_device *dev; struct pci_dev *pdev; -- cgit From f5ba6772f226be0266f95642c8162493246d3b79 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:29:18 -0800 Subject: bnx2x: Missing brackets Calculation bug due to missing brackets Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index d2350dd300b..a755fea996d 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -2920,7 +2920,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) #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; \ + s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ } while (0) /* difference = minuend - subtrahend */ -- cgit From 26c8fa4d8a08b6e7a61f23339e2236218957ecc0 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:29:55 -0800 Subject: bnx2x: Indirection table initialization index Wrong initialization of the multi-queue indirection table - it should be using the function and not the port index Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index a755fea996d..9e6aa8a1ee9 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -4524,7 +4524,7 @@ static void bnx2x_init_context(struct bnx2x *bp) static void bnx2x_init_ind_table(struct bnx2x *bp) { - int port = BP_PORT(bp); + int func = BP_FUNC(bp); int i; if (!is_multi(bp)) @@ -4533,10 +4533,8 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) DP(NETIF_MSG_IFUP, "Initializing indirection table\n"); for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) REG_WR8(bp, BAR_TSTRORM_INTMEM + - TSTORM_INDIRECTION_TABLE_OFFSET(port) + i, - i % bp->num_queues); - - REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); + TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, + BP_CL_ID(bp) + (i % bp->num_queues)); } static void bnx2x_set_client_config(struct bnx2x *bp) @@ -5240,6 +5238,7 @@ static int bnx2x_init_common(struct bnx2x *bp) } bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); + REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); /* set NIC mode */ REG_WR(bp, PRS_REG_NIC_MODE, 1); if (CHIP_IS_E1H(bp)) -- cgit From e7799c5f79072b5b34cf08170f142bcb8569cfff Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:30:27 -0800 Subject: bnx2x: MTU Filter Too big packets could pass due to wrong filter size Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 9e6aa8a1ee9..b573951600d 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -4543,7 +4543,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp) int port = BP_PORT(bp); int i; - tstorm_client.mtu = bp->dev->mtu + ETH_OVREHEAD; + tstorm_client.mtu = bp->dev->mtu; tstorm_client.statistics_counter_id = BP_CL_ID(bp); tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; -- cgit From 0ef00459a638ae4f5d1e5326d3e50232fa80119f Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:31:08 -0800 Subject: bnx2x: First slow path interrupt race The "read for interrupts" flag must be set before enabling slow-path interrupts as well (and not just before fast-path interrupts) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index b573951600d..7c533797c06 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -4812,6 +4812,15 @@ static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) 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); } @@ -6420,17 +6429,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } - bnx2x_stats_init(bp); - bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - /* Enable Rx interrupt handling before sending the ramrod - as it's completed on Rx FP queue */ - bnx2x_napi_enable(bp); - - /* Enable interrupt handling */ - atomic_set(&bp->intr_sem, 0); - rc = bnx2x_setup_leading(bp); if (rc) { BNX2X_ERR("Setup leading failed!\n"); -- cgit From b96ecfa689126d1e652ebd758da0b5b9b27dbd12 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:46:51 -0800 Subject: korina: fix usage of driver_data Using platform_set_drvdata() here makes no sense, since the driver_data field has already been filled with valuable data (i.e. the MAC address). Also having driver_data point to the net_device is rather pointless since struct korina_device contains an apropriate field for it. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 4a5580c1126..fefb33db79a 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -1089,7 +1089,6 @@ static int korina_probe(struct platform_device *pdev) return -ENOMEM; } SET_NETDEV_DEV(dev, &pdev->dev); - platform_set_drvdata(pdev, dev); lp = netdev_priv(dev); bif->dev = dev; -- cgit From a13b27826a67bfc0ca444fb42885f2069b6898e2 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:47:50 -0800 Subject: korina: reset resource buffer size to 1536 The new value is the one used in the external patch before and allows at least a standard MTU of 1500 to be handled correctly. Impact of this change gets visible when bigger packets are to be received, issuing: | ping -s 492 and bigger payload sized led to 100% packet loss. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli --- drivers/net/korina.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index fefb33db79a..e30c2f437d1 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -84,7 +84,10 @@ #define KORINA_NUM_RDS 64 /* number of receive descriptors */ #define KORINA_NUM_TDS 64 /* number of transmit descriptors */ -#define KORINA_RBSIZE 536 /* size of one resource buffer = Ether MTU */ +/* KORINA_RBSIZE is the hardware's default maximum receive + * frame size in bytes. Having this hardcoded means that there + * is no support for MTU sizes greater than 1500. */ +#define KORINA_RBSIZE 1536 /* size of one resource buffer = Ether MTU */ #define KORINA_RDS_MASK (KORINA_NUM_RDS - 1) #define KORINA_TDS_MASK (KORINA_NUM_TDS - 1) #define RD_RING_SIZE (KORINA_NUM_RDS * sizeof(struct dma_desc)) -- cgit From beb0babfb77eab0cbcc7f64a7b8f3545fec5c0ba Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:48:24 -0800 Subject: korina: disable napi on close and restart Without this the driver will crash when the NIC is being restarted. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index e30c2f437d1..65b8487c189 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -904,6 +904,8 @@ static int korina_restart(struct net_device *dev) korina_free_ring(dev); + napi_disable(&lp->napi); + ret = korina_init(dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: cannot restart device\n", @@ -1070,6 +1072,8 @@ static int korina_close(struct net_device *dev) korina_free_ring(dev); + napi_disable(&lp->napi); + free_irq(lp->rx_irq, dev); free_irq(lp->tx_irq, dev); free_irq(lp->ovr_irq, dev); -- cgit From 4cf83b664fc14f8262d3013566ca36645f891df2 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:48:59 -0800 Subject: korina: rework korina_rx() for use with napi This function needs an early exit condition to function properly, or else caller assumes napi workload wasn't enough to handle all received packets and korina_rx is called again (and again and again and ...). Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 109 +++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 56 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 65b8487c189..a1d8af7d0bc 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -353,15 +353,20 @@ static int korina_rx(struct net_device *dev, int limit) struct dma_desc *rd = &lp->rd_ring[lp->rx_next_done]; struct sk_buff *skb, *skb_new; u8 *pkt_buf; - u32 devcs, pkt_len, dmas, rx_free_desc; + u32 devcs, pkt_len, dmas; int count; dma_cache_inv((u32)rd, sizeof(*rd)); for (count = 0; count < limit; count++) { + skb = lp->rx_skb[lp->rx_next_done]; + skb_new = NULL; devcs = rd->devcs; + if ((KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) == 0) + break; + /* Update statistics counters */ if (devcs & ETH_RX_CRC) dev->stats.rx_crc_errors++; @@ -384,63 +389,55 @@ static int korina_rx(struct net_device *dev, int limit) * in Rc32434 (errata ref #077) */ dev->stats.rx_errors++; dev->stats.rx_dropped++; - } - - while ((rx_free_desc = KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) { - /* init the var. used for the later - * operations within the while loop */ - skb_new = NULL; + } else if ((devcs & ETH_RX_ROK)) { pkt_len = RCVPKT_LENGTH(devcs); - skb = lp->rx_skb[lp->rx_next_done]; - - if ((devcs & ETH_RX_ROK)) { - /* must be the (first and) last - * descriptor then */ - pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data; - - /* invalidate the cache */ - dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4); - - /* Malloc up new buffer. */ - skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2); - - if (!skb_new) - break; - /* Do not count the CRC */ - skb_put(skb, pkt_len - 4); - skb->protocol = eth_type_trans(skb, dev); - - /* Pass the packet to upper layers */ - netif_receive_skb(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; - - /* Update the mcast stats */ - if (devcs & ETH_RX_MP) - dev->stats.multicast++; - - lp->rx_skb[lp->rx_next_done] = skb_new; - } - - rd->devcs = 0; - - /* Restore descriptor's curr_addr */ - if (skb_new) - rd->ca = CPHYSADDR(skb_new->data); - else - rd->ca = CPHYSADDR(skb->data); - - rd->control = DMA_COUNT(KORINA_RBSIZE) | - DMA_DESC_COD | DMA_DESC_IOD; - lp->rd_ring[(lp->rx_next_done - 1) & - KORINA_RDS_MASK].control &= - ~DMA_DESC_COD; - - lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK; - dma_cache_wback((u32)rd, sizeof(*rd)); - rd = &lp->rd_ring[lp->rx_next_done]; - writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas); + + /* must be the (first and) last + * descriptor then */ + pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data; + + /* invalidate the cache */ + dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4); + + /* Malloc up new buffer. */ + skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2); + + if (!skb_new) + break; + /* Do not count the CRC */ + skb_put(skb, pkt_len - 4); + skb->protocol = eth_type_trans(skb, dev); + + /* Pass the packet to upper layers */ + netif_receive_skb(skb); + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; + + /* Update the mcast stats */ + if (devcs & ETH_RX_MP) + dev->stats.multicast++; + + lp->rx_skb[lp->rx_next_done] = skb_new; } + + rd->devcs = 0; + + /* Restore descriptor's curr_addr */ + if (skb_new) + rd->ca = CPHYSADDR(skb_new->data); + else + rd->ca = CPHYSADDR(skb->data); + + rd->control = DMA_COUNT(KORINA_RBSIZE) | + DMA_DESC_COD | DMA_DESC_IOD; + lp->rd_ring[(lp->rx_next_done - 1) & + KORINA_RDS_MASK].control &= + ~DMA_DESC_COD; + + lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK; + dma_cache_wback((u32)rd, sizeof(*rd)); + rd = &lp->rd_ring[lp->rx_next_done]; + writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas); } dmas = readl(&lp->rx_dma_regs->dmas); -- cgit From 4676f63d4c1e2e3530e42cb39bf88a1c1d4d78a5 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:49:39 -0800 Subject: korina: do schedule napi after testing for it The called netif_rx_schedule() does all the work for us: - it checks the return value of netif_rx_schedule_prep() and - if everything is ok calls __netif_rx_schedule(). Before this change, the driver received absolutely nothing. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index a1d8af7d0bc..7aa05f81fe9 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -330,7 +330,7 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id) dmas = readl(&lp->rx_dma_regs->dmas); if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) { - netif_rx_schedule_prep(&lp->napi); + netif_rx_schedule(&lp->napi); dmasm = readl(&lp->rx_dma_regs->dmasm); writel(dmasm | (DMA_STAT_DONE | -- cgit From 60d3f9827ca455e7272681d67a37137c328d7012 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:50:12 -0800 Subject: korina: do tx at the right position Triggering TX before the write to the DMA status mask register leads to transferring packets with maximum payload no matter what the actual packet size is. While here, also trigger RX scheduling after writing the DMA status mask register, like it was in the original driver before it was sent upstream. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 7aa05f81fe9..dced5e71463 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -330,13 +330,13 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id) dmas = readl(&lp->rx_dma_regs->dmas); if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) { - netif_rx_schedule(&lp->napi); - dmasm = readl(&lp->rx_dma_regs->dmasm); writel(dmasm | (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR), &lp->rx_dma_regs->dmasm); + netif_rx_schedule(&lp->napi); + if (dmas & DMA_STAT_ERR) printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name); @@ -623,12 +623,12 @@ korina_tx_dma_interrupt(int irq, void *dev_id) dmas = readl(&lp->tx_dma_regs->dmas); if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) { - korina_tx(dev); - dmasm = readl(&lp->tx_dma_regs->dmasm); writel(dmasm | (DMA_STAT_FINI | DMA_STAT_ERR), &lp->tx_dma_regs->dmasm); + korina_tx(dev); + if (lp->tx_chain_status == desc_filled && (readl(&(lp->tx_dma_regs->dmandptr)) == 0)) { writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), -- cgit From 97bc477cbc3d63f2a29c2c81031434b3a082f44c Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:50:41 -0800 Subject: korina: fix handling tx_chain_tail Originally this must have been a rewrite error when introducing 'chain_index'. But the original driver did not use the previous chain item everywhere: when altering the address tx_chain_tail points to, it should move forward, not backwards. Also this is not an "index" but rather the penultimate element in the chain, so rename it accordingly. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index dced5e71463..f2001750251 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -199,7 +199,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) struct korina_private *lp = netdev_priv(dev); unsigned long flags; u32 length; - u32 chain_index; + u32 chain_prev, chain_next; struct dma_desc *td; spin_lock_irqsave(&lp->lock, flags); @@ -231,8 +231,8 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) /* Setup the transmit descriptor. */ dma_cache_inv((u32) td, sizeof(*td)); td->ca = CPHYSADDR(skb->data); - chain_index = (lp->tx_chain_tail - 1) & - KORINA_TDS_MASK; + chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK; + chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK; if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) { if (lp->tx_chain_status == desc_empty) { @@ -240,7 +240,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; /* Move tail */ - lp->tx_chain_tail = chain_index; + lp->tx_chain_tail = chain_next; /* Write to NDPTR */ writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &lp->tx_dma_regs->dmandptr); @@ -251,12 +251,12 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; /* Link to prev */ - lp->td_ring[chain_index].control &= + lp->td_ring[chain_prev].control &= ~DMA_DESC_COF; /* Link to prev */ - lp->td_ring[chain_index].link = CPHYSADDR(td); + lp->td_ring[chain_prev].link = CPHYSADDR(td); /* Move tail */ - lp->tx_chain_tail = chain_index; + lp->tx_chain_tail = chain_next; /* Write to NDPTR */ writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); @@ -270,17 +270,17 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; /* Move tail */ - lp->tx_chain_tail = chain_index; + lp->tx_chain_tail = chain_next; lp->tx_chain_status = desc_filled; netif_stop_queue(dev); } else { /* Update tail */ td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; - lp->td_ring[chain_index].control &= + lp->td_ring[chain_prev].control &= ~DMA_DESC_COF; - lp->td_ring[chain_index].link = CPHYSADDR(td); - lp->tx_chain_tail = chain_index; + lp->td_ring[chain_prev].link = CPHYSADDR(td); + lp->tx_chain_tail = chain_next; } } dma_cache_wback((u32) td, sizeof(*td)); -- cgit From 5edc7668bbece4238a32943ae7a47135af076948 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:51:15 -0800 Subject: korina: do not stop queue here Apparently this doesn't make sense. Otherwise the queue gets disabled as soon as it's getting empty and can only be resurrected by a driver restart. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index f2001750251..bd33fa91599 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -272,7 +272,6 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) /* Move tail */ lp->tx_chain_tail = chain_next; lp->tx_chain_status = desc_filled; - netif_stop_queue(dev); } else { /* Update tail */ td->control = DMA_COUNT(length) | -- cgit From 1c5625cf0f121486abad4da0e0251ec67765aa95 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:51:48 -0800 Subject: korina: do not use IRQF_SHARED with IRQF_DISABLED As the kernel warning states: "IRQF_DISABLED is not guaranteed on shared IRQs". Since these IRQs' values are hardcoded and my test system doesn't show any shared use of IRQs at all, rather make them non-shared than non-disabled. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index bd33fa91599..1d6e48e1336 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -1000,14 +1000,14 @@ static int korina_open(struct net_device *dev) * that handles the Done Finished * Ovr and Und Events */ ret = request_irq(lp->rx_irq, &korina_rx_dma_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Korina ethernet Rx", dev); + IRQF_DISABLED, "Korina ethernet Rx", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: unable to get Rx DMA IRQ %d\n", dev->name, lp->rx_irq); goto err_release; } ret = request_irq(lp->tx_irq, &korina_tx_dma_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Korina ethernet Tx", dev); + IRQF_DISABLED, "Korina ethernet Tx", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: unable to get Tx DMA IRQ %d\n", dev->name, lp->tx_irq); @@ -1016,7 +1016,7 @@ static int korina_open(struct net_device *dev) /* Install handler for overrun error. */ ret = request_irq(lp->ovr_irq, &korina_ovr_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Ethernet Overflow", dev); + IRQF_DISABLED, "Ethernet Overflow", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME"%s: unable to get OVR IRQ %d\n", dev->name, lp->ovr_irq); @@ -1025,7 +1025,7 @@ static int korina_open(struct net_device *dev) /* Install handler for underflow error. */ ret = request_irq(lp->und_irq, &korina_und_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Ethernet Underflow", dev); + IRQF_DISABLED, "Ethernet Underflow", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: unable to get UND IRQ %d\n", dev->name, lp->und_irq); -- cgit From fe41cbb164a0dc55f3914a0e4cabe8240410157c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 15 Jan 2009 13:31:15 +0000 Subject: tty: Fix a kref leak in the HSO driver on re-open Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index c4918b86ed1..9df04dd1332 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1297,6 +1297,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) /* setup */ spin_lock_irq(&serial->serial_lock); tty->driver_data = serial; + tty_kref_put(serial->tty); serial->tty = tty_kref_get(tty); spin_unlock_irq(&serial->serial_lock); -- cgit From d45eb81c3e345fabaf27ef3ab437b85c0bf9fafa Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Thu, 15 Jan 2009 13:31:24 +0000 Subject: tty: Fix double grabbing of a spinlock The HSO changes for kref introduced a recursive spinlock take. All functions which call put_rxbuf_data already have serial->serial_lock grabbed. [Comment to code added-AC] Signed-off-by: Denis Joseph Barrow Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 9df04dd1332..e25a58f6ff6 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2044,9 +2044,8 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) return -2; } - spin_lock(&serial->serial_lock); + /* All callers to put_rxbuf_data hold serial_lock */ tty = tty_kref_get(serial->tty); - spin_unlock(&serial->serial_lock); /* Push data to tty */ if (tty) { -- cgit From 5839b414f9f9d2d6a471988763b61dbf85eb2dba Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Thu, 15 Jan 2009 13:31:34 +0000 Subject: hso serial throttled tty kref fix. This patch is for Alan Cox as it related to the tty layer. Hopefully the hso driver is again relatively stable with this fix. Signed-off-by: Denis Joseph Barrow Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index e25a58f6ff6..6478bf63f28 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2053,8 +2053,10 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) serial->curr_rx_urb_offset; D1("data to push to tty"); while (write_length_remaining) { - if (test_bit(TTY_THROTTLED, &tty->flags)) + if (test_bit(TTY_THROTTLED, &tty->flags)) { + tty_kref_put(tty); return -1; + } curr_write_len = tty_insert_flip_string (tty, urb->transfer_buffer + serial->curr_rx_urb_offset, -- cgit From a58c891a53aca81c78f9cbe0572a301042470e96 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 15 Jan 2009 15:29:35 -0800 Subject: b44: GFP_DMA skb should not escape from driver b44 chip has some hardware limitations, that need GFP_DMA bounce buffers in some situations. In order to not deplete DMA zone, we should keep allocated GFP_DMA skb only for driver use. At rx time, we copy such skb to newly allocated skb, reusing existing copybreak infrastructure. On machines with low amount of memory, all skb meet the hardware limitation, so no copy is needed. We detect this situation using a new device flag, set to one if one GFP_DMA skb was ever allocated by b44_alloc_rx_skb(). Previously allocated skb, even outside from DMA zone will then be recycled, to have minimal impact on DMA zone use. Signed-off-by: Eric Dumazet Tested-by: Ionut Leonte Signed-off-by: David S. Miller --- drivers/net/b44.c | 4 +++- drivers/net/b44.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 5ae131c147f..c38512ebcea 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -679,6 +679,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) dev_kfree_skb_any(skb); return -ENOMEM; } + bp->force_copybreak = 1; } rh = (struct rx_header *) skb->data; @@ -800,7 +801,7 @@ static int b44_rx(struct b44 *bp, int budget) /* Omit CRC. */ len -= 4; - if (len > RX_COPY_THRESHOLD) { + if (!bp->force_copybreak && len > RX_COPY_THRESHOLD) { int skb_size; skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); if (skb_size < 0) @@ -2152,6 +2153,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev, bp = netdev_priv(dev); bp->sdev = sdev; bp->dev = dev; + bp->force_copybreak = 0; bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE); diff --git a/drivers/net/b44.h b/drivers/net/b44.h index 7db0c84a795..e678498de6d 100644 --- a/drivers/net/b44.h +++ b/drivers/net/b44.h @@ -395,7 +395,7 @@ struct b44 { u32 rx_pending; u32 tx_pending; u8 phy_addr; - + u8 force_copybreak; struct mii_if_info mii_if; }; -- cgit From d3b924d960a808105180d229b4667061123cc4ef Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 15 Jan 2009 20:43:56 -0800 Subject: mlx4_core: Fix min() warning Fix drivers/net/mlx4/profile.c: In function `mlx4_make_profile': drivers/net/mlx4/profile.c:110: warning: comparison of distinct pointer types lacks a cast This happened because num_possible_cpus() was secretly changed by commit ae7a47e7 ("cpumask: make cpumask.h eat its own dogfood.") from returning "int" to (now) returning "unsigned int". I think that was a good change, so we should just swallow the fallout. Cc: "David S. Miller" Cc: Roland Dreier Cc: Yevgeny Petrilin Cc: Jack Morgenstein Cc: Vladimir Sokolovsky Cc: Michael S. Tsirkin Signed-off-by: Andrew Morton Signed-off-by: Roland Dreier --- drivers/net/mlx4/profile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c index 919fb9eb1b6..cebdf3243ca 100644 --- a/drivers/net/mlx4/profile.c +++ b/drivers/net/mlx4/profile.c @@ -107,9 +107,9 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, profile[MLX4_RES_AUXC].num = request->num_qp; profile[MLX4_RES_SRQ].num = request->num_srq; profile[MLX4_RES_CQ].num = request->num_cq; - profile[MLX4_RES_EQ].num = min(dev_cap->max_eqs, - dev_cap->reserved_eqs + - num_possible_cpus() + 1); + profile[MLX4_RES_EQ].num = min_t(unsigned, dev_cap->max_eqs, + dev_cap->reserved_eqs + + num_possible_cpus() + 1); profile[MLX4_RES_DMPT].num = request->num_mpt; profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS; profile[MLX4_RES_MTT].num = request->num_mtt; -- cgit From 3bfafd6b136bea2de9bd96c01b7e3808635a15b2 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 16 Jan 2009 11:03:01 -0800 Subject: netxen: avoid invalid iounmap For NX3031 only one I/O range is mapped, so unmapping other two which are used by older chips, causes this warning on ppc64. "Attempt to iounmap early bolted mapping at 0x0000000000000000" Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 86867405a36..f8e26290a22 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1004,8 +1004,10 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) iounmap(adapter->ahw.db_base); iounmap(adapter->ahw.pci_base0); - iounmap(adapter->ahw.pci_base1); - iounmap(adapter->ahw.pci_base2); + if (adapter->ahw.pci_base1 != NULL) + iounmap(adapter->ahw.pci_base1); + if (adapter->ahw.pci_base2 != NULL) + iounmap(adapter->ahw.pci_base2); pci_release_regions(pdev); pci_disable_device(pdev); -- cgit From 009777846165fcc49352c0f1487e3a96102884c3 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 16 Jan 2009 11:03:25 -0800 Subject: netxen: include ipv6.h (fixes build failure) Fixes a build error in absence of CONFIG_IPV6: drivers/net/netxen/netxen_nic_main.c:1189: error: implicit declaration of function 'ipv6_hdr' drivers/net/netxen/netxen_nic_main.c:1189: error: invalid type argument of '->' Reported-by: Ingo Molnar Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index f8e26290a22..d854f07ef4d 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -41,6 +41,7 @@ #include #include #include +#include MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); MODULE_LICENSE("GPL"); -- cgit From ef15aa490f2e447ce04fe643500b814ef40f6ea9 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 9 Jan 2009 21:06:30 +0100 Subject: p54: fix oops caused by bad eeproms This patch fixes a bug that could occur, if it the eeprom is incomplete or partly corrupted. BUG: unable to handle kernel NULL pointer dereference at 00000008 IP: p54_assign_address+0x108/0x15d [p54common] Oops: 0002 [#1] SMP Pid: 12988, comm: phy1 Tainted: P W 2.6.28-rc6-wl #3 RIP: 0010: p54_assign_address+0x108/0x15d [p54common] [...] Call Trace: p54_alloc_skb+0xa3/0xc0 [p54common] p54_scan+0x37/0x204 [p54common] [...] Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index c6a370fa9bc..3b44e8e7603 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1610,7 +1610,7 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell) err: printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy)); - kfree_skb(skb); + p54_free_skb(dev, skb); return -EINVAL; } -- cgit From d71038c05970ad0c9d7da6f797803f69e4f91837 Mon Sep 17 00:00:00 2001 From: Andrey Yurovsky Date: Mon, 12 Jan 2009 13:14:27 -0800 Subject: libertas: Fix alignment issues in libertas core Data structures that come over the wire from the WLAN firmware must be packed. This fixes alignment problems on the blackfin architecture and, reportedly, on the AVR32. This is a replacement for the previous version of this patch which had also explicitly used get_unaligned_ macros. As Johannes Berg pointed out, these macros were unnecessary. Signed-off-by: Andrey Yurovsky Signed-off-by: Colin McCabe Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/hostcmd.h | 91 ++++++++++++++++----------------- 1 file changed, 45 insertions(+), 46 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index e173b1b46c2..f6a79a653b7 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -32,7 +32,7 @@ struct txpd { u8 pktdelay_2ms; /* reserved */ u8 reserved1; -}; +} __attribute__ ((packed)); /* RxPD Descriptor */ struct rxpd { @@ -63,7 +63,7 @@ struct rxpd { /* Pkt Priority */ u8 priority; u8 reserved[3]; -}; +} __attribute__ ((packed)); struct cmd_header { __le16 command; @@ -97,7 +97,7 @@ struct enc_key { struct lbs_offset_value { u32 offset; u32 value; -}; +} __attribute__ ((packed)); /* Define general data structure */ /* cmd_DS_GEN */ @@ -107,7 +107,7 @@ struct cmd_ds_gen { __le16 seqnum; __le16 result; void *cmdresp[0]; -}; +} __attribute__ ((packed)); #define S_DS_GEN sizeof(struct cmd_ds_gen) @@ -163,7 +163,7 @@ struct cmd_ds_802_11_subscribe_event { * bump this up a bit. */ uint8_t tlv[128]; -}; +} __attribute__ ((packed)); /* * This scan handle Country Information IE(802.11d compliant) @@ -180,7 +180,7 @@ struct cmd_ds_802_11_scan { mrvlietypes_chanlistparamset_t ChanListParamSet; mrvlietypes_ratesparamset_t OpRateSet; #endif -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_scan_rsp { struct cmd_header hdr; @@ -188,7 +188,7 @@ struct cmd_ds_802_11_scan_rsp { __le16 bssdescriptsize; uint8_t nr_sets; uint8_t bssdesc_and_tlvbuffer[0]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_get_log { struct cmd_header hdr; @@ -206,33 +206,33 @@ struct cmd_ds_802_11_get_log { __le32 fcserror; __le32 txframe; __le32 wepundecryptable; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_control { struct cmd_header hdr; __le16 action; u16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_multicast_adr { struct cmd_header hdr; __le16 action; __le16 nr_of_adrs; u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_authenticate { u8 macaddr[ETH_ALEN]; u8 authtype; u8 reserved[10]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_deauthenticate { struct cmd_header hdr; u8 macaddr[ETH_ALEN]; __le16 reasoncode; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_associate { u8 peerstaaddr[6]; @@ -251,7 +251,7 @@ struct cmd_ds_802_11_associate { struct cmd_ds_802_11_associate_rsp { struct ieeetypes_assocrsp assocRsp; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_set_wep { struct cmd_header hdr; @@ -265,7 +265,7 @@ struct cmd_ds_802_11_set_wep { /* 40, 128bit or TXWEP */ uint8_t keytype[4]; uint8_t keymaterial[4][16]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_3_get_stat { __le32 xmitok; @@ -274,7 +274,7 @@ struct cmd_ds_802_3_get_stat { __le32 rcverror; __le32 rcvnobuffer; __le32 rcvcrcerror; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_get_stat { __le32 txfragmentcnt; @@ -294,7 +294,7 @@ struct cmd_ds_802_11_get_stat { __le32 txbeacon; __le32 rxbeacon; __le32 wepundecryptable; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_snmp_mib { struct cmd_header hdr; @@ -303,58 +303,58 @@ struct cmd_ds_802_11_snmp_mib { __le16 oid; __le16 bufsize; u8 value[128]; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_reg_map { __le16 buffersize; u8 regmap[128]; __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_bbp_reg_map { __le16 buffersize; u8 regmap[128]; __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_rf_reg_map { __le16 buffersize; u8 regmap[64]; __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_reg_access { __le16 action; __le16 offset; __le32 value; -}; +} __attribute__ ((packed)); struct cmd_ds_bbp_reg_access { __le16 action; __le16 offset; u8 value; u8 reserved[3]; -}; +} __attribute__ ((packed)); struct cmd_ds_rf_reg_access { __le16 action; __le16 offset; u8 value; u8 reserved[3]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_radio_control { struct cmd_header hdr; __le16 action; __le16 control; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_beacon_control { __le16 action; __le16 beacon_enable; __le16 beacon_period; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_sleep_params { struct cmd_header hdr; @@ -379,7 +379,7 @@ struct cmd_ds_802_11_sleep_params { /* reserved field, should be set to zero */ __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_inactivity_timeout { struct cmd_header hdr; @@ -389,7 +389,7 @@ struct cmd_ds_802_11_inactivity_timeout { /* Inactivity timeout in msec */ __le16 timeout; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rf_channel { struct cmd_header hdr; @@ -399,7 +399,7 @@ struct cmd_ds_802_11_rf_channel { __le16 rftype; /* unused */ __le16 reserved; /* unused */ u8 channellist[32]; /* unused */ -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rssi { /* weighting factor */ @@ -408,21 +408,21 @@ struct cmd_ds_802_11_rssi { __le16 reserved_0; __le16 reserved_1; __le16 reserved_2; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rssi_rsp { __le16 SNR; __le16 noisefloor; __le16 avgSNR; __le16 avgnoisefloor; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_mac_address { struct cmd_header hdr; __le16 action; u8 macadd[ETH_ALEN]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rf_tx_power { struct cmd_header hdr; @@ -431,7 +431,7 @@ struct cmd_ds_802_11_rf_tx_power { __le16 curlevel; s8 maxlevel; s8 minlevel; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rf_antenna { __le16 action; @@ -439,33 +439,33 @@ struct cmd_ds_802_11_rf_antenna { /* Number of antennas or 0xffff(diversity) */ __le16 antennamode; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_monitor_mode { __le16 action; __le16 mode; -}; +} __attribute__ ((packed)); struct cmd_ds_set_boot2_ver { struct cmd_header hdr; __le16 action; __le16 version; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_fw_wake_method { struct cmd_header hdr; __le16 action; __le16 method; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_sleep_period { struct cmd_header hdr; __le16 action; __le16 period; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_ps_mode { __le16 action; @@ -473,7 +473,7 @@ struct cmd_ds_802_11_ps_mode { __le16 multipledtim; __le16 reserved; __le16 locallisteninterval; -}; +} __attribute__ ((packed)); struct cmd_confirm_sleep { struct cmd_header hdr; @@ -483,7 +483,7 @@ struct cmd_confirm_sleep { __le16 multipledtim; __le16 reserved; __le16 locallisteninterval; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_data_rate { struct cmd_header hdr; @@ -491,14 +491,14 @@ struct cmd_ds_802_11_data_rate { __le16 action; __le16 reserved; u8 rates[MAX_RATES]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rate_adapt_rateset { struct cmd_header hdr; __le16 action; __le16 enablehwauto; __le16 bitmap; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_ad_hoc_start { struct cmd_header hdr; @@ -520,7 +520,7 @@ struct cmd_ds_802_11_ad_hoc_result { u8 pad[3]; u8 bssid[ETH_ALEN]; -}; +} __attribute__ ((packed)); struct adhoc_bssdesc { u8 bssid[ETH_ALEN]; @@ -578,7 +578,7 @@ struct MrvlIEtype_keyParamSet { /* key material of size keylen */ u8 key[32]; -}; +} __attribute__ ((packed)); #define MAX_WOL_RULES 16 @@ -590,7 +590,7 @@ struct host_wol_rule { __le16 reserve; __be32 sig_mask; __be32 signature; -}; +} __attribute__ ((packed)); struct wol_config { uint8_t action; @@ -598,8 +598,7 @@ struct wol_config { uint8_t no_rules_in_cmd; uint8_t result; struct host_wol_rule rule[MAX_WOL_RULES]; -}; - +} __attribute__ ((packed)); struct cmd_ds_host_sleep { struct cmd_header hdr; -- cgit From b657eade2f98b5c689e405bd6e4e445471066380 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 13 Jan 2009 14:33:49 +0200 Subject: ath9k: Fix an operator typo in phy rate validation This was not supposed to be a bitwise AND operation, but a check of two separate conditions. Anyway, the old code happened to result in the same behavior, so this is just changing the code to be easier to understand and also to keep sparse from warning about dubious operators. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 04ab457a8fa..1b71b934bb5 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -490,7 +490,7 @@ static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw) { - if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG)) + if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) return 0; if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) return 0; -- cgit From 9d97f2e55e3df44e3b6b4cc58b091501ba7ee0ac Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 13 Jan 2009 14:35:08 +0200 Subject: ath9k: Fix an operator typo in REG_DOMAIN_2GHZ_MASK Incorrect operator causes the REG_DOMAIN_2GHZ_MASK to be zero which surely was not the goal of this definition. Mask out the 11a flags correctly. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h index 9112c030b1e..6df1b3b77c2 100644 --- a/drivers/net/wireless/ath9k/regd_common.h +++ b/drivers/net/wireless/ath9k/regd_common.h @@ -228,7 +228,7 @@ enum { }; #define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \ - (!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB))) + (~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB))) #define REG_DOMAIN_5GHZ_MASK REQ_MASK static struct reg_dmn_pair_mapping regDomainPairs[] = { -- cgit From 73e1a65d3c4a013f6fa56e47133be95143a75fe3 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 8 Jan 2009 10:19:58 -0800 Subject: iwlwifi: remove CMD_WANT_SKB flag if send_cmd_sync failure In function iwl_send_cmd_sync(), if the flag CMD_WANT_SKB is set but we are not provided with a valid SKB (cmd->meta.u.skb == NULL), we need to remove the CMD_WANT_SKB flag from the TX cmd queue. Otherwise in case the cmd comes in later, it will possibly set an invalid address. Thus it causes an invalid memory access. This fixed the bug http://bugzilla.kernel.org/show_bug.cgi?id=11326. Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 8c71ad4f88c..4b35b30e493 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -224,7 +224,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) IWL_ERROR("Error: Response NULL in '%s'\n", get_cmd_string(cmd->id)); ret = -EIO; - goto out; + goto cancel; } ret = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index d64580805d6..15f5655c636 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -745,7 +745,7 @@ static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_ IWL_ERROR("Error: Response NULL in '%s'\n", get_cmd_string(cmd->id)); ret = -EIO; - goto out; + goto cancel; } ret = 0; -- cgit From e223b6dc051ad030a70d5c6ed6226b95bdfc3af7 Mon Sep 17 00:00:00 2001 From: Rami Rosen Date: Wed, 14 Jan 2009 00:00:13 +0200 Subject: rt2x00: fix a wrong parameter for __test_and_clear_bit() in rt2x00rfkill_free(). When running modprobe rt73usb, and then rmmod rt73usb, and then iwconfig, the wlan0 device does not disappear. When repeating this process again, we get a kernel Oops errors and "BUG: unable to handle kernel paging request..." message in the kernel log. The reason for this is that there is an error in rt2x00rfkill_free(), which is called in the process of removing the device (rt2x00lib_remove_dev() in rt2x00dev.c). rt2x00rfkill_free() clears the RFKILL_STATE_ALLOCATED bit , which is bit number 1 () in rt2x00dev->flags instead of in rt2x00dev->rfkill_state. As a result, when checking the DEVICE_STATE_REGISTERED_HW bit (bit number 1 in rt2x00dev->flags) in rt2x00lib_remove_hw() it is **unset**, and we wrongly **don't** call ieee80211_unregister_hw(). This patch corrects this: the parameter for __test_and_clear_bit() in rt2x00rfkill_free() should be &rt2x00dev->rfkill_state and not &rt2x00dev->flags. Signed-off-by: Rami Rosen Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00rfkill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index c3f53a92180..3298cae1e12 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c @@ -162,7 +162,7 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) { - if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->flags)) + if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) return; cancel_delayed_work_sync(&rt2x00dev->rfkill_work); -- cgit From 275719089bfe7dbf446b72c3e520966e7fa42b6a Mon Sep 17 00:00:00 2001 From: Artur Skawina Date: Thu, 15 Jan 2009 21:07:03 +0100 Subject: p54: set_tim must be atomic. Fix for: BUG: scheduling while atomic: named/2004/0x10000200 Pid: 2004, comm: named Not tainted 2.6.29-rc1-00271-ge9fa6b0 #45 Call Trace: [] schedule+0x2a7/0x320 [] __alloc_skb+0x34/0x110 [] __cond_resched+0x13/0x30 [] _cond_resched+0x2d/0x40 [] kmem_cache_alloc+0x95/0xc0 [] check_object+0xc4/0x230 [] __alloc_skb+0x34/0x110 [] p54_alloc_skb+0x71/0xf0 [] p54_set_tim+0x3f/0xa0 [] sta_info_set_tim_bit+0x64/0x80 [] invoke_tx_handlers+0xd57/0xd80 [] free_debug_processing+0x197/0x210 [] pskb_expand_head+0xf5/0x170 [] __ieee80211_tx_prepare+0x164/0x2f0 [] ieee80211_skb_resize+0x6d/0xe0 [] ieee80211_master_start_xmit+0x23f/0x550 [] __slab_alloc+0x2b8/0x4f0 [] getnstimeofday+0x51/0x120 [] dev_hard_start_xmit+0x1db/0x240 [] __qdisc_run+0x1ab/0x200 [] __run_hrtimer+0x31/0xf0 [] dev_queue_xmit+0x247/0x500 [] ieee80211_subif_start_xmit+0x356/0x7d0 [] packet_rcv_spkt+0x37/0x150 [] packet_rcv_spkt+0x37/0x150 [] dev_hard_start_xmit+0x1db/0x240 [] __qdisc_run+0x1ab/0x200 [] dev_queue_xmit+0x247/0x500 [] neigh_resolve_output+0xe2/0x200 [] ip_finish_output+0x0/0x290 [] ip_finish_output+0x1e7/0x290 [] ip_local_out+0x15/0x20 [] ip_push_pending_frames+0x272/0x380 [] udp_push_pending_frames+0x146/0x3a0 [] udp_sendmsg+0x2fa/0x6b0 [] inet_sendmsg+0x37/0x70 [] sock_sendmsg+0xbe/0x100 [] autoremove_wake_function+0x0/0x50 [] __wake_up_common+0x43/0x70 [] copy_from_user+0x32/0x130 [] copy_from_user+0x32/0x130 [] verify_iovec+0x2e/0xb0 [] sys_sendmsg+0x17f/0x290 [] pipe_write+0x29a/0x570 [] update_wall_time+0x492/0x8e0 [] getnstimeofday+0x51/0x120 [] sched_slice+0x3d/0x80 [] getnstimeofday+0x51/0x120 [] hrtimer_forward+0x147/0x1a0 [] lapic_next_event+0x10/0x20 [] clockevents_program_event+0xa3/0x170 [] sys_socketcall+0xa4/0x290 [] smp_apic_timer_interrupt+0x40/0x70 [] sysenter_do_call+0x12/0x25 Signed-off-by: Artur Skawina Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 3b44e8e7603..ae31e3775e0 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1147,7 +1147,7 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta, skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(struct p54_hdr) + sizeof(*tim), - P54_CONTROL_TYPE_TIM, GFP_KERNEL); + P54_CONTROL_TYPE_TIM, GFP_ATOMIC); if (!skb) return -ENOMEM; -- cgit From 674743033c1ae9f7cc94e1e0037f6f719e6d1d67 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 16 Jan 2009 19:46:28 +0100 Subject: p54: fix p54_set_key's return code p54 doesn't support AES-128-CMAC offload. This patch will fix the noisy mac80211 warnings, when 802.11w is enabled: mac80211-phy189: failed to set key (4, ff:ff:ff:ff:ff:ff) to hardware (-22) mac80211-phy189: failed to set key (5, ff:ff:ff:ff:ff:ff) to hardware (-22) Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index ae31e3775e0..12d0717c399 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -2077,7 +2077,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, algo = P54_CRYPTO_AESCCMP; break; default: - return -EINVAL; + return -EOPNOTSUPP; } } -- cgit From 70b9986ca4baaf6deb6f0e01d50f72457579adea Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:48 +0000 Subject: bnx2x: Free IRQ Error check could result with not freeing the IRQ Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 7c533797c06..ce98ecf8cb1 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6684,6 +6684,9 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); bnx2x_stats_handle(bp, STATS_EVENT_STOP); + /* Release IRQs */ + bnx2x_free_irq(bp); + /* Wait until tx fast path tasks complete */ for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; @@ -6711,9 +6714,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Give HW time to discard old tx messages */ msleep(1); - /* Release IRQs */ - bnx2x_free_irq(bp); - if (CHIP_IS_E1(bp)) { struct mac_configuration_cmd *config = bnx2x_sp(bp, mcast_config); -- cgit From 693fc0d14334859430733ab902adac182fdd8153 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:52 +0000 Subject: bnx2x: Handling probe failures Failures in the probe not handled correctly - separate the flow to handle different failures Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ce98ecf8cb1..911067586a4 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -10269,17 +10269,15 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return rc; } - rc = register_netdev(dev); - if (rc) { - dev_err(&pdev->dev, "Cannot register net device\n"); - goto init_one_exit; - } - pci_set_drvdata(pdev, dev); rc = bnx2x_init_bp(bp); + if (rc) + goto init_one_exit; + + rc = register_netdev(dev); if (rc) { - unregister_netdev(dev); + dev_err(&pdev->dev, "Cannot register net device\n"); goto init_one_exit; } -- cgit From b4661739c67acd15a02f8e112f8cc52d24b609ed Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:56 +0000 Subject: bnx2x: Potential race after iSCSI boot The lock was release too soon. Make sure the HW is marked as locked until the boot driver was unloaded from FW perspective Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 911067586a4..70fc61033dd 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6874,10 +6874,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) */ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); - if (val == 0x7) - REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - if (val == 0x7) { u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; /* save our func */ @@ -6885,6 +6881,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) u32 swap_en; u32 swap_val; + /* clear the UNDI indication */ + REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); + BNX2X_DEV_INFO("UNDI is active! reset device\n"); /* try unload UNDI on port 0 */ @@ -6910,6 +6909,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bnx2x_fw_command(bp, reset_code); } + /* now it's safe to release the lock */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); + REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0), 0x1000); @@ -6954,7 +6956,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bp->fw_seq = (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - } + + } else + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); } } -- cgit From af2464011f0954785687071b298f066f6cbb1c84 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:59 +0000 Subject: bnx2x: Wrong HDR offset in CAM Has a negative side effect when sending MAC update with no content (as done in the self-test) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 70fc61033dd..8f8271d76db 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6144,7 +6144,7 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set) * multicast 64-127:port0 128-191:port1 */ config->hdr.length_6b = 2; - config->hdr.offset = port ? 31 : 0; + config->hdr.offset = port ? 32 : 0; config->hdr.client_id = BP_CL_ID(bp); config->hdr.reserved1 = 0; @@ -8910,7 +8910,10 @@ static int bnx2x_test_intr(struct bnx2x *bp) return -ENODEV; config->hdr.length_6b = 0; - config->hdr.offset = 0; + if (CHIP_IS_E1(bp)) + config->hdr.offset = (BP_PORT(bp) ? 32 : 0); + else + config->hdr.offset = BP_FUNC(bp); config->hdr.client_id = BP_CL_ID(bp); config->hdr.reserved1 = 0; @@ -9863,7 +9866,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev) for (; i < old; i++) { if (CAM_IS_INVALID(config-> config_table[i])) { - i--; /* already invalidated */ + /* already invalidated */ break; } /* invalidate */ -- cgit From 5a40e08e666e8caa1227333de41fd1e2cd84d4f5 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:04 +0000 Subject: bnx2x: Read chip ID Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 8f8271d76db..7ee6a211f9b 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6975,7 +6975,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) id |= ((val & 0xf) << 12); val = REG_RD(bp, MISC_REG_CHIP_METAL); id |= ((val & 0xff) << 4); - REG_RD(bp, MISC_REG_BOND_ID); + 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; -- cgit From 2add3acb11a26cc14b54669433ae6ace6406cbf2 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:07 +0000 Subject: bnx2x: Block nvram access when the device is inactive Don't dump eeprom when bnx2x adapter is down. Running ethtool -e causes an eeh without it when the device is down Signed-off-by: Paul Larson Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 7ee6a211f9b..ca5090c3341 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -8107,6 +8107,9 @@ static int bnx2x_get_eeprom(struct net_device *dev, 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, -- cgit From 632da4d66324b5baf947a048dd1f1e9093b6dd90 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:10 +0000 Subject: bnx2x: Overstepping array bounds If the page size is > 8KB this violation happens Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ca5090c3341..2e00da6ab17 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -9427,6 +9427,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) return rc; } +#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) /* check if packet requires linearization (packet is too fragmented) */ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, u32 xmit_type) @@ -9504,6 +9505,7 @@ exit_lbl: return to_copy; } +#endif /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call @@ -9544,6 +9546,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); +#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) /* First, check if we need to linearize the skb (due to FW restrictions) */ if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) { @@ -9556,6 +9559,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } } +#endif /* Please read carefully. First we use one BD which we mark as start, -- cgit From 6c55c3cdc86881383075a933594748b30dd0054b Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:13 +0000 Subject: bnx2x: 1G-10G toggling race The HW should be configured so fast toggling between 1G and 10G will not be missed. Make sure that the HW is re-configured in full Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index fefa6ab1306..d9e1cfcd06d 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params, val &= ~0x810; EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); + /* enable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1); + /* enable emac for jumbo packets */ EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, (EMAC_RX_MTU_SIZE_JUMBO_ENA | @@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, u32 gp_status) { struct bnx2x *bp = params->bp; - + u16 new_line_speed; u8 rc = 0; vars->link_status = 0; @@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, switch (gp_status & GP_STATUS_SPEED_MASK) { case GP_STATUS_10M: - vars->line_speed = SPEED_10; + new_line_speed = SPEED_10; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_10TFD; else @@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, break; case GP_STATUS_100M: - vars->line_speed = SPEED_100; + new_line_speed = SPEED_100; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_100TXFD; else @@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, case GP_STATUS_1G: case GP_STATUS_1G_KX: - vars->line_speed = SPEED_1000; + new_line_speed = SPEED_1000; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_1000TFD; else @@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, break; case GP_STATUS_2_5G: - vars->line_speed = SPEED_2500; + new_line_speed = SPEED_2500; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_2500TFD; else @@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params, case GP_STATUS_10G_KX4: case GP_STATUS_10G_HIG: case GP_STATUS_10G_CX4: - vars->line_speed = SPEED_10000; + new_line_speed = SPEED_10000; vars->link_status |= LINK_10GTFD; break; case GP_STATUS_12G_HIG: - vars->line_speed = SPEED_12000; + new_line_speed = SPEED_12000; vars->link_status |= LINK_12GTFD; break; case GP_STATUS_12_5G: - vars->line_speed = SPEED_12500; + new_line_speed = SPEED_12500; vars->link_status |= LINK_12_5GTFD; break; case GP_STATUS_13G: - vars->line_speed = SPEED_13000; + new_line_speed = SPEED_13000; vars->link_status |= LINK_13GTFD; break; case GP_STATUS_15G: - vars->line_speed = SPEED_15000; + new_line_speed = SPEED_15000; vars->link_status |= LINK_15GTFD; break; case GP_STATUS_16G: - vars->line_speed = SPEED_16000; + new_line_speed = SPEED_16000; vars->link_status |= LINK_16GTFD; break; @@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params, break; } + /* Upon link speed change set the NIG into drain mode. + Comes to deals with possible FIFO glitch due to clk change + when speed is decreased without link down indicator */ + if (new_line_speed != vars->line_speed) { + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); + msleep(1); + } + vars->line_speed = new_line_speed; vars->link_status |= LINK_STATUS_SERDES_LINK; if ((params->req_line_speed == SPEED_AUTO_NEG) && @@ -4194,6 +4206,11 @@ static u8 bnx2x_update_link_down(struct link_params *params, /* activate nig drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + + msleep(10); + /* reset BigMac */ bnx2x_bmac_rx_disable(bp, params->port); REG_WR(bp, GRCBASE_MISC + @@ -4238,6 +4255,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, /* update shared memory */ bnx2x_update_mng(params, vars->link_status); + msleep(20); return rc; } /* This function should called upon link interrupt */ @@ -4276,6 +4294,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); /* Check external link change only for non-direct */ -- cgit From 3858276b7198074bf3570470463808627f0c9e31 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:16 +0000 Subject: bnx2x: Prevent self test loopback failures Setting loopback requires time to take effect Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index d9e1cfcd06d..4ce107c125d 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -3583,7 +3583,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params, (MDIO_REG_BANK_CL73_IEEEB0 + (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), 0x6041); - + msleep(200); /* set aer mmd back */ bnx2x_set_aer_mmd(params, vars); -- cgit From 44722d1d216c9dd4536de5f88fe8320b07e68a96 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:21 +0000 Subject: bnx2x: Legacy speeds autoneg failures 10M/100M autoneg was not establishing link. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index 4ce107c125d..2fd6be0cca1 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -3882,9 +3882,15 @@ static u8 bnx2x_link_initialize(struct link_params *params, } if (vars->phy_flags & PHY_XGXS_FLAG) { - if (params->req_line_speed && + if ((params->req_line_speed && ((params->req_line_speed == SPEED_100) || - (params->req_line_speed == SPEED_10))) { + (params->req_line_speed == SPEED_10))) || + (!params->req_line_speed && + (params->speed_cap_mask >= + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && + (params->speed_cap_mask < + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) + )) { vars->phy_flags |= PHY_SGMII_FLAG; } else { vars->phy_flags &= ~PHY_SGMII_FLAG; -- cgit From 16b311cc29806bb968746c1a752a087b32841af9 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:24 +0000 Subject: bnx2x: Handling PHY FW load failure If the default PHY version (0x4321) is read - the PHY FW load failed Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index 2fd6be0cca1..b4527a4a60e 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -4404,10 +4404,11 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) ext_phy_addr[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); - if (fw_ver1 == 0) { + if (fw_ver1 == 0 || fw_ver1 == 0x4321) { DP(NETIF_MSG_LINK, - "bnx2x_8073_common_init_phy port %x " - "fw Download failed\n", port); + "bnx2x_8073_common_init_phy port %x:" + "Download failed. fw version = 0x%x\n", + port, fw_ver1); return -EINVAL; } -- cgit From e47d7e6eb841c1850f0e69b95ae6cf3c86881f53 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:28 +0000 Subject: bnx2x: Driver description update The Driver supports the 57711 and 57711E as well but the description was out of date Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 2e00da6ab17..dc05e37c581 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -69,7 +69,7 @@ static char version[] __devinitdata = DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir"); -MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); +MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); -- cgit From 237907c1ded8a1a447cea7c4f97ab853e8b46052 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:42:44 +0000 Subject: bnx2x: Barriers for the compiler To make sure no swapping are made by the compiler, changed HAS_WORK to inline functions and added all the necessary barriers Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 9 +-------- drivers/net/bnx2x_main.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 6fcccef4cf3..18f60aa3efd 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -271,14 +271,7 @@ struct bnx2x_fastpath { #define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) -#define BNX2X_HAS_TX_WORK(fp) \ - ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \ - (fp->tx_pkt_prod != fp->tx_pkt_cons)) - -#define BNX2X_HAS_RX_WORK(fp) \ - (fp->rx_comp_cons != rx_cons_sb) - -#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp)) +#define BNX2X_HAS_WORK(fp) (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp)) /* MC hsi */ diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index dc05e37c581..3236527477a 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -733,6 +733,17 @@ static u16 bnx2x_ack_int(struct bnx2x *bp) * fast path service functions */ +static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) +{ + u16 tx_cons_sb; + + /* Tell compiler that status block fields can change */ + barrier(); + tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb); + return ((fp->tx_pkt_prod != tx_cons_sb) || + (fp->tx_pkt_prod != fp->tx_pkt_cons)); +} + /* free skb in the packet ring at pos idx * return idx of last bd freed */ @@ -6693,7 +6704,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) cnt = 1000; smp_rmb(); - while (BNX2X_HAS_TX_WORK(fp)) { + while (bnx2x_has_tx_work(fp)) { bnx2x_tx_int(fp, 1000); if (!cnt) { @@ -9281,6 +9292,18 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) return 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); +} + /* * net_device service functions */ @@ -9291,7 +9314,6 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) napi); struct bnx2x *bp = fp->bp; int work_done = 0; - u16 rx_cons_sb; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -9304,19 +9326,12 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) bnx2x_update_fpsb_idx(fp); - if (BNX2X_HAS_TX_WORK(fp)) + if (bnx2x_has_tx_work(fp)) bnx2x_tx_int(fp, budget); - 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++; - if (BNX2X_HAS_RX_WORK(fp)) + if (bnx2x_has_rx_work(fp)) work_done = bnx2x_rx_int(fp, budget); - rmb(); /* BNX2X_HAS_WORK() reads the status block */ - 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++; /* must not complete if we consumed full budget */ if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) { -- cgit From d05c26ce690e867aabfc7d708d481e0f86f23496 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Sat, 17 Jan 2009 23:26:13 -0800 Subject: bnx2x: Version update Updating the version and the year of updated files Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 2 +- drivers/net/bnx2x_link.c | 2 +- drivers/net/bnx2x_main.c | 6 +++--- drivers/net/bnx2x_reg.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 18f60aa3efd..15a5cf0f676 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -1,6 +1,6 @@ /* bnx2x.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2008 Broadcom Corporation + * Copyright (c) 2007-2009 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 diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index b4527a4a60e..aea26b4dc45 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -1,4 +1,4 @@ -/* Copyright 2008 Broadcom Corporation +/* Copyright 2008-2009 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 3236527477a..074374ff93f 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1,6 +1,6 @@ /* bnx2x_main.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2008 Broadcom Corporation + * Copyright (c) 2007-2009 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 @@ -57,8 +57,8 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "1.45.23" -#define DRV_MODULE_RELDATE "2008/11/03" +#define DRV_MODULE_VERSION "1.45.24" +#define DRV_MODULE_RELDATE "2009/01/14" #define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung */ diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h index a67b0c358ae..d084e5fc4b5 100644 --- a/drivers/net/bnx2x_reg.h +++ b/drivers/net/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2008 Broadcom Corporation + * Copyright (c) 2007-2009 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 -- cgit From 39eddb4c3970e9aadbc87b8a7cab7b4fefff077f Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Sun, 18 Jan 2009 21:57:35 -0800 Subject: macb: avoid lockup when TGO during underrun MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In rare cases when an underrun occur, all macb buffers where consumed and the netif_queue was stopped infinitely. This happens then the TGO (transfer ongoing) bit in the TSR is set (and UND). It seems like clening up after the underrun makes the driver and the macb hardware end up in an inconsistent state. The result of this is that in the following calls to macb_tx no TX buffers are released -> the netif_queue was stopped, and never woken up again. The solution is to disable the transmitter, if TGO is set, before clening up after the underrun, and re-enable the transmitter when the cleaning up is done. Signed-off-by: Richard Röjfors Signed-off-by: David S. Miller --- drivers/net/macb.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/macb.c b/drivers/net/macb.c index a04da4ecaa8..f6c4936e2fa 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -321,6 +321,10 @@ static void macb_tx(struct macb *bp) printk(KERN_ERR "%s: TX underrun, resetting buffers\n", bp->dev->name); + /* Transfer ongoing, disable transmitter, to avoid confusion */ + if (status & MACB_BIT(TGO)) + macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE)); + head = bp->tx_head; /*Mark all the buffer as used to avoid sending a lost buffer*/ @@ -343,6 +347,10 @@ static void macb_tx(struct macb *bp) } bp->tx_head = bp->tx_tail = 0; + + /* Enable the transmitter again */ + if (status & MACB_BIT(TGO)) + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE)); } if (!(status & MACB_BIT(COMP))) -- cgit From eed087e367591fc08490d7c6c2779b4b72c8f20c Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Sun, 18 Jan 2009 22:01:32 -0800 Subject: cxgb3: Fix LRO misalignment The lro manager's frag_align_pad setting was missing, leading to misaligned access to the skb passed up to the stack. Tested-by: Rick Jones Signed-off-by: Divy Le Ray Signed-off-by: David S. Miller --- drivers/net/cxgb3/sge.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 14f9fb3e879..379a1324db4 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2104,6 +2104,7 @@ static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr) { lro_mgr->dev = qs->netdev; lro_mgr->features = LRO_F_NAPI; + lro_mgr->frag_align_pad = NET_IP_ALIGN; lro_mgr->ip_summed = CHECKSUM_UNNECESSARY; lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; lro_mgr->max_desc = T3_MAX_LRO_SES; -- cgit From 6a2fe9834e578590f4a2fbe18a574465ab0e127c Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 15 Jan 2009 12:29:55 +0000 Subject: korina: fix loop back of receive descriptors After the last loop iteration, i has the value RC32434_NUM_RDS and therefore leads to an index overflow when used afterwards to address the last element. This is yet another another bug introduced when rewriting parts of the driver for upstream preparation, as the original driver used 'RC32434_NUM_RDS - 1' instead. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 1d6e48e1336..67fbdf40ace 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -769,11 +769,12 @@ static void korina_alloc_ring(struct net_device *dev) lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]); } - /* loop back */ - lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[0]); - lp->rx_next_done = 0; + /* loop back receive descriptors, so the last + * descriptor points to the first one */ + lp->rd_ring[i - 1].link = CPHYSADDR(&lp->rd_ring[0]); + lp->rd_ring[i - 1].control |= DMA_DESC_COD; - lp->rd_ring[i].control |= DMA_DESC_COD; + lp->rx_next_done = 0; lp->rx_chain_head = 0; lp->rx_chain_tail = 0; lp->rx_chain_status = desc_empty; -- cgit From 63a66c6c0debcae70183849121734fd4809e1dde Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 15 Jan 2009 12:29:56 +0000 Subject: korina: adjust headroom for new skb's also This is copy and paste from the original driver. As skb_reserve() is also called within korina_alloc_ring() when initially allocating the receive descriptors, the same should be done when allocating new space after passing an skb to upper layers. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 67fbdf40ace..60ae7bfb1d9 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -416,6 +416,9 @@ static int korina_rx(struct net_device *dev, int limit) if (devcs & ETH_RX_MP) dev->stats.multicast++; + /* 16 bit align */ + skb_reserve(skb_new, 2); + lp->rx_skb[lp->rx_next_done] = skb_new; } -- cgit From e85bf47e6ded66ea138f692fe149c00a4998afe8 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 15 Jan 2009 12:29:57 +0000 Subject: korina: drop leftover assignment As the assigned value is being overwritten shortly after, it can be dropped and so the whole variable definition moved to the start of the function. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 60ae7bfb1d9..75010cac76a 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -743,6 +743,7 @@ static struct ethtool_ops netdev_ethtool_ops = { static void korina_alloc_ring(struct net_device *dev) { struct korina_private *lp = netdev_priv(dev); + struct sk_buff *skb; int i; /* Initialize the transmit descriptors */ @@ -758,8 +759,6 @@ static void korina_alloc_ring(struct net_device *dev) /* Initialize the receive descriptors */ for (i = 0; i < KORINA_NUM_RDS; i++) { - struct sk_buff *skb = lp->rx_skb[i]; - skb = dev_alloc_skb(KORINA_RBSIZE + 2); if (!skb) break; -- cgit From 15005a320473b8d3676b878deb29bbe738ef9027 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Mon, 19 Jan 2009 16:54:13 -0800 Subject: ixgbe: fix dca issue with relaxed ordering turned on The is an issue where setting Relaxed Ordering (RO) bit (in a PCI-E write transaction) on 82598 causing the chipset to drop DCA hints. This patch forces RO not to be set for descriptors as well as payload. This will only be in effect while DCA is enabled and no performance difference was noticed in testing. Signed-off-by: Don Skidmore Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 3 +++ drivers/net/ixgbe/ixgbe_type.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index acef3c65cd2..92d9b17a081 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -318,6 +318,9 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl); rx_ring->cpu = cpu; } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 83a11ff9ffd..f011c57c920 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -404,6 +404,9 @@ #define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */ #define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */ #define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */ +#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */ +#define IXGBE_DCA_RXCTRL_DESC_WRO_EN (1 << 13) /* DCA Rx wr Desc Relax Order */ +#define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */ #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ -- cgit From 068c89b014ebd27b1c09c3c772e9d982988e7786 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Mon, 19 Jan 2009 16:54:36 -0800 Subject: ixgbe: fix tag stripping for VLAN ID 0 Register VLAN ID 0 so that frames with VLAN ID 0 are received and get their tag stripped when ixgbe is not in DCB mode. VLAN ID 0 means that the frame is 'priority tagged' only - it is not a VLAN, but the priority value is the tag in valid. The functions ixgbe_vlan_rx_register() and ixgbe_vlan_rx_kill_vid() were moved up a couple functions to correct compiling issues with this change. Signed-off-by: Don Skidmore Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Eric W Multanen Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 53 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 92d9b17a081..bf36737e2ec 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1744,6 +1744,32 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); } +static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + /* add VID to filter table */ + hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true); +} + +static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_disable(adapter); + + vlan_group_set_device(adapter->vlgrp, vid, NULL); + + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_enable(adapter); + + /* remove VID from filter table */ + hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false); +} + static void ixgbe_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { @@ -1763,6 +1789,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev, ctrl |= IXGBE_VLNCTRL_VME; ctrl &= ~IXGBE_VLNCTRL_CFIEN; IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl); + ixgbe_vlan_rx_add_vid(netdev, 0); if (grp) { /* enable VLAN tag insert/strip */ @@ -1776,32 +1803,6 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev, ixgbe_irq_enable(adapter); } -static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; - - /* add VID to filter table */ - hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true); -} - -static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_disable(adapter); - - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter); - - /* remove VID from filter table */ - hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false); -} - static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) { ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp); -- cgit From 1da100bb47ef32cb43bb6a365f64183898f830b5 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Mon, 19 Jan 2009 16:55:03 -0800 Subject: ixgbe: Fix usage of netif_*_all_queues() with netif_carrier_{off|on}() netif_carrier_off() is sufficient to stop Tx into the driver. Stopping the Tx queues is redundant and unnecessary. By the same token, netif_carrier_on() will be sufficient to re-enable Tx, so waking the queues is unnecessary. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index bf36737e2ec..d2f4d5f508b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2078,6 +2078,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) ixgbe_irq_enable(adapter); + /* enable transmits */ + netif_tx_start_all_queues(netdev); + /* bring the link up in the watchdog, this could race with our first * link up interrupt but shouldn't be a problem */ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; @@ -3479,7 +3482,6 @@ static void ixgbe_watchdog_task(struct work_struct *work) (FLOW_TX ? "TX" : "None")))); netif_carrier_on(netdev); - netif_tx_wake_all_queues(netdev); } else { /* Force detection of hung controller */ adapter->detect_tx_hung = true; @@ -3491,7 +3493,6 @@ static void ixgbe_watchdog_task(struct work_struct *work) printk(KERN_INFO "ixgbe: %s NIC Link is Down\n", netdev->name); netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); } } @@ -4222,7 +4223,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); -- cgit From 9e9fd12dc0679643c191fc9795a3021807e77de4 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 19 Jan 2009 16:57:45 -0800 Subject: tg3: Fix firmware loading This patch modifies how the tg3 driver handles device firmware. The patch starts by consolidating David Woodhouse's earlier patch under the same name. Specifically, the patch moves the request_firmware call into a separate tg3_request_firmware() function and calls that function from tg3_open() rather than tg3_init_one(). The patch then goes on to limit the number of devices that will make request_firmware calls. The original firmware patch unnecessarily requested TSO firmware for devices that did not need it. This patch reduces the set of devices making TSO firmware patches to approximately the following device set : 5703, 5704, and 5705. Finally, the patch reduces the effects of a request_firmware() failure. For those devices that are requesting TSO firmware, the driver will turn off the TSO capability. If TSO firmware becomes available at a later time, the device can be closed and then opened again to reacquire the TSO capability. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 81 ++++++++++++++++++++++++++++++++++--------------------- drivers/net/tg3.h | 1 + 2 files changed, 51 insertions(+), 31 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5e2dbaee125..8b3f8468538 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7535,11 +7535,58 @@ static int tg3_test_msi(struct tg3 *tp) return err; } +static int tg3_request_firmware(struct tg3 *tp) +{ + const __be32 *fw_data; + + if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { + printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", + tp->dev->name, tp->fw_needed); + return -ENOENT; + } + + fw_data = (void *)tp->fw->data; + + /* Firmware blob starts with version numbers, followed by + * start address and _full_ length including BSS sections + * (which must be longer than the actual data, of course + */ + + tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ + if (tp->fw_len < (tp->fw->size - 12)) { + printk(KERN_ERR "%s: bogus length %d in \"%s\"\n", + tp->dev->name, tp->fw_len, tp->fw_needed); + release_firmware(tp->fw); + tp->fw = NULL; + return -EINVAL; + } + + /* We no longer need firmware; we have it. */ + tp->fw_needed = NULL; + return 0; +} + static int tg3_open(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); int err; + if (tp->fw_needed) { + err = tg3_request_firmware(tp); + if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) { + if (err) + return err; + } else if (err) { + printk(KERN_WARNING "%s: TSO capability disabled.\n", + tp->dev->name); + tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; + } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { + printk(KERN_NOTICE "%s: TSO capability restored.\n", + tp->dev->name); + tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; + } + } + netif_carrier_off(tp->dev); err = tg3_set_power_state(tp, PCI_D0); @@ -12934,7 +12981,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, struct net_device *dev; struct tg3 *tp; int err, pm_cap; - const char *fw_name = NULL; char str[40]; u64 dma_mask, persist_dma_mask; @@ -13091,7 +13137,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tg3_init_bufmgr_config(tp); if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) - fw_name = FIRMWARE_TG3; + tp->fw_needed = FIRMWARE_TG3; if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; @@ -13104,37 +13150,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } else { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG; - } - if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) - fw_name = FIRMWARE_TG3TSO5; + tp->fw_needed = FIRMWARE_TG3TSO5; else - fw_name = FIRMWARE_TG3TSO; - } - - if (fw_name) { - const __be32 *fw_data; - - err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev); - if (err) { - printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n", - fw_name); - goto err_out_iounmap; - } - - fw_data = (void *)tp->fw->data; - - /* Firmware blob starts with version numbers, followed by - start address and _full_ length including BSS sections - (which must be longer than the actual data, of course */ - - tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ - if (tp->fw_len < (tp->fw->size - 12)) { - printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n", - tp->fw_len, fw_name); - err = -EINVAL; - goto err_out_fw; - } + tp->fw_needed = FIRMWARE_TG3TSO; } /* TSO is on by default on chips that support hardware TSO. diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index ae5da603c6a..508def3e077 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2764,6 +2764,7 @@ struct tg3 { struct ethtool_coalesce coal; /* firmware info */ + const char *fw_needed; const struct firmware *fw; u32 fw_len; /* includes BSS */ }; -- cgit From e0c6ef9388b58f297937fc9651331941d1579b25 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 19 Jan 2009 17:16:00 -0800 Subject: Revert "mv643xx_eth: use longer DMA bursts". This reverts commit cd4ccf76bfd2c36d351e68be7e6a597268f98a1a. On the Pegasos board, we can't do DMA burst that are longer than one cache line. For now, go back to using 32 byte DMA bursts for all mv643xx_eth platforms -- we can switch the ARM-based platforms back to doing long 128 byte bursts in the next development cycle. Signed-off-by: Lennert Buytenhek Reported-by: Alan Curry Reported-by: Gabriel Paubert Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 7253a499d9c..e2aa468d40f 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -136,21 +136,23 @@ static char mv643xx_eth_driver_version[] = "1.4"; /* * SDMA configuration register. */ +#define RX_BURST_SIZE_4_64BIT (2 << 1) #define RX_BURST_SIZE_16_64BIT (4 << 1) #define BLM_RX_NO_SWAP (1 << 4) #define BLM_TX_NO_SWAP (1 << 5) +#define TX_BURST_SIZE_4_64BIT (2 << 22) #define TX_BURST_SIZE_16_64BIT (4 << 22) #if defined(__BIG_ENDIAN) #define PORT_SDMA_CONFIG_DEFAULT_VALUE \ - (RX_BURST_SIZE_16_64BIT | \ - TX_BURST_SIZE_16_64BIT) + (RX_BURST_SIZE_4_64BIT | \ + TX_BURST_SIZE_4_64BIT) #elif defined(__LITTLE_ENDIAN) #define PORT_SDMA_CONFIG_DEFAULT_VALUE \ - (RX_BURST_SIZE_16_64BIT | \ - BLM_RX_NO_SWAP | \ - BLM_TX_NO_SWAP | \ - TX_BURST_SIZE_16_64BIT) + (RX_BURST_SIZE_4_64BIT | \ + BLM_RX_NO_SWAP | \ + BLM_TX_NO_SWAP | \ + TX_BURST_SIZE_4_64BIT) #else #error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined #endif -- cgit From 2b448334a255d34401562229f467ffd95d8ed6ef Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 19 Jan 2009 17:17:18 -0800 Subject: mv643xx_eth: fix multicast filter programming Commit 66e63ffbc04706568d8789cbb00eaa8ddbcae648 ("mv643xx_eth: implement ->set_rx_mode()") cleaned up mv643xx_eth's multicast filter programming, but broke it as well. The non-special multicast filter table (for multicast addresses that are not of the form 01:00:5e:00:00:xx) consists of 256 hash table buckets organised as 64 32-bit words, where the 'accept' bits are in the LSB of each byte, so in bits 24 16 8 0 of each 32-bit word. The old code got this right, but the referenced commit broke this by using bits 3 2 1 0 instead. This commit fixes this up. Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index e2aa468d40f..8c6979a26d6 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1596,7 +1596,7 @@ oom: entry = addr_crc(a); } - table[entry >> 2] |= 1 << (entry & 3); + table[entry >> 2] |= 1 << (8 * (entry & 3)); } for (i = 0; i < 0x100; i += 4) { -- cgit From fe65e704534de5d0661ebc3466a2b9018945f694 Mon Sep 17 00:00:00 2001 From: Gabriel Paubert Date: Mon, 19 Jan 2009 17:18:09 -0800 Subject: mv643xx_eth: prevent interrupt storm on ifconfig down Contrary to what the docs say, the 'extended interrupt cause' bit in the interrupt cause register (bit 1) appears to not be maskable on at least some of the mv643xx_eth platforms, making writing zeroes to the interrupt mask register but not the extended interrupt mask register insufficient to stop interrupts from occuring. Therefore, also write zeroes to the extended interrupt mask register when shutting down the port. This fixes the interrupt storm seen on the Pegasos board when shutting down the interface. Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 8c6979a26d6..5f31bbb614a 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2212,6 +2212,7 @@ static int mv643xx_eth_stop(struct net_device *dev) struct mv643xx_eth_private *mp = netdev_priv(dev); int i; + wrlp(mp, INT_MASK_EXT, 0x00000000); wrlp(mp, INT_MASK, 0x00000000); rdlp(mp, INT_MASK); -- cgit From f4895b8bc83a22a36446c4aee277e1750fcc6a18 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Mon, 19 Jan 2009 13:19:30 +0000 Subject: wimax/i2400m: error paths that need to free an skb should use kfree_skb() Roel Kluin reported a bug in two error paths where skbs were wrongly being freed using kfree(). He provided a fix where it was replaced to kfree_skb(), as it should be. However, in i2400mu_rx(), the error path was missing returning an indication of the failure. Changed to reset rx_skb to NULL and return it to the caller, i2400mu_rxd(). It will be treated as a transient error and just ignore the packet. Depending on the buffering conditions inside the device, the data packet might be dropped or the device will signal the host again for data-ready-to-read and the host will retry. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/control.c | 2 +- drivers/net/wimax/i2400m/usb-rx.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c index d3d37fed689..15d9f51b292 100644 --- a/drivers/net/wimax/i2400m/control.c +++ b/drivers/net/wimax/i2400m/control.c @@ -609,7 +609,7 @@ void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code) spin_lock_irqsave(&i2400m->rx_lock, flags); ack_skb = i2400m->ack_skb; if (ack_skb && !IS_ERR(ack_skb)) - kfree(ack_skb); + kfree_skb(ack_skb); i2400m->ack_skb = ERR_PTR(code); spin_unlock_irqrestore(&i2400m->rx_lock, flags); } diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c index 074cc1f8985..a314799967c 100644 --- a/drivers/net/wimax/i2400m/usb-rx.c +++ b/drivers/net/wimax/i2400m/usb-rx.c @@ -184,6 +184,8 @@ void i2400mu_rx_size_maybe_shrink(struct i2400mu *i2400mu) * NOTE: this function might realloc the skb (if it is too small), * so always update with the one returned. * ERR_PTR() is < 0 on error. + * Will return NULL if it cannot reallocate -- this can be + * considered a transient retryable error. */ static struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) @@ -243,8 +245,8 @@ retry: if (printk_ratelimit()) dev_err(dev, "RX: Can't reallocate skb to %d; " "RX dropped\n", rx_size); - kfree(rx_skb); - result = 0; + kfree_skb(rx_skb); + rx_skb = NULL; goto out; /* drop it...*/ } kfree_skb(rx_skb); @@ -344,7 +346,8 @@ int i2400mu_rxd(void *_i2400mu) if (IS_ERR(rx_skb)) goto out; atomic_dec(&i2400mu->rx_pending_count); - if (rx_skb->len == 0) { /* some ignorable condition */ + if (rx_skb == NULL || rx_skb->len == 0) { + /* some "ignorable" condition */ kfree_skb(rx_skb); continue; } -- cgit From e3fd553468738e0342cbd82a63ede00c983a0eb4 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Sat, 17 Jan 2009 08:27:19 +0000 Subject: myri10ge: don't forget pci_disable_device() Don't forget to call pci_disable_device() in myri10ge_remove() and when myri10ge_probe() fails. By the way, update the copyright years. Signed-off-by: Brice Goglin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 6bb71b687f7..e9c1296b267 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1,7 +1,7 @@ /************************************************************************* * myri10ge.c: Myricom Myri-10G Ethernet driver. * - * Copyright (C) 2005 - 2007 Myricom, Inc. + * Copyright (C) 2005 - 2009 Myricom, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.4.4-1.398" +#define MYRI10GE_VERSION_STR "1.4.4-1.401" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -3786,7 +3786,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (status != 0) { dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n", status); - goto abort_with_netdev; + goto abort_with_enabled; } pci_set_master(pdev); @@ -3801,13 +3801,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } if (status != 0) { dev_err(&pdev->dev, "Error %d setting DMA mask\n", status); - goto abort_with_netdev; + goto abort_with_enabled; } (void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd), &mgp->cmd_bus, GFP_KERNEL); if (mgp->cmd == NULL) - goto abort_with_netdev; + goto abort_with_enabled; mgp->board_span = pci_resource_len(pdev, 0); mgp->iomem_base = pci_resource_start(pdev, 0); @@ -3943,8 +3943,10 @@ abort_with_mtrr: dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), mgp->cmd, mgp->cmd_bus); -abort_with_netdev: +abort_with_enabled: + pci_disable_device(pdev); +abort_with_netdev: free_netdev(netdev); return status; } @@ -3990,6 +3992,7 @@ static void myri10ge_remove(struct pci_dev *pdev) mgp->cmd, mgp->cmd_bus); free_netdev(netdev); + pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } -- cgit From 0d1cfd20cc5f785d5345d249d4b6a6f84b29e6a6 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sat, 17 Jan 2009 11:14:31 +0000 Subject: via-velocity: fix hot spin while(--j >= 0) keeps spinning when j is unsigned: Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index a75f91dc315..c5691fdb707 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1302,7 +1302,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr) static int velocity_init_td_ring(struct velocity_info *vptr) { dma_addr_t curr; - unsigned int j; + int j; /* Init the TD ring entries */ for (j = 0; j < vptr->tx.numq; j++) { -- cgit From 0b491eee46012772cbf029450d123e933c2e7940 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Wed, 21 Jan 2009 12:35:43 -0800 Subject: usbnet: allow type check of devdbg arguments in non-debug build Improve usbnet's devdbg to always type-check diagnostic arguments, like dev_dbg (device.h). This makes no change to the resulting size of usbnet modules. This patch also removes an #ifdef DEBUG directive from rndis_wlan so it's devdbg statements are always type-checked at compile time. Signed-off-by: Steve Glendinning Signed-off-by: David Brownell Signed-off-by: David S. Miller --- drivers/net/wireless/rndis_wlan.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 607ce9f61b5..ed93ac41297 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1649,9 +1649,7 @@ static char *rndis_translate_scan(struct net_device *dev, char *end_buf, struct ndis_80211_bssid_ex *bssid) { -#ifdef DEBUG struct usbnet *usbdev = netdev_priv(dev); -#endif u8 *ie; char *current_val; int bssid_len, ie_len, i; -- cgit From 6d317482944250228255bcbe97a95b7e7ad9a538 Mon Sep 17 00:00:00 2001 From: Christian Eggers Date: Wed, 21 Jan 2009 12:56:24 -0800 Subject: usb/mcs7830: Don't use buffers from stack for USB transfers mcs7830_set_reg() and mcs7830_get_reg() are called with buffers from stack which must not be used directly for USB transfers. This causes corruption of the stack particulary on non x86 architectures because DMA may be used for these transfers. Signed-off-by: Christian Eggers Acked-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/usb/mcs7830.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 5385d66b306..ced8f36ebd0 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -94,10 +94,18 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) { struct usb_device *xdev = dev->udev; int ret; + void *buffer; + + buffer = kmalloc(size, GFP_NOIO); + if (buffer == NULL) + return -ENOMEM; ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ, - MCS7830_RD_BMREQ, 0x0000, index, data, + MCS7830_RD_BMREQ, 0x0000, index, buffer, size, MCS7830_CTRL_TIMEOUT); + memcpy(data, buffer, size); + kfree(buffer); + return ret; } @@ -105,10 +113,18 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data) { struct usb_device *xdev = dev->udev; int ret; + void *buffer; + + buffer = kmalloc(size, GFP_NOIO); + if (buffer == NULL) + return -ENOMEM; + + memcpy(buffer, data, size); ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ, - MCS7830_WR_BMREQ, 0x0000, index, data, + MCS7830_WR_BMREQ, 0x0000, index, buffer, size, MCS7830_CTRL_TIMEOUT); + kfree(buffer); return ret; } -- cgit From 7fe99c4e28ab54eada8aa456b417114e6ef21587 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Tue, 20 Jan 2009 20:26:46 +0300 Subject: orinoco: move kmalloc(..., GFP_KERNEL) outside spinlock in orinoco_ioctl_set_genie [ 56.923623] BUG: sleeping function called from invalid context at /home/bor/src/linux-git/mm/slub.c:1599 [ 56.923644] in_atomic(): 0, irqs_disabled(): 1, pid: 3031, name: wpa_supplicant [ 56.923656] 2 locks held by wpa_supplicant/3031: [ 56.923662] #0: (rtnl_mutex){--..}, at: [] rtnl_lock+0xf/0x20 [ 56.923703] #1: (&priv->lock){++..}, at: [] orinoco_ioctl_set_genie+0x52/0x130 [orinoco] [ 56.923782] irq event stamp: 910 [ 56.923788] hardirqs last enabled at (909): [] __kmalloc+0x7b/0x140 [ 56.923820] hardirqs last disabled at (910): [] _spin_lock_irqsave+0x19/0x80 [ 56.923847] softirqs last enabled at (880): [] __do_softirq+0xc4/0x110 [ 56.923865] softirqs last disabled at (871): [] do_softirq+0x8e/0xe0 [ 56.923895] Pid: 3031, comm: wpa_supplicant Not tainted 2.6.29-rc2-1avb #1 [ 56.923905] Call Trace: [ 56.923919] [] ? do_softirq+0x8e/0xe0 [ 56.923941] [] __might_sleep+0xd2/0x100 [ 56.923952] [] __kmalloc+0xd7/0x140 [ 56.923963] [] ? _spin_lock_irqsave+0x6a/0x80 [ 56.923981] [] ? orinoco_ioctl_set_genie+0x79/0x130 [orinoco] [ 56.923999] [] ? orinoco_ioctl_set_genie+0x52/0x130 [orinoco] [ 56.924017] [] orinoco_ioctl_set_genie+0x79/0x130 [orinoco] [ 56.924036] [] ? copy_from_user+0x35/0x130 [ 56.924061] [] ioctl_standard_call+0x196/0x380 [ 56.924085] [] ? __dev_get_by_name+0x85/0xb0 [ 56.924096] [] wext_handle_ioctl+0x14f/0x230 [ 56.924113] [] ? orinoco_ioctl_set_genie+0x0/0x130 [orinoco] [ 56.924132] [] dev_ioctl+0x495/0x570 [ 56.924155] [] ? sys_sendto+0xa5/0xd0 [ 56.924171] [] ? mark_held_locks+0x48/0x90 [ 56.924183] [] ? sock_ioctl+0x0/0x280 [ 56.924193] [] sock_ioctl+0xfd/0x280 [ 56.924203] [] ? sock_ioctl+0x0/0x280 [ 56.924235] [] vfs_ioctl+0x20/0x80 [ 56.924246] [] do_vfs_ioctl+0x72/0x570 [ 56.924257] [] ? sys_send+0x32/0x40 [ 56.924268] [] ? sys_socketcall+0x1d0/0x2a0 [ 56.924280] [] ? sysenter_exit+0xf/0x16 [ 56.924292] [] sys_ioctl+0x39/0x70 [ 56.924302] [] sysenter_do_call+0x12/0x31 Signed-off-by: Andrey Borzenkov Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c index c3bb85e0251..39eab39b065 100644 --- a/drivers/net/wireless/orinoco/orinoco.c +++ b/drivers/net/wireless/orinoco/orinoco.c @@ -5068,33 +5068,30 @@ static int orinoco_ioctl_set_genie(struct net_device *dev, struct orinoco_private *priv = netdev_priv(dev); u8 *buf; unsigned long flags; - int err = 0; /* cut off at IEEE80211_MAX_DATA_LEN */ if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) || (wrqu->data.length && (extra == NULL))) return -EINVAL; - if (orinoco_lock(priv, &flags) != 0) - return -EBUSY; - if (wrqu->data.length) { buf = kmalloc(wrqu->data.length, GFP_KERNEL); - if (buf == NULL) { - err = -ENOMEM; - goto out; - } + if (buf == NULL) + return -ENOMEM; memcpy(buf, extra, wrqu->data.length); - kfree(priv->wpa_ie); - priv->wpa_ie = buf; - priv->wpa_ie_len = wrqu->data.length; - } else { - kfree(priv->wpa_ie); - priv->wpa_ie = NULL; - priv->wpa_ie_len = 0; + } else + buf = NULL; + + if (orinoco_lock(priv, &flags) != 0) { + kfree(buf); + return -EBUSY; } + kfree(priv->wpa_ie); + priv->wpa_ie = buf; + priv->wpa_ie_len = wrqu->data.length; + if (priv->wpa_ie) { /* Looks like wl_lkm wants to check the auth alg, and * somehow pass it to the firmware. @@ -5103,9 +5100,8 @@ static int orinoco_ioctl_set_genie(struct net_device *dev, */ } -out: orinoco_unlock(priv, &flags); - return err; + return 0; } static int orinoco_ioctl_get_genie(struct net_device *dev, -- cgit From 7490889c105764d80af58dee5983d91a84e4aec8 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 18 Jan 2009 20:15:24 +0100 Subject: rt2x00: Fix TX rate short preamble detection Mac80211 provides 2 structures to handle bitrates, namely ieee80211_rate and ieee80211_tx_rate. To determine the short preamble mode for an outgoing frame, the flag IEEE80211_TX_RC_USE_SHORT_PREAMBLE must be checked on ieee80211_tx_rate and not ieee80211_rate (which rt2x00 did). This fixes a regression which was triggered in 2.6.29-rcX as reported by Chris Clayton. Signed-off-by: Ivo van Doorn Tested-By: Chris Clayton Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 746a8f36b93..0709decec9c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -154,6 +154,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; + struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; struct ieee80211_rate *rate = ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); const struct rt2x00_rate *hwrate; @@ -313,7 +314,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, * When preamble is enabled we should set the * preamble bit for the signal. */ - if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) txdesc->signal |= 0x08; } } -- cgit From 11eaea416716deebcb18383b201ba8033cbf33dc Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sun, 18 Jan 2009 23:20:58 -0500 Subject: orinoco: use KERN_DEBUG for link status messages KERN_INFO is too "loud" for messages that are generated by the ordinary events, such as accociation. Use of KERN_DEBUG is consistent with mac80211. Suggested by Michael Gilbert Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c index 39eab39b065..45a04faa781 100644 --- a/drivers/net/wireless/orinoco/orinoco.c +++ b/drivers/net/wireless/orinoco/orinoco.c @@ -1673,7 +1673,7 @@ static void print_linkstatus(struct net_device *dev, u16 status) s = "UNKNOWN"; } - printk(KERN_INFO "%s: New link status: %s (%04x)\n", + printk(KERN_DEBUG "%s: New link status: %s (%04x)\n", dev->name, s, status); } -- cgit From 40ab73cc6c38ce93253fe8c2d7e502c948adfd13 Mon Sep 17 00:00:00 2001 From: Chr Date: Mon, 19 Jan 2009 14:30:26 +0100 Subject: p54: add missing break in eeprom parser This patch fixes a obvious memory leak in the eeprom parser. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 12d0717c399..61b01930d9a 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -451,8 +451,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) } if (err) goto err; - - } + } + break; case PDR_PRISM_ZIF_TX_IQ_CALIBRATION: priv->iq_autocal = kmalloc(data_len, GFP_KERNEL); if (!priv->iq_autocal) { -- cgit From 12da401e0d616f738c8b8a368d1f63f365cc78e4 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 19 Jan 2009 16:08:48 +0100 Subject: p54: more cryptographic accelerator fixes If we let the firmware do the data encryption, we have to remove the ICV and (M)MIC at the end of the frame before we can give it back to mac80211. Or, these data frames have a few trailing bytes on cooked monitor interfaces. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 61b01930d9a..34561e6e816 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -745,7 +745,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); struct p54_hdr *entry_hdr; struct p54_tx_data *entry_data; - int pad = 0; + unsigned int pad = 0, frame_len; range = (void *)info->rate_driver_data; if (range->start_addr != addr) { @@ -768,6 +768,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) __skb_unlink(entry, &priv->tx_queue); spin_unlock_irqrestore(&priv->tx_queue.lock, flags); + frame_len = entry->len; entry_hdr = (struct p54_hdr *) entry->data; entry_data = (struct p54_tx_data *) entry_hdr->data; priv->tx_stats[entry_data->hw_queue].len--; @@ -814,15 +815,28 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) info->status.ack_signal = p54_rssi_to_dbm(dev, (int)payload->ack_rssi); - if (entry_data->key_type == P54_CRYPTO_TKIPMICHAEL) { + /* Undo all changes to the frame. */ + switch (entry_data->key_type) { + case P54_CRYPTO_TKIPMICHAEL: { u8 *iv = (u8 *)(entry_data->align + pad + - entry_data->crypt_offset); + entry_data->crypt_offset); /* Restore the original TKIP IV. */ iv[2] = iv[0]; iv[0] = iv[1]; iv[1] = (iv[0] | 0x20) & 0x7f; /* WEPSeed - 8.3.2.2 */ + + frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */ + break; + } + case P54_CRYPTO_AESCCMP: + frame_len -= 8; /* remove CCMP_MIC */ + break; + case P54_CRYPTO_WEP: + frame_len -= 4; /* remove WEP_ICV */ + break; } + skb_trim(entry, frame_len); skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); ieee80211_tx_status_irqsafe(dev, entry); goto out; -- cgit From e2fe154e918276e900067a9d1d3a6a963faee041 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 20 Jan 2009 00:27:57 +0100 Subject: p54usb: fix nasty use after free In theory, the firmware acks the received a data frame, before signaling the driver to free it again. However Artur Skawina has shown that it can happen in reverse order as well. This is very bad and could lead to memory corruptions, oopses and panics. Thanks to Artur Skawina for reporting and debugging this issue. Signed-off-by: Christian Lamparter Tested-by: Artur Skawina Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 6a6a72f6f82..4487cc5c928 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -144,11 +144,8 @@ static void p54u_tx_cb(struct urb *urb) struct sk_buff *skb = urb->context; struct ieee80211_hw *dev = (struct ieee80211_hw *) usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); - struct p54u_priv *priv = dev->priv; - skb_pull(skb, priv->common.tx_hdr_len); - if (FREE_AFTER_TX(skb)) - p54_free_skb(dev, skb); + p54_free_skb(dev, skb); } static void p54u_tx_dummy_cb(struct urb *urb) { } @@ -230,7 +227,8 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb) p54u_tx_dummy_cb, dev); usb_fill_bulk_urb(data_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), - skb->data, skb->len, p54u_tx_cb, skb); + skb->data, skb->len, FREE_AFTER_TX(skb) ? + p54u_tx_cb : p54u_tx_dummy_cb, skb); usb_anchor_urb(addr_urb, &priv->submitted); err = usb_submit_urb(addr_urb, GFP_ATOMIC); @@ -269,28 +267,24 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb) { struct p54u_priv *priv = dev->priv; struct urb *data_urb; - struct lm87_tx_hdr *hdr; - __le32 checksum; - __le32 addr = ((struct p54_hdr *)skb->data)->req_id; + struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr); data_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!data_urb) return; - checksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len); - hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr)); - hdr->chksum = checksum; - hdr->device_addr = addr; + hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len); + hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id; usb_fill_bulk_urb(data_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), - skb->data, skb->len, p54u_tx_cb, skb); + hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ? + p54u_tx_cb : p54u_tx_dummy_cb, skb); data_urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(data_urb, &priv->submitted); if (usb_submit_urb(data_urb, GFP_ATOMIC)) { usb_unanchor_urb(data_urb); - skb_pull(skb, sizeof(*hdr)); p54_free_skb(dev, skb); } usb_free_urb(data_urb); @@ -300,11 +294,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb) { struct p54u_priv *priv = dev->priv; struct urb *int_urb, *data_urb; - struct net2280_tx_hdr *hdr; + struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr); struct net2280_reg_write *reg; int err = 0; - __le32 addr = ((struct p54_hdr *) skb->data)->req_id; - __le16 len = cpu_to_le16(skb->len); reg = kmalloc(sizeof(*reg), GFP_ATOMIC); if (!reg) @@ -327,10 +319,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb) reg->addr = cpu_to_le32(P54U_DEV_BASE); reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); - hdr = (void *)skb_push(skb, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr)); - hdr->len = len; - hdr->device_addr = addr; + hdr->len = cpu_to_le16(skb->len); + hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id; usb_fill_bulk_urb(int_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), @@ -345,7 +336,8 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb) usb_fill_bulk_urb(data_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), - skb->data, skb->len, p54u_tx_cb, skb); + hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ? + p54u_tx_cb : p54u_tx_dummy_cb, skb); usb_anchor_urb(int_urb, &priv->submitted); err = usb_submit_urb(int_urb, GFP_ATOMIC); -- cgit From de2624966f9bc6ffafc4fd6555336fabc2854420 Mon Sep 17 00:00:00 2001 From: Hin-Tak Leung Date: Mon, 19 Jan 2009 23:39:09 +0000 Subject: zd1211rw: adding Sitecom WL-603 (0df6:0036) to the USB id list Giuseppe Cala (The second "a" in "Cala" should be a grave, U+00E0) reported success on zd1211-devs@lists.sourceforge.net. The chip info is: zd1211b chip 0df6:0036 v4810 high 00-0c-f6 AL2230_RF pa0 g--N- The Sitecom WL-603 is detected as a zd1211b with a AL2230 RF transceiver chip. Signed-off-by: Giuseppe Cala Signed-off-by: Hin-Tak Leung Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index b5db57d2fcf..17527f765b3 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -84,6 +84,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, /* "Driverless" devices that need ejecting */ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, -- cgit From 637f883739b32746889a191f282c9ea2590ecf4f Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Mon, 19 Jan 2009 15:30:32 -0800 Subject: iwlwifi: return NETDEV_TX_OK from _tx ops be consistent with mac80211 drivers and return correct return code. NETDEV_TX_OK is 0, but we need to be consistent wrt formatting amongst implementations re: http://marc.info/?l=linux-wireless&m=123119327419865&w=2 Signed-off-by: Reinette Chatre Reviewed-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5da6b35cd26..0dc8eed1640 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2482,7 +2482,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); IWL_DEBUG_MACDUMP("leave\n"); - return 0; + return NETDEV_TX_OK; } static int iwl_mac_add_interface(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 15f5655c636..95d01984c80 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6538,7 +6538,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); IWL_DEBUG_MAC80211("leave\n"); - return 0; + return NETDEV_TX_OK; } static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, -- cgit From 81f75bbf67c7a26ea1266ac93b9319bb985d588d Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 03:37:31 +0000 Subject: bnx2x: Reset HW before use To avoid complications, make sure that the HW is in reset (as it should be) before trying to take it out of reset. In normal flows, the HW is indeed in rest so this should have no effect Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 074374ff93f..ed8b3466593 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -5148,12 +5148,21 @@ static void enable_blocks_attention(struct bnx2x *bp) } +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 int bnx2x_init_common(struct bnx2x *bp) { u32 val, i; 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); @@ -6640,14 +6649,6 @@ static void bnx2x_reset_port(struct bnx2x *bp) /* TODO: Close Doorbell port? */ } -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_reset_chip(struct bnx2x *bp, u32 reset_code) { DP(BNX2X_MSG_MCP, "function %d reset_code %x\n", -- cgit From e94d8af3da79f4bfbd22819d28ecf0602456f06f Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 03:37:36 +0000 Subject: bnx2x: Disable napi Calling napi disabled unconditionally at netif stop Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ed8b3466593..860b9f8ddd3 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6143,8 +6143,8 @@ static void bnx2x_netif_start(struct bnx2x *bp) static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) { bnx2x_int_disable_sync(bp, disable_hw); + bnx2x_napi_disable(bp); if (netif_running(bp->dev)) { - bnx2x_napi_disable(bp); netif_tx_disable(bp->dev); bp->dev->trans_start = jiffies; /* prevent tx timeout */ } @@ -6689,8 +6689,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_set_storm_rx_mode(bp); bnx2x_netif_stop(bp, 1); - if (!netif_running(bp->dev)) - bnx2x_napi_disable(bp); + 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)); -- cgit From 2dfe0e1fecb582b4aae7f2490904864c05472f3a Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 03:37:44 +0000 Subject: bnx2x: Handling load failures Failures on load were not handled correctly - separate the flow to handle different failures Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 154 +++++++++++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 66 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 860b9f8ddd3..707c4bbe46a 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6328,7 +6328,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev); static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { u32 load_code; - int i, rc; + int i, rc = 0; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) return -EPERM; @@ -6336,48 +6336,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; - /* 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"); - return -EBUSY; - } - if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) - return -EBUSY; /* other port in diagnostic mode */ - - } else { - int port = BP_PORT(bp); - - DP(NETIF_MSG_IFUP, "NO MCP load counts before us %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); - - /* 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 inta with one fp - */ if (use_inta) { bp->num_queues = 1; @@ -6392,7 +6350,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) else bp->num_queues = 1; - if (bnx2x_enable_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; if (use_multi) @@ -6400,8 +6366,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) " to enable MSI-X\n"); } } - DP(NETIF_MSG_IFUP, - "set number of queues to %d\n", bp->num_queues); if (bnx2x_alloc_mem(bp)) return -ENOMEM; @@ -6410,30 +6374,85 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) 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); + +#ifdef BNX2X_STOP_ON_ERROR + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + fp->poll_no_work = 0; + fp->poll_calls = 0; + fp->poll_max_calls = 0; + fp->poll_complete = 0; + fp->poll_exit = 0; + } +#endif + bnx2x_napi_enable(bp); + if (bp->flags & USING_MSIX_FLAG) { rc = bnx2x_req_msix_irqs(bp); if (rc) { pci_disable_msix(bp->pdev); - goto load_error; + goto load_error1; } + printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name); } else { bnx2x_ack_int(bp); rc = bnx2x_req_irq(bp); if (rc) { - BNX2X_ERR("IRQ request failed, aborting\n"); - goto load_error; + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); + goto load_error1; } } - for_each_queue(bp, i) - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, 128); + /* 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 before us %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"); - goto load_int_disable; + goto load_error2; } /* Setup NIC internals and enable interrupts */ @@ -6445,7 +6464,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; - goto load_rings_free; + goto load_error3; } } @@ -6454,7 +6473,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_setup_leading(bp); if (rc) { BNX2X_ERR("Setup leading failed!\n"); - goto load_netif_stop; + goto load_error3; } if (CHIP_IS_E1H(bp)) @@ -6467,7 +6486,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) for_each_nondefault_queue(bp, i) { rc = bnx2x_setup_multi(bp, i); if (rc) - goto load_netif_stop; + goto load_error3; } if (CHIP_IS_E1(bp)) @@ -6483,18 +6502,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) case LOAD_NORMAL: /* Tx queue should be only reenabled */ netif_wake_queue(bp->dev); + /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); break; case LOAD_OPEN: netif_start_queue(bp->dev); + /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); - if (bp->flags & USING_MSIX_FLAG) - printk(KERN_INFO PFX "%s: using MSI-X\n", - bp->dev->name); break; case LOAD_DIAG: + /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); bp->state = BNX2X_STATE_DIAG; break; @@ -6512,20 +6531,23 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) return 0; -load_netif_stop: - bnx2x_napi_disable(bp); -load_rings_free: +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_int_disable: - bnx2x_int_disable_sync(bp, 1); +load_error2: /* Release IRQs */ bnx2x_free_irq(bp); -load_error: +load_error1: + bnx2x_napi_disable(bp); bnx2x_free_mem(bp); - bp->port.pmf = 0; /* TBD we really need to reset the chip if we want to recover from this */ -- cgit From 6eccabb301d442e6106ecc84b07a976c2816d9fb Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 03:37:48 +0000 Subject: bnx2x: Carrier off first call Call carrier off should not be called after register_netdev since after register netdev open can be called at any time followed by an interrupt that will set it to carrier_on and the probe will resume control and set it to off Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 707c4bbe46a..fbd71659cca 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -9827,6 +9827,8 @@ static int bnx2x_open(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); + netif_carrier_off(dev); + bnx2x_set_power_state(bp, PCI_D0); return bnx2x_nic_load(bp, LOAD_OPEN); @@ -10332,8 +10334,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, goto init_one_exit; } - netif_carrier_off(dev); - bp->common.name = board_info[ent->driver_data].name; printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx," " IRQ %d, ", dev->name, bp->common.name, -- cgit From 7cde1c8b79f913a0158bae4f4c612de2cb98e7e4 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 06:01:25 +0000 Subject: bnx2x: Calling napi_del rmmod might hang without this patch since the reference counter is not going down Signed-off-by: Yitchak Gertner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index fbd71659cca..71fbf2dbda3 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6547,6 +6547,8 @@ load_error2: bnx2x_free_irq(bp); load_error1: bnx2x_napi_disable(bp); + for_each_queue(bp, i) + netif_napi_del(&bnx2x_fp(bp, i, napi)); bnx2x_free_mem(bp); /* TBD we really need to reset the chip @@ -6855,6 +6857,8 @@ unload_error: 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; @@ -10481,6 +10485,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) 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; -- cgit From 5650d9d4cbf3898d3f9725ccad5dfca6bc086324 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 06:01:29 +0000 Subject: bnx2x: Missing rmb when waiting for FW response Waiting for the FW to response requires a memory barrier Signed-off-by: Michal Kalderon Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 71fbf2dbda3..f71b8a5872b 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6622,6 +6622,7 @@ static int bnx2x_stop_leading(struct bnx2x *bp) } cnt--; msleep(1); + rmb(); /* Refresh the dsb_sp_prod */ } bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; bp->fp[0].state = BNX2X_FP_STATE_CLOSED; -- cgit From 3910c8ae44c59cebed721e33aa496f0a385b4e03 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 06:01:32 +0000 Subject: bnx2x: loopback test failure A link change interrupt might be queued and activated after the loopback was set and it will cause the loopback to fail. The PHY lock should be kept until the loopback test is over. That implies that the bnx2x_test_link should used within the loopback function and not bnx2x_wait_for_link since that function also takes the PHY link Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index f71b8a5872b..d95714f780f 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -8750,18 +8750,17 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) if (loopback_mode == BNX2X_MAC_LOOPBACK) { bp->link_params.loopback_mode = LOOPBACK_BMAC; - bnx2x_acquire_phy_lock(bp); bnx2x_phy_init(&bp->link_params, &bp->link_vars); - bnx2x_release_phy_lock(bp); } else if (loopback_mode == BNX2X_PHY_LOOPBACK) { + u16 cnt = 1000; bp->link_params.loopback_mode = LOOPBACK_XGXS_10; - bnx2x_acquire_phy_lock(bp); bnx2x_phy_init(&bp->link_params, &bp->link_vars); - bnx2x_release_phy_lock(bp); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); - + if (link_up) + while (cnt-- && bnx2x_test_link(&bp->link_params, + &bp->link_vars)) + msleep(10); } else return -EINVAL; @@ -8867,6 +8866,7 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) return BNX2X_LOOPBACK_FAILED; bnx2x_netif_stop(bp, 1); + bnx2x_acquire_phy_lock(bp); if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) { DP(NETIF_MSG_PROBE, "MAC loopback failed\n"); @@ -8878,6 +8878,7 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) rc |= BNX2X_PHY_LOOPBACK_FAILED; } + bnx2x_release_phy_lock(bp); bnx2x_netif_start(bp); return rc; -- cgit From 5422a2257350d984094e655b2361abed51a9ddc1 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 22 Jan 2009 06:01:37 +0000 Subject: bnx2x: Version Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index d95714f780f..4b84f6ce5ed 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -57,8 +57,8 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "1.45.24" -#define DRV_MODULE_RELDATE "2009/01/14" +#define DRV_MODULE_VERSION "1.45.25" +#define DRV_MODULE_RELDATE "2009/01/22" #define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung */ -- cgit From 6f051069d8a2045666055e3020ae8a7dec9762e0 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 22 Jan 2009 13:51:24 -0800 Subject: phylib: Fix oops in suspend/resume paths Suspend/resume routines check for phydrv != NULL, but that is wrong because "phydrv" comes from container_of(drv). If drv is NULL, then container_of(drv) will return non-NULL result, and the checks won't work. The Freescale TBI PHYs are driver-less, so "drv" is NULL, and that leads to the following oops: Unable to handle kernel paging request for data at address 0xffffffe4 Faulting instruction address: 0xc0215554 Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c0215554] mdio_bus_suspend+0x34/0x70 LR [c01cc508] suspend_device+0x258/0x2bc Call Trace: [cfad3da0] [cfad3db8] 0xcfad3db8 (unreliable) [cfad3db0] [c01cc508] suspend_device+0x258/0x2bc [cfad3dd0] [c01cc62c] dpm_suspend+0xc0/0x140 [cfad3e20] [c01cc6f4] device_suspend+0x48/0x5c [cfad3e40] [c0068dd8] suspend_devices_and_enter+0x8c/0x148 [cfad3e60] [c00690f8] enter_state+0x100/0x118 [cfad3e80] [c00691c0] state_store+0xb0/0xe4 [cfad3ea0] [c018c938] kobj_attr_store+0x24/0x3c [cfad3eb0] [c00ea9a8] flush_write_buffer+0x58/0x7c [cfad3ed0] [c00eadf0] sysfs_write_file+0x58/0xa0 [cfad3ef0] [c009e810] vfs_write+0xb4/0x16c [cfad3f10] [c009ed40] sys_write+0x4c/0x90 [cfad3f40] [c0014954] ret_from_syscall+0x0/0x38 [...] This patch fixes the issue, plus removes unneeded parentheses and fixes indentation level in mdio_bus_suspend(). Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 11adf6ed462..811a637695c 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -296,9 +296,8 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state) struct phy_driver *phydrv = to_phy_driver(drv); struct phy_device *phydev = to_phy_device(dev); - if ((!device_may_wakeup(phydev->dev.parent)) && - (phydrv && phydrv->suspend)) - ret = phydrv->suspend(phydev); + if (drv && phydrv->suspend && !device_may_wakeup(phydev->dev.parent)) + ret = phydrv->suspend(phydev); return ret; } @@ -310,8 +309,7 @@ static int mdio_bus_resume(struct device * dev) struct phy_driver *phydrv = to_phy_driver(drv); struct phy_device *phydev = to_phy_device(dev); - if ((!device_may_wakeup(phydev->dev.parent)) && - (phydrv && phydrv->resume)) + if (drv && phydrv->resume && !device_may_wakeup(phydev->dev.parent)) ret = phydrv->resume(phydev); return ret; -- cgit From c64d2a9afbccd0aecb122d108770a407fe7b7e3f Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 22 Jan 2009 14:07:43 -0800 Subject: phy: Add suspend/resume support to SMSC PHYs All supported SMSC PHYs implement the standard "power down" bit 11 of BMCR, so this patch adds support using the generic genphy_{suspend,resume} functions. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/phy/smsc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index c05d38d4635..1387187543e 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -81,6 +81,9 @@ static struct phy_driver lan83c185_driver = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, + .driver = { .owner = THIS_MODULE, } }; @@ -102,6 +105,9 @@ static struct phy_driver lan8187_driver = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, + .driver = { .owner = THIS_MODULE, } }; @@ -123,6 +129,9 @@ static struct phy_driver lan8700_driver = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, + .driver = { .owner = THIS_MODULE, } }; @@ -144,6 +153,9 @@ static struct phy_driver lan911x_int_driver = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + .suspend = genphy_suspend, + .resume = genphy_resume, + .driver = { .owner = THIS_MODULE, } }; -- cgit From b4068a80492022848c11123bf485aff5c902c583 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 20 Jan 2009 23:11:21 +0100 Subject: p54usb: fix packet loss with first generation devices Artur Skawina confirmed that the first generation devices needs the same URB_ZERO_PACKET flag, in oder to finish the pending transfer properly. The second generation has been successfully fixed by "p54usb: fix random traffic stalls (LM87)" (43af18f06d5) Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 4487cc5c928..5de2ebfb28c 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -229,6 +229,8 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb) usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), skb->data, skb->len, FREE_AFTER_TX(skb) ? p54u_tx_cb : p54u_tx_dummy_cb, skb); + addr_urb->transfer_flags |= URB_ZERO_PACKET; + data_urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(addr_urb, &priv->submitted); err = usb_submit_urb(addr_urb, GFP_ATOMIC); @@ -237,7 +239,7 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb) goto out; } - usb_anchor_urb(addr_urb, &priv->submitted); + usb_anchor_urb(data_urb, &priv->submitted); err = usb_submit_urb(data_urb, GFP_ATOMIC); if (err) usb_unanchor_urb(data_urb); @@ -332,12 +334,13 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb) * free what's inside the transfer_buffer after the callback routine * has completed. */ - int_urb->transfer_flags |= URB_FREE_BUFFER; + int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET; usb_fill_bulk_urb(data_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ? p54u_tx_cb : p54u_tx_dummy_cb, skb); + data_urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(int_urb, &priv->submitted); err = usb_submit_urb(int_urb, GFP_ATOMIC); -- cgit From c338ba3ca5bef2df2082d9e8d336ff7b2880c326 Mon Sep 17 00:00:00 2001 From: "Abbas, Mohamed" Date: Wed, 21 Jan 2009 10:58:02 -0800 Subject: iwlwifi: fix rs_get_rate WARN_ON() In ieee80211_sta structure there is u64 supp_rates[IEEE80211_NUM_BANDS] this is filled with all support rate from assoc_resp. If we associate with G-band AP only supp_rates of G-band will be set the other band supp_rates will be set to 0. If the user type this command this will cause mac80211 to set to new channel, mac80211 does not disassociate in setting new channel, so the active band is now A-band. then in handling the new essid mac80211 will kick in the assoc steps which involve sending disassociation frame. in this mac80211 will WARN_ON sta->supp_rates[A_BAND] == 0. This fixes: http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1822 http://www.kerneloops.org/searchweek.php?search=rs_get_rate Signed-off-by: mohamed abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 14 +++++++++++--- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 9b60a0c5de5..21c841847d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -638,12 +638,16 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, s8 scale_action = 0; unsigned long flags; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u16 fc, rate_mask; + u16 fc; + u16 rate_mask = 0; struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); IWL_DEBUG_RATE("enter\n"); + if (sta) + rate_mask = sta->supp_rates[sband->band]; + /* Send management frames and broadcast/multicast data using lowest * rate. */ fc = le16_to_cpu(hdr->frame_control); @@ -651,11 +655,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, is_multicast_ether_addr(hdr->addr1) || !sta || !priv_sta) { IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); - info->control.rates[0].idx = rate_lowest_index(sband, sta); + if (!rate_mask) + info->control.rates[0].idx = + rate_lowest_index(sband, NULL); + else + info->control.rates[0].idx = + rate_lowest_index(sband, sta); return; } - rate_mask = sta->supp_rates[sband->band]; index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); if (sband->band == IEEE80211_BAND_5GHZ) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index f3f17929ca0..27f50471aed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -944,7 +944,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, } /* See if there's a better rate or modulation mode to try. */ - rs_rate_scale_perform(priv, hdr, sta, lq_sta); + if (sta && sta->supp_rates[sband->band]) + rs_rate_scale_perform(priv, hdr, sta, lq_sta); out: return; } @@ -2101,14 +2102,23 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_lq_sta *lq_sta = priv_sta; int rate_idx; + u64 mask_bit = 0; IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); + if (sta) + mask_bit = sta->supp_rates[sband->band]; + /* Send management frames and broadcast/multicast data using lowest * rate. */ if (!ieee80211_is_data(hdr->frame_control) || is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) { - info->control.rates[0].idx = rate_lowest_index(sband, sta); + if (!mask_bit) + info->control.rates[0].idx = + rate_lowest_index(sband, NULL); + else + info->control.rates[0].idx = + rate_lowest_index(sband, sta); return; } -- cgit From 2fcbab044a3faf4d4a6e269148dd1f188303b206 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 23 Jan 2009 11:46:32 -0600 Subject: rtl8187: Add termination packet to prevent stall The RTL8187 and RTL8187B devices can stall unless an explicit termination packet is sent. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 6ad6bac3770..22bc07ef2f3 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -273,6 +273,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), buf, skb->len, rtl8187_tx_cb, skb); + urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(urb, &priv->anchored); rc = usb_submit_urb(urb, GFP_ATOMIC); if (rc < 0) { -- cgit From fb22d72782b023cda5e9876d3381f30932a64f91 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 22 Jan 2009 23:29:42 +0100 Subject: [NET] am79c961a: fix spin_lock usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit spin_lock functions take a pointer to the lock, not the lock itself. This error was noticed by compiling ebsa110_defconfig for linux-rt where the locking functions obviously are more picky about their arguments. Signed-off-by: Uwe Kleine-König Cc: Roel Kluin <12o3l@tiscali.nl> Cc: Steven Rostedt Cc: netdev@vger.kernel.org Signed-off-by: Russell King --- drivers/net/arm/am79c961a.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 0c628a9e533..c2d012fcc29 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -208,9 +208,9 @@ am79c961_init_for_open(struct net_device *dev) /* * Stop the chip. */ - spin_lock_irqsave(priv->chip_lock, flags); + spin_lock_irqsave(&priv->chip_lock, flags); write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP); - spin_unlock_irqrestore(priv->chip_lock, flags); + spin_unlock_irqrestore(&priv->chip_lock, flags); write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */ write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */ @@ -332,10 +332,10 @@ am79c961_close(struct net_device *dev) netif_stop_queue(dev); netif_carrier_off(dev); - spin_lock_irqsave(priv->chip_lock, flags); + spin_lock_irqsave(&priv->chip_lock, flags); write_rreg (dev->base_addr, CSR0, CSR0_STOP); write_rreg (dev->base_addr, CSR3, CSR3_MASKALL); - spin_unlock_irqrestore(priv->chip_lock, flags); + spin_unlock_irqrestore(&priv->chip_lock, flags); free_irq (dev->irq, dev); @@ -391,7 +391,7 @@ static void am79c961_setmulticastlist (struct net_device *dev) am79c961_mc_hash(dmi, multi_hash); } - spin_lock_irqsave(priv->chip_lock, flags); + spin_lock_irqsave(&priv->chip_lock, flags); stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP; @@ -405,9 +405,9 @@ static void am79c961_setmulticastlist (struct net_device *dev) * Spin waiting for chip to report suspend mode */ while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) { - spin_unlock_irqrestore(priv->chip_lock, flags); + spin_unlock_irqrestore(&priv->chip_lock, flags); nop(); - spin_lock_irqsave(priv->chip_lock, flags); + spin_lock_irqsave(&priv->chip_lock, flags); } } @@ -429,7 +429,7 @@ static void am79c961_setmulticastlist (struct net_device *dev) write_rreg(dev->base_addr, CTRL1, 0); } - spin_unlock_irqrestore(priv->chip_lock, flags); + spin_unlock_irqrestore(&priv->chip_lock, flags); } static void am79c961_timeout(struct net_device *dev) @@ -467,10 +467,10 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev) am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP); priv->txhead = head; - spin_lock_irqsave(priv->chip_lock, flags); + spin_lock_irqsave(&priv->chip_lock, flags); write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA); dev->trans_start = jiffies; - spin_unlock_irqrestore(priv->chip_lock, flags); + spin_unlock_irqrestore(&priv->chip_lock, flags); /* * If the next packet is owned by the ethernet device, -- cgit From e918085aaff34086e265f825dd469926b1aec4a4 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Sun, 25 Jan 2009 18:06:26 -0800 Subject: virtio_net: Fix MAX_PACKET_LEN to support 802.1Q VLANs 802.1Q expanded the maximum ethernet frame size by 4 bytes for the VLAN tag. We're not taking this into account in virtio_net, which means the buffers we provide to the backend in the virtqueue RX ring aren't big enough to hold a full MTU VLAN packet. For QEMU/KVM, this results in the backend exiting with a packet truncation error. Signed-off-by: Alex Williamson Acked-by: Mark McLoughlin Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 43f6523c40b..63ef2a8905f 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -24,6 +24,7 @@ #include #include #include +#include static int napi_weight = 128; module_param(napi_weight, int, 0444); @@ -33,7 +34,7 @@ module_param(csum, bool, 0444); module_param(gso, bool, 0444); /* FIXME: MTU in config. */ -#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) +#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN) #define GOOD_COPY_LEN 128 struct virtnet_info -- cgit From 78272bbab895cc8f63bab5181dee55b72208e3b7 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Mon, 26 Jan 2009 12:16:26 -0800 Subject: e1000e: workaround hw errata There is a hardware errata in some revisions of the 82574 that needs to be worked around in the driver by setting a register bit at init. If this bit is not set A0 versions of the 82574 can generate tx hangs. Signed-off-by: Jesse Brandeburg Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/82571.c | 6 +++++- drivers/net/e1000e/hw.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index cf43ee743b3..0890162953e 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -981,11 +981,15 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) ew32(PBA_ECC, reg); } - /* PCI-Ex Control Register */ + /* PCI-Ex Control Registers */ if (hw->mac.type == e1000_82574) { reg = er32(GCR); reg |= (1 << 22); ew32(GCR, reg); + + reg = er32(GCR2); + reg |= 1; + ew32(GCR2, reg); } return; diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index f25e961c6b3..2d4ce0492df 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -206,6 +206,7 @@ enum e1e_registers { E1000_MANC2H = 0x05860, /* Management Control To Host - RW */ E1000_SW_FW_SYNC = 0x05B5C, /* Software-Firmware Synchronization - RW */ E1000_GCR = 0x05B00, /* PCI-Ex Control */ + E1000_GCR2 = 0x05B64, /* PCI-Ex Control #2 */ E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ E1000_SWSM = 0x05B50, /* SW Semaphore */ E1000_FWSM = 0x05B54, /* FW Semaphore */ -- cgit From cdff1036492ac97b4213aeab2546914a633a7de7 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Mon, 26 Jan 2009 12:34:57 -0800 Subject: netxen: fix vlan tso/checksum offload o set netdev->vlan_features appropriately. o fix tso descriptor initialization for vlan case. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index d854f07ef4d..645d384fe87 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -735,17 +735,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); - /* ScatterGather support */ - netdev->features = NETIF_F_SG; - netdev->features |= NETIF_F_IP_CSUM; - netdev->features |= NETIF_F_TSO; + netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); + netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); + if (NX_IS_REVISION_P3(revision_id)) { - netdev->features |= NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_TSO6; + netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); + netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); } - if (adapter->pci_using_dac) + if (adapter->pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } /* * Set the CRB window to invalid. If any register in window 0 is @@ -1166,6 +1167,14 @@ static bool netxen_tso_check(struct net_device *netdev, { bool tso = false; u8 opcode = TX_ETHER_PKT; + __be16 protocol = skb->protocol; + u16 flags = 0; + + if (protocol == __constant_htons(ETH_P_8021Q)) { + struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data; + protocol = vh->h_vlan_encapsulated_proto; + flags = FLAGS_VLAN_TAGGED; + } if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && skb_shinfo(skb)->gso_size > 0) { @@ -1174,21 +1183,21 @@ static bool netxen_tso_check(struct net_device *netdev, desc->total_hdr_length = skb_transport_offset(skb) + tcp_hdrlen(skb); - opcode = (skb->protocol == htons(ETH_P_IPV6)) ? + opcode = (protocol == __constant_htons(ETH_P_IPV6)) ? TX_TCP_LSO6 : TX_TCP_LSO; tso = true; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { u8 l4proto; - if (skb->protocol == htons(ETH_P_IP)) { + if (protocol == __constant_htons(ETH_P_IP)) { l4proto = ip_hdr(skb)->protocol; if (l4proto == IPPROTO_TCP) opcode = TX_TCP_PKT; else if(l4proto == IPPROTO_UDP) opcode = TX_UDP_PKT; - } else if (skb->protocol == htons(ETH_P_IPV6)) { + } else if (protocol == __constant_htons(ETH_P_IPV6)) { l4proto = ipv6_hdr(skb)->nexthdr; if (l4proto == IPPROTO_TCP) @@ -1199,7 +1208,7 @@ static bool netxen_tso_check(struct net_device *netdev, } desc->tcp_hdr_offset = skb_transport_offset(skb); desc->ip_hdr_offset = skb_network_offset(skb); - netxen_set_tx_flags_opcode(desc, 0, opcode); + netxen_set_tx_flags_opcode(desc, flags, opcode); return tso; } -- cgit From 32ec803348b4d5f1353e1d7feae30880b8b3e342 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Mon, 26 Jan 2009 12:35:19 -0800 Subject: netxen: reduce memory footprint o reduce rx ring size from 8192 to 4096. o cut down old huge lro buffers. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 12 ++++++------ drivers/net/netxen/netxen_nic_ethtool.c | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index c11c568fd7d..a75a31005fd 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -146,7 +146,7 @@ #define MAX_RX_BUFFER_LENGTH 1760 #define MAX_RX_JUMBO_BUFFER_LENGTH 8062 -#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) +#define MAX_RX_LRO_BUFFER_LENGTH (8062) #define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2) #define RX_JUMBO_DMA_MAP_LEN \ (MAX_RX_JUMBO_BUFFER_LENGTH - 2) @@ -207,11 +207,11 @@ #define MAX_CMD_DESCRIPTORS 4096 #define MAX_RCV_DESCRIPTORS 16384 -#define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) -#define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) -#define MAX_RCV_DESCRIPTORS_10G 8192 -#define MAX_JUMBO_RCV_DESCRIPTORS 1024 -#define MAX_LRO_RCV_DESCRIPTORS 64 +#define MAX_CMD_DESCRIPTORS_HOST 1024 +#define MAX_RCV_DESCRIPTORS_1G 2048 +#define MAX_RCV_DESCRIPTORS_10G 4096 +#define MAX_JUMBO_RCV_DESCRIPTORS 512 +#define MAX_LRO_RCV_DESCRIPTORS 8 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index c0bd40fcf70..0894a7be022 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -561,7 +561,10 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) } ring->tx_pending = adapter->max_tx_desc_count; - ring->rx_max_pending = MAX_RCV_DESCRIPTORS; + if (adapter->ahw.board_type == NETXEN_NIC_GBE) + ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G; + else + ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G; ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST; ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS; ring->rx_mini_max_pending = 0; -- cgit From e8b5fc514d1c7637cb4b8f77e7d8ac33ef66130c Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 26 Jan 2009 12:36:42 -0800 Subject: bnx2x: tx_has_work should not wait for FW The current tx_has_work waited until all packets sent by the driver are marked as completed by the FW. This is too greedy and it causes the bnx2x_poll to spin in vain. The driver should only check that all packets FW already completed are freed - only in unload flow the driver should make sure that transmit queue is empty Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 4b84f6ce5ed..d3e7775a9cc 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -57,8 +57,8 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "1.45.25" -#define DRV_MODULE_RELDATE "2009/01/22" +#define DRV_MODULE_VERSION "1.45.26" +#define DRV_MODULE_RELDATE "2009/01/26" #define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung */ @@ -740,8 +740,15 @@ static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) /* Tell compiler that status block fields can change */ barrier(); tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb); - return ((fp->tx_pkt_prod != tx_cons_sb) || - (fp->tx_pkt_prod != fp->tx_pkt_cons)); + return (fp->tx_pkt_cons != tx_cons_sb); +} + +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 @@ -6729,7 +6736,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) cnt = 1000; smp_rmb(); - while (bnx2x_has_tx_work(fp)) { + while (bnx2x_has_tx_work_unload(fp)) { bnx2x_tx_int(fp, 1000); if (!cnt) { -- cgit From cd1f55a5b49b74e13ed9e7bc74d005803aaa0da8 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 26 Jan 2009 14:33:23 -0800 Subject: gianfar: Revive VLAN support commit 77ecaf2d5a8bfd548eed3f05c1c2e6573d5de4ba ("gianfar: Fix VLAN HW feature related frame/buffer size calculation") wrongly removed priv->vlgrp assignment, and now priv->vlgrp is always NULL. This patch fixes the issue, plus fixes following sparse warning introduced by the same commit: gianfar.c:1406:13: warning: context imbalance in 'gfar_vlan_rx_register' - wrong count at exit gfar_vlan_rx_register() checks for "if (old_grp == grp)" and tries to return w/o dropping the lock. According to net/8021q/vlan.c VLAN core issues rx_register() callback: 1. In register_vlan_dev() only on a newly created group; 2. In unregister_vlan_dev() only if the group becomes empty. Thus the check in the gianfar driver isn't needed. Signed-off-by: Anton Vorontsov Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index ea530673236..3f7eab42aef 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1423,15 +1423,11 @@ static void gfar_vlan_rx_register(struct net_device *dev, { struct gfar_private *priv = netdev_priv(dev); unsigned long flags; - struct vlan_group *old_grp; u32 tempval; spin_lock_irqsave(&priv->rxlock, flags); - old_grp = priv->vlgrp; - - if (old_grp == grp) - return; + priv->vlgrp = grp; if (grp) { /* Enable VLAN tag insertion */ -- cgit From 8527bec548e01a29c6d1928d20d6d3be71861482 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Mon, 26 Jan 2009 21:00:33 -0800 Subject: virtio_net: use correct accessors for scatterlists Without this fix, virtio_net makes incorrect usage of scatterlists. It sets the end of the scatterlist chain after the first element, despite the fact that more entries come after it. If you try to run dma_map_sg() on one of the scatterlists given to you by add_buf(), you will get a null pointer oops. Signed-off-by: Ira W. Snyder Signed-off-by: Rusty Russell Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 63ef2a8905f..c68808336c8 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -287,7 +287,7 @@ static void try_fill_recv_maxbufs(struct virtnet_info *vi) skb_put(skb, MAX_PACKET_LEN); hdr = skb_vnet_hdr(skb); - sg_init_one(sg, hdr, sizeof(*hdr)); + sg_set_buf(sg, hdr, sizeof(*hdr)); if (vi->big_packets) { for (i = 0; i < MAX_SKB_FRAGS; i++) { @@ -488,9 +488,9 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) /* Encode metadata header at front. */ if (vi->mergeable_rx_bufs) - sg_init_one(sg, mhdr, sizeof(*mhdr)); + sg_set_buf(sg, mhdr, sizeof(*mhdr)); else - sg_init_one(sg, hdr, sizeof(*hdr)); + sg_set_buf(sg, hdr, sizeof(*hdr)); num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; -- cgit From a7a41acf99d9150b424839b0d7b4f5ad9d211e2d Mon Sep 17 00:00:00 2001 From: Manish Katiyar Date: Mon, 26 Jan 2009 21:54:21 -0800 Subject: r6040: Remove unused variable pdev from drivers/net/r6040.c drivers/net/r6040.c:441: warning: unused variable 'pdev' Signed-off-by: Manish Katiyar Signed-off-by: David S. Miller --- drivers/net/r6040.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 72fd9e97c19..b2dcdb5ed8b 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -438,7 +438,6 @@ static void r6040_down(struct net_device *dev) { struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - struct pci_dev *pdev = lp->pdev; int limit = 2048; u16 *adrp; u16 cmd; -- cgit From d4732d3c59b84bb093e11c8f755f32801b4bf86d Mon Sep 17 00:00:00 2001 From: Matt Waddel Date: Tue, 13 Jan 2009 17:13:06 +1000 Subject: m68knommu: add ColdFire M532x to the FEC configuration options Signed-off-by: Matt Waddel Signed-off-by: Greg Ungerer --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9fe8cb7d43a..6bdfd47d679 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1829,7 +1829,7 @@ config 68360_ENET config FEC bool "FEC ethernet controller (of ColdFire CPUs)" - depends on M523x || M527x || M5272 || M528x || M520x + depends on M523x || M527x || M5272 || M528x || M520x || M532x help Say Y here if you want to use the built-in 10/100 Fast ethernet controller on some Motorola ColdFire processors. -- cgit From b9d57f94bb0ed56a5a2b58552a9ff4453013ff0b Mon Sep 17 00:00:00 2001 From: Matt Waddel Date: Tue, 13 Jan 2009 17:14:20 +1000 Subject: m68knommu: correct the mii calculations for 532x ColdFire FEC Signed-off-by: Matt Waddel Signed-off-by: Greg Ungerer --- drivers/net/fec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 7e33c129d51..2769083bfe8 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1698,7 +1698,7 @@ static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_priva /* * Set MII speed to 2.5 MHz */ - fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; + fep->phy_speed = (MCF_CLK / 3) / (2500000 * 2 ) * 2; fecp->fec_mii_speed = fep->phy_speed; fec_restart(dev, 0); -- cgit From 15b2bee22a0390d951301b53e83df88d0350c499 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 27 Jan 2009 16:41:58 -0800 Subject: e1000: fix bug with shared interrupt during reset A nasty bug was found where an MTU change (or anything else that caused a reset) could race with the interrupt code. The interrupt code was entered by a shared interrupt during the MTU change. This change prevents the interrupt code from running while the driver is in the middle of its reset path. Signed-off-by: Jesse Brandeburg Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 26474c92193..c986978ce76 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -31,7 +31,7 @@ char e1000_driver_name[] = "e1000"; static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -#define DRV_VERSION "7.3.20-k3-NAPI" +#define DRV_VERSION "7.3.21-k3-NAPI" const char e1000_driver_version[] = DRV_VERSION; static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -3712,7 +3712,7 @@ static irqreturn_t e1000_intr(int irq, void *data) struct e1000_hw *hw = &adapter->hw; u32 rctl, icr = er32(ICR); - if (unlikely(!icr)) + if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags))) return IRQ_NONE; /* Not our interrupt */ /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is -- cgit From a71558d0eca1bbb23737f832297926666f9b36db Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 27 Jan 2009 22:32:29 +0000 Subject: [ARM] etherh: continue fixing build failure Further to 483a2b3a3182abcb7fcea986d7ea13e793bb00b1, also fix: drivers/net/arm/etherh.c:649: error: 'eth_set_mac_addr' undeclared here (not in a function) Signed-off-by: Russell King --- drivers/net/arm/etherh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index d15d8b79d8e..54b52e5b182 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -646,7 +646,7 @@ static const struct net_device_ops etherh_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_set_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, -- cgit From eb83bbf57429ab80f49b413e3e44d3b19c3fdc5a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 27 Jan 2009 12:31:23 -0600 Subject: rtl8187: Fix error in setting OFDM power settings for RTL8187L MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After reports of poor performance, a review of the latest vendor driver (rtl8187_linux_26.1025.0328.2007) for RTL8187L devices was undertaken. A difference was found in the code used to index the OFDM power tables. When the Linux driver was changed, my unit works at a much greater range than before. I think this fixes Bugzilla #12380 and has been tested by at least two other users. Signed-off-by: Larry Finger Tested-by: Martín Ernesto Barreyro Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index 4e75e8e7fa9..78df281b297 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c @@ -285,7 +285,10 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) ofdm_power = priv->channels[channel - 1].hw_value >> 4; cck_power = min(cck_power, (u8)11); - ofdm_power = min(ofdm_power, (u8)35); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); @@ -536,7 +539,10 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) cck_power += priv->txpwr_base & 0xF; cck_power = min(cck_power, (u8)35); - ofdm_power = min(ofdm_power, (u8)15); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; ofdm_power += priv->txpwr_base >> 4; ofdm_power = min(ofdm_power, (u8)35); -- cgit From 1f304e4e3bb161163d9f5bc3c6467a2a6fa9b3ae Mon Sep 17 00:00:00 2001 From: "Zhu, Yi" Date: Fri, 23 Jan 2009 13:45:22 -0800 Subject: iwlwifi: fix kernel oops when ucode DMA memory allocation failure The patch fixes memcpy to NULL address when the ucode DMA allocation failure. This is a fix to bug http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1861 Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0dc8eed1640..b35c8813bef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1719,6 +1719,10 @@ static int iwl_read_ucode(struct iwl_priv *priv) priv->ucode_data_backup.len = data_size; iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || + !priv->ucode_data_backup.v_addr) + goto err_pci_alloc; + /* Initialization instructions and data */ if (init_size && init_data_size) { priv->ucode_init.len = init_size; -- cgit From be0093705c3ce98d73cac0ca8f93ea105cdf4e9c Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Thu, 22 Jan 2009 08:44:16 -0500 Subject: ath5k: fix locking in ath5k_config ath5k_config updates the software context without taking sc->lock. Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 8ef87356e08..a533ed60bb4 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1028,6 +1028,8 @@ ath5k_setup_bands(struct ieee80211_hw *hw) * it's done by reseting the chip. To accomplish this we must * first cleanup any pending DMA, then restart stuff after a la * ath5k_init. + * + * Called with sc->lock. */ static int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) @@ -2814,11 +2816,17 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) { struct ath5k_softc *sc = hw->priv; struct ieee80211_conf *conf = &hw->conf; + int ret; + + mutex_lock(&sc->lock); sc->bintval = conf->beacon_int; sc->power_level = conf->power_level; - return ath5k_chan_set(sc, conf->channel); + ret = ath5k_chan_set(sc, conf->channel); + + mutex_unlock(&sc->lock); + return ret; } static int -- cgit From e125646ab56b490d0390b158e0afa9cccfc1f897 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Thu, 29 Jan 2009 16:05:19 -0800 Subject: netxen: revert jumbo ringsize Reducing jumbo ring size below 1024 reduces throughput for old firmwares (3.4.216 and older) running on older (NX2031) chip, so restore it back to 1024. This was reduced in commit 32ec803348b4d5f1353e1d7feae30880b8b3e342 ("netxen: reduce memory footprint"). Raising jumbo ring size from 512 to 1024, adds ~4MB per port, but there's still big saving because of original patch (~20MB per port). Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index a75a31005fd..9c78c963b72 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -210,7 +210,7 @@ #define MAX_CMD_DESCRIPTORS_HOST 1024 #define MAX_RCV_DESCRIPTORS_1G 2048 #define MAX_RCV_DESCRIPTORS_10G 4096 -#define MAX_JUMBO_RCV_DESCRIPTORS 512 +#define MAX_JUMBO_RCV_DESCRIPTORS 1024 #define MAX_LRO_RCV_DESCRIPTORS 8 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS -- cgit From 584dbe9475313e117abf9d2af88164edfd429c9a Mon Sep 17 00:00:00 2001 From: Daniel Marjamäki Date: Thu, 29 Jan 2009 08:55:56 +0000 Subject: netxen: fix memory leak in drivers/net/netxen_nic_init.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For kernel bugzilla #12537: http://bugzilla.kernel.org/show_bug.cgi?id=12537 Free memory. Signed-off-by: Daniel Marjamäki Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index ca7c8d8050c..ffd37bea162 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -947,8 +947,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) } for (i = 0; i < n; i++) { if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || - netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) + netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { + kfree(buf); return -EIO; + } buf[i].addr = addr; buf[i].data = val; -- cgit From 1af7ad51049d6a310a19d497960597198290ddfa Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Thu, 29 Jan 2009 17:18:31 -0800 Subject: wimax: fix build issue when debugfs is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As reported by Toralf Förster and Randy Dunlap. - http://linuxwimax.org/pipermail/wimax/2009-January/000460.html - http://lkml.org/lkml/2009/1/29/279 The definitions needed for the wimax stack and i2400m driver debug infrastructure was, by mistake, compiled depending on CONFIG_DEBUG_FS (by them being placed in the debugfs.c files); thus the build broke in 2.6.29-rc3 when debugging was enabled (CONFIG_WIMAX_DEBUG) and DEBUG_FS was disabled. These definitions are always needed if debug is enabled at compile time (independently of DEBUG_FS being or not enabled), so moving them to a file that is always compiled fixes the issue. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/debugfs.c | 14 -------------- drivers/net/wimax/i2400m/driver.c | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c index 62663298597..9b81af3f80a 100644 --- a/drivers/net/wimax/i2400m/debugfs.c +++ b/drivers/net/wimax/i2400m/debugfs.c @@ -234,20 +234,6 @@ struct dentry *debugfs_create_i2400m_reset( &fops_i2400m_reset); } -/* - * Debug levels control; see debug.h - */ -struct d_level D_LEVEL[] = { - D_SUBMODULE_DEFINE(control), - D_SUBMODULE_DEFINE(driver), - D_SUBMODULE_DEFINE(debugfs), - D_SUBMODULE_DEFINE(fw), - D_SUBMODULE_DEFINE(netdev), - D_SUBMODULE_DEFINE(rfkill), - D_SUBMODULE_DEFINE(rx), - D_SUBMODULE_DEFINE(tx), -}; -size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); #define __debugfs_register(prefix, name, parent) \ do { \ diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index 5f98047e18c..e80a0b65a75 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -707,6 +707,22 @@ void i2400m_release(struct i2400m *i2400m) EXPORT_SYMBOL_GPL(i2400m_release); +/* + * Debug levels control; see debug.h + */ +struct d_level D_LEVEL[] = { + D_SUBMODULE_DEFINE(control), + D_SUBMODULE_DEFINE(driver), + D_SUBMODULE_DEFINE(debugfs), + D_SUBMODULE_DEFINE(fw), + D_SUBMODULE_DEFINE(netdev), + D_SUBMODULE_DEFINE(rfkill), + D_SUBMODULE_DEFINE(rx), + D_SUBMODULE_DEFINE(tx), +}; +size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); + + static int __init i2400m_driver_init(void) { -- cgit From b1c4a9dddf09fe99b8f88252718ac5b357363dc4 Mon Sep 17 00:00:00 2001 From: Haiying Wang Date: Thu, 29 Jan 2009 17:28:04 -0800 Subject: ucc_geth: Change uec phy id to the same format as gianfar's The commit b31a1d8b41513b96e9c7ec2f68c5734cef0b26a4 ("gianfar: Convert gianfar to an of_platform_driver") changes the gianfar's phy id to the format like "mdio@xxxx:xx", but uec still uses the old format like "xxxxxxxx:xx". For the board whose UEC uses gianfar-mdio like MPC8568MDS, the phy can not be attached because of the incompatible phy id format. This patch changes uec's phy id to the same format as gianfar's. Signed-off-by: Haiying Wang Signed-off-by: David S. Miller --- drivers/net/ucc_geth.c | 20 ++++++++++++++++++-- drivers/net/ucc_geth.h | 2 ++ drivers/net/ucc_geth_mii.c | 12 +++++++++++- drivers/net/ucc_geth_mii.h | 1 + 4 files changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 11441225bf4..e87986867ba 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1536,6 +1536,11 @@ static void adjust_link(struct net_device *dev) static int init_phy(struct net_device *dev) { struct ucc_geth_private *priv = netdev_priv(dev); + struct device_node *np = priv->node; + struct device_node *phy, *mdio; + const phandle *ph; + char bus_name[MII_BUS_ID_SIZE]; + const unsigned int *id; struct phy_device *phydev; char phy_id[BUS_ID_SIZE]; @@ -1543,8 +1548,18 @@ static int init_phy(struct net_device *dev) priv->oldspeed = 0; priv->oldduplex = -1; - snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->ug_info->mdio_bus, - priv->ug_info->phy_address); + ph = of_get_property(np, "phy-handle", NULL); + phy = of_find_node_by_phandle(*ph); + mdio = of_get_parent(phy); + + id = of_get_property(phy, "reg", NULL); + + of_node_put(phy); + of_node_put(mdio); + + uec_mdio_bus_name(bus_name, mdio); + snprintf(phy_id, sizeof(phy_id), "%s:%02x", + bus_name, *id); phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface); @@ -3748,6 +3763,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ugeth->ug_info = ug_info; ugeth->dev = dev; + ugeth->node = np; return 0; } diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 8f699cb773e..16cbe42ba43 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -1186,6 +1186,8 @@ struct ucc_geth_private { int oldspeed; int oldduplex; int oldlink; + + struct device_node *node; }; void uec_set_ethtool_ops(struct net_device *netdev); diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index c001d261366..54635911305 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c @@ -156,7 +156,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma if (err) goto reg_map_fail; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); + uec_mdio_bus_name(new_bus->id, np); new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL); @@ -283,3 +283,13 @@ void uec_mdio_exit(void) { of_unregister_platform_driver(&uec_mdio_driver); } + +void uec_mdio_bus_name(char *name, struct device_node *np) +{ + const u32 *reg; + + reg = of_get_property(np, "reg", NULL); + + snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0); +} + diff --git a/drivers/net/ucc_geth_mii.h b/drivers/net/ucc_geth_mii.h index 1e45b2028a5..840cf80235b 100644 --- a/drivers/net/ucc_geth_mii.h +++ b/drivers/net/ucc_geth_mii.h @@ -97,4 +97,5 @@ int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum); int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); int __init uec_mdio_init(void); void uec_mdio_exit(void); +void uec_mdio_bus_name(char *name, struct device_node *np); #endif /* __UEC_MII_H */ -- cgit From 1609559547ae0ddc2e4829c7f78ac2c4869875b9 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 29 Jan 2009 17:29:15 -0800 Subject: smsc9420: fix interrupt signalling test failures smsc9420 performs an interrupt signalling test when the interface is brought up. The current code mistakenly sets its test flag to false AFTER enabling the software interrupt source, making failure quite likely. This patch changes the code to set the test flag BEFORE enabling interrupts. I've also removed an smp_wmb because the following spinlock provides an implicit memory barrier. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc9420.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index c14a4c6452c..d801900a503 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -1378,6 +1378,7 @@ static int smsc9420_open(struct net_device *dev) /* test the IRQ connection to the ISR */ smsc_dbg(IFUP, "Testing ISR using IRQ %d", dev->irq); + pd->software_irq_signal = false; spin_lock_irqsave(&pd->int_lock, flags); /* configure interrupt deassertion timer and enable interrupts */ @@ -1393,8 +1394,6 @@ static int smsc9420_open(struct net_device *dev) smsc9420_pci_flush_write(pd); timeout = 1000; - pd->software_irq_signal = false; - smp_wmb(); while (timeout--) { if (pd->software_irq_signal) break; -- cgit From f307dbd88d82c4ccab7aec49613c366023b89cde Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 29 Jan 2009 17:30:00 -0800 Subject: smsc911x: timeout reaches -1 With a postfix decrement the timeout will reach -1 rather than 0, so the warning will not be issued. Signed-off-by: Roel Kluin Acked-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index f513bdf1c88..783c1a7b869 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -953,7 +953,7 @@ smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) do { udelay(1); val = smsc911x_reg_read(pdata, RX_DP_CTRL); - } while (timeout-- && (val & RX_DP_CTRL_RX_FFWD_)); + } while (--timeout && (val & RX_DP_CTRL_RX_FFWD_)); if (unlikely(timeout == 0)) SMSC_WARNING(HW, "Timed out waiting for " -- cgit From e5664bb2a7fd8ae1bee1281c2e44653c471af9ca Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 29 Jan 2009 17:31:13 -0800 Subject: gianfar: Fix Wake-on-LAN support commit 0f0ca340e57bd7446855fefd07a64249acf81223 ("phy: power management support") caused a regression in the gianfar driver. Now phylib turns off PHY power during suspend, and thus WOL doesn't work anymore. This patch workarounds the issue by enabling wakeup in the MDIO device, i.e. just restores the old behaviour for the gianfar driver. Note that this way all PHYs on a given MDIO bus won't be turned off during suspend, which isn't good from the power saving point of view. A proper, per netdevice wakeup management support will need a bit reworked phylib suspend/resume logic. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/gianfar_mii.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index f3706e415b4..f49a426ad68 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -234,6 +234,8 @@ static int gfar_mdio_probe(struct of_device *ofdev, if (NULL == new_bus) return -ENOMEM; + device_init_wakeup(&ofdev->dev, 1); + new_bus->name = "Gianfar MII Bus", new_bus->read = &gfar_mdio_read, new_bus->write = &gfar_mdio_write, -- cgit From c25b9abbc2c2c0da88e180c3933d6e773245815a Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 29 Jan 2009 17:32:20 -0800 Subject: drivers/net/skfp: if !capable(CAP_NET_ADMIN): inverted logic Fix inverted logic Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/skfp/skfddi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 607efeaf0bc..9a00e5566af 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -1003,9 +1003,9 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; case SKFP_CLR_STATS: /* Zero out the driver statistics */ if (!capable(CAP_NET_ADMIN)) { - memset(&lp->MacStat, 0, sizeof(lp->MacStat)); - } else { status = -EPERM; + } else { + memset(&lp->MacStat, 0, sizeof(lp->MacStat)); } break; default: -- cgit From f99ec0649accb581cf3e8fcfeea796e82d05f4ea Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Thu, 29 Jan 2009 17:35:04 -0800 Subject: tulip: fix 21142 with 10Mbps without negotiation with current kernels, tulip 21142 ethernet controllers fail to connect to a 10Mbps only (i.e. without negotiation-partner) network. It used to work in 2.4 kernels. Fix that. Tested on a 21142 Rev 0x11. Signed-off-by: Philippe De Muyter Signed-off-by: David S. Miller --- drivers/net/tulip/21142.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index 1210fb3748a..db7d5e11855 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c @@ -9,6 +9,11 @@ Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html} for more information on this driver. + + DC21143 manual "21143 PCI/CardBus 10/100Mb/s Ethernet LAN Controller + Hardware Reference Manual" is currently available at : + http://developer.intel.com/design/network/manuals/278074.htm + Please submit bugs to http://bugzilla.kernel.org/ . */ @@ -32,7 +37,11 @@ void t21142_media_task(struct work_struct *work) int csr12 = ioread32(ioaddr + CSR12); int next_tick = 60*HZ; int new_csr6 = 0; + int csr14 = ioread32(ioaddr + CSR14); + /* CSR12[LS10,LS100] are not reliable during autonegotiation */ + if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000) + csr12 |= 6; if (tulip_debug > 2) printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n", dev->name, csr12, medianame[dev->if_port]); @@ -76,7 +85,7 @@ void t21142_media_task(struct work_struct *work) new_csr6 = 0x83860000; dev->if_port = 3; iowrite32(0, ioaddr + CSR13); - iowrite32(0x0003FF7F, ioaddr + CSR14); + iowrite32(0x0003FFFF, ioaddr + CSR14); iowrite16(8, ioaddr + CSR15); iowrite32(1, ioaddr + CSR13); } @@ -132,10 +141,14 @@ void t21142_lnk_change(struct net_device *dev, int csr5) struct tulip_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->base_addr; int csr12 = ioread32(ioaddr + CSR12); + int csr14 = ioread32(ioaddr + CSR14); + /* CSR12[LS10,LS100] are not reliable during autonegotiation */ + if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000) + csr12 |= 6; if (tulip_debug > 1) printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, " - "%8.8x.\n", dev->name, csr12, csr5, ioread32(ioaddr + CSR14)); + "%8.8x.\n", dev->name, csr12, csr5, csr14); /* If NWay finished and we have a negotiated partner capability. */ if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { @@ -143,7 +156,9 @@ void t21142_lnk_change(struct net_device *dev, int csr5) int negotiated = tp->sym_advertise & (csr12 >> 16); tp->lpar = csr12 >> 16; tp->nwayset = 1; - if (negotiated & 0x0100) dev->if_port = 5; + /* If partner cannot negotiate, it is 10Mbps Half Duplex */ + if (!(csr12 & 0x8000)) dev->if_port = 0; + else if (negotiated & 0x0100) dev->if_port = 5; else if (negotiated & 0x0080) dev->if_port = 3; else if (negotiated & 0x0040) dev->if_port = 4; else if (negotiated & 0x0020) dev->if_port = 0; @@ -214,7 +229,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5) tp->timer.expires = RUN_AT(3*HZ); add_timer(&tp->timer); } else if (dev->if_port == 5) - iowrite32(ioread32(ioaddr + CSR14) & ~0x080, ioaddr + CSR14); + iowrite32(csr14 & ~0x080, ioaddr + CSR14); } else if (dev->if_port == 0 || dev->if_port == 4) { if ((csr12 & 4) == 0) printk(KERN_INFO"%s: 21143 10baseT link beat good.\n", -- cgit From a11da890e4c9850411303efcf6514f048ca880ee Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 30 Jan 2009 13:45:31 -0800 Subject: sky2: fix hard hang with netconsoling and iface going up Printing anything over netconsole before hw is up and running is, of course, not going to work. Signed-off-by: Alexey Dobriyan Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3668e81e474..994703cc0db 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1403,9 +1403,6 @@ static int sky2_up(struct net_device *dev) } - if (netif_msg_ifup(sky2)) - printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); - netif_carrier_off(dev); /* must be power of 2 */ @@ -1484,6 +1481,9 @@ static int sky2_up(struct net_device *dev) sky2_write32(hw, B0_IMSK, imask); sky2_set_multicast(dev); + + if (netif_msg_ifup(sky2)) + printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); return 0; err_out: -- cgit From 869b5b3888fbd2024af632e3648c00860ba3cca6 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 29 Jan 2009 17:48:10 +0000 Subject: sfc: SFT9001: Enable robust link training Enable a firmware option that appears to be necessary for reliable operation. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/tenxpress.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 9ecb77da954..19cfc318954 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -67,6 +67,8 @@ #define PMA_PMD_EXT_CLK312_WIDTH 1 #define PMA_PMD_EXT_LPOWER_LBN 12 #define PMA_PMD_EXT_LPOWER_WIDTH 1 +#define PMA_PMD_EXT_ROBUST_LBN 14 +#define PMA_PMD_EXT_ROBUST_WIDTH 1 #define PMA_PMD_EXT_SSR_LBN 15 #define PMA_PMD_EXT_SSR_WIDTH 1 @@ -284,7 +286,9 @@ static int tenxpress_init(struct efx_nic *efx) PMA_PMD_XCONTROL_REG); reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | (1 << PMA_PMD_EXT_CLK_OUT_LBN) | - (1 << PMA_PMD_EXT_CLK312_LBN)); + (1 << PMA_PMD_EXT_CLK312_LBN) | + (1 << PMA_PMD_EXT_ROBUST_LBN)); + mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, -- cgit From 2d18835d65b7433e7e6583f65395f8c01e7874af Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 29 Jan 2009 17:48:43 +0000 Subject: sfc: SFX7101: Remove workaround for bad link training Early versions of the SFX7101 firmware could complete link training in a state where it would not adequately cancel noise (Solarflare bug 10750). We previously worked around this by resetting the PHY after seeing many Ethernet CRC errors. This workaround is unsafe since it takes no account of the interval between errors; it also appears to be unnecessary with production firmware. Therefore remove it. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 4 ---- drivers/net/sfc/phy.h | 1 - drivers/net/sfc/tenxpress.c | 20 -------------------- drivers/net/sfc/workarounds.h | 3 --- 4 files changed, 28 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 5b9f2d9cc4e..ae7b0b48bfd 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -824,10 +824,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, rx_ev_pause_frm ? " [PAUSE]" : ""); } #endif - - if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) && - efx->phy_type == PHY_TYPE_SFX7101)) - tenxpress_crc_err(efx); } /* Handle receive events that are not in-order. */ diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index 58c493ef81b..07e855c148b 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h @@ -17,7 +17,6 @@ extern struct efx_phy_operations falcon_sfx7101_phy_ops; extern struct efx_phy_operations falcon_sft9001_phy_ops; extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); -extern void tenxpress_crc_err(struct efx_nic *efx); /**************************************************************************** * Exported functions from the driver for XFP optical PHYs diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 19cfc318954..80c8d6e3131 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -189,25 +189,12 @@ * rails */ #define LNPGA_PDOWN_WAIT (HZ / 5) -static int crc_error_reset_threshold = 100; -module_param(crc_error_reset_threshold, int, 0644); -MODULE_PARM_DESC(crc_error_reset_threshold, - "Max number of CRC errors before XAUI reset"); - struct tenxpress_phy_data { enum efx_loopback_mode loopback_mode; - atomic_t bad_crc_count; enum efx_phy_mode phy_mode; int bad_lp_tries; }; -void tenxpress_crc_err(struct efx_nic *efx) -{ - struct tenxpress_phy_data *phy_data = efx->phy_data; - if (phy_data != NULL) - atomic_inc(&phy_data->bad_crc_count); -} - static ssize_t show_phy_short_reach(struct device *dev, struct device_attribute *attr, char *buf) { @@ -627,13 +614,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx) if (phy_data->phy_mode != PHY_MODE_NORMAL) return; - - if (EFX_WORKAROUND_10750(efx) && - atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { - EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); - falcon_reset_xaui(efx); - atomic_set(&phy_data->bad_crc_count, 0); - } } static void tenxpress_phy_fini(struct efx_nic *efx) diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index 82e03e1d737..797a0cf7cd6 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -18,7 +18,6 @@ #define EFX_WORKAROUND_ALWAYS(efx) 1 #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) -#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101) #define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) /* XAUI resets if link not detected */ @@ -29,8 +28,6 @@ #define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G /* TX pkt parser problem with <= 16 byte TXes */ #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS -/* Low rate CRC errors require XAUI reset */ -#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101 /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor * or a PCIe error (bug 11028) */ #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS -- cgit From 8b9dc8dd447cfe27c0214761ced22a8e4aa58f5e Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 29 Jan 2009 17:49:09 +0000 Subject: sfc: SFT9001: Fix speed reporting in 1G PHY loopback Instead of disabling AN in loopback, just prevent restarting AN and override the speed in sft9001_get_settings(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/mdio_10g.c | 4 ++++ drivers/net/sfc/tenxpress.c | 27 +++++++++------------------ drivers/net/sfc/workarounds.h | 5 +++++ 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index f6a16428113..7f09ab58194 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -15,6 +15,7 @@ #include "net_driver.h" #include "mdio_10g.h" #include "boards.h" +#include "workarounds.h" int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, int spins, int spintime) @@ -517,6 +518,9 @@ int mdio_clause45_set_settings(struct efx_nic *efx, reg |= BMCR_ANENABLE | BMCR_ANRESTART; else reg &= ~BMCR_ANENABLE; + if (EFX_WORKAROUND_15195(efx) + && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) + reg &= ~BMCR_ANRESTART; if (xnp) reg |= 1 << MDIO_AN_CTRL_XNP_LBN; else diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 80c8d6e3131..bc2833f9cbe 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -511,7 +511,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) { struct tenxpress_phy_data *phy_data = efx->phy_data; struct ethtool_cmd ecmd; - bool phy_mode_change, loop_reset, loop_toggle, loopback; + bool phy_mode_change, loop_reset; if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { phy_data->phy_mode = efx->phy_mode; @@ -522,12 +522,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && phy_data->phy_mode != PHY_MODE_NORMAL); - loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks; - loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks); loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); - if (loop_reset || loop_toggle || loopback || phy_mode_change) { + if (loop_reset || phy_mode_change) { int rc; efx->phy_op->get_settings(efx, &ecmd); @@ -542,20 +540,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) falcon_reset_xaui(efx); } - if (efx->phy_type != PHY_TYPE_SFX7101) { - /* Only change autoneg once, on coming out or - * going into loopback */ - if (loop_toggle) - ecmd.autoneg = !loopback; - if (loopback) { - ecmd.duplex = DUPLEX_FULL; - if (efx->loopback_mode == LOOPBACK_GPHY) - ecmd.speed = SPEED_1000; - else - ecmd.speed = SPEED_10000; - } - } - rc = efx->phy_op->set_settings(efx, &ecmd); WARN_ON(rc); } @@ -813,6 +797,13 @@ static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ? DUPLEX_FULL : DUPLEX_HALF); } + + /* In loopback, the PHY automatically brings up the correct interface, + * but doesn't advertise the correct speed. So override it */ + if (efx->loopback_mode == LOOPBACK_GPHY) + ecmd->speed = SPEED_1000; + else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS) + ecmd->speed = SPEED_10000; } static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index 797a0cf7cd6..420fe153ea2 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -19,6 +19,8 @@ #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) #define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) +#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ + (efx)->phy_type == PHY_TYPE_SFT9001B) /* XAUI resets if link not detected */ #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS @@ -56,4 +58,7 @@ /* Need to keep AN enabled */ #define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A +/* Don't restart AN in near-side loopback */ +#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 + #endif /* EFX_WORKAROUNDS_H */ -- cgit From 2f08575389ac37ece5922094777442d8fdd8c00a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 29 Jan 2009 17:49:29 +0000 Subject: sfc: SFN4111T: Fix GPIO sharing between I2C and FLASH_CFG_1 Change sfn4111t_reset() to change only GPIO output enables so that it doesn't break subsequent I2C operations. Update comments to explain exactly what we're doing. Add a short sleep to make sure the FLASH_CFG_1 value is latched before any subsequent I2C operations. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/sfe4001.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 16b80acb999..c7c95db2af6 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c @@ -186,19 +186,22 @@ static int sfn4111t_reset(struct efx_nic *efx) { efx_oword_t reg; - /* GPIO pins are also used for I2C, so block that temporarily */ + /* GPIO 3 and the GPIO register are shared with I2C, so block that */ mutex_lock(&efx->i2c_adap.bus_lock); + /* Pull RST_N (GPIO 2) low then let it up again, setting the + * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the + * output enables; the output levels should always be 0 (low) + * and we rely on external pull-ups. */ falcon_read(efx, ®, GPIO_CTL_REG_KER); EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true); - EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false); falcon_write(efx, ®, GPIO_CTL_REG_KER); msleep(1000); - EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true); - EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true); - EFX_SET_OWORD_FIELD(reg, GPIO3_OUT, - !(efx->phy_mode & PHY_MODE_SPECIAL)); + EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false); + EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, + !!(efx->phy_mode & PHY_MODE_SPECIAL)); falcon_write(efx, ®, GPIO_CTL_REG_KER); + msleep(1); mutex_unlock(&efx->i2c_adap.bus_lock); -- cgit From 0cc128387969753ae037401eb49e4bbb474186ea Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 29 Jan 2009 17:49:59 +0000 Subject: sfc: Fix post-reset MAC selection Modify falcon_switch_mac() to always set NIC_STAT_REG, even if the the MAC is the same as it was before. This ensures that the value is correct after an online reset. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/falcon.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index ae7b0b48bfd..d9412f83a78 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2283,16 +2283,12 @@ int falcon_switch_mac(struct efx_nic *efx) efx->link_fd = true; } + WARN_ON(!mutex_is_locked(&efx->mac_lock)); efx->mac_op = (EFX_IS10G(efx) ? &falcon_xmac_operations : &falcon_gmac_operations); - if (old_mac_op == efx->mac_op) - return 0; - - WARN_ON(!mutex_is_locked(&efx->mac_lock)); - - /* Not all macs support a mac-level link state */ - efx->mac_up = true; + /* Always push the NIC_STAT_REG setting even if the mac hasn't + * changed, because this function is run post online reset */ falcon_read(efx, &nic_stat, NIC_STAT_REG); strap_val = EFX_IS10G(efx) ? 5 : 3; if (falcon_rev(efx) >= FALCON_REV_B0) { @@ -2305,8 +2301,13 @@ int falcon_switch_mac(struct efx_nic *efx) BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val); } + if (old_mac_op == efx->mac_op) + return 0; EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); + /* Not all macs support a mac-level link state */ + efx->mac_up = true; + return falcon_reset_macs(efx); } -- cgit From 4b988280be13a1b4c17f51cc66948aef467e7601 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 29 Jan 2009 17:50:51 +0000 Subject: sfc: Reinitialise the PHY completely in case of a PHY or NIC reset In particular, set pause advertising bits properly. A PHY reset is not necessary to recover from the register self-test, so use a "invisible" reset there instead. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 26 +++++++++++++++++++------- drivers/net/sfc/efx.h | 7 ++++--- drivers/net/sfc/selftest.c | 7 ++++--- drivers/net/sfc/tenxpress.c | 1 + 4 files changed, 28 insertions(+), 13 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 7673fd92eaf..b0e53087bda 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -676,9 +676,8 @@ static int efx_init_port(struct efx_nic *efx) rc = efx->phy_op->init(efx); if (rc) return rc; - efx->phy_op->reconfigure(efx); - mutex_lock(&efx->mac_lock); + efx->phy_op->reconfigure(efx); rc = falcon_switch_mac(efx); mutex_unlock(&efx->mac_lock); if (rc) @@ -1622,7 +1621,8 @@ static void efx_unregister_netdev(struct efx_nic *efx) /* Tears down the entire software state and most of the hardware state * before reset. */ -void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) +void efx_reset_down(struct efx_nic *efx, enum reset_type method, + struct ethtool_cmd *ecmd) { EFX_ASSERT_RESET_SERIALISED(efx); @@ -1639,6 +1639,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) efx->phy_op->get_settings(efx, ecmd); efx_fini_channels(efx); + if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) + efx->phy_op->fini(efx); } /* This function will always ensure that the locks acquired in @@ -1646,7 +1648,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) * that we were unable to reinitialise the hardware, and the * driver should be disabled. If ok is false, then the rx and tx * engines are not restarted, pending a RESET_DISABLE. */ -int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) +int efx_reset_up(struct efx_nic *efx, enum reset_type method, + struct ethtool_cmd *ecmd, bool ok) { int rc; @@ -1658,6 +1661,15 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) ok = false; } + if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) { + if (ok) { + rc = efx->phy_op->init(efx); + if (rc) + ok = false; + } else + efx->port_initialized = false; + } + if (ok) { efx_init_channels(efx); @@ -1702,7 +1714,7 @@ static int efx_reset(struct efx_nic *efx) EFX_INFO(efx, "resetting (%d)\n", method); - efx_reset_down(efx, &ecmd); + efx_reset_down(efx, method, &ecmd); rc = falcon_reset_hw(efx, method); if (rc) { @@ -1721,10 +1733,10 @@ static int efx_reset(struct efx_nic *efx) /* Leave device stopped if necessary */ if (method == RESET_TYPE_DISABLE) { - efx_reset_up(efx, &ecmd, false); + efx_reset_up(efx, method, &ecmd, false); rc = -EIO; } else { - rc = efx_reset_up(efx, &ecmd, true); + rc = efx_reset_up(efx, method, &ecmd, true); } out_disable: diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 0dd7a532c78..ac201587a16 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -40,9 +40,10 @@ extern void efx_reconfigure_port(struct efx_nic *efx); extern void __efx_reconfigure_port(struct efx_nic *efx); /* Reset handling */ -extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd); -extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, - bool ok); +extern void efx_reset_down(struct efx_nic *efx, enum reset_type method, + struct ethtool_cmd *ecmd); +extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, + struct ethtool_cmd *ecmd, bool ok); /* Global */ extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index dba0d64d50c..0a598084c51 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -665,6 +665,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, { enum efx_loopback_mode loopback_mode = efx->loopback_mode; int phy_mode = efx->phy_mode; + enum reset_type reset_method = RESET_TYPE_INVISIBLE; struct ethtool_cmd ecmd; struct efx_channel *channel; int rc_test = 0, rc_reset = 0, rc; @@ -718,21 +719,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, mutex_unlock(&efx->mac_lock); /* free up all consumers of SRAM (including all the queues) */ - efx_reset_down(efx, &ecmd); + efx_reset_down(efx, reset_method, &ecmd); rc = efx_test_chip(efx, tests); if (rc && !rc_test) rc_test = rc; /* reset the chip to recover from the register test */ - rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL); + rc_reset = falcon_reset_hw(efx, reset_method); /* Ensure that the phy is powered and out of loopback * for the bist and loopback tests */ efx->phy_mode &= ~PHY_MODE_LOW_POWER; efx->loopback_mode = LOOPBACK_NONE; - rc = efx_reset_up(efx, &ecmd, rc_reset == 0); + rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0); if (rc && !rc_reset) rc_reset = rc; diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index bc2833f9cbe..c9584619322 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -337,6 +337,7 @@ static int tenxpress_phy_init(struct efx_nic *efx) rc = tenxpress_init(efx); if (rc < 0) goto fail; + mdio_clause45_set_pause(efx); if (efx->phy_type == PHY_TYPE_SFT9001B) { rc = device_create_file(&efx->pci_dev->dev, -- cgit From 67797763c60bfe3bbf99ef81ce1042e71678d109 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 29 Jan 2009 17:51:15 +0000 Subject: sfc: Test for PHYXS faults whenever we cannot test link state bits Depending on the loopback mode, there may be no pertinent link state bits. In this case we test the PHYXS RX fault bit instead. Make sure to do this in all cases where there are no link state bits. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/mdio_10g.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 7f09ab58194..16bc5853d0e 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -180,17 +180,12 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) return false; else if (efx_phy_mode_disabled(efx->phy_mode)) return false; - else if (efx->loopback_mode == LOOPBACK_PHYXS) { + else if (efx->loopback_mode == LOOPBACK_PHYXS) mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | MDIO_MMDREG_DEVS_PCS | MDIO_MMDREG_DEVS_PMAPMD | MDIO_MMDREG_DEVS_AN); - if (!mmd_mask) { - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, - MDIO_PHYXS_STATUS2); - return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); - } - } else if (efx->loopback_mode == LOOPBACK_PCS) + else if (efx->loopback_mode == LOOPBACK_PCS) mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | MDIO_MMDREG_DEVS_PMAPMD | MDIO_MMDREG_DEVS_AN); @@ -198,6 +193,13 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD | MDIO_MMDREG_DEVS_AN); + if (!mmd_mask) { + /* Use presence of XGMII faults in leui of link state */ + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, + MDIO_PHYXS_STATUS2); + return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); + } + while (mmd_mask) { if (mmd_mask & 1) { /* Double reads because link state is latched, and a -- cgit From 44176b45d1aae04d99c505e6ee98d2d3c3fce173 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 29 Jan 2009 17:51:48 +0000 Subject: sfc: Update board info for hardware monitor on SFN4111T-R5 and later Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/sfe4001.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index c7c95db2af6..853057e87fb 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c @@ -375,17 +375,25 @@ static void sfn4111t_fini(struct efx_nic *efx) i2c_unregister_device(efx->board_info.hwmon_client); } -static struct i2c_board_info sfn4111t_hwmon_info = { +static struct i2c_board_info sfn4111t_a0_hwmon_info = { I2C_BOARD_INFO("max6647", 0x4e), .irq = -1, }; +static struct i2c_board_info sfn4111t_r5_hwmon_info = { + I2C_BOARD_INFO("max6646", 0x4d), + .irq = -1, +}; + int sfn4111t_init(struct efx_nic *efx) { int rc; efx->board_info.hwmon_client = - i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info); + i2c_new_device(&efx->i2c_adap, + (efx->board_info.minor < 5) ? + &sfn4111t_a0_hwmon_info : + &sfn4111t_r5_hwmon_info); if (!efx->board_info.hwmon_client) return -EIO; -- cgit From c9d5a53f060bb9ac6cd20d9768b4b75e22bc8689 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 29 Jan 2009 17:52:11 +0000 Subject: sfc: SFT9001: Always enable XNP exchange on SFT9001 rev B This workaround is not specific to rev A. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/workarounds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index 420fe153ea2..b810dcdf468 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -54,7 +54,7 @@ #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A /* Need to send XNP pages for 100BaseT */ -#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A +#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 /* Need to keep AN enabled */ #define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A -- cgit From af4ad9bca0c4039355b20d760b4fd39afa48c59d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 29 Jan 2009 17:59:37 +0000 Subject: sfc: SFX7101/SFT9001: Fix AN advertisements All 10Xpress PHYs require autonegotiation all the time; enforce this in the set_settings() method and do not treat it as a workaround. Remove claimed support for 100M HD mode since it is not supported by current firmware. Do not set speed override bits when AN is enabled, and do not use register 1.49192 for AN configuration as it can override what we set elsewhere. Always set the AN selector bits to 1 (802.3). Fix confusion between Next Page and Extended Next Page. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/ethtool.c | 3 - drivers/net/sfc/mdio_10g.c | 177 +++++++++++++++++++----------------------- drivers/net/sfc/mdio_10g.h | 3 +- drivers/net/sfc/net_driver.h | 4 +- drivers/net/sfc/tenxpress.c | 151 ++++++++++++++--------------------- drivers/net/sfc/workarounds.h | 4 - 6 files changed, 141 insertions(+), 201 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 53d259e9018..7b5924c039b 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev, struct efx_nic *efx = netdev_priv(net_dev); int rc; - if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg) - return -EINVAL; - /* Falcon GMAC does not support 1000Mbps HD */ if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 16bc5853d0e..f9e2f95c3b4 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -266,7 +266,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, } } -static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) +static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr) { int phy_id = efx->mii.phy_id; u32 result = 0; @@ -281,9 +281,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) result |= ADVERTISED_100baseT_Half; if (reg & ADVERTISE_100FULL) result |= ADVERTISED_100baseT_Full; - if (reg & LPA_RESV) - result |= xnp; - return result; } @@ -313,7 +310,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx, */ void mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd, - u32 xnp, u32 xnp_lpa) + u32 npage_adv, u32 npage_lpa) { int phy_id = efx->mii.phy_id; int reg; @@ -364,8 +361,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx, ecmd->autoneg = AUTONEG_ENABLE; ecmd->advertising |= ADVERTISED_Autoneg | - mdio_clause45_get_an(efx, - MDIO_AN_ADVERTISE, xnp); + mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) | + npage_adv; } else ecmd->autoneg = AUTONEG_DISABLE; } else @@ -374,27 +371,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx, if (ecmd->autoneg) { /* If AN is complete, report best common mode, * otherwise report best advertised mode. */ - u32 common = ecmd->advertising; + u32 modes = 0; if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_MMDREG_STAT1) & - (1 << MDIO_AN_STATUS_AN_DONE_LBN)) { - common &= mdio_clause45_get_an(efx, MDIO_AN_LPA, - xnp_lpa); - } - if (common & ADVERTISED_10000baseT_Full) { + (1 << MDIO_AN_STATUS_AN_DONE_LBN)) + modes = (ecmd->advertising & + (mdio_clause45_get_an(efx, MDIO_AN_LPA) | + npage_lpa)); + if (modes == 0) + modes = ecmd->advertising; + + if (modes & ADVERTISED_10000baseT_Full) { ecmd->speed = SPEED_10000; ecmd->duplex = DUPLEX_FULL; - } else if (common & (ADVERTISED_1000baseT_Full | - ADVERTISED_1000baseT_Half)) { + } else if (modes & (ADVERTISED_1000baseT_Full | + ADVERTISED_1000baseT_Half)) { ecmd->speed = SPEED_1000; - ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full); - } else if (common & (ADVERTISED_100baseT_Full | - ADVERTISED_100baseT_Half)) { + ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); + } else if (modes & (ADVERTISED_100baseT_Full | + ADVERTISED_100baseT_Half)) { ecmd->speed = SPEED_100; - ecmd->duplex = !!(common & ADVERTISED_100baseT_Full); + ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); } else { ecmd->speed = SPEED_10; - ecmd->duplex = !!(common & ADVERTISED_10baseT_Full); + ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); } } else { /* Report forced settings */ @@ -418,7 +418,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx, int phy_id = efx->mii.phy_id; struct ethtool_cmd prev; u32 required; - int ctrl1_bits, reg; + int reg; efx->phy_op->get_settings(efx, &prev); @@ -433,102 +433,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx, if (prev.port != PORT_TP || ecmd->port != PORT_TP) return -EINVAL; - /* Check that PHY supports these settings and work out the - * basic control bits */ - if (ecmd->duplex) { + /* Check that PHY supports these settings */ + if (ecmd->autoneg) { + required = SUPPORTED_Autoneg; + } else if (ecmd->duplex) { switch (ecmd->speed) { - case SPEED_10: - ctrl1_bits = BMCR_FULLDPLX; - required = SUPPORTED_10baseT_Full; - break; - case SPEED_100: - ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX; - required = SUPPORTED_100baseT_Full; - break; - case SPEED_1000: - ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX; - required = SUPPORTED_1000baseT_Full; - break; - case SPEED_10000: - ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 | - BMCR_FULLDPLX); - required = SUPPORTED_10000baseT_Full; - break; - default: - return -EINVAL; + case SPEED_10: required = SUPPORTED_10baseT_Full; break; + case SPEED_100: required = SUPPORTED_100baseT_Full; break; + default: return -EINVAL; } } else { switch (ecmd->speed) { - case SPEED_10: - ctrl1_bits = 0; - required = SUPPORTED_10baseT_Half; - break; - case SPEED_100: - ctrl1_bits = BMCR_SPEED100; - required = SUPPORTED_100baseT_Half; - break; - case SPEED_1000: - ctrl1_bits = BMCR_SPEED1000; - required = SUPPORTED_1000baseT_Half; - break; - default: - return -EINVAL; + case SPEED_10: required = SUPPORTED_10baseT_Half; break; + case SPEED_100: required = SUPPORTED_100baseT_Half; break; + default: return -EINVAL; } } - if (ecmd->autoneg) - required |= SUPPORTED_Autoneg; required |= ecmd->advertising; if (required & ~prev.supported) return -EINVAL; - /* Set the basic control bits */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_CTRL1); - reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c); - reg |= ctrl1_bits; - mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1, - reg); - - /* Set the AN registers */ - if (ecmd->autoneg != prev.autoneg || - ecmd->advertising != prev.advertising) { - bool xnp = false; - - if (efx->phy_op->set_xnp_advertise) - xnp = efx->phy_op->set_xnp_advertise(efx, - ecmd->advertising); - - if (ecmd->autoneg) { - reg = 0; - if (ecmd->advertising & ADVERTISED_10baseT_Half) - reg |= ADVERTISE_10HALF; - if (ecmd->advertising & ADVERTISED_10baseT_Full) - reg |= ADVERTISE_10FULL; - if (ecmd->advertising & ADVERTISED_100baseT_Half) - reg |= ADVERTISE_100HALF; - if (ecmd->advertising & ADVERTISED_100baseT_Full) - reg |= ADVERTISE_100FULL; - if (xnp) - reg |= ADVERTISE_RESV; - mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_ADVERTISE, reg); - } + if (ecmd->autoneg) { + bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full + || EFX_WORKAROUND_13204(efx)); + + /* Set up the base page */ + reg = ADVERTISE_CSMA; + if (ecmd->advertising & ADVERTISED_10baseT_Half) + reg |= ADVERTISE_10HALF; + if (ecmd->advertising & ADVERTISED_10baseT_Full) + reg |= ADVERTISE_10FULL; + if (ecmd->advertising & ADVERTISED_100baseT_Half) + reg |= ADVERTISE_100HALF; + if (ecmd->advertising & ADVERTISED_100baseT_Full) + reg |= ADVERTISE_100FULL; + if (xnp) + reg |= ADVERTISE_RESV; + else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full)) + reg |= ADVERTISE_NPAGE; + reg |= efx_fc_advertise(efx->wanted_fc); + mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, + MDIO_AN_ADVERTISE, reg); + + /* Set up the (extended) next page if necessary */ + if (efx->phy_op->set_npage_adv) + efx->phy_op->set_npage_adv(efx, ecmd->advertising); + /* Enable and restart AN */ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_MMDREG_CTRL1); - if (ecmd->autoneg) - reg |= BMCR_ANENABLE | BMCR_ANRESTART; - else - reg &= ~BMCR_ANENABLE; - if (EFX_WORKAROUND_15195(efx) - && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) - reg &= ~BMCR_ANRESTART; + reg |= BMCR_ANENABLE; + if (!(EFX_WORKAROUND_15195(efx) && + LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) + reg |= BMCR_ANRESTART; if (xnp) reg |= 1 << MDIO_AN_CTRL_XNP_LBN; else reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, MDIO_MMDREG_CTRL1, reg); + } else { + /* Disable AN */ + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, + MDIO_MMDREG_CTRL1, + __ffs(BMCR_ANENABLE), false); + + /* Set the basic control bits */ + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, + MDIO_MMDREG_CTRL1); + reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | + 0x003c); + if (ecmd->speed == SPEED_100) + reg |= BMCR_SPEED100; + if (ecmd->duplex) + reg |= BMCR_FULLDPLX; + mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, + MDIO_MMDREG_CTRL1, reg); } return 0; diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 09bf801d056..8ba49773ce7 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h @@ -155,7 +155,8 @@ #define MDIO_AN_XNP 22 #define MDIO_AN_LPA_XNP 25 -#define MDIO_AN_10GBT_ADVERTISE 32 +#define MDIO_AN_10GBT_CTRL 32 +#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12 #define MDIO_AN_10GBT_STATUS (33) #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 5f255f75754..8eb411a1c82 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -566,7 +566,7 @@ struct efx_mac_operations { * @poll: Poll for hardware state. Serialised by the mac_lock. * @get_settings: Get ethtool settings. Serialised by the mac_lock. * @set_settings: Set ethtool settings. Serialised by the mac_lock. - * @set_xnp_advertise: Set abilities advertised in Extended Next Page + * @set_npage_adv: Set abilities advertised in (Extended) Next Page * (only needed where AN bit is set in mmds) * @num_tests: Number of PHY-specific tests/results * @test_names: Names of the tests/results @@ -586,7 +586,7 @@ struct efx_phy_operations { struct ethtool_cmd *ecmd); int (*set_settings) (struct efx_nic *efx, struct ethtool_cmd *ecmd); - bool (*set_xnp_advertise) (struct efx_nic *efx, u32); + void (*set_npage_adv) (struct efx_nic *efx, u32); u32 num_tests; const char *const *test_names; int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index c9584619322..412d209d831 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -179,11 +179,13 @@ #define C22EXT_STATUS_LINK_LBN 2 #define C22EXT_STATUS_LINK_WIDTH 1 -#define C22EXT_MSTSLV_REG 49162 -#define C22EXT_MSTSLV_1000_HD_LBN 10 -#define C22EXT_MSTSLV_1000_HD_WIDTH 1 -#define C22EXT_MSTSLV_1000_FD_LBN 11 -#define C22EXT_MSTSLV_1000_FD_WIDTH 1 +#define C22EXT_MSTSLV_CTRL 49161 +#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8 +#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9 + +#define C22EXT_MSTSLV_STATUS 49162 +#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10 +#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11 /* Time to wait between powering down the LNPGA and turning off the power * rails */ @@ -741,114 +743,76 @@ reset: return rc; } -static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) +static void +tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { - int phy = efx->mii.phy_id; - u32 lpa = 0; + int phy_id = efx->mii.phy_id; + u32 adv = 0, lpa = 0; int reg; if (efx->phy_type != PHY_TYPE_SFX7101) { - reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT, - C22EXT_MSTSLV_REG); - if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN)) + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, + C22EXT_MSTSLV_CTRL); + if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) + adv |= ADVERTISED_1000baseT_Full; + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, + C22EXT_MSTSLV_STATUS); + if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) lpa |= ADVERTISED_1000baseT_Half; - if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN)) + if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) lpa |= ADVERTISED_1000baseT_Full; } - reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, + MDIO_AN_10GBT_CTRL); + if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN)) + adv |= ADVERTISED_10000baseT_Full; + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, + MDIO_AN_10GBT_STATUS); if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) lpa |= ADVERTISED_10000baseT_Full; - return lpa; -} - -static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) -{ - mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full, - tenxpress_get_xnp_lpa(efx)); - ecmd->supported |= SUPPORTED_10000baseT_Full; - ecmd->advertising |= ADVERTISED_10000baseT_Full; -} - -static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) -{ - int phy_id = efx->mii.phy_id; - u32 xnp_adv = 0; - int reg; - - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_SPEED_ENABLE_REG); - if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN))) - xnp_adv |= ADVERTISED_100baseT_Full; - if (reg & (1 << PMA_PMD_1000T_ADV_LBN)) - xnp_adv |= ADVERTISED_1000baseT_Full; - if (reg & (1 << PMA_PMD_10000T_ADV_LBN)) - xnp_adv |= ADVERTISED_10000baseT_Full; - - mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv, - tenxpress_get_xnp_lpa(efx)); - ecmd->supported |= (SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full); + mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa); - /* Use the vendor defined C22ext register for duplex settings */ - if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) { - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, - GPHY_XCONTROL_REG); - ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ? - DUPLEX_FULL : DUPLEX_HALF); - } + if (efx->phy_type != PHY_TYPE_SFX7101) + ecmd->supported |= (SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full); /* In loopback, the PHY automatically brings up the correct interface, * but doesn't advertise the correct speed. So override it */ if (efx->loopback_mode == LOOPBACK_GPHY) ecmd->speed = SPEED_1000; - else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS) + else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) ecmd->speed = SPEED_10000; } -static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) +static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { - int phy_id = efx->mii.phy_id; - int rc; - - rc = mdio_clause45_set_settings(efx, ecmd); - if (rc) - return rc; + if (!ecmd->autoneg) + return -EINVAL; - if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, - GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN, - ecmd->duplex == DUPLEX_FULL); + return mdio_clause45_set_settings(efx, ecmd); +} - return rc; +static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) +{ + mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, + MDIO_AN_10GBT_CTRL, + MDIO_AN_10GBT_CTRL_ADV_10G_LBN, + advertising & ADVERTISED_10000baseT_Full); } -static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) +static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) { - int phy = efx->mii.phy_id; - int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD, - PMA_PMD_SPEED_ENABLE_REG); - bool enabled; - - reg &= ~((1 << 2) | (1 << 3)); - if (EFX_WORKAROUND_13204(efx) && - (advertising & ADVERTISED_100baseT_Full)) - reg |= 1 << PMA_PMD_100TX_ADV_LBN; - if (advertising & ADVERTISED_1000baseT_Full) - reg |= 1 << PMA_PMD_1000T_ADV_LBN; - if (advertising & ADVERTISED_10000baseT_Full) - reg |= 1 << PMA_PMD_10000T_ADV_LBN; - mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD, - PMA_PMD_SPEED_ENABLE_REG, reg); - - enabled = (advertising & - (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full | - ADVERTISED_10000baseT_Full)); - if (EFX_WORKAROUND_13204(efx)) - enabled |= (advertising & ADVERTISED_100baseT_Full); - return enabled; + int phy_id = efx->mii.phy_id; + + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, + C22EXT_MSTSLV_CTRL, + C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, + advertising & ADVERTISED_1000baseT_Full); + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, + MDIO_AN_10GBT_CTRL, + MDIO_AN_10GBT_CTRL_ADV_10G_LBN, + advertising & ADVERTISED_10000baseT_Full); } struct efx_phy_operations falcon_sfx7101_phy_ops = { @@ -858,8 +822,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { .poll = tenxpress_phy_poll, .fini = tenxpress_phy_fini, .clear_interrupt = efx_port_dummy_op_void, - .get_settings = sfx7101_get_settings, - .set_settings = mdio_clause45_set_settings, + .get_settings = tenxpress_get_settings, + .set_settings = tenxpress_set_settings, + .set_npage_adv = sfx7101_set_npage_adv, .num_tests = ARRAY_SIZE(sfx7101_test_names), .test_names = sfx7101_test_names, .run_tests = sfx7101_run_tests, @@ -874,9 +839,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = { .poll = tenxpress_phy_poll, .fini = tenxpress_phy_fini, .clear_interrupt = efx_port_dummy_op_void, - .get_settings = sft9001_get_settings, - .set_settings = sft9001_set_settings, - .set_xnp_advertise = sft9001_set_xnp_advertise, + .get_settings = tenxpress_get_settings, + .set_settings = tenxpress_set_settings, + .set_npage_adv = sft9001_set_npage_adv, .num_tests = ARRAY_SIZE(sft9001_test_names), .test_names = sft9001_test_names, .run_tests = sft9001_run_tests, diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index b810dcdf468..78de68f4a95 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -18,7 +18,6 @@ #define EFX_WORKAROUND_ALWAYS(efx) 1 #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) -#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) #define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ (efx)->phy_type == PHY_TYPE_SFT9001B) @@ -55,9 +54,6 @@ /* Need to send XNP pages for 100BaseT */ #define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 -/* Need to keep AN enabled */ -#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A - /* Don't restart AN in near-side loopback */ #define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 -- cgit From 1974cc205e63cec4a17a6b3fca31fa4240ded77e Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 29 Jan 2009 18:00:07 +0000 Subject: sfc: Replace stats_enabled flag with a disable count Currently we use a spin-lock to serialise statistics fetches and also to inhibit them for short periods of time, plus a flag to enable/disable statistics fetches for longer periods of time, during online reset. This was apparently insufficient to deal with the several reasons for stats being disabled. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 33 ++++++++++++++++++++++----------- drivers/net/sfc/efx.h | 2 ++ drivers/net/sfc/falcon.c | 15 +++++++++++---- drivers/net/sfc/net_driver.h | 5 ++--- drivers/net/sfc/sfe4001.c | 15 ++++++++++++++- drivers/net/sfc/tenxpress.c | 12 ++++++------ 6 files changed, 57 insertions(+), 25 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index b0e53087bda..ab0e09bf154 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -685,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx) efx->mac_op->reconfigure(efx); efx->port_initialized = true; - efx->stats_enabled = true; + efx_stats_enable(efx); return 0; fail: @@ -734,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx) if (!efx->port_initialized) return; + efx_stats_disable(efx); efx->phy_op->fini(efx); efx->port_initialized = false; @@ -1360,6 +1361,20 @@ static int efx_net_stop(struct net_device *net_dev) return 0; } +void efx_stats_disable(struct efx_nic *efx) +{ + spin_lock(&efx->stats_lock); + ++efx->stats_disable_count; + spin_unlock(&efx->stats_lock); +} + +void efx_stats_enable(struct efx_nic *efx) +{ + spin_lock(&efx->stats_lock); + --efx->stats_disable_count; + spin_unlock(&efx->stats_lock); +} + /* Context: process, dev_base_lock or RTNL held, non-blocking. */ static struct net_device_stats *efx_net_stats(struct net_device *net_dev) { @@ -1368,12 +1383,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev) struct net_device_stats *stats = &net_dev->stats; /* Update stats if possible, but do not wait if another thread - * is updating them (or resetting the NIC); slightly stale - * stats are acceptable. + * is updating them or if MAC stats fetches are temporarily + * disabled; slightly stale stats are acceptable. */ if (!spin_trylock(&efx->stats_lock)) return stats; - if (efx->stats_enabled) { + if (!efx->stats_disable_count) { efx->mac_op->update_stats(efx); falcon_update_nic_stats(efx); } @@ -1626,12 +1641,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method, { EFX_ASSERT_RESET_SERIALISED(efx); - /* The net_dev->get_stats handler is quite slow, and will fail - * if a fetch is pending over reset. Serialise against it. */ - spin_lock(&efx->stats_lock); - efx->stats_enabled = false; - spin_unlock(&efx->stats_lock); - + efx_stats_disable(efx); efx_stop_all(efx); mutex_lock(&efx->mac_lock); mutex_lock(&efx->spi_lock); @@ -1682,7 +1692,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, if (ok) { efx_start_all(efx); - efx->stats_enabled = true; + efx_stats_enable(efx); } return rc; } @@ -1888,6 +1898,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, efx->rx_checksum_enabled = true; spin_lock_init(&efx->netif_stop_lock); spin_lock_init(&efx->stats_lock); + efx->stats_disable_count = 1; mutex_init(&efx->mac_lock); efx->mac_op = &efx_dummy_mac_operations; efx->phy_op = &efx_dummy_phy_operations; diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index ac201587a16..55d0f131b0e 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -36,6 +36,8 @@ extern void efx_process_channel_now(struct efx_channel *channel); extern void efx_flush_queues(struct efx_nic *efx); /* Ports */ +extern void efx_stats_disable(struct efx_nic *efx); +extern void efx_stats_enable(struct efx_nic *efx); extern void efx_reconfigure_port(struct efx_nic *efx); extern void __efx_reconfigure_port(struct efx_nic *efx); diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index d9412f83a78..d5378e60fcd 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1883,7 +1883,7 @@ static int falcon_reset_macs(struct efx_nic *efx) /* MAC stats will fail whilst the TX fifo is draining. Serialise * the drain sequence with the statistics fetch */ - spin_lock(&efx->stats_lock); + efx_stats_disable(efx); falcon_read(efx, ®, MAC0_CTRL_REG_KER); EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1); @@ -1913,7 +1913,7 @@ static int falcon_reset_macs(struct efx_nic *efx) udelay(10); } - spin_unlock(&efx->stats_lock); + efx_stats_enable(efx); /* If we've reset the EM block and the link is up, then * we'll have to kick the XAUI link so the PHY can recover */ @@ -2273,6 +2273,10 @@ int falcon_switch_mac(struct efx_nic *efx) struct efx_mac_operations *old_mac_op = efx->mac_op; efx_oword_t nic_stat; unsigned strap_val; + int rc = 0; + + /* Don't try to fetch MAC stats while we're switching MACs */ + efx_stats_disable(efx); /* Internal loopbacks override the phy speed setting */ if (efx->loopback_mode == LOOPBACK_GMAC) { @@ -2302,13 +2306,16 @@ int falcon_switch_mac(struct efx_nic *efx) } if (old_mac_op == efx->mac_op) - return 0; + goto out; EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); /* Not all macs support a mac-level link state */ efx->mac_up = true; - return falcon_reset_macs(efx); + rc = falcon_reset_macs(efx); +out: + efx_stats_enable(efx); + return rc; } /* This call is responsible for hooking in the MAC and PHY operations */ diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 8eb411a1c82..e019ad1fb9a 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -754,8 +754,7 @@ union efx_multicast_hash { * &struct net_device_stats. * @stats_buffer: DMA buffer for statistics * @stats_lock: Statistics update lock. Serialises statistics fetches - * @stats_enabled: Temporarily disable statistics fetches. - * Serialised by @stats_lock + * @stats_disable_count: Nest count for disabling statistics fetches * @mac_op: MAC interface * @mac_address: Permanent MAC address * @phy_type: PHY type @@ -837,7 +836,7 @@ struct efx_nic { struct efx_mac_stats mac_stats; struct efx_buffer stats_buffer; spinlock_t stats_lock; - bool stats_enabled; + unsigned int stats_disable_count; struct efx_mac_operations *mac_op; unsigned char mac_address[ETH_ALEN]; diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 853057e87fb..cb25ae5b257 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c @@ -235,12 +235,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev, } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { err = -EBUSY; } else { + /* Reset the PHY, reconfigure the MAC and enable/disable + * MAC stats accordingly. */ efx->phy_mode = new_mode; + if (new_mode & PHY_MODE_SPECIAL) + efx_stats_disable(efx); if (efx->board_info.type == EFX_BOARD_SFE4001) err = sfe4001_poweron(efx); else err = sfn4111t_reset(efx); efx_reconfigure_port(efx); + if (!(new_mode & PHY_MODE_SPECIAL)) + efx_stats_enable(efx); } rtnl_unlock(); @@ -329,6 +335,11 @@ int sfe4001_init(struct efx_nic *efx) efx->board_info.monitor = sfe4001_check_hw; efx->board_info.fini = sfe4001_fini; + if (efx->phy_mode & PHY_MODE_SPECIAL) { + /* PHY won't generate a 156.25 MHz clock and MAC stats fetch + * will fail. */ + efx_stats_disable(efx); + } rc = sfe4001_poweron(efx); if (rc) goto fail_ioexp; @@ -405,8 +416,10 @@ int sfn4111t_init(struct efx_nic *efx) if (rc) goto fail_hwmon; - if (efx->phy_mode & PHY_MODE_SPECIAL) + if (efx->phy_mode & PHY_MODE_SPECIAL) { + efx_stats_disable(efx); sfn4111t_reset(efx); + } return 0; diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 412d209d831..f0efd246962 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -370,8 +370,8 @@ static int tenxpress_special_reset(struct efx_nic *efx) /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so * a special software reset can glitch the XGMAC sufficiently for stats - * requests to fail. Since we don't often special_reset, just lock. */ - spin_lock(&efx->stats_lock); + * requests to fail. */ + efx_stats_disable(efx); /* Initiate reset */ reg = mdio_clause45_read(efx, efx->mii.phy_id, @@ -386,17 +386,17 @@ static int tenxpress_special_reset(struct efx_nic *efx) rc = mdio_clause45_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) - goto unlock; + goto out; /* Try and reconfigure the device */ rc = tenxpress_init(efx); if (rc < 0) - goto unlock; + goto out; /* Wait for the XGXS state machine to churn */ mdelay(10); -unlock: - spin_unlock(&efx->stats_lock); +out: + efx_stats_enable(efx); return rc; } -- cgit From bbd98fe48a43464b4a044bc4cbeefad284d6aa80 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 31 Jan 2009 00:52:30 -0800 Subject: igb: Fix DCA errors and do not use context index for 82576 82576 was being incorrectly flagged as needing a context index. It does not as each ring has it's own table of 2 contexts. Driver was registering after registering the driver instead of the other way around. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb.h | 9 ++++----- drivers/net/igb/igb_main.c | 16 ++++++---------- 2 files changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 5a27825cc48..aebef8e48e7 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -300,11 +300,10 @@ struct igb_adapter { #define IGB_FLAG_HAS_MSI (1 << 0) #define IGB_FLAG_MSI_ENABLE (1 << 1) -#define IGB_FLAG_HAS_DCA (1 << 2) -#define IGB_FLAG_DCA_ENABLED (1 << 3) -#define IGB_FLAG_IN_NETPOLL (1 << 5) -#define IGB_FLAG_QUAD_PORT_A (1 << 6) -#define IGB_FLAG_NEED_CTX_IDX (1 << 7) +#define IGB_FLAG_DCA_ENABLED (1 << 2) +#define IGB_FLAG_IN_NETPOLL (1 << 3) +#define IGB_FLAG_QUAD_PORT_A (1 << 4) +#define IGB_FLAG_NEED_CTX_IDX (1 << 5) enum e1000_state_t { __IGB_TESTING, diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index b82b0fb2056..cc94412ddf8 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -206,10 +206,11 @@ static int __init igb_init_module(void) global_quad_port_a = 0; - ret = pci_register_driver(&igb_driver); #ifdef CONFIG_IGB_DCA dca_register_notify(&dca_notifier); #endif + + ret = pci_register_driver(&igb_driver); return ret; } @@ -1156,11 +1157,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, /* set flags */ switch (hw->mac.type) { - case e1000_82576: case e1000_82575: - adapter->flags |= IGB_FLAG_HAS_DCA; adapter->flags |= IGB_FLAG_NEED_CTX_IDX; break; + case e1000_82576: default: break; } @@ -1310,8 +1310,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, goto err_register; #ifdef CONFIG_IGB_DCA - if ((adapter->flags & IGB_FLAG_HAS_DCA) && - (dca_add_requester(&pdev->dev) == 0)) { + if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IGB_FLAG_DCA_ENABLED; dev_info(&pdev->dev, "DCA enabled\n"); /* Always use CB2 mode, difference is masked @@ -3473,19 +3472,16 @@ static int __igb_notify_dca(struct device *dev, void *data) struct e1000_hw *hw = &adapter->hw; unsigned long event = *(unsigned long *)data; - if (!(adapter->flags & IGB_FLAG_HAS_DCA)) - goto out; - switch (event) { case DCA_PROVIDER_ADD: /* if already enabled, don't do it again */ if (adapter->flags & IGB_FLAG_DCA_ENABLED) break; - adapter->flags |= IGB_FLAG_DCA_ENABLED; /* Always use CB2 mode, difference is masked * in the CB driver. */ wr32(E1000_DCA_CTRL, 2); if (dca_add_requester(dev) == 0) { + adapter->flags |= IGB_FLAG_DCA_ENABLED; dev_info(&adapter->pdev->dev, "DCA enabled\n"); igb_setup_dca(adapter); break; @@ -3502,7 +3498,7 @@ static int __igb_notify_dca(struct device *dev, void *data) } break; } -out: + return 0; } -- cgit From ec54d7d6e40b04c16dfce0e41e506198a20c8645 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 31 Jan 2009 00:52:57 -0800 Subject: igb: prevent skb_over panic w/ mtu smaller than 1K A panic has been observed with frame sizes smaller than 1K. This has been root caused to the hardware spanning larger frames across multiple buffers and then reporting the original frame size in the first descriptor. To prevent this we can enable set the LPE bit which in turn will restrict packet sizes to those set in the RLPML register. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index cc94412ddf8..a50db5398fa 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1834,11 +1834,11 @@ static void igb_setup_rctl(struct igb_adapter *adapter) rctl |= E1000_RCTL_SECRC; /* - * disable store bad packets, long packet enable, and clear size bits. + * disable store bad packets and clear size bits. */ - rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256); + rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256); - if (adapter->netdev->mtu > ETH_DATA_LEN) + /* enable LPE when to prevent packets larger than max_frame_size */ rctl |= E1000_RCTL_LPE; /* Setup buffer sizes */ @@ -1864,7 +1864,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter) */ /* allocations using alloc_page take too long for regular MTU * so only enable packet split for jumbo frames */ - if (rctl & E1000_RCTL_LPE) { + if (adapter->netdev->mtu > ETH_DATA_LEN) { adapter->rx_ps_hdr_size = IGB_RXBUFFER_128; srrctl |= adapter->rx_ps_hdr_size << E1000_SRRCTL_BSIZEHDRSIZE_SHIFT; -- cgit From 5d0932a5dd00d83df5d1e15eeffb6edf015a8579 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Sat, 31 Jan 2009 00:53:18 -0800 Subject: igb: fix link reporting when using sgmii When using sgmii the link was not being properly passed up to the driver from the underlying link management functions. This change corrects it so that get_link_status is cleared when a link has been found. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/e1000_82575.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index f5e2e7235fc..13ca73f96ec 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -699,11 +699,18 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw) /* SGMII link check is done through the PCS register. */ if ((hw->phy.media_type != e1000_media_type_copper) || - (igb_sgmii_active_82575(hw))) + (igb_sgmii_active_82575(hw))) { ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed, &duplex); - else + /* + * Use this flag to determine if link needs to be checked or + * not. If we have link clear the flag so that we do not + * continue to check for link. + */ + hw->mac.get_link_status = !hw->mac.serdes_has_link; + } else { ret_val = igb_check_for_copper_link(hw); + } return ret_val; } -- cgit From 309ea626b164f2abba8e639b3eb6f2e5d34708b9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:09:30 +0000 Subject: powerpc/ps3: Printing fixups for l64 to ll64 convserion drivers/net Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Acked-by: David S. Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/net/ps3_gelic_wireless.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index ec231424668..335da4831ab 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -2168,7 +2168,7 @@ static void gelic_wl_connected_event(struct gelic_wl_info *wl, complete(&wl->assoc_done); netif_carrier_on(port_to_netdev(wl_port(wl))); } else - pr_debug("%s: event %#lx under wpa\n", + pr_debug("%s: event %#llx under wpa\n", __func__, event); } -- cgit From 26351479ed43288be92935826c215fbe01e2abb2 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 2 Feb 2009 13:53:57 -0800 Subject: qlge: bugfix: Fix endian issue when reading flash. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 10 +++++----- drivers/net/qlge/qlge_main.c | 11 +++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index c1dadadfab1..e6fdce9206c 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -787,12 +787,12 @@ struct mbox_params { struct flash_params { u8 dev_id_str[4]; - u16 size; - u16 csum; - u16 ver; - u16 sub_dev_id; + __le16 size; + __le16 csum; + __le16 ver; + __le16 sub_dev_id; u8 mac_addr[6]; - u16 res; + __le16 res; }; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 45421c8b601..17d02eb6c8b 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -641,7 +641,7 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev) } -static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data) +static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data) { int status = 0; /* wait for reg to come ready */ @@ -656,8 +656,11 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data) FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR); if (status) goto exit; - /* get the data */ - *data = ql_read32(qdev, FLASH_DATA); + /* This data is stored on flash as an array of + * __le32. Since ql_read32() returns cpu endian + * we need to swap it back. + */ + *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA)); exit: return status; } @@ -666,7 +669,7 @@ static int ql_get_flash_params(struct ql_adapter *qdev) { int i; int status; - u32 *p = (u32 *)&qdev->flash; + __le32 *p = (__le32 *)&qdev->flash; if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) return -ETIMEDOUT; -- cgit From e78f5fa7cc1a211eb9909ef90b0de3311086ba55 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 2 Feb 2009 13:54:15 -0800 Subject: qlge: bugfix: Add flash offset for second port. Without this the 2nd port gets first ports MAC addr. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 17d02eb6c8b..c6c070475f0 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -670,12 +670,19 @@ static int ql_get_flash_params(struct ql_adapter *qdev) int i; int status; __le32 *p = (__le32 *)&qdev->flash; + u32 offset = 0; + + /* Second function's parameters follow the first + * function's. + */ + if (qdev->func) + offset = sizeof(qdev->flash) / sizeof(u32); if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) return -ETIMEDOUT; for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) { - status = ql_read_flash_word(qdev, i, p); + status = ql_read_flash_word(qdev, i+offset, p); if (status) { QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n"); goto exit; -- cgit From 0047e5d240ede4e84c03bc9001375175900fd259 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Mon, 2 Feb 2009 13:54:31 -0800 Subject: qlge: bugfix: Add missing netif_napi_del call. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c6c070475f0..3d1d7b6e55a 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3836,7 +3836,7 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *ndev = pci_get_drvdata(pdev); struct ql_adapter *qdev = netdev_priv(ndev); - int err; + int err, i; netif_device_detach(ndev); @@ -3846,6 +3846,9 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state) return err; } + for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) + netif_napi_del(&qdev->rx_ring[i].napi); + err = pci_save_state(pdev); if (err) return err; -- cgit From 46578a6913e6f5e69229561736b94c18c2e88ae4 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 2 Feb 2009 21:39:02 -0800 Subject: net: variables reach -1, but 0 tested while (timeout--) { ... } timeout becomes -1 if the loop isn't ended otherwise, not 0. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/ibm_newemac/phy.c | 4 ++-- drivers/net/smc911x.c | 4 ++-- drivers/net/smsc9420.c | 12 ++++++------ drivers/net/sungem.c | 2 +- drivers/net/sunqe.c | 2 +- drivers/net/tsi108_eth.c | 2 +- drivers/net/tulip/de2104x.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c index c40cd8df221..ac9d964e59e 100644 --- a/drivers/net/ibm_newemac/phy.c +++ b/drivers/net/ibm_newemac/phy.c @@ -60,7 +60,7 @@ int emac_mii_reset_phy(struct mii_phy *phy) udelay(300); - while (limit--) { + while (--limit) { val = phy_read(phy, MII_BMCR); if (val >= 0 && (val & BMCR_RESET) == 0) break; @@ -84,7 +84,7 @@ int emac_mii_reset_gpcs(struct mii_phy *phy) udelay(300); - while (limit--) { + while (--limit) { val = gpcs_phy_read(phy, MII_BMCR); if (val >= 0 && (val & BMCR_RESET) == 0) break; diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index bf3aa2a1eff..223cde0d43b 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -220,9 +220,9 @@ static void smc911x_reset(struct net_device *dev) /* make sure EEPROM has finished loading before setting GPIO_CFG */ timeout=1000; - while ( timeout-- && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) { + while (--timeout && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) udelay(10); - } + if (timeout == 0){ PRINTK("%s: smc911x_reset timeout waiting for EEPROM busy\n", dev->name); return; diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index d801900a503..a1e4b3895b3 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -498,7 +498,7 @@ static void smsc9420_check_mac_address(struct net_device *dev) static void smsc9420_stop_tx(struct smsc9420_pdata *pd) { u32 dmac_control, mac_cr, dma_intr_ena; - int timeOut = 1000; + int timeout = 1000; /* disable TX DMAC */ dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL); @@ -506,13 +506,13 @@ static void smsc9420_stop_tx(struct smsc9420_pdata *pd) smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control); /* Wait max 10ms for transmit process to stop */ - while (timeOut--) { + while (--timeout) { if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_TS_) break; udelay(10); } - if (!timeOut) + if (!timeout) smsc_warn(IFDOWN, "TX DMAC failed to stop"); /* ACK Tx DMAC stop bit */ @@ -596,7 +596,7 @@ static void smsc9420_free_rx_ring(struct smsc9420_pdata *pd) static void smsc9420_stop_rx(struct smsc9420_pdata *pd) { - int timeOut = 1000; + int timeout = 1000; u32 mac_cr, dmac_control, dma_intr_ena; /* mask RX DMAC interrupts */ @@ -617,13 +617,13 @@ static void smsc9420_stop_rx(struct smsc9420_pdata *pd) smsc9420_pci_flush_write(pd); /* wait up to 10ms for receive to stop */ - while (timeOut--) { + while (--timeout) { if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_RS_) break; udelay(10); } - if (!timeOut) + if (!timeout) smsc_warn(IFDOWN, "RX DMAC did not stop! timeout."); /* ACK the Rx DMAC stop bit */ diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 86c765d83de..b17efa9cc53 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -148,7 +148,7 @@ static u16 __phy_read(struct gem *gp, int phy_addr, int reg) cmd |= (MIF_FRAME_TAMSB); writel(cmd, gp->regs + MIF_FRAME); - while (limit--) { + while (--limit) { cmd = readl(gp->regs + MIF_FRAME); if (cmd & MIF_FRAME_TALSB) break; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 6e8f377355f..fe0c3f24456 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -227,7 +227,7 @@ static int qe_init(struct sunqe *qep, int from_irq) if (!(sbus_readb(mregs + MREGS_PHYCONFIG) & MREGS_PHYCONFIG_LTESTDIS)) { int tries = 50; - while (tries--) { + while (--tries) { u8 tmp; mdelay(5); diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 75461dbd487..a9fd2b2ccaf 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -1237,7 +1237,7 @@ static void tsi108_init_phy(struct net_device *dev) spin_lock_irqsave(&phy_lock, flags); tsi108_write_mii(data, MII_BMCR, BMCR_RESET); - while (i--){ + while (--i) { if(!(tsi108_read_mii(data, MII_BMCR) & BMCR_RESET)) break; udelay(10); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index d5d53b633cf..0bf2114738b 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -392,7 +392,7 @@ static void de_rx (struct de_private *de) unsigned drop = 0; int rc; - while (rx_work--) { + while (--rx_work) { u32 status, len; dma_addr_t mapping; struct sk_buff *skb, *copy_skb; -- cgit From ff01b9163655ace76b29b7ff2f56b25c32f795da Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 2 Feb 2009 23:19:50 -0800 Subject: cassini/sungem: limit reaches -1, but 0 tested while (limit--) if (test()) break; if (limit <= 0) goto test_failed; In the last iteration, limit is decremented after the test to 0. If just thereafter test() succeeds and a break occurs, the goto still occurs because limit is 0. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/cassini.c | 4 ++-- drivers/net/sungem_phy.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 840b3d1a22f..bbbc3bb08aa 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -806,7 +806,7 @@ static int cas_reset_mii_phy(struct cas *cp) cas_phy_write(cp, MII_BMCR, BMCR_RESET); udelay(100); - while (limit--) { + while (--limit) { val = cas_phy_read(cp, MII_BMCR); if ((val & BMCR_RESET) == 0) break; @@ -979,7 +979,7 @@ static void cas_phy_init(struct cas *cp) writel(val, cp->regs + REG_PCS_MII_CTRL); limit = STOP_TRIES; - while (limit-- > 0) { + while (--limit > 0) { udelay(10); if ((readl(cp->regs + REG_PCS_MII_CTRL) & PCS_MII_RESET) == 0) diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c index 61843fd5752..78f8cee5fd7 100644 --- a/drivers/net/sungem_phy.c +++ b/drivers/net/sungem_phy.c @@ -79,7 +79,7 @@ static int reset_one_mii_phy(struct mii_phy* phy, int phy_id) udelay(100); - while (limit--) { + while (--limit) { val = __phy_read(phy, phy_id, MII_BMCR); if ((val & BMCR_RESET) == 0) break; -- cgit From 67dd82462d553c35bef14de1bf8afcb1095e041d Mon Sep 17 00:00:00 2001 From: Filip Aben Date: Tue, 3 Feb 2009 15:13:26 -0800 Subject: hso: add new device id's This patch adds a few device ID's. It also removes an ID that was used in an internal engineering version of a device and will never see commercial light. Even if this ID will be 'recycled' in the future, which is very unlikely, we don't know what kind of device will be behind it. Therefore it's safer to remove it. Signed-off-by: Filip Aben Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 0d0fa91c025..fe98acaead9 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -455,6 +455,7 @@ static const struct usb_device_id hso_ids[] = { {icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */ {USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */ {USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */ + {USB_DEVICE(0x0af0, 0x7381)}, /* GE40x */ {USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */ {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ @@ -462,7 +463,8 @@ static const struct usb_device_id hso_ids[] = { {USB_DEVICE(0x0af0, 0x7801)}, {USB_DEVICE(0x0af0, 0x7901)}, {USB_DEVICE(0x0af0, 0x7361)}, - {icon321_port_device(0x0af0, 0xd051)}, + {USB_DEVICE(0x0af0, 0xd057)}, + {USB_DEVICE(0x0af0, 0xd055)}, {} }; MODULE_DEVICE_TABLE(usb, hso_ids); -- cgit From a9d3a146923d374b945aa388dc884df69564a818 Mon Sep 17 00:00:00 2001 From: Cord Walter Date: Tue, 3 Feb 2009 15:14:05 -0800 Subject: pcnet_cs: Fix misuse of the equality operator. Signed-off-by: Cord Walter Signed-off-by: Komuro Signed-off-by: David S. Miller --- drivers/net/pcmcia/pcnet_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index c38ed777f0a..a6999403f37 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -586,7 +586,7 @@ static int pcnet_config(struct pcmcia_device *link) } if ((link->conf.ConfigBase == 0x03c0) - && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) { + && (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n"); printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n"); goto failed; -- cgit From 4d7155b932b8129c72e2f2714890e20b2a05e0b7 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Tue, 3 Feb 2009 15:18:01 -0800 Subject: e1000: Fix PCI enable to honor the need_ioport flag On machine were no IO ports are assigned the call to pci_enable_device() will fail, even if need_ioport is false, we need to use pci_enable_device_mem() here. Signed-off-by: Karsten Keil Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c986978ce76..6bd63cc67b3 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -940,7 +940,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, err = pci_enable_device(pdev); } else { bars = pci_select_bars(pdev, IORESOURCE_MEM); - err = pci_enable_device(pdev); + err = pci_enable_device_mem(pdev); } if (err) return err; -- cgit