Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

+9954 -152
+8
drivers/net/Kconfig
··· 548 548 Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also 549 549 <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>. 550 550 551 + config CASSINI 552 + tristate "Sun Cassini support" 553 + depends on NET_ETHERNET && PCI 554 + select CRC32 555 + help 556 + Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also 557 + <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf> 558 + 551 559 config NET_VENDOR_3COM 552 560 bool "3COM cards" 553 561 depends on NET_ETHERNET && (ISA || EISA || MCA || PCI)
+1
drivers/net/Makefile
··· 28 28 obj-$(CONFIG_SUNBMAC) += sunbmac.o 29 29 obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o 30 30 obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o 31 + obj-$(CONFIG_CASSINI) += cassini.o 31 32 32 33 obj-$(CONFIG_MACE) += mace.o 33 34 obj-$(CONFIG_BMAC) += bmac.o
+5311
drivers/net/cassini.c
··· 1 + /* cassini.c: Sun Microsystems Cassini(+) ethernet driver. 2 + * 3 + * Copyright (C) 2004 Sun Microsystems Inc. 4 + * Copyright (C) 2003 Adrian Sun (asun@darksunrising.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License as 8 + * published by the Free Software Foundation; either version 2 of the 9 + * License, or (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 + * 02111-1307, USA. 20 + * 21 + * This driver uses the sungem driver (c) David Miller 22 + * (davem@redhat.com) as its basis. 23 + * 24 + * The cassini chip has a number of features that distinguish it from 25 + * the gem chip: 26 + * 4 transmit descriptor rings that are used for either QoS (VLAN) or 27 + * load balancing (non-VLAN mode) 28 + * batching of multiple packets 29 + * multiple CPU dispatching 30 + * page-based RX descriptor engine with separate completion rings 31 + * Gigabit support (GMII and PCS interface) 32 + * MIF link up/down detection works 33 + * 34 + * RX is handled by page sized buffers that are attached as fragments to 35 + * the skb. here's what's done: 36 + * -- driver allocates pages at a time and keeps reference counts 37 + * on them. 38 + * -- the upper protocol layers assume that the header is in the skb 39 + * itself. as a result, cassini will copy a small amount (64 bytes) 40 + * to make them happy. 41 + * -- driver appends the rest of the data pages as frags to skbuffs 42 + * and increments the reference count 43 + * -- on page reclamation, the driver swaps the page with a spare page. 44 + * if that page is still in use, it frees its reference to that page, 45 + * and allocates a new page for use. otherwise, it just recycles the 46 + * the page. 47 + * 48 + * NOTE: cassini can parse the header. however, it's not worth it 49 + * as long as the network stack requires a header copy. 50 + * 51 + * TX has 4 queues. currently these queues are used in a round-robin 52 + * fashion for load balancing. They can also be used for QoS. for that 53 + * to work, however, QoS information needs to be exposed down to the driver 54 + * level so that subqueues get targetted to particular transmit rings. 55 + * alternatively, the queues can be configured via use of the all-purpose 56 + * ioctl. 57 + * 58 + * RX DATA: the rx completion ring has all the info, but the rx desc 59 + * ring has all of the data. RX can conceivably come in under multiple 60 + * interrupts, but the INT# assignment needs to be set up properly by 61 + * the BIOS and conveyed to the driver. PCI BIOSes don't know how to do 62 + * that. also, the two descriptor rings are designed to distinguish between 63 + * encrypted and non-encrypted packets, but we use them for buffering 64 + * instead. 65 + * 66 + * by default, the selective clear mask is set up to process rx packets. 67 + */ 68 + 69 + #include <linux/config.h> 70 + #include <linux/version.h> 71 + 72 + #include <linux/module.h> 73 + #include <linux/kernel.h> 74 + #include <linux/types.h> 75 + #include <linux/compiler.h> 76 + #include <linux/slab.h> 77 + #include <linux/delay.h> 78 + #include <linux/init.h> 79 + #include <linux/ioport.h> 80 + #include <linux/pci.h> 81 + #include <linux/mm.h> 82 + #include <linux/highmem.h> 83 + #include <linux/list.h> 84 + #include <linux/dma-mapping.h> 85 + 86 + #include <linux/netdevice.h> 87 + #include <linux/etherdevice.h> 88 + #include <linux/skbuff.h> 89 + #include <linux/ethtool.h> 90 + #include <linux/crc32.h> 91 + #include <linux/random.h> 92 + #include <linux/mii.h> 93 + #include <linux/ip.h> 94 + #include <linux/tcp.h> 95 + 96 + #include <net/checksum.h> 97 + 98 + #include <asm/atomic.h> 99 + #include <asm/system.h> 100 + #include <asm/io.h> 101 + #include <asm/byteorder.h> 102 + #include <asm/uaccess.h> 103 + 104 + #define cas_page_map(x) kmap_atomic((x), KM_SKB_DATA_SOFTIRQ) 105 + #define cas_page_unmap(x) kunmap_atomic((x), KM_SKB_DATA_SOFTIRQ) 106 + #define CAS_NCPUS num_online_cpus() 107 + 108 + #if defined(CONFIG_CASSINI_NAPI) && defined(HAVE_NETDEV_POLL) 109 + #define USE_NAPI 110 + #define cas_skb_release(x) netif_receive_skb(x) 111 + #else 112 + #define cas_skb_release(x) netif_rx(x) 113 + #endif 114 + 115 + /* select which firmware to use */ 116 + #define USE_HP_WORKAROUND 117 + #define HP_WORKAROUND_DEFAULT /* select which firmware to use as default */ 118 + #define CAS_HP_ALT_FIRMWARE cas_prog_null /* alternate firmware */ 119 + 120 + #include "cassini.h" 121 + 122 + #define USE_TX_COMPWB /* use completion writeback registers */ 123 + #define USE_CSMA_CD_PROTO /* standard CSMA/CD */ 124 + #define USE_RX_BLANK /* hw interrupt mitigation */ 125 + #undef USE_ENTROPY_DEV /* don't test for entropy device */ 126 + 127 + /* NOTE: these aren't useable unless PCI interrupts can be assigned. 128 + * also, we need to make cp->lock finer-grained. 129 + */ 130 + #undef USE_PCI_INTB 131 + #undef USE_PCI_INTC 132 + #undef USE_PCI_INTD 133 + #undef USE_QOS 134 + 135 + #undef USE_VPD_DEBUG /* debug vpd information if defined */ 136 + 137 + /* rx processing options */ 138 + #define USE_PAGE_ORDER /* specify to allocate large rx pages */ 139 + #define RX_DONT_BATCH 0 /* if 1, don't batch flows */ 140 + #define RX_COPY_ALWAYS 0 /* if 0, use frags */ 141 + #define RX_COPY_MIN 64 /* copy a little to make upper layers happy */ 142 + #undef RX_COUNT_BUFFERS /* define to calculate RX buffer stats */ 143 + 144 + #define DRV_MODULE_NAME "cassini" 145 + #define PFX DRV_MODULE_NAME ": " 146 + #define DRV_MODULE_VERSION "1.4" 147 + #define DRV_MODULE_RELDATE "1 July 2004" 148 + 149 + #define CAS_DEF_MSG_ENABLE \ 150 + (NETIF_MSG_DRV | \ 151 + NETIF_MSG_PROBE | \ 152 + NETIF_MSG_LINK | \ 153 + NETIF_MSG_TIMER | \ 154 + NETIF_MSG_IFDOWN | \ 155 + NETIF_MSG_IFUP | \ 156 + NETIF_MSG_RX_ERR | \ 157 + NETIF_MSG_TX_ERR) 158 + 159 + /* length of time before we decide the hardware is borked, 160 + * and dev->tx_timeout() should be called to fix the problem 161 + */ 162 + #define CAS_TX_TIMEOUT (HZ) 163 + #define CAS_LINK_TIMEOUT (22*HZ/10) 164 + #define CAS_LINK_FAST_TIMEOUT (1) 165 + 166 + /* timeout values for state changing. these specify the number 167 + * of 10us delays to be used before giving up. 168 + */ 169 + #define STOP_TRIES_PHY 1000 170 + #define STOP_TRIES 5000 171 + 172 + /* specify a minimum frame size to deal with some fifo issues 173 + * max mtu == 2 * page size - ethernet header - 64 - swivel = 174 + * 2 * page_size - 0x50 175 + */ 176 + #define CAS_MIN_FRAME 97 177 + #define CAS_1000MB_MIN_FRAME 255 178 + #define CAS_MIN_MTU 60 179 + #define CAS_MAX_MTU min(((cp->page_size << 1) - 0x50), 9000) 180 + 181 + #if 1 182 + /* 183 + * Eliminate these and use separate atomic counters for each, to 184 + * avoid a race condition. 185 + */ 186 + #else 187 + #define CAS_RESET_MTU 1 188 + #define CAS_RESET_ALL 2 189 + #define CAS_RESET_SPARE 3 190 + #endif 191 + 192 + static char version[] __devinitdata = 193 + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 194 + 195 + MODULE_AUTHOR("Adrian Sun (asun@darksunrising.com)"); 196 + MODULE_DESCRIPTION("Sun Cassini(+) ethernet driver"); 197 + MODULE_LICENSE("GPL"); 198 + MODULE_PARM(cassini_debug, "i"); 199 + MODULE_PARM_DESC(cassini_debug, "Cassini bitmapped debugging message enable value"); 200 + MODULE_PARM(link_mode, "i"); 201 + MODULE_PARM_DESC(link_mode, "default link mode"); 202 + 203 + /* 204 + * Work around for a PCS bug in which the link goes down due to the chip 205 + * being confused and never showing a link status of "up." 206 + */ 207 + #define DEFAULT_LINKDOWN_TIMEOUT 5 208 + /* 209 + * Value in seconds, for user input. 210 + */ 211 + static int linkdown_timeout = DEFAULT_LINKDOWN_TIMEOUT; 212 + MODULE_PARM(linkdown_timeout, "i"); 213 + MODULE_PARM_DESC(linkdown_timeout, 214 + "min reset interval in sec. for PCS linkdown issue; disabled if not positive"); 215 + 216 + /* 217 + * value in 'ticks' (units used by jiffies). Set when we init the 218 + * module because 'HZ' in actually a function call on some flavors of 219 + * Linux. This will default to DEFAULT_LINKDOWN_TIMEOUT * HZ. 220 + */ 221 + static int link_transition_timeout; 222 + 223 + 224 + static int cassini_debug = -1; /* -1 == use CAS_DEF_MSG_ENABLE as value */ 225 + static int link_mode; 226 + 227 + static u16 link_modes[] __devinitdata = { 228 + BMCR_ANENABLE, /* 0 : autoneg */ 229 + 0, /* 1 : 10bt half duplex */ 230 + BMCR_SPEED100, /* 2 : 100bt half duplex */ 231 + BMCR_FULLDPLX, /* 3 : 10bt full duplex */ 232 + BMCR_SPEED100|BMCR_FULLDPLX, /* 4 : 100bt full duplex */ 233 + CAS_BMCR_SPEED1000|BMCR_FULLDPLX /* 5 : 1000bt full duplex */ 234 + }; 235 + 236 + static struct pci_device_id cas_pci_tbl[] __devinitdata = { 237 + { PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_CASSINI, 238 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, 239 + { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SATURN, 240 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, 241 + { 0, } 242 + }; 243 + 244 + MODULE_DEVICE_TABLE(pci, cas_pci_tbl); 245 + 246 + static void cas_set_link_modes(struct cas *cp); 247 + 248 + static inline void cas_lock_tx(struct cas *cp) 249 + { 250 + int i; 251 + 252 + for (i = 0; i < N_TX_RINGS; i++) 253 + spin_lock(&cp->tx_lock[i]); 254 + } 255 + 256 + static inline void cas_lock_all(struct cas *cp) 257 + { 258 + spin_lock_irq(&cp->lock); 259 + cas_lock_tx(cp); 260 + } 261 + 262 + /* WTZ: QA was finding deadlock problems with the previous 263 + * versions after long test runs with multiple cards per machine. 264 + * See if replacing cas_lock_all with safer versions helps. The 265 + * symptoms QA is reporting match those we'd expect if interrupts 266 + * aren't being properly restored, and we fixed a previous deadlock 267 + * with similar symptoms by using save/restore versions in other 268 + * places. 269 + */ 270 + #define cas_lock_all_save(cp, flags) \ 271 + do { \ 272 + struct cas *xxxcp = (cp); \ 273 + spin_lock_irqsave(&xxxcp->lock, flags); \ 274 + cas_lock_tx(xxxcp); \ 275 + } while (0) 276 + 277 + static inline void cas_unlock_tx(struct cas *cp) 278 + { 279 + int i; 280 + 281 + for (i = N_TX_RINGS; i > 0; i--) 282 + spin_unlock(&cp->tx_lock[i - 1]); 283 + } 284 + 285 + static inline void cas_unlock_all(struct cas *cp) 286 + { 287 + cas_unlock_tx(cp); 288 + spin_unlock_irq(&cp->lock); 289 + } 290 + 291 + #define cas_unlock_all_restore(cp, flags) \ 292 + do { \ 293 + struct cas *xxxcp = (cp); \ 294 + cas_unlock_tx(xxxcp); \ 295 + spin_unlock_irqrestore(&xxxcp->lock, flags); \ 296 + } while (0) 297 + 298 + static void cas_disable_irq(struct cas *cp, const int ring) 299 + { 300 + /* Make sure we won't get any more interrupts */ 301 + if (ring == 0) { 302 + writel(0xFFFFFFFF, cp->regs + REG_INTR_MASK); 303 + return; 304 + } 305 + 306 + /* disable completion interrupts and selectively mask */ 307 + if (cp->cas_flags & CAS_FLAG_REG_PLUS) { 308 + switch (ring) { 309 + #if defined (USE_PCI_INTB) || defined(USE_PCI_INTC) || defined(USE_PCI_INTD) 310 + #ifdef USE_PCI_INTB 311 + case 1: 312 + #endif 313 + #ifdef USE_PCI_INTC 314 + case 2: 315 + #endif 316 + #ifdef USE_PCI_INTD 317 + case 3: 318 + #endif 319 + writel(INTRN_MASK_CLEAR_ALL | INTRN_MASK_RX_EN, 320 + cp->regs + REG_PLUS_INTRN_MASK(ring)); 321 + break; 322 + #endif 323 + default: 324 + writel(INTRN_MASK_CLEAR_ALL, cp->regs + 325 + REG_PLUS_INTRN_MASK(ring)); 326 + break; 327 + } 328 + } 329 + } 330 + 331 + static inline void cas_mask_intr(struct cas *cp) 332 + { 333 + int i; 334 + 335 + for (i = 0; i < N_RX_COMP_RINGS; i++) 336 + cas_disable_irq(cp, i); 337 + } 338 + 339 + static void cas_enable_irq(struct cas *cp, const int ring) 340 + { 341 + if (ring == 0) { /* all but TX_DONE */ 342 + writel(INTR_TX_DONE, cp->regs + REG_INTR_MASK); 343 + return; 344 + } 345 + 346 + if (cp->cas_flags & CAS_FLAG_REG_PLUS) { 347 + switch (ring) { 348 + #if defined (USE_PCI_INTB) || defined(USE_PCI_INTC) || defined(USE_PCI_INTD) 349 + #ifdef USE_PCI_INTB 350 + case 1: 351 + #endif 352 + #ifdef USE_PCI_INTC 353 + case 2: 354 + #endif 355 + #ifdef USE_PCI_INTD 356 + case 3: 357 + #endif 358 + writel(INTRN_MASK_RX_EN, cp->regs + 359 + REG_PLUS_INTRN_MASK(ring)); 360 + break; 361 + #endif 362 + default: 363 + break; 364 + } 365 + } 366 + } 367 + 368 + static inline void cas_unmask_intr(struct cas *cp) 369 + { 370 + int i; 371 + 372 + for (i = 0; i < N_RX_COMP_RINGS; i++) 373 + cas_enable_irq(cp, i); 374 + } 375 + 376 + static inline void cas_entropy_gather(struct cas *cp) 377 + { 378 + #ifdef USE_ENTROPY_DEV 379 + if ((cp->cas_flags & CAS_FLAG_ENTROPY_DEV) == 0) 380 + return; 381 + 382 + batch_entropy_store(readl(cp->regs + REG_ENTROPY_IV), 383 + readl(cp->regs + REG_ENTROPY_IV), 384 + sizeof(uint64_t)*8); 385 + #endif 386 + } 387 + 388 + static inline void cas_entropy_reset(struct cas *cp) 389 + { 390 + #ifdef USE_ENTROPY_DEV 391 + if ((cp->cas_flags & CAS_FLAG_ENTROPY_DEV) == 0) 392 + return; 393 + 394 + writel(BIM_LOCAL_DEV_PAD | BIM_LOCAL_DEV_PROM | BIM_LOCAL_DEV_EXT, 395 + cp->regs + REG_BIM_LOCAL_DEV_EN); 396 + writeb(ENTROPY_RESET_STC_MODE, cp->regs + REG_ENTROPY_RESET); 397 + writeb(0x55, cp->regs + REG_ENTROPY_RAND_REG); 398 + 399 + /* if we read back 0x0, we don't have an entropy device */ 400 + if (readb(cp->regs + REG_ENTROPY_RAND_REG) == 0) 401 + cp->cas_flags &= ~CAS_FLAG_ENTROPY_DEV; 402 + #endif 403 + } 404 + 405 + /* access to the phy. the following assumes that we've initialized the MIF to 406 + * be in frame rather than bit-bang mode 407 + */ 408 + static u16 cas_phy_read(struct cas *cp, int reg) 409 + { 410 + u32 cmd; 411 + int limit = STOP_TRIES_PHY; 412 + 413 + cmd = MIF_FRAME_ST | MIF_FRAME_OP_READ; 414 + cmd |= CAS_BASE(MIF_FRAME_PHY_ADDR, cp->phy_addr); 415 + cmd |= CAS_BASE(MIF_FRAME_REG_ADDR, reg); 416 + cmd |= MIF_FRAME_TURN_AROUND_MSB; 417 + writel(cmd, cp->regs + REG_MIF_FRAME); 418 + 419 + /* poll for completion */ 420 + while (limit-- > 0) { 421 + udelay(10); 422 + cmd = readl(cp->regs + REG_MIF_FRAME); 423 + if (cmd & MIF_FRAME_TURN_AROUND_LSB) 424 + return (cmd & MIF_FRAME_DATA_MASK); 425 + } 426 + return 0xFFFF; /* -1 */ 427 + } 428 + 429 + static int cas_phy_write(struct cas *cp, int reg, u16 val) 430 + { 431 + int limit = STOP_TRIES_PHY; 432 + u32 cmd; 433 + 434 + cmd = MIF_FRAME_ST | MIF_FRAME_OP_WRITE; 435 + cmd |= CAS_BASE(MIF_FRAME_PHY_ADDR, cp->phy_addr); 436 + cmd |= CAS_BASE(MIF_FRAME_REG_ADDR, reg); 437 + cmd |= MIF_FRAME_TURN_AROUND_MSB; 438 + cmd |= val & MIF_FRAME_DATA_MASK; 439 + writel(cmd, cp->regs + REG_MIF_FRAME); 440 + 441 + /* poll for completion */ 442 + while (limit-- > 0) { 443 + udelay(10); 444 + cmd = readl(cp->regs + REG_MIF_FRAME); 445 + if (cmd & MIF_FRAME_TURN_AROUND_LSB) 446 + return 0; 447 + } 448 + return -1; 449 + } 450 + 451 + static void cas_phy_powerup(struct cas *cp) 452 + { 453 + u16 ctl = cas_phy_read(cp, MII_BMCR); 454 + 455 + if ((ctl & BMCR_PDOWN) == 0) 456 + return; 457 + ctl &= ~BMCR_PDOWN; 458 + cas_phy_write(cp, MII_BMCR, ctl); 459 + } 460 + 461 + static void cas_phy_powerdown(struct cas *cp) 462 + { 463 + u16 ctl = cas_phy_read(cp, MII_BMCR); 464 + 465 + if (ctl & BMCR_PDOWN) 466 + return; 467 + ctl |= BMCR_PDOWN; 468 + cas_phy_write(cp, MII_BMCR, ctl); 469 + } 470 + 471 + /* cp->lock held. note: the last put_page will free the buffer */ 472 + static int cas_page_free(struct cas *cp, cas_page_t *page) 473 + { 474 + pci_unmap_page(cp->pdev, page->dma_addr, cp->page_size, 475 + PCI_DMA_FROMDEVICE); 476 + __free_pages(page->buffer, cp->page_order); 477 + kfree(page); 478 + return 0; 479 + } 480 + 481 + #ifdef RX_COUNT_BUFFERS 482 + #define RX_USED_ADD(x, y) ((x)->used += (y)) 483 + #define RX_USED_SET(x, y) ((x)->used = (y)) 484 + #else 485 + #define RX_USED_ADD(x, y) 486 + #define RX_USED_SET(x, y) 487 + #endif 488 + 489 + /* local page allocation routines for the receive buffers. jumbo pages 490 + * require at least 8K contiguous and 8K aligned buffers. 491 + */ 492 + static cas_page_t *cas_page_alloc(struct cas *cp, const int flags) 493 + { 494 + cas_page_t *page; 495 + 496 + page = kmalloc(sizeof(cas_page_t), flags); 497 + if (!page) 498 + return NULL; 499 + 500 + INIT_LIST_HEAD(&page->list); 501 + RX_USED_SET(page, 0); 502 + page->buffer = alloc_pages(flags, cp->page_order); 503 + if (!page->buffer) 504 + goto page_err; 505 + page->dma_addr = pci_map_page(cp->pdev, page->buffer, 0, 506 + cp->page_size, PCI_DMA_FROMDEVICE); 507 + return page; 508 + 509 + page_err: 510 + kfree(page); 511 + return NULL; 512 + } 513 + 514 + /* initialize spare pool of rx buffers, but allocate during the open */ 515 + static void cas_spare_init(struct cas *cp) 516 + { 517 + spin_lock(&cp->rx_inuse_lock); 518 + INIT_LIST_HEAD(&cp->rx_inuse_list); 519 + spin_unlock(&cp->rx_inuse_lock); 520 + 521 + spin_lock(&cp->rx_spare_lock); 522 + INIT_LIST_HEAD(&cp->rx_spare_list); 523 + cp->rx_spares_needed = RX_SPARE_COUNT; 524 + spin_unlock(&cp->rx_spare_lock); 525 + } 526 + 527 + /* used on close. free all the spare buffers. */ 528 + static void cas_spare_free(struct cas *cp) 529 + { 530 + struct list_head list, *elem, *tmp; 531 + 532 + /* free spare buffers */ 533 + INIT_LIST_HEAD(&list); 534 + spin_lock(&cp->rx_spare_lock); 535 + list_splice(&cp->rx_spare_list, &list); 536 + INIT_LIST_HEAD(&cp->rx_spare_list); 537 + spin_unlock(&cp->rx_spare_lock); 538 + list_for_each_safe(elem, tmp, &list) { 539 + cas_page_free(cp, list_entry(elem, cas_page_t, list)); 540 + } 541 + 542 + INIT_LIST_HEAD(&list); 543 + #if 1 544 + /* 545 + * Looks like Adrian had protected this with a different 546 + * lock than used everywhere else to manipulate this list. 547 + */ 548 + spin_lock(&cp->rx_inuse_lock); 549 + list_splice(&cp->rx_inuse_list, &list); 550 + INIT_LIST_HEAD(&cp->rx_inuse_list); 551 + spin_unlock(&cp->rx_inuse_lock); 552 + #else 553 + spin_lock(&cp->rx_spare_lock); 554 + list_splice(&cp->rx_inuse_list, &list); 555 + INIT_LIST_HEAD(&cp->rx_inuse_list); 556 + spin_unlock(&cp->rx_spare_lock); 557 + #endif 558 + list_for_each_safe(elem, tmp, &list) { 559 + cas_page_free(cp, list_entry(elem, cas_page_t, list)); 560 + } 561 + } 562 + 563 + /* replenish spares if needed */ 564 + static void cas_spare_recover(struct cas *cp, const int flags) 565 + { 566 + struct list_head list, *elem, *tmp; 567 + int needed, i; 568 + 569 + /* check inuse list. if we don't need any more free buffers, 570 + * just free it 571 + */ 572 + 573 + /* make a local copy of the list */ 574 + INIT_LIST_HEAD(&list); 575 + spin_lock(&cp->rx_inuse_lock); 576 + list_splice(&cp->rx_inuse_list, &list); 577 + INIT_LIST_HEAD(&cp->rx_inuse_list); 578 + spin_unlock(&cp->rx_inuse_lock); 579 + 580 + list_for_each_safe(elem, tmp, &list) { 581 + cas_page_t *page = list_entry(elem, cas_page_t, list); 582 + 583 + if (page_count(page->buffer) > 1) 584 + continue; 585 + 586 + list_del(elem); 587 + spin_lock(&cp->rx_spare_lock); 588 + if (cp->rx_spares_needed > 0) { 589 + list_add(elem, &cp->rx_spare_list); 590 + cp->rx_spares_needed--; 591 + spin_unlock(&cp->rx_spare_lock); 592 + } else { 593 + spin_unlock(&cp->rx_spare_lock); 594 + cas_page_free(cp, page); 595 + } 596 + } 597 + 598 + /* put any inuse buffers back on the list */ 599 + if (!list_empty(&list)) { 600 + spin_lock(&cp->rx_inuse_lock); 601 + list_splice(&list, &cp->rx_inuse_list); 602 + spin_unlock(&cp->rx_inuse_lock); 603 + } 604 + 605 + spin_lock(&cp->rx_spare_lock); 606 + needed = cp->rx_spares_needed; 607 + spin_unlock(&cp->rx_spare_lock); 608 + if (!needed) 609 + return; 610 + 611 + /* we still need spares, so try to allocate some */ 612 + INIT_LIST_HEAD(&list); 613 + i = 0; 614 + while (i < needed) { 615 + cas_page_t *spare = cas_page_alloc(cp, flags); 616 + if (!spare) 617 + break; 618 + list_add(&spare->list, &list); 619 + i++; 620 + } 621 + 622 + spin_lock(&cp->rx_spare_lock); 623 + list_splice(&list, &cp->rx_spare_list); 624 + cp->rx_spares_needed -= i; 625 + spin_unlock(&cp->rx_spare_lock); 626 + } 627 + 628 + /* pull a page from the list. */ 629 + static cas_page_t *cas_page_dequeue(struct cas *cp) 630 + { 631 + struct list_head *entry; 632 + int recover; 633 + 634 + spin_lock(&cp->rx_spare_lock); 635 + if (list_empty(&cp->rx_spare_list)) { 636 + /* try to do a quick recovery */ 637 + spin_unlock(&cp->rx_spare_lock); 638 + cas_spare_recover(cp, GFP_ATOMIC); 639 + spin_lock(&cp->rx_spare_lock); 640 + if (list_empty(&cp->rx_spare_list)) { 641 + if (netif_msg_rx_err(cp)) 642 + printk(KERN_ERR "%s: no spare buffers " 643 + "available.\n", cp->dev->name); 644 + spin_unlock(&cp->rx_spare_lock); 645 + return NULL; 646 + } 647 + } 648 + 649 + entry = cp->rx_spare_list.next; 650 + list_del(entry); 651 + recover = ++cp->rx_spares_needed; 652 + spin_unlock(&cp->rx_spare_lock); 653 + 654 + /* trigger the timer to do the recovery */ 655 + if ((recover & (RX_SPARE_RECOVER_VAL - 1)) == 0) { 656 + #if 1 657 + atomic_inc(&cp->reset_task_pending); 658 + atomic_inc(&cp->reset_task_pending_spare); 659 + schedule_work(&cp->reset_task); 660 + #else 661 + atomic_set(&cp->reset_task_pending, CAS_RESET_SPARE); 662 + schedule_work(&cp->reset_task); 663 + #endif 664 + } 665 + return list_entry(entry, cas_page_t, list); 666 + } 667 + 668 + 669 + static void cas_mif_poll(struct cas *cp, const int enable) 670 + { 671 + u32 cfg; 672 + 673 + cfg = readl(cp->regs + REG_MIF_CFG); 674 + cfg &= (MIF_CFG_MDIO_0 | MIF_CFG_MDIO_1); 675 + 676 + if (cp->phy_type & CAS_PHY_MII_MDIO1) 677 + cfg |= MIF_CFG_PHY_SELECT; 678 + 679 + /* poll and interrupt on link status change. */ 680 + if (enable) { 681 + cfg |= MIF_CFG_POLL_EN; 682 + cfg |= CAS_BASE(MIF_CFG_POLL_REG, MII_BMSR); 683 + cfg |= CAS_BASE(MIF_CFG_POLL_PHY, cp->phy_addr); 684 + } 685 + writel((enable) ? ~(BMSR_LSTATUS | BMSR_ANEGCOMPLETE) : 0xFFFF, 686 + cp->regs + REG_MIF_MASK); 687 + writel(cfg, cp->regs + REG_MIF_CFG); 688 + } 689 + 690 + /* Must be invoked under cp->lock */ 691 + static void cas_begin_auto_negotiation(struct cas *cp, struct ethtool_cmd *ep) 692 + { 693 + u16 ctl; 694 + #if 1 695 + int lcntl; 696 + int changed = 0; 697 + int oldstate = cp->lstate; 698 + int link_was_not_down = !(oldstate == link_down); 699 + #endif 700 + /* Setup link parameters */ 701 + if (!ep) 702 + goto start_aneg; 703 + lcntl = cp->link_cntl; 704 + if (ep->autoneg == AUTONEG_ENABLE) 705 + cp->link_cntl = BMCR_ANENABLE; 706 + else { 707 + cp->link_cntl = 0; 708 + if (ep->speed == SPEED_100) 709 + cp->link_cntl |= BMCR_SPEED100; 710 + else if (ep->speed == SPEED_1000) 711 + cp->link_cntl |= CAS_BMCR_SPEED1000; 712 + if (ep->duplex == DUPLEX_FULL) 713 + cp->link_cntl |= BMCR_FULLDPLX; 714 + } 715 + #if 1 716 + changed = (lcntl != cp->link_cntl); 717 + #endif 718 + start_aneg: 719 + if (cp->lstate == link_up) { 720 + printk(KERN_INFO "%s: PCS link down.\n", 721 + cp->dev->name); 722 + } else { 723 + if (changed) { 724 + printk(KERN_INFO "%s: link configuration changed\n", 725 + cp->dev->name); 726 + } 727 + } 728 + cp->lstate = link_down; 729 + cp->link_transition = LINK_TRANSITION_LINK_DOWN; 730 + if (!cp->hw_running) 731 + return; 732 + #if 1 733 + /* 734 + * WTZ: If the old state was link_up, we turn off the carrier 735 + * to replicate everything we do elsewhere on a link-down 736 + * event when we were already in a link-up state.. 737 + */ 738 + if (oldstate == link_up) 739 + netif_carrier_off(cp->dev); 740 + if (changed && link_was_not_down) { 741 + /* 742 + * WTZ: This branch will simply schedule a full reset after 743 + * we explicitly changed link modes in an ioctl. See if this 744 + * fixes the link-problems we were having for forced mode. 745 + */ 746 + atomic_inc(&cp->reset_task_pending); 747 + atomic_inc(&cp->reset_task_pending_all); 748 + schedule_work(&cp->reset_task); 749 + cp->timer_ticks = 0; 750 + mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT); 751 + return; 752 + } 753 + #endif 754 + if (cp->phy_type & CAS_PHY_SERDES) { 755 + u32 val = readl(cp->regs + REG_PCS_MII_CTRL); 756 + 757 + if (cp->link_cntl & BMCR_ANENABLE) { 758 + val |= (PCS_MII_RESTART_AUTONEG | PCS_MII_AUTONEG_EN); 759 + cp->lstate = link_aneg; 760 + } else { 761 + if (cp->link_cntl & BMCR_FULLDPLX) 762 + val |= PCS_MII_CTRL_DUPLEX; 763 + val &= ~PCS_MII_AUTONEG_EN; 764 + cp->lstate = link_force_ok; 765 + } 766 + cp->link_transition = LINK_TRANSITION_LINK_CONFIG; 767 + writel(val, cp->regs + REG_PCS_MII_CTRL); 768 + 769 + } else { 770 + cas_mif_poll(cp, 0); 771 + ctl = cas_phy_read(cp, MII_BMCR); 772 + ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | 773 + CAS_BMCR_SPEED1000 | BMCR_ANENABLE); 774 + ctl |= cp->link_cntl; 775 + if (ctl & BMCR_ANENABLE) { 776 + ctl |= BMCR_ANRESTART; 777 + cp->lstate = link_aneg; 778 + } else { 779 + cp->lstate = link_force_ok; 780 + } 781 + cp->link_transition = LINK_TRANSITION_LINK_CONFIG; 782 + cas_phy_write(cp, MII_BMCR, ctl); 783 + cas_mif_poll(cp, 1); 784 + } 785 + 786 + cp->timer_ticks = 0; 787 + mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT); 788 + } 789 + 790 + /* Must be invoked under cp->lock. */ 791 + static int cas_reset_mii_phy(struct cas *cp) 792 + { 793 + int limit = STOP_TRIES_PHY; 794 + u16 val; 795 + 796 + cas_phy_write(cp, MII_BMCR, BMCR_RESET); 797 + udelay(100); 798 + while (limit--) { 799 + val = cas_phy_read(cp, MII_BMCR); 800 + if ((val & BMCR_RESET) == 0) 801 + break; 802 + udelay(10); 803 + } 804 + return (limit <= 0); 805 + } 806 + 807 + static void cas_saturn_firmware_load(struct cas *cp) 808 + { 809 + cas_saturn_patch_t *patch = cas_saturn_patch; 810 + 811 + cas_phy_powerdown(cp); 812 + 813 + /* expanded memory access mode */ 814 + cas_phy_write(cp, DP83065_MII_MEM, 0x0); 815 + 816 + /* pointer configuration for new firmware */ 817 + cas_phy_write(cp, DP83065_MII_REGE, 0x8ff9); 818 + cas_phy_write(cp, DP83065_MII_REGD, 0xbd); 819 + cas_phy_write(cp, DP83065_MII_REGE, 0x8ffa); 820 + cas_phy_write(cp, DP83065_MII_REGD, 0x82); 821 + cas_phy_write(cp, DP83065_MII_REGE, 0x8ffb); 822 + cas_phy_write(cp, DP83065_MII_REGD, 0x0); 823 + cas_phy_write(cp, DP83065_MII_REGE, 0x8ffc); 824 + cas_phy_write(cp, DP83065_MII_REGD, 0x39); 825 + 826 + /* download new firmware */ 827 + cas_phy_write(cp, DP83065_MII_MEM, 0x1); 828 + cas_phy_write(cp, DP83065_MII_REGE, patch->addr); 829 + while (patch->addr) { 830 + cas_phy_write(cp, DP83065_MII_REGD, patch->val); 831 + patch++; 832 + } 833 + 834 + /* enable firmware */ 835 + cas_phy_write(cp, DP83065_MII_REGE, 0x8ff8); 836 + cas_phy_write(cp, DP83065_MII_REGD, 0x1); 837 + } 838 + 839 + 840 + /* phy initialization */ 841 + static void cas_phy_init(struct cas *cp) 842 + { 843 + u16 val; 844 + 845 + /* if we're in MII/GMII mode, set up phy */ 846 + if (CAS_PHY_MII(cp->phy_type)) { 847 + writel(PCS_DATAPATH_MODE_MII, 848 + cp->regs + REG_PCS_DATAPATH_MODE); 849 + 850 + cas_mif_poll(cp, 0); 851 + cas_reset_mii_phy(cp); /* take out of isolate mode */ 852 + 853 + if (PHY_LUCENT_B0 == cp->phy_id) { 854 + /* workaround link up/down issue with lucent */ 855 + cas_phy_write(cp, LUCENT_MII_REG, 0x8000); 856 + cas_phy_write(cp, MII_BMCR, 0x00f1); 857 + cas_phy_write(cp, LUCENT_MII_REG, 0x0); 858 + 859 + } else if (PHY_BROADCOM_B0 == (cp->phy_id & 0xFFFFFFFC)) { 860 + /* workarounds for broadcom phy */ 861 + cas_phy_write(cp, BROADCOM_MII_REG8, 0x0C20); 862 + cas_phy_write(cp, BROADCOM_MII_REG7, 0x0012); 863 + cas_phy_write(cp, BROADCOM_MII_REG5, 0x1804); 864 + cas_phy_write(cp, BROADCOM_MII_REG7, 0x0013); 865 + cas_phy_write(cp, BROADCOM_MII_REG5, 0x1204); 866 + cas_phy_write(cp, BROADCOM_MII_REG7, 0x8006); 867 + cas_phy_write(cp, BROADCOM_MII_REG5, 0x0132); 868 + cas_phy_write(cp, BROADCOM_MII_REG7, 0x8006); 869 + cas_phy_write(cp, BROADCOM_MII_REG5, 0x0232); 870 + cas_phy_write(cp, BROADCOM_MII_REG7, 0x201F); 871 + cas_phy_write(cp, BROADCOM_MII_REG5, 0x0A20); 872 + 873 + } else if (PHY_BROADCOM_5411 == cp->phy_id) { 874 + val = cas_phy_read(cp, BROADCOM_MII_REG4); 875 + val = cas_phy_read(cp, BROADCOM_MII_REG4); 876 + if (val & 0x0080) { 877 + /* link workaround */ 878 + cas_phy_write(cp, BROADCOM_MII_REG4, 879 + val & ~0x0080); 880 + } 881 + 882 + } else if (cp->cas_flags & CAS_FLAG_SATURN) { 883 + writel((cp->phy_type & CAS_PHY_MII_MDIO0) ? 884 + SATURN_PCFG_FSI : 0x0, 885 + cp->regs + REG_SATURN_PCFG); 886 + 887 + /* load firmware to address 10Mbps auto-negotiation 888 + * issue. NOTE: this will need to be changed if the 889 + * default firmware gets fixed. 890 + */ 891 + if (PHY_NS_DP83065 == cp->phy_id) { 892 + cas_saturn_firmware_load(cp); 893 + } 894 + cas_phy_powerup(cp); 895 + } 896 + 897 + /* advertise capabilities */ 898 + val = cas_phy_read(cp, MII_BMCR); 899 + val &= ~BMCR_ANENABLE; 900 + cas_phy_write(cp, MII_BMCR, val); 901 + udelay(10); 902 + 903 + cas_phy_write(cp, MII_ADVERTISE, 904 + cas_phy_read(cp, MII_ADVERTISE) | 905 + (ADVERTISE_10HALF | ADVERTISE_10FULL | 906 + ADVERTISE_100HALF | ADVERTISE_100FULL | 907 + CAS_ADVERTISE_PAUSE | 908 + CAS_ADVERTISE_ASYM_PAUSE)); 909 + 910 + if (cp->cas_flags & CAS_FLAG_1000MB_CAP) { 911 + /* make sure that we don't advertise half 912 + * duplex to avoid a chip issue 913 + */ 914 + val = cas_phy_read(cp, CAS_MII_1000_CTRL); 915 + val &= ~CAS_ADVERTISE_1000HALF; 916 + val |= CAS_ADVERTISE_1000FULL; 917 + cas_phy_write(cp, CAS_MII_1000_CTRL, val); 918 + } 919 + 920 + } else { 921 + /* reset pcs for serdes */ 922 + u32 val; 923 + int limit; 924 + 925 + writel(PCS_DATAPATH_MODE_SERDES, 926 + cp->regs + REG_PCS_DATAPATH_MODE); 927 + 928 + /* enable serdes pins on saturn */ 929 + if (cp->cas_flags & CAS_FLAG_SATURN) 930 + writel(0, cp->regs + REG_SATURN_PCFG); 931 + 932 + /* Reset PCS unit. */ 933 + val = readl(cp->regs + REG_PCS_MII_CTRL); 934 + val |= PCS_MII_RESET; 935 + writel(val, cp->regs + REG_PCS_MII_CTRL); 936 + 937 + limit = STOP_TRIES; 938 + while (limit-- > 0) { 939 + udelay(10); 940 + if ((readl(cp->regs + REG_PCS_MII_CTRL) & 941 + PCS_MII_RESET) == 0) 942 + break; 943 + } 944 + if (limit <= 0) 945 + printk(KERN_WARNING "%s: PCS reset bit would not " 946 + "clear [%08x].\n", cp->dev->name, 947 + readl(cp->regs + REG_PCS_STATE_MACHINE)); 948 + 949 + /* Make sure PCS is disabled while changing advertisement 950 + * configuration. 951 + */ 952 + writel(0x0, cp->regs + REG_PCS_CFG); 953 + 954 + /* Advertise all capabilities except half-duplex. */ 955 + val = readl(cp->regs + REG_PCS_MII_ADVERT); 956 + val &= ~PCS_MII_ADVERT_HD; 957 + val |= (PCS_MII_ADVERT_FD | PCS_MII_ADVERT_SYM_PAUSE | 958 + PCS_MII_ADVERT_ASYM_PAUSE); 959 + writel(val, cp->regs + REG_PCS_MII_ADVERT); 960 + 961 + /* enable PCS */ 962 + writel(PCS_CFG_EN, cp->regs + REG_PCS_CFG); 963 + 964 + /* pcs workaround: enable sync detect */ 965 + writel(PCS_SERDES_CTRL_SYNCD_EN, 966 + cp->regs + REG_PCS_SERDES_CTRL); 967 + } 968 + } 969 + 970 + 971 + static int cas_pcs_link_check(struct cas *cp) 972 + { 973 + u32 stat, state_machine; 974 + int retval = 0; 975 + 976 + /* The link status bit latches on zero, so you must 977 + * read it twice in such a case to see a transition 978 + * to the link being up. 979 + */ 980 + stat = readl(cp->regs + REG_PCS_MII_STATUS); 981 + if ((stat & PCS_MII_STATUS_LINK_STATUS) == 0) 982 + stat = readl(cp->regs + REG_PCS_MII_STATUS); 983 + 984 + /* The remote-fault indication is only valid 985 + * when autoneg has completed. 986 + */ 987 + if ((stat & (PCS_MII_STATUS_AUTONEG_COMP | 988 + PCS_MII_STATUS_REMOTE_FAULT)) == 989 + (PCS_MII_STATUS_AUTONEG_COMP | PCS_MII_STATUS_REMOTE_FAULT)) { 990 + if (netif_msg_link(cp)) 991 + printk(KERN_INFO "%s: PCS RemoteFault\n", 992 + cp->dev->name); 993 + } 994 + 995 + /* work around link detection issue by querying the PCS state 996 + * machine directly. 997 + */ 998 + state_machine = readl(cp->regs + REG_PCS_STATE_MACHINE); 999 + if ((state_machine & PCS_SM_LINK_STATE_MASK) != SM_LINK_STATE_UP) { 1000 + stat &= ~PCS_MII_STATUS_LINK_STATUS; 1001 + } else if (state_machine & PCS_SM_WORD_SYNC_STATE_MASK) { 1002 + stat |= PCS_MII_STATUS_LINK_STATUS; 1003 + } 1004 + 1005 + if (stat & PCS_MII_STATUS_LINK_STATUS) { 1006 + if (cp->lstate != link_up) { 1007 + if (cp->opened) { 1008 + cp->lstate = link_up; 1009 + cp->link_transition = LINK_TRANSITION_LINK_UP; 1010 + 1011 + cas_set_link_modes(cp); 1012 + netif_carrier_on(cp->dev); 1013 + } 1014 + } 1015 + } else if (cp->lstate == link_up) { 1016 + cp->lstate = link_down; 1017 + if (link_transition_timeout != 0 && 1018 + cp->link_transition != LINK_TRANSITION_REQUESTED_RESET && 1019 + !cp->link_transition_jiffies_valid) { 1020 + /* 1021 + * force a reset, as a workaround for the 1022 + * link-failure problem. May want to move this to a 1023 + * point a bit earlier in the sequence. If we had 1024 + * generated a reset a short time ago, we'll wait for 1025 + * the link timer to check the status until a 1026 + * timer expires (link_transistion_jiffies_valid is 1027 + * true when the timer is running.) Instead of using 1028 + * a system timer, we just do a check whenever the 1029 + * link timer is running - this clears the flag after 1030 + * a suitable delay. 1031 + */ 1032 + retval = 1; 1033 + cp->link_transition = LINK_TRANSITION_REQUESTED_RESET; 1034 + cp->link_transition_jiffies = jiffies; 1035 + cp->link_transition_jiffies_valid = 1; 1036 + } else { 1037 + cp->link_transition = LINK_TRANSITION_ON_FAILURE; 1038 + } 1039 + netif_carrier_off(cp->dev); 1040 + if (cp->opened && netif_msg_link(cp)) { 1041 + printk(KERN_INFO "%s: PCS link down.\n", 1042 + cp->dev->name); 1043 + } 1044 + 1045 + /* Cassini only: if you force a mode, there can be 1046 + * sync problems on link down. to fix that, the following 1047 + * things need to be checked: 1048 + * 1) read serialink state register 1049 + * 2) read pcs status register to verify link down. 1050 + * 3) if link down and serial link == 0x03, then you need 1051 + * to global reset the chip. 1052 + */ 1053 + if ((cp->cas_flags & CAS_FLAG_REG_PLUS) == 0) { 1054 + /* should check to see if we're in a forced mode */ 1055 + stat = readl(cp->regs + REG_PCS_SERDES_STATE); 1056 + if (stat == 0x03) 1057 + return 1; 1058 + } 1059 + } else if (cp->lstate == link_down) { 1060 + if (link_transition_timeout != 0 && 1061 + cp->link_transition != LINK_TRANSITION_REQUESTED_RESET && 1062 + !cp->link_transition_jiffies_valid) { 1063 + /* force a reset, as a workaround for the 1064 + * link-failure problem. May want to move 1065 + * this to a point a bit earlier in the 1066 + * sequence. 1067 + */ 1068 + retval = 1; 1069 + cp->link_transition = LINK_TRANSITION_REQUESTED_RESET; 1070 + cp->link_transition_jiffies = jiffies; 1071 + cp->link_transition_jiffies_valid = 1; 1072 + } else { 1073 + cp->link_transition = LINK_TRANSITION_STILL_FAILED; 1074 + } 1075 + } 1076 + 1077 + return retval; 1078 + } 1079 + 1080 + static int cas_pcs_interrupt(struct net_device *dev, 1081 + struct cas *cp, u32 status) 1082 + { 1083 + u32 stat = readl(cp->regs + REG_PCS_INTR_STATUS); 1084 + 1085 + if ((stat & PCS_INTR_STATUS_LINK_CHANGE) == 0) 1086 + return 0; 1087 + return cas_pcs_link_check(cp); 1088 + } 1089 + 1090 + static int cas_txmac_interrupt(struct net_device *dev, 1091 + struct cas *cp, u32 status) 1092 + { 1093 + u32 txmac_stat = readl(cp->regs + REG_MAC_TX_STATUS); 1094 + 1095 + if (!txmac_stat) 1096 + return 0; 1097 + 1098 + if (netif_msg_intr(cp)) 1099 + printk(KERN_DEBUG "%s: txmac interrupt, txmac_stat: 0x%x\n", 1100 + cp->dev->name, txmac_stat); 1101 + 1102 + /* Defer timer expiration is quite normal, 1103 + * don't even log the event. 1104 + */ 1105 + if ((txmac_stat & MAC_TX_DEFER_TIMER) && 1106 + !(txmac_stat & ~MAC_TX_DEFER_TIMER)) 1107 + return 0; 1108 + 1109 + spin_lock(&cp->stat_lock[0]); 1110 + if (txmac_stat & MAC_TX_UNDERRUN) { 1111 + printk(KERN_ERR "%s: TX MAC xmit underrun.\n", 1112 + dev->name); 1113 + cp->net_stats[0].tx_fifo_errors++; 1114 + } 1115 + 1116 + if (txmac_stat & MAC_TX_MAX_PACKET_ERR) { 1117 + printk(KERN_ERR "%s: TX MAC max packet size error.\n", 1118 + dev->name); 1119 + cp->net_stats[0].tx_errors++; 1120 + } 1121 + 1122 + /* The rest are all cases of one of the 16-bit TX 1123 + * counters expiring. 1124 + */ 1125 + if (txmac_stat & MAC_TX_COLL_NORMAL) 1126 + cp->net_stats[0].collisions += 0x10000; 1127 + 1128 + if (txmac_stat & MAC_TX_COLL_EXCESS) { 1129 + cp->net_stats[0].tx_aborted_errors += 0x10000; 1130 + cp->net_stats[0].collisions += 0x10000; 1131 + } 1132 + 1133 + if (txmac_stat & MAC_TX_COLL_LATE) { 1134 + cp->net_stats[0].tx_aborted_errors += 0x10000; 1135 + cp->net_stats[0].collisions += 0x10000; 1136 + } 1137 + spin_unlock(&cp->stat_lock[0]); 1138 + 1139 + /* We do not keep track of MAC_TX_COLL_FIRST and 1140 + * MAC_TX_PEAK_ATTEMPTS events. 1141 + */ 1142 + return 0; 1143 + } 1144 + 1145 + static void cas_load_firmware(struct cas *cp, cas_hp_inst_t *firmware) 1146 + { 1147 + cas_hp_inst_t *inst; 1148 + u32 val; 1149 + int i; 1150 + 1151 + i = 0; 1152 + while ((inst = firmware) && inst->note) { 1153 + writel(i, cp->regs + REG_HP_INSTR_RAM_ADDR); 1154 + 1155 + val = CAS_BASE(HP_INSTR_RAM_HI_VAL, inst->val); 1156 + val |= CAS_BASE(HP_INSTR_RAM_HI_MASK, inst->mask); 1157 + writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_HI); 1158 + 1159 + val = CAS_BASE(HP_INSTR_RAM_MID_OUTARG, inst->outarg >> 10); 1160 + val |= CAS_BASE(HP_INSTR_RAM_MID_OUTOP, inst->outop); 1161 + val |= CAS_BASE(HP_INSTR_RAM_MID_FNEXT, inst->fnext); 1162 + val |= CAS_BASE(HP_INSTR_RAM_MID_FOFF, inst->foff); 1163 + val |= CAS_BASE(HP_INSTR_RAM_MID_SNEXT, inst->snext); 1164 + val |= CAS_BASE(HP_INSTR_RAM_MID_SOFF, inst->soff); 1165 + val |= CAS_BASE(HP_INSTR_RAM_MID_OP, inst->op); 1166 + writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_MID); 1167 + 1168 + val = CAS_BASE(HP_INSTR_RAM_LOW_OUTMASK, inst->outmask); 1169 + val |= CAS_BASE(HP_INSTR_RAM_LOW_OUTSHIFT, inst->outshift); 1170 + val |= CAS_BASE(HP_INSTR_RAM_LOW_OUTEN, inst->outenab); 1171 + val |= CAS_BASE(HP_INSTR_RAM_LOW_OUTARG, inst->outarg); 1172 + writel(val, cp->regs + REG_HP_INSTR_RAM_DATA_LOW); 1173 + ++firmware; 1174 + ++i; 1175 + } 1176 + } 1177 + 1178 + static void cas_init_rx_dma(struct cas *cp) 1179 + { 1180 + u64 desc_dma = cp->block_dvma; 1181 + u32 val; 1182 + int i, size; 1183 + 1184 + /* rx free descriptors */ 1185 + val = CAS_BASE(RX_CFG_SWIVEL, RX_SWIVEL_OFF_VAL); 1186 + val |= CAS_BASE(RX_CFG_DESC_RING, RX_DESC_RINGN_INDEX(0)); 1187 + val |= CAS_BASE(RX_CFG_COMP_RING, RX_COMP_RINGN_INDEX(0)); 1188 + if ((N_RX_DESC_RINGS > 1) && 1189 + (cp->cas_flags & CAS_FLAG_REG_PLUS)) /* do desc 2 */ 1190 + val |= CAS_BASE(RX_CFG_DESC_RING1, RX_DESC_RINGN_INDEX(1)); 1191 + writel(val, cp->regs + REG_RX_CFG); 1192 + 1193 + val = (unsigned long) cp->init_rxds[0] - 1194 + (unsigned long) cp->init_block; 1195 + writel((desc_dma + val) >> 32, cp->regs + REG_RX_DB_HI); 1196 + writel((desc_dma + val) & 0xffffffff, cp->regs + REG_RX_DB_LOW); 1197 + writel(RX_DESC_RINGN_SIZE(0) - 4, cp->regs + REG_RX_KICK); 1198 + 1199 + if (cp->cas_flags & CAS_FLAG_REG_PLUS) { 1200 + /* rx desc 2 is for IPSEC packets. however, 1201 + * we don't it that for that purpose. 1202 + */ 1203 + val = (unsigned long) cp->init_rxds[1] - 1204 + (unsigned long) cp->init_block; 1205 + writel((desc_dma + val) >> 32, cp->regs + REG_PLUS_RX_DB1_HI); 1206 + writel((desc_dma + val) & 0xffffffff, cp->regs + 1207 + REG_PLUS_RX_DB1_LOW); 1208 + writel(RX_DESC_RINGN_SIZE(1) - 4, cp->regs + 1209 + REG_PLUS_RX_KICK1); 1210 + } 1211 + 1212 + /* rx completion registers */ 1213 + val = (unsigned long) cp->init_rxcs[0] - 1214 + (unsigned long) cp->init_block; 1215 + writel((desc_dma + val) >> 32, cp->regs + REG_RX_CB_HI); 1216 + writel((desc_dma + val) & 0xffffffff, cp->regs + REG_RX_CB_LOW); 1217 + 1218 + if (cp->cas_flags & CAS_FLAG_REG_PLUS) { 1219 + /* rx comp 2-4 */ 1220 + for (i = 1; i < MAX_RX_COMP_RINGS; i++) { 1221 + val = (unsigned long) cp->init_rxcs[i] - 1222 + (unsigned long) cp->init_block; 1223 + writel((desc_dma + val) >> 32, cp->regs + 1224 + REG_PLUS_RX_CBN_HI(i)); 1225 + writel((desc_dma + val) & 0xffffffff, cp->regs + 1226 + REG_PLUS_RX_CBN_LOW(i)); 1227 + } 1228 + } 1229 + 1230 + /* read selective clear regs to prevent spurious interrupts 1231 + * on reset because complete == kick. 1232 + * selective clear set up to prevent interrupts on resets 1233 + */ 1234 + readl(cp->regs + REG_INTR_STATUS_ALIAS); 1235 + writel(INTR_RX_DONE | INTR_RX_BUF_UNAVAIL, cp->regs + REG_ALIAS_CLEAR); 1236 + if (cp->cas_flags & CAS_FLAG_REG_PLUS) { 1237 + for (i = 1; i < N_RX_COMP_RINGS; i++) 1238 + readl(cp->regs + REG_PLUS_INTRN_STATUS_ALIAS(i)); 1239 + 1240 + /* 2 is different from 3 and 4 */ 1241 + if (N_RX_COMP_RINGS > 1) 1242 + writel(INTR_RX_DONE_ALT | INTR_RX_BUF_UNAVAIL_1, 1243 + cp->regs + REG_PLUS_ALIASN_CLEAR(1)); 1244 + 1245 + for (i = 2; i < N_RX_COMP_RINGS; i++) 1246 + writel(INTR_RX_DONE_ALT, 1247 + cp->regs + REG_PLUS_ALIASN_CLEAR(i)); 1248 + } 1249 + 1250 + /* set up pause thresholds */ 1251 + val = CAS_BASE(RX_PAUSE_THRESH_OFF, 1252 + cp->rx_pause_off / RX_PAUSE_THRESH_QUANTUM); 1253 + val |= CAS_BASE(RX_PAUSE_THRESH_ON, 1254 + cp->rx_pause_on / RX_PAUSE_THRESH_QUANTUM); 1255 + writel(val, cp->regs + REG_RX_PAUSE_THRESH); 1256 + 1257 + /* zero out dma reassembly buffers */ 1258 + for (i = 0; i < 64; i++) { 1259 + writel(i, cp->regs + REG_RX_TABLE_ADDR); 1260 + writel(0x0, cp->regs + REG_RX_TABLE_DATA_LOW); 1261 + writel(0x0, cp->regs + REG_RX_TABLE_DATA_MID); 1262 + writel(0x0, cp->regs + REG_RX_TABLE_DATA_HI); 1263 + } 1264 + 1265 + /* make sure address register is 0 for normal operation */ 1266 + writel(0x0, cp->regs + REG_RX_CTRL_FIFO_ADDR); 1267 + writel(0x0, cp->regs + REG_RX_IPP_FIFO_ADDR); 1268 + 1269 + /* interrupt mitigation */ 1270 + #ifdef USE_RX_BLANK 1271 + val = CAS_BASE(RX_BLANK_INTR_TIME, RX_BLANK_INTR_TIME_VAL); 1272 + val |= CAS_BASE(RX_BLANK_INTR_PKT, RX_BLANK_INTR_PKT_VAL); 1273 + writel(val, cp->regs + REG_RX_BLANK); 1274 + #else 1275 + writel(0x0, cp->regs + REG_RX_BLANK); 1276 + #endif 1277 + 1278 + /* interrupt generation as a function of low water marks for 1279 + * free desc and completion entries. these are used to trigger 1280 + * housekeeping for rx descs. we don't use the free interrupt 1281 + * as it's not very useful 1282 + */ 1283 + /* val = CAS_BASE(RX_AE_THRESH_FREE, RX_AE_FREEN_VAL(0)); */ 1284 + val = CAS_BASE(RX_AE_THRESH_COMP, RX_AE_COMP_VAL); 1285 + writel(val, cp->regs + REG_RX_AE_THRESH); 1286 + if (cp->cas_flags & CAS_FLAG_REG_PLUS) { 1287 + val = CAS_BASE(RX_AE1_THRESH_FREE, RX_AE_FREEN_VAL(1)); 1288 + writel(val, cp->regs + REG_PLUS_RX_AE1_THRESH); 1289 + } 1290 + 1291 + /* Random early detect registers. useful for congestion avoidance. 1292 + * this should be tunable. 1293 + */ 1294 + writel(0x0, cp->regs + REG_RX_RED); 1295 + 1296 + /* receive page sizes. default == 2K (0x800) */ 1297 + val = 0; 1298 + if (cp->page_size == 0x1000) 1299 + val = 0x1; 1300 + else if (cp->page_size == 0x2000) 1301 + val = 0x2; 1302 + else if (cp->page_size == 0x4000) 1303 + val = 0x3; 1304 + 1305 + /* round mtu + offset. constrain to page size. */ 1306 + size = cp->dev->mtu + 64; 1307 + if (size > cp->page_size) 1308 + size = cp->page_size; 1309 + 1310 + if (size <= 0x400) 1311 + i = 0x0; 1312 + else if (size <= 0x800) 1313 + i = 0x1; 1314 + else if (size <= 0x1000) 1315 + i = 0x2; 1316 + else 1317 + i = 0x3; 1318 + 1319 + cp->mtu_stride = 1 << (i + 10); 1320 + val = CAS_BASE(RX_PAGE_SIZE, val); 1321 + val |= CAS_BASE(RX_PAGE_SIZE_MTU_STRIDE, i); 1322 + val |= CAS_BASE(RX_PAGE_SIZE_MTU_COUNT, cp->page_size >> (i + 10)); 1323 + val |= CAS_BASE(RX_PAGE_SIZE_MTU_OFF, 0x1); 1324 + writel(val, cp->regs + REG_RX_PAGE_SIZE); 1325 + 1326 + /* enable the header parser if desired */ 1327 + if (CAS_HP_FIRMWARE == cas_prog_null) 1328 + return; 1329 + 1330 + val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS); 1331 + val |= HP_CFG_PARSE_EN | HP_CFG_SYN_INC_MASK; 1332 + val |= CAS_BASE(HP_CFG_TCP_THRESH, HP_TCP_THRESH_VAL); 1333 + writel(val, cp->regs + REG_HP_CFG); 1334 + } 1335 + 1336 + static inline void cas_rxc_init(struct cas_rx_comp *rxc) 1337 + { 1338 + memset(rxc, 0, sizeof(*rxc)); 1339 + rxc->word4 = cpu_to_le64(RX_COMP4_ZERO); 1340 + } 1341 + 1342 + /* NOTE: we use the ENC RX DESC ring for spares. the rx_page[0,1] 1343 + * flipping is protected by the fact that the chip will not 1344 + * hand back the same page index while it's being processed. 1345 + */ 1346 + static inline cas_page_t *cas_page_spare(struct cas *cp, const int index) 1347 + { 1348 + cas_page_t *page = cp->rx_pages[1][index]; 1349 + cas_page_t *new; 1350 + 1351 + if (page_count(page->buffer) == 1) 1352 + return page; 1353 + 1354 + new = cas_page_dequeue(cp); 1355 + if (new) { 1356 + spin_lock(&cp->rx_inuse_lock); 1357 + list_add(&page->list, &cp->rx_inuse_list); 1358 + spin_unlock(&cp->rx_inuse_lock); 1359 + } 1360 + return new; 1361 + } 1362 + 1363 + /* this needs to be changed if we actually use the ENC RX DESC ring */ 1364 + static cas_page_t *cas_page_swap(struct cas *cp, const int ring, 1365 + const int index) 1366 + { 1367 + cas_page_t **page0 = cp->rx_pages[0]; 1368 + cas_page_t **page1 = cp->rx_pages[1]; 1369 + 1370 + /* swap if buffer is in use */ 1371 + if (page_count(page0[index]->buffer) > 1) { 1372 + cas_page_t *new = cas_page_spare(cp, index); 1373 + if (new) { 1374 + page1[index] = page0[index]; 1375 + page0[index] = new; 1376 + } 1377 + } 1378 + RX_USED_SET(page0[index], 0); 1379 + return page0[index]; 1380 + } 1381 + 1382 + static void cas_clean_rxds(struct cas *cp) 1383 + { 1384 + /* only clean ring 0 as ring 1 is used for spare buffers */ 1385 + struct cas_rx_desc *rxd = cp->init_rxds[0]; 1386 + int i, size; 1387 + 1388 + /* release all rx flows */ 1389 + for (i = 0; i < N_RX_FLOWS; i++) { 1390 + struct sk_buff *skb; 1391 + while ((skb = __skb_dequeue(&cp->rx_flows[i]))) { 1392 + cas_skb_release(skb); 1393 + } 1394 + } 1395 + 1396 + /* initialize descriptors */ 1397 + size = RX_DESC_RINGN_SIZE(0); 1398 + for (i = 0; i < size; i++) { 1399 + cas_page_t *page = cas_page_swap(cp, 0, i); 1400 + rxd[i].buffer = cpu_to_le64(page->dma_addr); 1401 + rxd[i].index = cpu_to_le64(CAS_BASE(RX_INDEX_NUM, i) | 1402 + CAS_BASE(RX_INDEX_RING, 0)); 1403 + } 1404 + 1405 + cp->rx_old[0] = RX_DESC_RINGN_SIZE(0) - 4; 1406 + cp->rx_last[0] = 0; 1407 + cp->cas_flags &= ~CAS_FLAG_RXD_POST(0); 1408 + } 1409 + 1410 + static void cas_clean_rxcs(struct cas *cp) 1411 + { 1412 + int i, j; 1413 + 1414 + /* take ownership of rx comp descriptors */ 1415 + memset(cp->rx_cur, 0, sizeof(*cp->rx_cur)*N_RX_COMP_RINGS); 1416 + memset(cp->rx_new, 0, sizeof(*cp->rx_new)*N_RX_COMP_RINGS); 1417 + for (i = 0; i < N_RX_COMP_RINGS; i++) { 1418 + struct cas_rx_comp *rxc = cp->init_rxcs[i]; 1419 + for (j = 0; j < RX_COMP_RINGN_SIZE(i); j++) { 1420 + cas_rxc_init(rxc + j); 1421 + } 1422 + } 1423 + } 1424 + 1425 + #if 0 1426 + /* When we get a RX fifo overflow, the RX unit is probably hung 1427 + * so we do the following. 1428 + * 1429 + * If any part of the reset goes wrong, we return 1 and that causes the 1430 + * whole chip to be reset. 1431 + */ 1432 + static int cas_rxmac_reset(struct cas *cp) 1433 + { 1434 + struct net_device *dev = cp->dev; 1435 + int limit; 1436 + u32 val; 1437 + 1438 + /* First, reset MAC RX. */ 1439 + writel(cp->mac_rx_cfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG); 1440 + for (limit = 0; limit < STOP_TRIES; limit++) { 1441 + if (!(readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_EN)) 1442 + break; 1443 + udelay(10); 1444 + } 1445 + if (limit == STOP_TRIES) { 1446 + printk(KERN_ERR "%s: RX MAC will not disable, resetting whole " 1447 + "chip.\n", dev->name); 1448 + return 1; 1449 + } 1450 + 1451 + /* Second, disable RX DMA. */ 1452 + writel(0, cp->regs + REG_RX_CFG); 1453 + for (limit = 0; limit < STOP_TRIES; limit++) { 1454 + if (!(readl(cp->regs + REG_RX_CFG) & RX_CFG_DMA_EN)) 1455 + break; 1456 + udelay(10); 1457 + } 1458 + if (limit == STOP_TRIES) { 1459 + printk(KERN_ERR "%s: RX DMA will not disable, resetting whole " 1460 + "chip.\n", dev->name); 1461 + return 1; 1462 + } 1463 + 1464 + mdelay(5); 1465 + 1466 + /* Execute RX reset command. */ 1467 + writel(SW_RESET_RX, cp->regs + REG_SW_RESET); 1468 + for (limit = 0; limit < STOP_TRIES; limit++) { 1469 + if (!(readl(cp->regs + REG_SW_RESET) & SW_RESET_RX)) 1470 + break; 1471 + udelay(10); 1472 + } 1473 + if (limit == STOP_TRIES) { 1474 + printk(KERN_ERR "%s: RX reset command will not execute, " 1475 + "resetting whole chip.\n", dev->name); 1476 + return 1; 1477 + } 1478 + 1479 + /* reset driver rx state */ 1480 + cas_clean_rxds(cp); 1481 + cas_clean_rxcs(cp); 1482 + 1483 + /* Now, reprogram the rest of RX unit. */ 1484 + cas_init_rx_dma(cp); 1485 + 1486 + /* re-enable */ 1487 + val = readl(cp->regs + REG_RX_CFG); 1488 + writel(val | RX_CFG_DMA_EN, cp->regs + REG_RX_CFG); 1489 + writel(MAC_RX_FRAME_RECV, cp->regs + REG_MAC_RX_MASK); 1490 + val = readl(cp->regs + REG_MAC_RX_CFG); 1491 + writel(val | MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG); 1492 + return 0; 1493 + } 1494 + #endif 1495 + 1496 + static int cas_rxmac_interrupt(struct net_device *dev, struct cas *cp, 1497 + u32 status) 1498 + { 1499 + u32 stat = readl(cp->regs + REG_MAC_RX_STATUS); 1500 + 1501 + if (!stat) 1502 + return 0; 1503 + 1504 + if (netif_msg_intr(cp)) 1505 + printk(KERN_DEBUG "%s: rxmac interrupt, stat: 0x%x\n", 1506 + cp->dev->name, stat); 1507 + 1508 + /* these are all rollovers */ 1509 + spin_lock(&cp->stat_lock[0]); 1510 + if (stat & MAC_RX_ALIGN_ERR) 1511 + cp->net_stats[0].rx_frame_errors += 0x10000; 1512 + 1513 + if (stat & MAC_RX_CRC_ERR) 1514 + cp->net_stats[0].rx_crc_errors += 0x10000; 1515 + 1516 + if (stat & MAC_RX_LEN_ERR) 1517 + cp->net_stats[0].rx_length_errors += 0x10000; 1518 + 1519 + if (stat & MAC_RX_OVERFLOW) { 1520 + cp->net_stats[0].rx_over_errors++; 1521 + cp->net_stats[0].rx_fifo_errors++; 1522 + } 1523 + 1524 + /* We do not track MAC_RX_FRAME_COUNT and MAC_RX_VIOL_ERR 1525 + * events. 1526 + */ 1527 + spin_unlock(&cp->stat_lock[0]); 1528 + return 0; 1529 + } 1530 + 1531 + static int cas_mac_interrupt(struct net_device *dev, struct cas *cp, 1532 + u32 status) 1533 + { 1534 + u32 stat = readl(cp->regs + REG_MAC_CTRL_STATUS); 1535 + 1536 + if (!stat) 1537 + return 0; 1538 + 1539 + if (netif_msg_intr(cp)) 1540 + printk(KERN_DEBUG "%s: mac interrupt, stat: 0x%x\n", 1541 + cp->dev->name, stat); 1542 + 1543 + /* This interrupt is just for pause frame and pause 1544 + * tracking. It is useful for diagnostics and debug 1545 + * but probably by default we will mask these events. 1546 + */ 1547 + if (stat & MAC_CTRL_PAUSE_STATE) 1548 + cp->pause_entered++; 1549 + 1550 + if (stat & MAC_CTRL_PAUSE_RECEIVED) 1551 + cp->pause_last_time_recvd = (stat >> 16); 1552 + 1553 + return 0; 1554 + } 1555 + 1556 + 1557 + /* Must be invoked under cp->lock. */ 1558 + static inline int cas_mdio_link_not_up(struct cas *cp) 1559 + { 1560 + u16 val; 1561 + 1562 + switch (cp->lstate) { 1563 + case link_force_ret: 1564 + if (netif_msg_link(cp)) 1565 + printk(KERN_INFO "%s: Autoneg failed again, keeping" 1566 + " forced mode\n", cp->dev->name); 1567 + cas_phy_write(cp, MII_BMCR, cp->link_fcntl); 1568 + cp->timer_ticks = 5; 1569 + cp->lstate = link_force_ok; 1570 + cp->link_transition = LINK_TRANSITION_LINK_CONFIG; 1571 + break; 1572 + 1573 + case link_aneg: 1574 + val = cas_phy_read(cp, MII_BMCR); 1575 + 1576 + /* Try forced modes. we try things in the following order: 1577 + * 1000 full -> 100 full/half -> 10 half 1578 + */ 1579 + val &= ~(BMCR_ANRESTART | BMCR_ANENABLE); 1580 + val |= BMCR_FULLDPLX; 1581 + val |= (cp->cas_flags & CAS_FLAG_1000MB_CAP) ? 1582 + CAS_BMCR_SPEED1000 : BMCR_SPEED100; 1583 + cas_phy_write(cp, MII_BMCR, val); 1584 + cp->timer_ticks = 5; 1585 + cp->lstate = link_force_try; 1586 + cp->link_transition = LINK_TRANSITION_LINK_CONFIG; 1587 + break; 1588 + 1589 + case link_force_try: 1590 + /* Downgrade from 1000 to 100 to 10 Mbps if necessary. */ 1591 + val = cas_phy_read(cp, MII_BMCR); 1592 + cp->timer_ticks = 5; 1593 + if (val & CAS_BMCR_SPEED1000) { /* gigabit */ 1594 + val &= ~CAS_BMCR_SPEED1000; 1595 + val |= (BMCR_SPEED100 | BMCR_FULLDPLX); 1596 + cas_phy_write(cp, MII_BMCR, val); 1597 + break; 1598 + } 1599 + 1600 + if (val & BMCR_SPEED100) { 1601 + if (val & BMCR_FULLDPLX) /* fd failed */ 1602 + val &= ~BMCR_FULLDPLX; 1603 + else { /* 100Mbps failed */ 1604 + val &= ~BMCR_SPEED100; 1605 + } 1606 + cas_phy_write(cp, MII_BMCR, val); 1607 + break; 1608 + } 1609 + default: 1610 + break; 1611 + } 1612 + return 0; 1613 + } 1614 + 1615 + 1616 + /* must be invoked with cp->lock held */ 1617 + static int cas_mii_link_check(struct cas *cp, const u16 bmsr) 1618 + { 1619 + int restart; 1620 + 1621 + if (bmsr & BMSR_LSTATUS) { 1622 + /* Ok, here we got a link. If we had it due to a forced 1623 + * fallback, and we were configured for autoneg, we 1624 + * retry a short autoneg pass. If you know your hub is 1625 + * broken, use ethtool ;) 1626 + */ 1627 + if ((cp->lstate == link_force_try) && 1628 + (cp->link_cntl & BMCR_ANENABLE)) { 1629 + cp->lstate = link_force_ret; 1630 + cp->link_transition = LINK_TRANSITION_LINK_CONFIG; 1631 + cas_mif_poll(cp, 0); 1632 + cp->link_fcntl = cas_phy_read(cp, MII_BMCR); 1633 + cp->timer_ticks = 5; 1634 + if (cp->opened && netif_msg_link(cp)) 1635 + printk(KERN_INFO "%s: Got link after fallback, retrying" 1636 + " autoneg once...\n", cp->dev->name); 1637 + cas_phy_write(cp, MII_BMCR, 1638 + cp->link_fcntl | BMCR_ANENABLE | 1639 + BMCR_ANRESTART); 1640 + cas_mif_poll(cp, 1); 1641 + 1642 + } else if (cp->lstate != link_up) { 1643 + cp->lstate = link_up; 1644 + cp->link_transition = LINK_TRANSITION_LINK_UP; 1645 + 1646 + if (cp->opened) { 1647 + cas_set_link_modes(cp); 1648 + netif_carrier_on(cp->dev); 1649 + } 1650 + } 1651 + return 0; 1652 + } 1653 + 1654 + /* link not up. if the link was previously up, we restart the 1655 + * whole process 1656 + */ 1657 + restart = 0; 1658 + if (cp->lstate == link_up) { 1659 + cp->lstate = link_down; 1660 + cp->link_transition = LINK_TRANSITION_LINK_DOWN; 1661 + 1662 + netif_carrier_off(cp->dev); 1663 + if (cp->opened && netif_msg_link(cp)) 1664 + printk(KERN_INFO "%s: Link down\n", 1665 + cp->dev->name); 1666 + restart = 1; 1667 + 1668 + } else if (++cp->timer_ticks > 10) 1669 + cas_mdio_link_not_up(cp); 1670 + 1671 + return restart; 1672 + } 1673 + 1674 + static int cas_mif_interrupt(struct net_device *dev, struct cas *cp, 1675 + u32 status) 1676 + { 1677 + u32 stat = readl(cp->regs + REG_MIF_STATUS); 1678 + u16 bmsr; 1679 + 1680 + /* check for a link change */ 1681 + if (CAS_VAL(MIF_STATUS_POLL_STATUS, stat) == 0) 1682 + return 0; 1683 + 1684 + bmsr = CAS_VAL(MIF_STATUS_POLL_DATA, stat); 1685 + return cas_mii_link_check(cp, bmsr); 1686 + } 1687 + 1688 + static int cas_pci_interrupt(struct net_device *dev, struct cas *cp, 1689 + u32 status) 1690 + { 1691 + u32 stat = readl(cp->regs + REG_PCI_ERR_STATUS); 1692 + 1693 + if (!stat) 1694 + return 0; 1695 + 1696 + printk(KERN_ERR "%s: PCI error [%04x:%04x] ", dev->name, stat, 1697 + readl(cp->regs + REG_BIM_DIAG)); 1698 + 1699 + /* cassini+ has this reserved */ 1700 + if ((stat & PCI_ERR_BADACK) && 1701 + ((cp->cas_flags & CAS_FLAG_REG_PLUS) == 0)) 1702 + printk("<No ACK64# during ABS64 cycle> "); 1703 + 1704 + if (stat & PCI_ERR_DTRTO) 1705 + printk("<Delayed transaction timeout> "); 1706 + if (stat & PCI_ERR_OTHER) 1707 + printk("<other> "); 1708 + if (stat & PCI_ERR_BIM_DMA_WRITE) 1709 + printk("<BIM DMA 0 write req> "); 1710 + if (stat & PCI_ERR_BIM_DMA_READ) 1711 + printk("<BIM DMA 0 read req> "); 1712 + printk("\n"); 1713 + 1714 + if (stat & PCI_ERR_OTHER) { 1715 + u16 cfg; 1716 + 1717 + /* Interrogate PCI config space for the 1718 + * true cause. 1719 + */ 1720 + pci_read_config_word(cp->pdev, PCI_STATUS, &cfg); 1721 + printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n", 1722 + dev->name, cfg); 1723 + if (cfg & PCI_STATUS_PARITY) 1724 + printk(KERN_ERR "%s: PCI parity error detected.\n", 1725 + dev->name); 1726 + if (cfg & PCI_STATUS_SIG_TARGET_ABORT) 1727 + printk(KERN_ERR "%s: PCI target abort.\n", 1728 + dev->name); 1729 + if (cfg & PCI_STATUS_REC_TARGET_ABORT) 1730 + printk(KERN_ERR "%s: PCI master acks target abort.\n", 1731 + dev->name); 1732 + if (cfg & PCI_STATUS_REC_MASTER_ABORT) 1733 + printk(KERN_ERR "%s: PCI master abort.\n", dev->name); 1734 + if (cfg & PCI_STATUS_SIG_SYSTEM_ERROR) 1735 + printk(KERN_ERR "%s: PCI system error SERR#.\n", 1736 + dev->name); 1737 + if (cfg & PCI_STATUS_DETECTED_PARITY) 1738 + printk(KERN_ERR "%s: PCI parity error.\n", 1739 + dev->name); 1740 + 1741 + /* Write the error bits back to clear them. */ 1742 + cfg &= (PCI_STATUS_PARITY | 1743 + PCI_STATUS_SIG_TARGET_ABORT | 1744 + PCI_STATUS_REC_TARGET_ABORT | 1745 + PCI_STATUS_REC_MASTER_ABORT | 1746 + PCI_STATUS_SIG_SYSTEM_ERROR | 1747 + PCI_STATUS_DETECTED_PARITY); 1748 + pci_write_config_word(cp->pdev, PCI_STATUS, cfg); 1749 + } 1750 + 1751 + /* For all PCI errors, we should reset the chip. */ 1752 + return 1; 1753 + } 1754 + 1755 + /* All non-normal interrupt conditions get serviced here. 1756 + * Returns non-zero if we should just exit the interrupt 1757 + * handler right now (ie. if we reset the card which invalidates 1758 + * all of the other original irq status bits). 1759 + */ 1760 + static int cas_abnormal_irq(struct net_device *dev, struct cas *cp, 1761 + u32 status) 1762 + { 1763 + if (status & INTR_RX_TAG_ERROR) { 1764 + /* corrupt RX tag framing */ 1765 + if (netif_msg_rx_err(cp)) 1766 + printk(KERN_DEBUG "%s: corrupt rx tag framing\n", 1767 + cp->dev->name); 1768 + spin_lock(&cp->stat_lock[0]); 1769 + cp->net_stats[0].rx_errors++; 1770 + spin_unlock(&cp->stat_lock[0]); 1771 + goto do_reset; 1772 + } 1773 + 1774 + if (status & INTR_RX_LEN_MISMATCH) { 1775 + /* length mismatch. */ 1776 + if (netif_msg_rx_err(cp)) 1777 + printk(KERN_DEBUG "%s: length mismatch for rx frame\n", 1778 + cp->dev->name); 1779 + spin_lock(&cp->stat_lock[0]); 1780 + cp->net_stats[0].rx_errors++; 1781 + spin_unlock(&cp->stat_lock[0]); 1782 + goto do_reset; 1783 + } 1784 + 1785 + if (status & INTR_PCS_STATUS) { 1786 + if (cas_pcs_interrupt(dev, cp, status)) 1787 + goto do_reset; 1788 + } 1789 + 1790 + if (status & INTR_TX_MAC_STATUS) { 1791 + if (cas_txmac_interrupt(dev, cp, status)) 1792 + goto do_reset; 1793 + } 1794 + 1795 + if (status & INTR_RX_MAC_STATUS) { 1796 + if (cas_rxmac_interrupt(dev, cp, status)) 1797 + goto do_reset; 1798 + } 1799 + 1800 + if (status & INTR_MAC_CTRL_STATUS) { 1801 + if (cas_mac_interrupt(dev, cp, status)) 1802 + goto do_reset; 1803 + } 1804 + 1805 + if (status & INTR_MIF_STATUS) { 1806 + if (cas_mif_interrupt(dev, cp, status)) 1807 + goto do_reset; 1808 + } 1809 + 1810 + if (status & INTR_PCI_ERROR_STATUS) { 1811 + if (cas_pci_interrupt(dev, cp, status)) 1812 + goto do_reset; 1813 + } 1814 + return 0; 1815 + 1816 + do_reset: 1817 + #if 1 1818 + atomic_inc(&cp->reset_task_pending); 1819 + atomic_inc(&cp->reset_task_pending_all); 1820 + printk(KERN_ERR "%s:reset called in cas_abnormal_irq [0x%x]\n", 1821 + dev->name, status); 1822 + schedule_work(&cp->reset_task); 1823 + #else 1824 + atomic_set(&cp->reset_task_pending, CAS_RESET_ALL); 1825 + printk(KERN_ERR "reset called in cas_abnormal_irq\n"); 1826 + schedule_work(&cp->reset_task); 1827 + #endif 1828 + return 1; 1829 + } 1830 + 1831 + /* NOTE: CAS_TABORT returns 1 or 2 so that it can be used when 1832 + * determining whether to do a netif_stop/wakeup 1833 + */ 1834 + #define CAS_TABORT(x) (((x)->cas_flags & CAS_FLAG_TARGET_ABORT) ? 2 : 1) 1835 + #define CAS_ROUND_PAGE(x) (((x) + PAGE_SIZE - 1) & PAGE_MASK) 1836 + static inline int cas_calc_tabort(struct cas *cp, const unsigned long addr, 1837 + const int len) 1838 + { 1839 + unsigned long off = addr + len; 1840 + 1841 + if (CAS_TABORT(cp) == 1) 1842 + return 0; 1843 + if ((CAS_ROUND_PAGE(off) - off) > TX_TARGET_ABORT_LEN) 1844 + return 0; 1845 + return TX_TARGET_ABORT_LEN; 1846 + } 1847 + 1848 + static inline void cas_tx_ringN(struct cas *cp, int ring, int limit) 1849 + { 1850 + struct cas_tx_desc *txds; 1851 + struct sk_buff **skbs; 1852 + struct net_device *dev = cp->dev; 1853 + int entry, count; 1854 + 1855 + spin_lock(&cp->tx_lock[ring]); 1856 + txds = cp->init_txds[ring]; 1857 + skbs = cp->tx_skbs[ring]; 1858 + entry = cp->tx_old[ring]; 1859 + 1860 + count = TX_BUFF_COUNT(ring, entry, limit); 1861 + while (entry != limit) { 1862 + struct sk_buff *skb = skbs[entry]; 1863 + dma_addr_t daddr; 1864 + u32 dlen; 1865 + int frag; 1866 + 1867 + if (!skb) { 1868 + /* this should never occur */ 1869 + entry = TX_DESC_NEXT(ring, entry); 1870 + continue; 1871 + } 1872 + 1873 + /* however, we might get only a partial skb release. */ 1874 + count -= skb_shinfo(skb)->nr_frags + 1875 + + cp->tx_tiny_use[ring][entry].nbufs + 1; 1876 + if (count < 0) 1877 + break; 1878 + 1879 + if (netif_msg_tx_done(cp)) 1880 + printk(KERN_DEBUG "%s: tx[%d] done, slot %d\n", 1881 + cp->dev->name, ring, entry); 1882 + 1883 + skbs[entry] = NULL; 1884 + cp->tx_tiny_use[ring][entry].nbufs = 0; 1885 + 1886 + for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) { 1887 + struct cas_tx_desc *txd = txds + entry; 1888 + 1889 + daddr = le64_to_cpu(txd->buffer); 1890 + dlen = CAS_VAL(TX_DESC_BUFLEN, 1891 + le64_to_cpu(txd->control)); 1892 + pci_unmap_page(cp->pdev, daddr, dlen, 1893 + PCI_DMA_TODEVICE); 1894 + entry = TX_DESC_NEXT(ring, entry); 1895 + 1896 + /* tiny buffer may follow */ 1897 + if (cp->tx_tiny_use[ring][entry].used) { 1898 + cp->tx_tiny_use[ring][entry].used = 0; 1899 + entry = TX_DESC_NEXT(ring, entry); 1900 + } 1901 + } 1902 + 1903 + spin_lock(&cp->stat_lock[ring]); 1904 + cp->net_stats[ring].tx_packets++; 1905 + cp->net_stats[ring].tx_bytes += skb->len; 1906 + spin_unlock(&cp->stat_lock[ring]); 1907 + dev_kfree_skb_irq(skb); 1908 + } 1909 + cp->tx_old[ring] = entry; 1910 + 1911 + /* this is wrong for multiple tx rings. the net device needs 1912 + * multiple queues for this to do the right thing. we wait 1913 + * for 2*packets to be available when using tiny buffers 1914 + */ 1915 + if (netif_queue_stopped(dev) && 1916 + (TX_BUFFS_AVAIL(cp, ring) > CAS_TABORT(cp)*(MAX_SKB_FRAGS + 1))) 1917 + netif_wake_queue(dev); 1918 + spin_unlock(&cp->tx_lock[ring]); 1919 + } 1920 + 1921 + static void cas_tx(struct net_device *dev, struct cas *cp, 1922 + u32 status) 1923 + { 1924 + int limit, ring; 1925 + #ifdef USE_TX_COMPWB 1926 + u64 compwb = le64_to_cpu(cp->init_block->tx_compwb); 1927 + #endif 1928 + if (netif_msg_intr(cp)) 1929 + printk(KERN_DEBUG "%s: tx interrupt, status: 0x%x, %lx\n", 1930 + cp->dev->name, status, compwb); 1931 + /* process all the rings */ 1932 + for (ring = 0; ring < N_TX_RINGS; ring++) { 1933 + #ifdef USE_TX_COMPWB 1934 + /* use the completion writeback registers */ 1935 + limit = (CAS_VAL(TX_COMPWB_MSB, compwb) << 8) | 1936 + CAS_VAL(TX_COMPWB_LSB, compwb); 1937 + compwb = TX_COMPWB_NEXT(compwb); 1938 + #else 1939 + limit = readl(cp->regs + REG_TX_COMPN(ring)); 1940 + #endif 1941 + if (cp->tx_old[ring] != limit) 1942 + cas_tx_ringN(cp, ring, limit); 1943 + } 1944 + } 1945 + 1946 + 1947 + static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, 1948 + int entry, const u64 *words, 1949 + struct sk_buff **skbref) 1950 + { 1951 + int dlen, hlen, len, i, alloclen; 1952 + int off, swivel = RX_SWIVEL_OFF_VAL; 1953 + struct cas_page *page; 1954 + struct sk_buff *skb; 1955 + void *addr, *crcaddr; 1956 + char *p; 1957 + 1958 + hlen = CAS_VAL(RX_COMP2_HDR_SIZE, words[1]); 1959 + dlen = CAS_VAL(RX_COMP1_DATA_SIZE, words[0]); 1960 + len = hlen + dlen; 1961 + 1962 + if (RX_COPY_ALWAYS || (words[2] & RX_COMP3_SMALL_PKT)) 1963 + alloclen = len; 1964 + else 1965 + alloclen = max(hlen, RX_COPY_MIN); 1966 + 1967 + skb = dev_alloc_skb(alloclen + swivel + cp->crc_size); 1968 + if (skb == NULL) 1969 + return -1; 1970 + 1971 + *skbref = skb; 1972 + skb->dev = cp->dev; 1973 + skb_reserve(skb, swivel); 1974 + 1975 + p = skb->data; 1976 + addr = crcaddr = NULL; 1977 + if (hlen) { /* always copy header pages */ 1978 + i = CAS_VAL(RX_COMP2_HDR_INDEX, words[1]); 1979 + page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; 1980 + off = CAS_VAL(RX_COMP2_HDR_OFF, words[1]) * 0x100 + 1981 + swivel; 1982 + 1983 + i = hlen; 1984 + if (!dlen) /* attach FCS */ 1985 + i += cp->crc_size; 1986 + pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i, 1987 + PCI_DMA_FROMDEVICE); 1988 + addr = cas_page_map(page->buffer); 1989 + memcpy(p, addr + off, i); 1990 + pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i, 1991 + PCI_DMA_FROMDEVICE); 1992 + cas_page_unmap(addr); 1993 + RX_USED_ADD(page, 0x100); 1994 + p += hlen; 1995 + swivel = 0; 1996 + } 1997 + 1998 + 1999 + if (alloclen < (hlen + dlen)) { 2000 + skb_frag_t *frag = skb_shinfo(skb)->frags; 2001 + 2002 + /* normal or jumbo packets. we use frags */ 2003 + i = CAS_VAL(RX_COMP1_DATA_INDEX, words[0]); 2004 + page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; 2005 + off = CAS_VAL(RX_COMP1_DATA_OFF, words[0]) + swivel; 2006 + 2007 + hlen = min(cp->page_size - off, dlen); 2008 + if (hlen < 0) { 2009 + if (netif_msg_rx_err(cp)) { 2010 + printk(KERN_DEBUG "%s: rx page overflow: " 2011 + "%d\n", cp->dev->name, hlen); 2012 + } 2013 + dev_kfree_skb_irq(skb); 2014 + return -1; 2015 + } 2016 + i = hlen; 2017 + if (i == dlen) /* attach FCS */ 2018 + i += cp->crc_size; 2019 + pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i, 2020 + PCI_DMA_FROMDEVICE); 2021 + 2022 + /* make sure we always copy a header */ 2023 + swivel = 0; 2024 + if (p == (char *) skb->data) { /* not split */ 2025 + addr = cas_page_map(page->buffer); 2026 + memcpy(p, addr + off, RX_COPY_MIN); 2027 + pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i, 2028 + PCI_DMA_FROMDEVICE); 2029 + cas_page_unmap(addr); 2030 + off += RX_COPY_MIN; 2031 + swivel = RX_COPY_MIN; 2032 + RX_USED_ADD(page, cp->mtu_stride); 2033 + } else { 2034 + RX_USED_ADD(page, hlen); 2035 + } 2036 + skb_put(skb, alloclen); 2037 + 2038 + skb_shinfo(skb)->nr_frags++; 2039 + skb->data_len += hlen - swivel; 2040 + skb->len += hlen - swivel; 2041 + 2042 + get_page(page->buffer); 2043 + frag->page = page->buffer; 2044 + frag->page_offset = off; 2045 + frag->size = hlen - swivel; 2046 + 2047 + /* any more data? */ 2048 + if ((words[0] & RX_COMP1_SPLIT_PKT) && ((dlen -= hlen) > 0)) { 2049 + hlen = dlen; 2050 + off = 0; 2051 + 2052 + i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]); 2053 + page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; 2054 + pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr, 2055 + hlen + cp->crc_size, 2056 + PCI_DMA_FROMDEVICE); 2057 + pci_dma_sync_single_for_device(cp->pdev, page->dma_addr, 2058 + hlen + cp->crc_size, 2059 + PCI_DMA_FROMDEVICE); 2060 + 2061 + skb_shinfo(skb)->nr_frags++; 2062 + skb->data_len += hlen; 2063 + skb->len += hlen; 2064 + frag++; 2065 + 2066 + get_page(page->buffer); 2067 + frag->page = page->buffer; 2068 + frag->page_offset = 0; 2069 + frag->size = hlen; 2070 + RX_USED_ADD(page, hlen + cp->crc_size); 2071 + } 2072 + 2073 + if (cp->crc_size) { 2074 + addr = cas_page_map(page->buffer); 2075 + crcaddr = addr + off + hlen; 2076 + } 2077 + 2078 + } else { 2079 + /* copying packet */ 2080 + if (!dlen) 2081 + goto end_copy_pkt; 2082 + 2083 + i = CAS_VAL(RX_COMP1_DATA_INDEX, words[0]); 2084 + page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; 2085 + off = CAS_VAL(RX_COMP1_DATA_OFF, words[0]) + swivel; 2086 + hlen = min(cp->page_size - off, dlen); 2087 + if (hlen < 0) { 2088 + if (netif_msg_rx_err(cp)) { 2089 + printk(KERN_DEBUG "%s: rx page overflow: " 2090 + "%d\n", cp->dev->name, hlen); 2091 + } 2092 + dev_kfree_skb_irq(skb); 2093 + return -1; 2094 + } 2095 + i = hlen; 2096 + if (i == dlen) /* attach FCS */ 2097 + i += cp->crc_size; 2098 + pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr + off, i, 2099 + PCI_DMA_FROMDEVICE); 2100 + addr = cas_page_map(page->buffer); 2101 + memcpy(p, addr + off, i); 2102 + pci_dma_sync_single_for_device(cp->pdev, page->dma_addr + off, i, 2103 + PCI_DMA_FROMDEVICE); 2104 + cas_page_unmap(addr); 2105 + if (p == (char *) skb->data) /* not split */ 2106 + RX_USED_ADD(page, cp->mtu_stride); 2107 + else 2108 + RX_USED_ADD(page, i); 2109 + 2110 + /* any more data? */ 2111 + if ((words[0] & RX_COMP1_SPLIT_PKT) && ((dlen -= hlen) > 0)) { 2112 + p += hlen; 2113 + i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]); 2114 + page = cp->rx_pages[CAS_VAL(RX_INDEX_RING, i)][CAS_VAL(RX_INDEX_NUM, i)]; 2115 + pci_dma_sync_single_for_cpu(cp->pdev, page->dma_addr, 2116 + dlen + cp->crc_size, 2117 + PCI_DMA_FROMDEVICE); 2118 + addr = cas_page_map(page->buffer); 2119 + memcpy(p, addr, dlen + cp->crc_size); 2120 + pci_dma_sync_single_for_device(cp->pdev, page->dma_addr, 2121 + dlen + cp->crc_size, 2122 + PCI_DMA_FROMDEVICE); 2123 + cas_page_unmap(addr); 2124 + RX_USED_ADD(page, dlen + cp->crc_size); 2125 + } 2126 + end_copy_pkt: 2127 + if (cp->crc_size) { 2128 + addr = NULL; 2129 + crcaddr = skb->data + alloclen; 2130 + } 2131 + skb_put(skb, alloclen); 2132 + } 2133 + 2134 + i = CAS_VAL(RX_COMP4_TCP_CSUM, words[3]); 2135 + if (cp->crc_size) { 2136 + /* checksum includes FCS. strip it out. */ 2137 + i = csum_fold(csum_partial(crcaddr, cp->crc_size, i)); 2138 + if (addr) 2139 + cas_page_unmap(addr); 2140 + } 2141 + skb->csum = ntohs(i ^ 0xffff); 2142 + skb->ip_summed = CHECKSUM_HW; 2143 + skb->protocol = eth_type_trans(skb, cp->dev); 2144 + return len; 2145 + } 2146 + 2147 + 2148 + /* we can handle up to 64 rx flows at a time. we do the same thing 2149 + * as nonreassm except that we batch up the buffers. 2150 + * NOTE: we currently just treat each flow as a bunch of packets that 2151 + * we pass up. a better way would be to coalesce the packets 2152 + * into a jumbo packet. to do that, we need to do the following: 2153 + * 1) the first packet will have a clean split between header and 2154 + * data. save both. 2155 + * 2) each time the next flow packet comes in, extend the 2156 + * data length and merge the checksums. 2157 + * 3) on flow release, fix up the header. 2158 + * 4) make sure the higher layer doesn't care. 2159 + * because packets get coalesced, we shouldn't run into fragment count 2160 + * issues. 2161 + */ 2162 + static inline void cas_rx_flow_pkt(struct cas *cp, const u64 *words, 2163 + struct sk_buff *skb) 2164 + { 2165 + int flowid = CAS_VAL(RX_COMP3_FLOWID, words[2]) & (N_RX_FLOWS - 1); 2166 + struct sk_buff_head *flow = &cp->rx_flows[flowid]; 2167 + 2168 + /* this is protected at a higher layer, so no need to 2169 + * do any additional locking here. stick the buffer 2170 + * at the end. 2171 + */ 2172 + __skb_insert(skb, flow->prev, (struct sk_buff *) flow, flow); 2173 + if (words[0] & RX_COMP1_RELEASE_FLOW) { 2174 + while ((skb = __skb_dequeue(flow))) { 2175 + cas_skb_release(skb); 2176 + } 2177 + } 2178 + } 2179 + 2180 + /* put rx descriptor back on ring. if a buffer is in use by a higher 2181 + * layer, this will need to put in a replacement. 2182 + */ 2183 + static void cas_post_page(struct cas *cp, const int ring, const int index) 2184 + { 2185 + cas_page_t *new; 2186 + int entry; 2187 + 2188 + entry = cp->rx_old[ring]; 2189 + 2190 + new = cas_page_swap(cp, ring, index); 2191 + cp->init_rxds[ring][entry].buffer = cpu_to_le64(new->dma_addr); 2192 + cp->init_rxds[ring][entry].index = 2193 + cpu_to_le64(CAS_BASE(RX_INDEX_NUM, index) | 2194 + CAS_BASE(RX_INDEX_RING, ring)); 2195 + 2196 + entry = RX_DESC_ENTRY(ring, entry + 1); 2197 + cp->rx_old[ring] = entry; 2198 + 2199 + if (entry % 4) 2200 + return; 2201 + 2202 + if (ring == 0) 2203 + writel(entry, cp->regs + REG_RX_KICK); 2204 + else if ((N_RX_DESC_RINGS > 1) && 2205 + (cp->cas_flags & CAS_FLAG_REG_PLUS)) 2206 + writel(entry, cp->regs + REG_PLUS_RX_KICK1); 2207 + } 2208 + 2209 + 2210 + /* only when things are bad */ 2211 + static int cas_post_rxds_ringN(struct cas *cp, int ring, int num) 2212 + { 2213 + unsigned int entry, last, count, released; 2214 + int cluster; 2215 + cas_page_t **page = cp->rx_pages[ring]; 2216 + 2217 + entry = cp->rx_old[ring]; 2218 + 2219 + if (netif_msg_intr(cp)) 2220 + printk(KERN_DEBUG "%s: rxd[%d] interrupt, done: %d\n", 2221 + cp->dev->name, ring, entry); 2222 + 2223 + cluster = -1; 2224 + count = entry & 0x3; 2225 + last = RX_DESC_ENTRY(ring, num ? entry + num - 4: entry - 4); 2226 + released = 0; 2227 + while (entry != last) { 2228 + /* make a new buffer if it's still in use */ 2229 + if (page_count(page[entry]->buffer) > 1) { 2230 + cas_page_t *new = cas_page_dequeue(cp); 2231 + if (!new) { 2232 + /* let the timer know that we need to 2233 + * do this again 2234 + */ 2235 + cp->cas_flags |= CAS_FLAG_RXD_POST(ring); 2236 + if (!timer_pending(&cp->link_timer)) 2237 + mod_timer(&cp->link_timer, jiffies + 2238 + CAS_LINK_FAST_TIMEOUT); 2239 + cp->rx_old[ring] = entry; 2240 + cp->rx_last[ring] = num ? num - released : 0; 2241 + return -ENOMEM; 2242 + } 2243 + spin_lock(&cp->rx_inuse_lock); 2244 + list_add(&page[entry]->list, &cp->rx_inuse_list); 2245 + spin_unlock(&cp->rx_inuse_lock); 2246 + cp->init_rxds[ring][entry].buffer = 2247 + cpu_to_le64(new->dma_addr); 2248 + page[entry] = new; 2249 + 2250 + } 2251 + 2252 + if (++count == 4) { 2253 + cluster = entry; 2254 + count = 0; 2255 + } 2256 + released++; 2257 + entry = RX_DESC_ENTRY(ring, entry + 1); 2258 + } 2259 + cp->rx_old[ring] = entry; 2260 + 2261 + if (cluster < 0) 2262 + return 0; 2263 + 2264 + if (ring == 0) 2265 + writel(cluster, cp->regs + REG_RX_KICK); 2266 + else if ((N_RX_DESC_RINGS > 1) && 2267 + (cp->cas_flags & CAS_FLAG_REG_PLUS)) 2268 + writel(cluster, cp->regs + REG_PLUS_RX_KICK1); 2269 + return 0; 2270 + } 2271 + 2272 + 2273 + /* process a completion ring. packets are set up in three basic ways: 2274 + * small packets: should be copied header + data in single buffer. 2275 + * large packets: header and data in a single buffer. 2276 + * split packets: header in a separate buffer from data. 2277 + * data may be in multiple pages. data may be > 256 2278 + * bytes but in a single page. 2279 + * 2280 + * NOTE: RX page posting is done in this routine as well. while there's 2281 + * the capability of using multiple RX completion rings, it isn't 2282 + * really worthwhile due to the fact that the page posting will 2283 + * force serialization on the single descriptor ring. 2284 + */ 2285 + static int cas_rx_ringN(struct cas *cp, int ring, int budget) 2286 + { 2287 + struct cas_rx_comp *rxcs = cp->init_rxcs[ring]; 2288 + int entry, drops; 2289 + int npackets = 0; 2290 + 2291 + if (netif_msg_intr(cp)) 2292 + printk(KERN_DEBUG "%s: rx[%d] interrupt, done: %d/%d\n", 2293 + cp->dev->name, ring, 2294 + readl(cp->regs + REG_RX_COMP_HEAD), 2295 + cp->rx_new[ring]); 2296 + 2297 + entry = cp->rx_new[ring]; 2298 + drops = 0; 2299 + while (1) { 2300 + struct cas_rx_comp *rxc = rxcs + entry; 2301 + struct sk_buff *skb; 2302 + int type, len; 2303 + u64 words[4]; 2304 + int i, dring; 2305 + 2306 + words[0] = le64_to_cpu(rxc->word1); 2307 + words[1] = le64_to_cpu(rxc->word2); 2308 + words[2] = le64_to_cpu(rxc->word3); 2309 + words[3] = le64_to_cpu(rxc->word4); 2310 + 2311 + /* don't touch if still owned by hw */ 2312 + type = CAS_VAL(RX_COMP1_TYPE, words[0]); 2313 + if (type == 0) 2314 + break; 2315 + 2316 + /* hw hasn't cleared the zero bit yet */ 2317 + if (words[3] & RX_COMP4_ZERO) { 2318 + break; 2319 + } 2320 + 2321 + /* get info on the packet */ 2322 + if (words[3] & (RX_COMP4_LEN_MISMATCH | RX_COMP4_BAD)) { 2323 + spin_lock(&cp->stat_lock[ring]); 2324 + cp->net_stats[ring].rx_errors++; 2325 + if (words[3] & RX_COMP4_LEN_MISMATCH) 2326 + cp->net_stats[ring].rx_length_errors++; 2327 + if (words[3] & RX_COMP4_BAD) 2328 + cp->net_stats[ring].rx_crc_errors++; 2329 + spin_unlock(&cp->stat_lock[ring]); 2330 + 2331 + /* We'll just return it to Cassini. */ 2332 + drop_it: 2333 + spin_lock(&cp->stat_lock[ring]); 2334 + ++cp->net_stats[ring].rx_dropped; 2335 + spin_unlock(&cp->stat_lock[ring]); 2336 + goto next; 2337 + } 2338 + 2339 + len = cas_rx_process_pkt(cp, rxc, entry, words, &skb); 2340 + if (len < 0) { 2341 + ++drops; 2342 + goto drop_it; 2343 + } 2344 + 2345 + /* see if it's a flow re-assembly or not. the driver 2346 + * itself handles release back up. 2347 + */ 2348 + if (RX_DONT_BATCH || (type == 0x2)) { 2349 + /* non-reassm: these always get released */ 2350 + cas_skb_release(skb); 2351 + } else { 2352 + cas_rx_flow_pkt(cp, words, skb); 2353 + } 2354 + 2355 + spin_lock(&cp->stat_lock[ring]); 2356 + cp->net_stats[ring].rx_packets++; 2357 + cp->net_stats[ring].rx_bytes += len; 2358 + spin_unlock(&cp->stat_lock[ring]); 2359 + cp->dev->last_rx = jiffies; 2360 + 2361 + next: 2362 + npackets++; 2363 + 2364 + /* should it be released? */ 2365 + if (words[0] & RX_COMP1_RELEASE_HDR) { 2366 + i = CAS_VAL(RX_COMP2_HDR_INDEX, words[1]); 2367 + dring = CAS_VAL(RX_INDEX_RING, i); 2368 + i = CAS_VAL(RX_INDEX_NUM, i); 2369 + cas_post_page(cp, dring, i); 2370 + } 2371 + 2372 + if (words[0] & RX_COMP1_RELEASE_DATA) { 2373 + i = CAS_VAL(RX_COMP1_DATA_INDEX, words[0]); 2374 + dring = CAS_VAL(RX_INDEX_RING, i); 2375 + i = CAS_VAL(RX_INDEX_NUM, i); 2376 + cas_post_page(cp, dring, i); 2377 + } 2378 + 2379 + if (words[0] & RX_COMP1_RELEASE_NEXT) { 2380 + i = CAS_VAL(RX_COMP2_NEXT_INDEX, words[1]); 2381 + dring = CAS_VAL(RX_INDEX_RING, i); 2382 + i = CAS_VAL(RX_INDEX_NUM, i); 2383 + cas_post_page(cp, dring, i); 2384 + } 2385 + 2386 + /* skip to the next entry */ 2387 + entry = RX_COMP_ENTRY(ring, entry + 1 + 2388 + CAS_VAL(RX_COMP1_SKIP, words[0])); 2389 + #ifdef USE_NAPI 2390 + if (budget && (npackets >= budget)) 2391 + break; 2392 + #endif 2393 + } 2394 + cp->rx_new[ring] = entry; 2395 + 2396 + if (drops) 2397 + printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", 2398 + cp->dev->name); 2399 + return npackets; 2400 + } 2401 + 2402 + 2403 + /* put completion entries back on the ring */ 2404 + static void cas_post_rxcs_ringN(struct net_device *dev, 2405 + struct cas *cp, int ring) 2406 + { 2407 + struct cas_rx_comp *rxc = cp->init_rxcs[ring]; 2408 + int last, entry; 2409 + 2410 + last = cp->rx_cur[ring]; 2411 + entry = cp->rx_new[ring]; 2412 + if (netif_msg_intr(cp)) 2413 + printk(KERN_DEBUG "%s: rxc[%d] interrupt, done: %d/%d\n", 2414 + dev->name, ring, readl(cp->regs + REG_RX_COMP_HEAD), 2415 + entry); 2416 + 2417 + /* zero and re-mark descriptors */ 2418 + while (last != entry) { 2419 + cas_rxc_init(rxc + last); 2420 + last = RX_COMP_ENTRY(ring, last + 1); 2421 + } 2422 + cp->rx_cur[ring] = last; 2423 + 2424 + if (ring == 0) 2425 + writel(last, cp->regs + REG_RX_COMP_TAIL); 2426 + else if (cp->cas_flags & CAS_FLAG_REG_PLUS) 2427 + writel(last, cp->regs + REG_PLUS_RX_COMPN_TAIL(ring)); 2428 + } 2429 + 2430 + 2431 + 2432 + /* cassini can use all four PCI interrupts for the completion ring. 2433 + * rings 3 and 4 are identical 2434 + */ 2435 + #if defined(USE_PCI_INTC) || defined(USE_PCI_INTD) 2436 + static inline void cas_handle_irqN(struct net_device *dev, 2437 + struct cas *cp, const u32 status, 2438 + const int ring) 2439 + { 2440 + if (status & (INTR_RX_COMP_FULL_ALT | INTR_RX_COMP_AF_ALT)) 2441 + cas_post_rxcs_ringN(dev, cp, ring); 2442 + } 2443 + 2444 + static irqreturn_t cas_interruptN(int irq, void *dev_id, struct pt_regs *regs) 2445 + { 2446 + struct net_device *dev = dev_id; 2447 + struct cas *cp = netdev_priv(dev); 2448 + unsigned long flags; 2449 + int ring; 2450 + u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring)); 2451 + 2452 + /* check for shared irq */ 2453 + if (status == 0) 2454 + return IRQ_NONE; 2455 + 2456 + ring = (irq == cp->pci_irq_INTC) ? 2 : 3; 2457 + spin_lock_irqsave(&cp->lock, flags); 2458 + if (status & INTR_RX_DONE_ALT) { /* handle rx separately */ 2459 + #ifdef USE_NAPI 2460 + cas_mask_intr(cp); 2461 + netif_rx_schedule(dev); 2462 + #else 2463 + cas_rx_ringN(cp, ring, 0); 2464 + #endif 2465 + status &= ~INTR_RX_DONE_ALT; 2466 + } 2467 + 2468 + if (status) 2469 + cas_handle_irqN(dev, cp, status, ring); 2470 + spin_unlock_irqrestore(&cp->lock, flags); 2471 + return IRQ_HANDLED; 2472 + } 2473 + #endif 2474 + 2475 + #ifdef USE_PCI_INTB 2476 + /* everything but rx packets */ 2477 + static inline void cas_handle_irq1(struct cas *cp, const u32 status) 2478 + { 2479 + if (status & INTR_RX_BUF_UNAVAIL_1) { 2480 + /* Frame arrived, no free RX buffers available. 2481 + * NOTE: we can get this on a link transition. */ 2482 + cas_post_rxds_ringN(cp, 1, 0); 2483 + spin_lock(&cp->stat_lock[1]); 2484 + cp->net_stats[1].rx_dropped++; 2485 + spin_unlock(&cp->stat_lock[1]); 2486 + } 2487 + 2488 + if (status & INTR_RX_BUF_AE_1) 2489 + cas_post_rxds_ringN(cp, 1, RX_DESC_RINGN_SIZE(1) - 2490 + RX_AE_FREEN_VAL(1)); 2491 + 2492 + if (status & (INTR_RX_COMP_AF | INTR_RX_COMP_FULL)) 2493 + cas_post_rxcs_ringN(cp, 1); 2494 + } 2495 + 2496 + /* ring 2 handles a few more events than 3 and 4 */ 2497 + static irqreturn_t cas_interrupt1(int irq, void *dev_id, struct pt_regs *regs) 2498 + { 2499 + struct net_device *dev = dev_id; 2500 + struct cas *cp = netdev_priv(dev); 2501 + unsigned long flags; 2502 + u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(1)); 2503 + 2504 + /* check for shared interrupt */ 2505 + if (status == 0) 2506 + return IRQ_NONE; 2507 + 2508 + spin_lock_irqsave(&cp->lock, flags); 2509 + if (status & INTR_RX_DONE_ALT) { /* handle rx separately */ 2510 + #ifdef USE_NAPI 2511 + cas_mask_intr(cp); 2512 + netif_rx_schedule(dev); 2513 + #else 2514 + cas_rx_ringN(cp, 1, 0); 2515 + #endif 2516 + status &= ~INTR_RX_DONE_ALT; 2517 + } 2518 + if (status) 2519 + cas_handle_irq1(cp, status); 2520 + spin_unlock_irqrestore(&cp->lock, flags); 2521 + return IRQ_HANDLED; 2522 + } 2523 + #endif 2524 + 2525 + static inline void cas_handle_irq(struct net_device *dev, 2526 + struct cas *cp, const u32 status) 2527 + { 2528 + /* housekeeping interrupts */ 2529 + if (status & INTR_ERROR_MASK) 2530 + cas_abnormal_irq(dev, cp, status); 2531 + 2532 + if (status & INTR_RX_BUF_UNAVAIL) { 2533 + /* Frame arrived, no free RX buffers available. 2534 + * NOTE: we can get this on a link transition. 2535 + */ 2536 + cas_post_rxds_ringN(cp, 0, 0); 2537 + spin_lock(&cp->stat_lock[0]); 2538 + cp->net_stats[0].rx_dropped++; 2539 + spin_unlock(&cp->stat_lock[0]); 2540 + } else if (status & INTR_RX_BUF_AE) { 2541 + cas_post_rxds_ringN(cp, 0, RX_DESC_RINGN_SIZE(0) - 2542 + RX_AE_FREEN_VAL(0)); 2543 + } 2544 + 2545 + if (status & (INTR_RX_COMP_AF | INTR_RX_COMP_FULL)) 2546 + cas_post_rxcs_ringN(dev, cp, 0); 2547 + } 2548 + 2549 + static irqreturn_t cas_interrupt(int irq, void *dev_id, struct pt_regs *regs) 2550 + { 2551 + struct net_device *dev = dev_id; 2552 + struct cas *cp = netdev_priv(dev); 2553 + unsigned long flags; 2554 + u32 status = readl(cp->regs + REG_INTR_STATUS); 2555 + 2556 + if (status == 0) 2557 + return IRQ_NONE; 2558 + 2559 + spin_lock_irqsave(&cp->lock, flags); 2560 + if (status & (INTR_TX_ALL | INTR_TX_INTME)) { 2561 + cas_tx(dev, cp, status); 2562 + status &= ~(INTR_TX_ALL | INTR_TX_INTME); 2563 + } 2564 + 2565 + if (status & INTR_RX_DONE) { 2566 + #ifdef USE_NAPI 2567 + cas_mask_intr(cp); 2568 + netif_rx_schedule(dev); 2569 + #else 2570 + cas_rx_ringN(cp, 0, 0); 2571 + #endif 2572 + status &= ~INTR_RX_DONE; 2573 + } 2574 + 2575 + if (status) 2576 + cas_handle_irq(dev, cp, status); 2577 + spin_unlock_irqrestore(&cp->lock, flags); 2578 + return IRQ_HANDLED; 2579 + } 2580 + 2581 + 2582 + #ifdef USE_NAPI 2583 + static int cas_poll(struct net_device *dev, int *budget) 2584 + { 2585 + struct cas *cp = netdev_priv(dev); 2586 + int i, enable_intr, todo, credits; 2587 + u32 status = readl(cp->regs + REG_INTR_STATUS); 2588 + unsigned long flags; 2589 + 2590 + spin_lock_irqsave(&cp->lock, flags); 2591 + cas_tx(dev, cp, status); 2592 + spin_unlock_irqrestore(&cp->lock, flags); 2593 + 2594 + /* NAPI rx packets. we spread the credits across all of the 2595 + * rxc rings 2596 + */ 2597 + todo = min(*budget, dev->quota); 2598 + 2599 + /* to make sure we're fair with the work we loop through each 2600 + * ring N_RX_COMP_RING times with a request of 2601 + * todo / N_RX_COMP_RINGS 2602 + */ 2603 + enable_intr = 1; 2604 + credits = 0; 2605 + for (i = 0; i < N_RX_COMP_RINGS; i++) { 2606 + int j; 2607 + for (j = 0; j < N_RX_COMP_RINGS; j++) { 2608 + credits += cas_rx_ringN(cp, j, todo / N_RX_COMP_RINGS); 2609 + if (credits >= todo) { 2610 + enable_intr = 0; 2611 + goto rx_comp; 2612 + } 2613 + } 2614 + } 2615 + 2616 + rx_comp: 2617 + *budget -= credits; 2618 + dev->quota -= credits; 2619 + 2620 + /* final rx completion */ 2621 + spin_lock_irqsave(&cp->lock, flags); 2622 + if (status) 2623 + cas_handle_irq(dev, cp, status); 2624 + 2625 + #ifdef USE_PCI_INTB 2626 + if (N_RX_COMP_RINGS > 1) { 2627 + status = readl(cp->regs + REG_PLUS_INTRN_STATUS(1)); 2628 + if (status) 2629 + cas_handle_irq1(dev, cp, status); 2630 + } 2631 + #endif 2632 + 2633 + #ifdef USE_PCI_INTC 2634 + if (N_RX_COMP_RINGS > 2) { 2635 + status = readl(cp->regs + REG_PLUS_INTRN_STATUS(2)); 2636 + if (status) 2637 + cas_handle_irqN(dev, cp, status, 2); 2638 + } 2639 + #endif 2640 + 2641 + #ifdef USE_PCI_INTD 2642 + if (N_RX_COMP_RINGS > 3) { 2643 + status = readl(cp->regs + REG_PLUS_INTRN_STATUS(3)); 2644 + if (status) 2645 + cas_handle_irqN(dev, cp, status, 3); 2646 + } 2647 + #endif 2648 + spin_unlock_irqrestore(&cp->lock, flags); 2649 + if (enable_intr) { 2650 + netif_rx_complete(dev); 2651 + cas_unmask_intr(cp); 2652 + return 0; 2653 + } 2654 + return 1; 2655 + } 2656 + #endif 2657 + 2658 + #ifdef CONFIG_NET_POLL_CONTROLLER 2659 + static void cas_netpoll(struct net_device *dev) 2660 + { 2661 + struct cas *cp = netdev_priv(dev); 2662 + 2663 + cas_disable_irq(cp, 0); 2664 + cas_interrupt(cp->pdev->irq, dev, NULL); 2665 + cas_enable_irq(cp, 0); 2666 + 2667 + #ifdef USE_PCI_INTB 2668 + if (N_RX_COMP_RINGS > 1) { 2669 + /* cas_interrupt1(); */ 2670 + } 2671 + #endif 2672 + #ifdef USE_PCI_INTC 2673 + if (N_RX_COMP_RINGS > 2) { 2674 + /* cas_interruptN(); */ 2675 + } 2676 + #endif 2677 + #ifdef USE_PCI_INTD 2678 + if (N_RX_COMP_RINGS > 3) { 2679 + /* cas_interruptN(); */ 2680 + } 2681 + #endif 2682 + } 2683 + #endif 2684 + 2685 + static void cas_tx_timeout(struct net_device *dev) 2686 + { 2687 + struct cas *cp = netdev_priv(dev); 2688 + 2689 + printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name); 2690 + if (!cp->hw_running) { 2691 + printk("%s: hrm.. hw not running!\n", dev->name); 2692 + return; 2693 + } 2694 + 2695 + printk(KERN_ERR "%s: MIF_STATE[%08x]\n", 2696 + dev->name, readl(cp->regs + REG_MIF_STATE_MACHINE)); 2697 + 2698 + printk(KERN_ERR "%s: MAC_STATE[%08x]\n", 2699 + dev->name, readl(cp->regs + REG_MAC_STATE_MACHINE)); 2700 + 2701 + printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x] " 2702 + "FIFO[%08x:%08x:%08x] SM1[%08x] SM2[%08x]\n", 2703 + dev->name, 2704 + readl(cp->regs + REG_TX_CFG), 2705 + readl(cp->regs + REG_MAC_TX_STATUS), 2706 + readl(cp->regs + REG_MAC_TX_CFG), 2707 + readl(cp->regs + REG_TX_FIFO_PKT_CNT), 2708 + readl(cp->regs + REG_TX_FIFO_WRITE_PTR), 2709 + readl(cp->regs + REG_TX_FIFO_READ_PTR), 2710 + readl(cp->regs + REG_TX_SM_1), 2711 + readl(cp->regs + REG_TX_SM_2)); 2712 + 2713 + printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n", 2714 + dev->name, 2715 + readl(cp->regs + REG_RX_CFG), 2716 + readl(cp->regs + REG_MAC_RX_STATUS), 2717 + readl(cp->regs + REG_MAC_RX_CFG)); 2718 + 2719 + printk(KERN_ERR "%s: HP_STATE[%08x:%08x:%08x:%08x]\n", 2720 + dev->name, 2721 + readl(cp->regs + REG_HP_STATE_MACHINE), 2722 + readl(cp->regs + REG_HP_STATUS0), 2723 + readl(cp->regs + REG_HP_STATUS1), 2724 + readl(cp->regs + REG_HP_STATUS2)); 2725 + 2726 + #if 1 2727 + atomic_inc(&cp->reset_task_pending); 2728 + atomic_inc(&cp->reset_task_pending_all); 2729 + schedule_work(&cp->reset_task); 2730 + #else 2731 + atomic_set(&cp->reset_task_pending, CAS_RESET_ALL); 2732 + schedule_work(&cp->reset_task); 2733 + #endif 2734 + } 2735 + 2736 + static inline int cas_intme(int ring, int entry) 2737 + { 2738 + /* Algorithm: IRQ every 1/2 of descriptors. */ 2739 + if (!(entry & ((TX_DESC_RINGN_SIZE(ring) >> 1) - 1))) 2740 + return 1; 2741 + return 0; 2742 + } 2743 + 2744 + 2745 + static void cas_write_txd(struct cas *cp, int ring, int entry, 2746 + dma_addr_t mapping, int len, u64 ctrl, int last) 2747 + { 2748 + struct cas_tx_desc *txd = cp->init_txds[ring] + entry; 2749 + 2750 + ctrl |= CAS_BASE(TX_DESC_BUFLEN, len); 2751 + if (cas_intme(ring, entry)) 2752 + ctrl |= TX_DESC_INTME; 2753 + if (last) 2754 + ctrl |= TX_DESC_EOF; 2755 + txd->control = cpu_to_le64(ctrl); 2756 + txd->buffer = cpu_to_le64(mapping); 2757 + } 2758 + 2759 + static inline void *tx_tiny_buf(struct cas *cp, const int ring, 2760 + const int entry) 2761 + { 2762 + return cp->tx_tiny_bufs[ring] + TX_TINY_BUF_LEN*entry; 2763 + } 2764 + 2765 + static inline dma_addr_t tx_tiny_map(struct cas *cp, const int ring, 2766 + const int entry, const int tentry) 2767 + { 2768 + cp->tx_tiny_use[ring][tentry].nbufs++; 2769 + cp->tx_tiny_use[ring][entry].used = 1; 2770 + return cp->tx_tiny_dvma[ring] + TX_TINY_BUF_LEN*entry; 2771 + } 2772 + 2773 + static inline int cas_xmit_tx_ringN(struct cas *cp, int ring, 2774 + struct sk_buff *skb) 2775 + { 2776 + struct net_device *dev = cp->dev; 2777 + int entry, nr_frags, frag, tabort, tentry; 2778 + dma_addr_t mapping; 2779 + unsigned long flags; 2780 + u64 ctrl; 2781 + u32 len; 2782 + 2783 + spin_lock_irqsave(&cp->tx_lock[ring], flags); 2784 + 2785 + /* This is a hard error, log it. */ 2786 + if (TX_BUFFS_AVAIL(cp, ring) <= 2787 + CAS_TABORT(cp)*(skb_shinfo(skb)->nr_frags + 1)) { 2788 + netif_stop_queue(dev); 2789 + spin_unlock_irqrestore(&cp->tx_lock[ring], flags); 2790 + printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " 2791 + "queue awake!\n", dev->name); 2792 + return 1; 2793 + } 2794 + 2795 + ctrl = 0; 2796 + if (skb->ip_summed == CHECKSUM_HW) { 2797 + u64 csum_start_off, csum_stuff_off; 2798 + 2799 + csum_start_off = (u64) (skb->h.raw - skb->data); 2800 + csum_stuff_off = (u64) ((skb->h.raw + skb->csum) - skb->data); 2801 + 2802 + ctrl = TX_DESC_CSUM_EN | 2803 + CAS_BASE(TX_DESC_CSUM_START, csum_start_off) | 2804 + CAS_BASE(TX_DESC_CSUM_STUFF, csum_stuff_off); 2805 + } 2806 + 2807 + entry = cp->tx_new[ring]; 2808 + cp->tx_skbs[ring][entry] = skb; 2809 + 2810 + nr_frags = skb_shinfo(skb)->nr_frags; 2811 + len = skb_headlen(skb); 2812 + mapping = pci_map_page(cp->pdev, virt_to_page(skb->data), 2813 + offset_in_page(skb->data), len, 2814 + PCI_DMA_TODEVICE); 2815 + 2816 + tentry = entry; 2817 + tabort = cas_calc_tabort(cp, (unsigned long) skb->data, len); 2818 + if (unlikely(tabort)) { 2819 + /* NOTE: len is always > tabort */ 2820 + cas_write_txd(cp, ring, entry, mapping, len - tabort, 2821 + ctrl | TX_DESC_SOF, 0); 2822 + entry = TX_DESC_NEXT(ring, entry); 2823 + 2824 + memcpy(tx_tiny_buf(cp, ring, entry), skb->data + 2825 + len - tabort, tabort); 2826 + mapping = tx_tiny_map(cp, ring, entry, tentry); 2827 + cas_write_txd(cp, ring, entry, mapping, tabort, ctrl, 2828 + (nr_frags == 0)); 2829 + } else { 2830 + cas_write_txd(cp, ring, entry, mapping, len, ctrl | 2831 + TX_DESC_SOF, (nr_frags == 0)); 2832 + } 2833 + entry = TX_DESC_NEXT(ring, entry); 2834 + 2835 + for (frag = 0; frag < nr_frags; frag++) { 2836 + skb_frag_t *fragp = &skb_shinfo(skb)->frags[frag]; 2837 + 2838 + len = fragp->size; 2839 + mapping = pci_map_page(cp->pdev, fragp->page, 2840 + fragp->page_offset, len, 2841 + PCI_DMA_TODEVICE); 2842 + 2843 + tabort = cas_calc_tabort(cp, fragp->page_offset, len); 2844 + if (unlikely(tabort)) { 2845 + void *addr; 2846 + 2847 + /* NOTE: len is always > tabort */ 2848 + cas_write_txd(cp, ring, entry, mapping, len - tabort, 2849 + ctrl, 0); 2850 + entry = TX_DESC_NEXT(ring, entry); 2851 + 2852 + addr = cas_page_map(fragp->page); 2853 + memcpy(tx_tiny_buf(cp, ring, entry), 2854 + addr + fragp->page_offset + len - tabort, 2855 + tabort); 2856 + cas_page_unmap(addr); 2857 + mapping = tx_tiny_map(cp, ring, entry, tentry); 2858 + len = tabort; 2859 + } 2860 + 2861 + cas_write_txd(cp, ring, entry, mapping, len, ctrl, 2862 + (frag + 1 == nr_frags)); 2863 + entry = TX_DESC_NEXT(ring, entry); 2864 + } 2865 + 2866 + cp->tx_new[ring] = entry; 2867 + if (TX_BUFFS_AVAIL(cp, ring) <= CAS_TABORT(cp)*(MAX_SKB_FRAGS + 1)) 2868 + netif_stop_queue(dev); 2869 + 2870 + if (netif_msg_tx_queued(cp)) 2871 + printk(KERN_DEBUG "%s: tx[%d] queued, slot %d, skblen %d, " 2872 + "avail %d\n", 2873 + dev->name, ring, entry, skb->len, 2874 + TX_BUFFS_AVAIL(cp, ring)); 2875 + writel(entry, cp->regs + REG_TX_KICKN(ring)); 2876 + spin_unlock_irqrestore(&cp->tx_lock[ring], flags); 2877 + return 0; 2878 + } 2879 + 2880 + static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev) 2881 + { 2882 + struct cas *cp = netdev_priv(dev); 2883 + 2884 + /* this is only used as a load-balancing hint, so it doesn't 2885 + * need to be SMP safe 2886 + */ 2887 + static int ring; 2888 + 2889 + skb = skb_padto(skb, cp->min_frame_size); 2890 + if (!skb) 2891 + return 0; 2892 + 2893 + /* XXX: we need some higher-level QoS hooks to steer packets to 2894 + * individual queues. 2895 + */ 2896 + if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb)) 2897 + return 1; 2898 + dev->trans_start = jiffies; 2899 + return 0; 2900 + } 2901 + 2902 + static void cas_init_tx_dma(struct cas *cp) 2903 + { 2904 + u64 desc_dma = cp->block_dvma; 2905 + unsigned long off; 2906 + u32 val; 2907 + int i; 2908 + 2909 + /* set up tx completion writeback registers. must be 8-byte aligned */ 2910 + #ifdef USE_TX_COMPWB 2911 + off = offsetof(struct cas_init_block, tx_compwb); 2912 + writel((desc_dma + off) >> 32, cp->regs + REG_TX_COMPWB_DB_HI); 2913 + writel((desc_dma + off) & 0xffffffff, cp->regs + REG_TX_COMPWB_DB_LOW); 2914 + #endif 2915 + 2916 + /* enable completion writebacks, enable paced mode, 2917 + * disable read pipe, and disable pre-interrupt compwbs 2918 + */ 2919 + val = TX_CFG_COMPWB_Q1 | TX_CFG_COMPWB_Q2 | 2920 + TX_CFG_COMPWB_Q3 | TX_CFG_COMPWB_Q4 | 2921 + TX_CFG_DMA_RDPIPE_DIS | TX_CFG_PACED_MODE | 2922 + TX_CFG_INTR_COMPWB_DIS; 2923 + 2924 + /* write out tx ring info and tx desc bases */ 2925 + for (i = 0; i < MAX_TX_RINGS; i++) { 2926 + off = (unsigned long) cp->init_txds[i] - 2927 + (unsigned long) cp->init_block; 2928 + 2929 + val |= CAS_TX_RINGN_BASE(i); 2930 + writel((desc_dma + off) >> 32, cp->regs + REG_TX_DBN_HI(i)); 2931 + writel((desc_dma + off) & 0xffffffff, cp->regs + 2932 + REG_TX_DBN_LOW(i)); 2933 + /* don't zero out the kick register here as the system 2934 + * will wedge 2935 + */ 2936 + } 2937 + writel(val, cp->regs + REG_TX_CFG); 2938 + 2939 + /* program max burst sizes. these numbers should be different 2940 + * if doing QoS. 2941 + */ 2942 + #ifdef USE_QOS 2943 + writel(0x800, cp->regs + REG_TX_MAXBURST_0); 2944 + writel(0x1600, cp->regs + REG_TX_MAXBURST_1); 2945 + writel(0x2400, cp->regs + REG_TX_MAXBURST_2); 2946 + writel(0x4800, cp->regs + REG_TX_MAXBURST_3); 2947 + #else 2948 + writel(0x800, cp->regs + REG_TX_MAXBURST_0); 2949 + writel(0x800, cp->regs + REG_TX_MAXBURST_1); 2950 + writel(0x800, cp->regs + REG_TX_MAXBURST_2); 2951 + writel(0x800, cp->regs + REG_TX_MAXBURST_3); 2952 + #endif 2953 + } 2954 + 2955 + /* Must be invoked under cp->lock. */ 2956 + static inline void cas_init_dma(struct cas *cp) 2957 + { 2958 + cas_init_tx_dma(cp); 2959 + cas_init_rx_dma(cp); 2960 + } 2961 + 2962 + /* Must be invoked under cp->lock. */ 2963 + static u32 cas_setup_multicast(struct cas *cp) 2964 + { 2965 + u32 rxcfg = 0; 2966 + int i; 2967 + 2968 + if (cp->dev->flags & IFF_PROMISC) { 2969 + rxcfg |= MAC_RX_CFG_PROMISC_EN; 2970 + 2971 + } else if (cp->dev->flags & IFF_ALLMULTI) { 2972 + for (i=0; i < 16; i++) 2973 + writel(0xFFFF, cp->regs + REG_MAC_HASH_TABLEN(i)); 2974 + rxcfg |= MAC_RX_CFG_HASH_FILTER_EN; 2975 + 2976 + } else { 2977 + u16 hash_table[16]; 2978 + u32 crc; 2979 + struct dev_mc_list *dmi = cp->dev->mc_list; 2980 + int i; 2981 + 2982 + /* use the alternate mac address registers for the 2983 + * first 15 multicast addresses 2984 + */ 2985 + for (i = 1; i <= CAS_MC_EXACT_MATCH_SIZE; i++) { 2986 + if (!dmi) { 2987 + writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 0)); 2988 + writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 1)); 2989 + writel(0x0, cp->regs + REG_MAC_ADDRN(i*3 + 2)); 2990 + continue; 2991 + } 2992 + writel((dmi->dmi_addr[4] << 8) | dmi->dmi_addr[5], 2993 + cp->regs + REG_MAC_ADDRN(i*3 + 0)); 2994 + writel((dmi->dmi_addr[2] << 8) | dmi->dmi_addr[3], 2995 + cp->regs + REG_MAC_ADDRN(i*3 + 1)); 2996 + writel((dmi->dmi_addr[0] << 8) | dmi->dmi_addr[1], 2997 + cp->regs + REG_MAC_ADDRN(i*3 + 2)); 2998 + dmi = dmi->next; 2999 + } 3000 + 3001 + /* use hw hash table for the next series of 3002 + * multicast addresses 3003 + */ 3004 + memset(hash_table, 0, sizeof(hash_table)); 3005 + while (dmi) { 3006 + crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr); 3007 + crc >>= 24; 3008 + hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); 3009 + dmi = dmi->next; 3010 + } 3011 + for (i=0; i < 16; i++) 3012 + writel(hash_table[i], cp->regs + 3013 + REG_MAC_HASH_TABLEN(i)); 3014 + rxcfg |= MAC_RX_CFG_HASH_FILTER_EN; 3015 + } 3016 + 3017 + return rxcfg; 3018 + } 3019 + 3020 + /* must be invoked under cp->stat_lock[N_TX_RINGS] */ 3021 + static void cas_clear_mac_err(struct cas *cp) 3022 + { 3023 + writel(0, cp->regs + REG_MAC_COLL_NORMAL); 3024 + writel(0, cp->regs + REG_MAC_COLL_FIRST); 3025 + writel(0, cp->regs + REG_MAC_COLL_EXCESS); 3026 + writel(0, cp->regs + REG_MAC_COLL_LATE); 3027 + writel(0, cp->regs + REG_MAC_TIMER_DEFER); 3028 + writel(0, cp->regs + REG_MAC_ATTEMPTS_PEAK); 3029 + writel(0, cp->regs + REG_MAC_RECV_FRAME); 3030 + writel(0, cp->regs + REG_MAC_LEN_ERR); 3031 + writel(0, cp->regs + REG_MAC_ALIGN_ERR); 3032 + writel(0, cp->regs + REG_MAC_FCS_ERR); 3033 + writel(0, cp->regs + REG_MAC_RX_CODE_ERR); 3034 + } 3035 + 3036 + 3037 + static void cas_mac_reset(struct cas *cp) 3038 + { 3039 + int i; 3040 + 3041 + /* do both TX and RX reset */ 3042 + writel(0x1, cp->regs + REG_MAC_TX_RESET); 3043 + writel(0x1, cp->regs + REG_MAC_RX_RESET); 3044 + 3045 + /* wait for TX */ 3046 + i = STOP_TRIES; 3047 + while (i-- > 0) { 3048 + if (readl(cp->regs + REG_MAC_TX_RESET) == 0) 3049 + break; 3050 + udelay(10); 3051 + } 3052 + 3053 + /* wait for RX */ 3054 + i = STOP_TRIES; 3055 + while (i-- > 0) { 3056 + if (readl(cp->regs + REG_MAC_RX_RESET) == 0) 3057 + break; 3058 + udelay(10); 3059 + } 3060 + 3061 + if (readl(cp->regs + REG_MAC_TX_RESET) | 3062 + readl(cp->regs + REG_MAC_RX_RESET)) 3063 + printk(KERN_ERR "%s: mac tx[%d]/rx[%d] reset failed [%08x]\n", 3064 + cp->dev->name, readl(cp->regs + REG_MAC_TX_RESET), 3065 + readl(cp->regs + REG_MAC_RX_RESET), 3066 + readl(cp->regs + REG_MAC_STATE_MACHINE)); 3067 + } 3068 + 3069 + 3070 + /* Must be invoked under cp->lock. */ 3071 + static void cas_init_mac(struct cas *cp) 3072 + { 3073 + unsigned char *e = &cp->dev->dev_addr[0]; 3074 + int i; 3075 + #ifdef CONFIG_CASSINI_MULTICAST_REG_WRITE 3076 + u32 rxcfg; 3077 + #endif 3078 + cas_mac_reset(cp); 3079 + 3080 + /* setup core arbitration weight register */ 3081 + writel(CAWR_RR_DIS, cp->regs + REG_CAWR); 3082 + 3083 + /* XXX Use pci_dma_burst_advice() */ 3084 + #if !defined(CONFIG_SPARC64) && !defined(CONFIG_ALPHA) 3085 + /* set the infinite burst register for chips that don't have 3086 + * pci issues. 3087 + */ 3088 + if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) == 0) 3089 + writel(INF_BURST_EN, cp->regs + REG_INF_BURST); 3090 + #endif 3091 + 3092 + writel(0x1BF0, cp->regs + REG_MAC_SEND_PAUSE); 3093 + 3094 + writel(0x00, cp->regs + REG_MAC_IPG0); 3095 + writel(0x08, cp->regs + REG_MAC_IPG1); 3096 + writel(0x04, cp->regs + REG_MAC_IPG2); 3097 + 3098 + /* change later for 802.3z */ 3099 + writel(0x40, cp->regs + REG_MAC_SLOT_TIME); 3100 + 3101 + /* min frame + FCS */ 3102 + writel(ETH_ZLEN + 4, cp->regs + REG_MAC_FRAMESIZE_MIN); 3103 + 3104 + /* Ethernet payload + header + FCS + optional VLAN tag. NOTE: we 3105 + * specify the maximum frame size to prevent RX tag errors on 3106 + * oversized frames. 3107 + */ 3108 + writel(CAS_BASE(MAC_FRAMESIZE_MAX_BURST, 0x2000) | 3109 + CAS_BASE(MAC_FRAMESIZE_MAX_FRAME, 3110 + (CAS_MAX_MTU + ETH_HLEN + 4 + 4)), 3111 + cp->regs + REG_MAC_FRAMESIZE_MAX); 3112 + 3113 + /* NOTE: crc_size is used as a surrogate for half-duplex. 3114 + * workaround saturn half-duplex issue by increasing preamble 3115 + * size to 65 bytes. 3116 + */ 3117 + if ((cp->cas_flags & CAS_FLAG_SATURN) && cp->crc_size) 3118 + writel(0x41, cp->regs + REG_MAC_PA_SIZE); 3119 + else 3120 + writel(0x07, cp->regs + REG_MAC_PA_SIZE); 3121 + writel(0x04, cp->regs + REG_MAC_JAM_SIZE); 3122 + writel(0x10, cp->regs + REG_MAC_ATTEMPT_LIMIT); 3123 + writel(0x8808, cp->regs + REG_MAC_CTRL_TYPE); 3124 + 3125 + writel((e[5] | (e[4] << 8)) & 0x3ff, cp->regs + REG_MAC_RANDOM_SEED); 3126 + 3127 + writel(0, cp->regs + REG_MAC_ADDR_FILTER0); 3128 + writel(0, cp->regs + REG_MAC_ADDR_FILTER1); 3129 + writel(0, cp->regs + REG_MAC_ADDR_FILTER2); 3130 + writel(0, cp->regs + REG_MAC_ADDR_FILTER2_1_MASK); 3131 + writel(0, cp->regs + REG_MAC_ADDR_FILTER0_MASK); 3132 + 3133 + /* setup mac address in perfect filter array */ 3134 + for (i = 0; i < 45; i++) 3135 + writel(0x0, cp->regs + REG_MAC_ADDRN(i)); 3136 + 3137 + writel((e[4] << 8) | e[5], cp->regs + REG_MAC_ADDRN(0)); 3138 + writel((e[2] << 8) | e[3], cp->regs + REG_MAC_ADDRN(1)); 3139 + writel((e[0] << 8) | e[1], cp->regs + REG_MAC_ADDRN(2)); 3140 + 3141 + writel(0x0001, cp->regs + REG_MAC_ADDRN(42)); 3142 + writel(0xc200, cp->regs + REG_MAC_ADDRN(43)); 3143 + writel(0x0180, cp->regs + REG_MAC_ADDRN(44)); 3144 + 3145 + #ifndef CONFIG_CASSINI_MULTICAST_REG_WRITE 3146 + cp->mac_rx_cfg = cas_setup_multicast(cp); 3147 + #else 3148 + /* WTZ: Do what Adrian did in cas_set_multicast. Doing 3149 + * a writel does not seem to be necessary because Cassini 3150 + * seems to preserve the configuration when we do the reset. 3151 + * If the chip is in trouble, though, it is not clear if we 3152 + * can really count on this behavior. cas_set_multicast uses 3153 + * spin_lock_irqsave, but we are called only in cas_init_hw and 3154 + * cas_init_hw is protected by cas_lock_all, which calls 3155 + * spin_lock_irq (so it doesn't need to save the flags, and 3156 + * we should be OK for the writel, as that is the only 3157 + * difference). 3158 + */ 3159 + cp->mac_rx_cfg = rxcfg = cas_setup_multicast(cp); 3160 + writel(rxcfg, cp->regs + REG_MAC_RX_CFG); 3161 + #endif 3162 + spin_lock(&cp->stat_lock[N_TX_RINGS]); 3163 + cas_clear_mac_err(cp); 3164 + spin_unlock(&cp->stat_lock[N_TX_RINGS]); 3165 + 3166 + /* Setup MAC interrupts. We want to get all of the interesting 3167 + * counter expiration events, but we do not want to hear about 3168 + * normal rx/tx as the DMA engine tells us that. 3169 + */ 3170 + writel(MAC_TX_FRAME_XMIT, cp->regs + REG_MAC_TX_MASK); 3171 + writel(MAC_RX_FRAME_RECV, cp->regs + REG_MAC_RX_MASK); 3172 + 3173 + /* Don't enable even the PAUSE interrupts for now, we 3174 + * make no use of those events other than to record them. 3175 + */ 3176 + writel(0xffffffff, cp->regs + REG_MAC_CTRL_MASK); 3177 + } 3178 + 3179 + /* Must be invoked under cp->lock. */ 3180 + static void cas_init_pause_thresholds(struct cas *cp) 3181 + { 3182 + /* Calculate pause thresholds. Setting the OFF threshold to the 3183 + * full RX fifo size effectively disables PAUSE generation 3184 + */ 3185 + if (cp->rx_fifo_size <= (2 * 1024)) { 3186 + cp->rx_pause_off = cp->rx_pause_on = cp->rx_fifo_size; 3187 + } else { 3188 + int max_frame = (cp->dev->mtu + ETH_HLEN + 4 + 4 + 64) & ~63; 3189 + if (max_frame * 3 > cp->rx_fifo_size) { 3190 + cp->rx_pause_off = 7104; 3191 + cp->rx_pause_on = 960; 3192 + } else { 3193 + int off = (cp->rx_fifo_size - (max_frame * 2)); 3194 + int on = off - max_frame; 3195 + cp->rx_pause_off = off; 3196 + cp->rx_pause_on = on; 3197 + } 3198 + } 3199 + } 3200 + 3201 + static int cas_vpd_match(const void __iomem *p, const char *str) 3202 + { 3203 + int len = strlen(str) + 1; 3204 + int i; 3205 + 3206 + for (i = 0; i < len; i++) { 3207 + if (readb(p + i) != str[i]) 3208 + return 0; 3209 + } 3210 + return 1; 3211 + } 3212 + 3213 + 3214 + /* get the mac address by reading the vpd information in the rom. 3215 + * also get the phy type and determine if there's an entropy generator. 3216 + * NOTE: this is a bit convoluted for the following reasons: 3217 + * 1) vpd info has order-dependent mac addresses for multinic cards 3218 + * 2) the only way to determine the nic order is to use the slot 3219 + * number. 3220 + * 3) fiber cards don't have bridges, so their slot numbers don't 3221 + * mean anything. 3222 + * 4) we don't actually know we have a fiber card until after 3223 + * the mac addresses are parsed. 3224 + */ 3225 + static int cas_get_vpd_info(struct cas *cp, unsigned char *dev_addr, 3226 + const int offset) 3227 + { 3228 + void __iomem *p = cp->regs + REG_EXPANSION_ROM_RUN_START; 3229 + void __iomem *base, *kstart; 3230 + int i, len; 3231 + int found = 0; 3232 + #define VPD_FOUND_MAC 0x01 3233 + #define VPD_FOUND_PHY 0x02 3234 + 3235 + int phy_type = CAS_PHY_MII_MDIO0; /* default phy type */ 3236 + int mac_off = 0; 3237 + 3238 + /* give us access to the PROM */ 3239 + writel(BIM_LOCAL_DEV_PROM | BIM_LOCAL_DEV_PAD, 3240 + cp->regs + REG_BIM_LOCAL_DEV_EN); 3241 + 3242 + /* check for an expansion rom */ 3243 + if (readb(p) != 0x55 || readb(p + 1) != 0xaa) 3244 + goto use_random_mac_addr; 3245 + 3246 + /* search for beginning of vpd */ 3247 + base = 0; 3248 + for (i = 2; i < EXPANSION_ROM_SIZE; i++) { 3249 + /* check for PCIR */ 3250 + if ((readb(p + i + 0) == 0x50) && 3251 + (readb(p + i + 1) == 0x43) && 3252 + (readb(p + i + 2) == 0x49) && 3253 + (readb(p + i + 3) == 0x52)) { 3254 + base = p + (readb(p + i + 8) | 3255 + (readb(p + i + 9) << 8)); 3256 + break; 3257 + } 3258 + } 3259 + 3260 + if (!base || (readb(base) != 0x82)) 3261 + goto use_random_mac_addr; 3262 + 3263 + i = (readb(base + 1) | (readb(base + 2) << 8)) + 3; 3264 + while (i < EXPANSION_ROM_SIZE) { 3265 + if (readb(base + i) != 0x90) /* no vpd found */ 3266 + goto use_random_mac_addr; 3267 + 3268 + /* found a vpd field */ 3269 + len = readb(base + i + 1) | (readb(base + i + 2) << 8); 3270 + 3271 + /* extract keywords */ 3272 + kstart = base + i + 3; 3273 + p = kstart; 3274 + while ((p - kstart) < len) { 3275 + int klen = readb(p + 2); 3276 + int j; 3277 + char type; 3278 + 3279 + p += 3; 3280 + 3281 + /* look for the following things: 3282 + * -- correct length == 29 3283 + * 3 (type) + 2 (size) + 3284 + * 18 (strlen("local-mac-address") + 1) + 3285 + * 6 (mac addr) 3286 + * -- VPD Instance 'I' 3287 + * -- VPD Type Bytes 'B' 3288 + * -- VPD data length == 6 3289 + * -- property string == local-mac-address 3290 + * 3291 + * -- correct length == 24 3292 + * 3 (type) + 2 (size) + 3293 + * 12 (strlen("entropy-dev") + 1) + 3294 + * 7 (strlen("vms110") + 1) 3295 + * -- VPD Instance 'I' 3296 + * -- VPD Type String 'B' 3297 + * -- VPD data length == 7 3298 + * -- property string == entropy-dev 3299 + * 3300 + * -- correct length == 18 3301 + * 3 (type) + 2 (size) + 3302 + * 9 (strlen("phy-type") + 1) + 3303 + * 4 (strlen("pcs") + 1) 3304 + * -- VPD Instance 'I' 3305 + * -- VPD Type String 'S' 3306 + * -- VPD data length == 4 3307 + * -- property string == phy-type 3308 + * 3309 + * -- correct length == 23 3310 + * 3 (type) + 2 (size) + 3311 + * 14 (strlen("phy-interface") + 1) + 3312 + * 4 (strlen("pcs") + 1) 3313 + * -- VPD Instance 'I' 3314 + * -- VPD Type String 'S' 3315 + * -- VPD data length == 4 3316 + * -- property string == phy-interface 3317 + */ 3318 + if (readb(p) != 'I') 3319 + goto next; 3320 + 3321 + /* finally, check string and length */ 3322 + type = readb(p + 3); 3323 + if (type == 'B') { 3324 + if ((klen == 29) && readb(p + 4) == 6 && 3325 + cas_vpd_match(p + 5, 3326 + "local-mac-address")) { 3327 + if (mac_off++ > offset) 3328 + goto next; 3329 + 3330 + /* set mac address */ 3331 + for (j = 0; j < 6; j++) 3332 + dev_addr[j] = 3333 + readb(p + 23 + j); 3334 + goto found_mac; 3335 + } 3336 + } 3337 + 3338 + if (type != 'S') 3339 + goto next; 3340 + 3341 + #ifdef USE_ENTROPY_DEV 3342 + if ((klen == 24) && 3343 + cas_vpd_match(p + 5, "entropy-dev") && 3344 + cas_vpd_match(p + 17, "vms110")) { 3345 + cp->cas_flags |= CAS_FLAG_ENTROPY_DEV; 3346 + goto next; 3347 + } 3348 + #endif 3349 + 3350 + if (found & VPD_FOUND_PHY) 3351 + goto next; 3352 + 3353 + if ((klen == 18) && readb(p + 4) == 4 && 3354 + cas_vpd_match(p + 5, "phy-type")) { 3355 + if (cas_vpd_match(p + 14, "pcs")) { 3356 + phy_type = CAS_PHY_SERDES; 3357 + goto found_phy; 3358 + } 3359 + } 3360 + 3361 + if ((klen == 23) && readb(p + 4) == 4 && 3362 + cas_vpd_match(p + 5, "phy-interface")) { 3363 + if (cas_vpd_match(p + 19, "pcs")) { 3364 + phy_type = CAS_PHY_SERDES; 3365 + goto found_phy; 3366 + } 3367 + } 3368 + found_mac: 3369 + found |= VPD_FOUND_MAC; 3370 + goto next; 3371 + 3372 + found_phy: 3373 + found |= VPD_FOUND_PHY; 3374 + 3375 + next: 3376 + p += klen; 3377 + } 3378 + i += len + 3; 3379 + } 3380 + 3381 + use_random_mac_addr: 3382 + if (found & VPD_FOUND_MAC) 3383 + goto done; 3384 + 3385 + /* Sun MAC prefix then 3 random bytes. */ 3386 + printk(PFX "MAC address not found in ROM VPD\n"); 3387 + dev_addr[0] = 0x08; 3388 + dev_addr[1] = 0x00; 3389 + dev_addr[2] = 0x20; 3390 + get_random_bytes(dev_addr + 3, 3); 3391 + 3392 + done: 3393 + writel(0, cp->regs + REG_BIM_LOCAL_DEV_EN); 3394 + return phy_type; 3395 + } 3396 + 3397 + /* check pci invariants */ 3398 + static void cas_check_pci_invariants(struct cas *cp) 3399 + { 3400 + struct pci_dev *pdev = cp->pdev; 3401 + u8 rev; 3402 + 3403 + cp->cas_flags = 0; 3404 + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); 3405 + if ((pdev->vendor == PCI_VENDOR_ID_SUN) && 3406 + (pdev->device == PCI_DEVICE_ID_SUN_CASSINI)) { 3407 + if (rev >= CAS_ID_REVPLUS) 3408 + cp->cas_flags |= CAS_FLAG_REG_PLUS; 3409 + if (rev < CAS_ID_REVPLUS02u) 3410 + cp->cas_flags |= CAS_FLAG_TARGET_ABORT; 3411 + 3412 + /* Original Cassini supports HW CSUM, but it's not 3413 + * enabled by default as it can trigger TX hangs. 3414 + */ 3415 + if (rev < CAS_ID_REV2) 3416 + cp->cas_flags |= CAS_FLAG_NO_HW_CSUM; 3417 + } else { 3418 + /* Only sun has original cassini chips. */ 3419 + cp->cas_flags |= CAS_FLAG_REG_PLUS; 3420 + 3421 + /* We use a flag because the same phy might be externally 3422 + * connected. 3423 + */ 3424 + if ((pdev->vendor == PCI_VENDOR_ID_NS) && 3425 + (pdev->device == PCI_DEVICE_ID_NS_SATURN)) 3426 + cp->cas_flags |= CAS_FLAG_SATURN; 3427 + } 3428 + } 3429 + 3430 + 3431 + static int cas_check_invariants(struct cas *cp) 3432 + { 3433 + struct pci_dev *pdev = cp->pdev; 3434 + u32 cfg; 3435 + int i; 3436 + 3437 + /* get page size for rx buffers. */ 3438 + cp->page_order = 0; 3439 + #ifdef USE_PAGE_ORDER 3440 + if (PAGE_SHIFT < CAS_JUMBO_PAGE_SHIFT) { 3441 + /* see if we can allocate larger pages */ 3442 + struct page *page = alloc_pages(GFP_ATOMIC, 3443 + CAS_JUMBO_PAGE_SHIFT - 3444 + PAGE_SHIFT); 3445 + if (page) { 3446 + __free_pages(page, CAS_JUMBO_PAGE_SHIFT - PAGE_SHIFT); 3447 + cp->page_order = CAS_JUMBO_PAGE_SHIFT - PAGE_SHIFT; 3448 + } else { 3449 + printk(PFX "MTU limited to %d bytes\n", CAS_MAX_MTU); 3450 + } 3451 + } 3452 + #endif 3453 + cp->page_size = (PAGE_SIZE << cp->page_order); 3454 + 3455 + /* Fetch the FIFO configurations. */ 3456 + cp->tx_fifo_size = readl(cp->regs + REG_TX_FIFO_SIZE) * 64; 3457 + cp->rx_fifo_size = RX_FIFO_SIZE; 3458 + 3459 + /* finish phy determination. MDIO1 takes precedence over MDIO0 if 3460 + * they're both connected. 3461 + */ 3462 + cp->phy_type = cas_get_vpd_info(cp, cp->dev->dev_addr, 3463 + PCI_SLOT(pdev->devfn)); 3464 + if (cp->phy_type & CAS_PHY_SERDES) { 3465 + cp->cas_flags |= CAS_FLAG_1000MB_CAP; 3466 + return 0; /* no more checking needed */ 3467 + } 3468 + 3469 + /* MII */ 3470 + cfg = readl(cp->regs + REG_MIF_CFG); 3471 + if (cfg & MIF_CFG_MDIO_1) { 3472 + cp->phy_type = CAS_PHY_MII_MDIO1; 3473 + } else if (cfg & MIF_CFG_MDIO_0) { 3474 + cp->phy_type = CAS_PHY_MII_MDIO0; 3475 + } 3476 + 3477 + cas_mif_poll(cp, 0); 3478 + writel(PCS_DATAPATH_MODE_MII, cp->regs + REG_PCS_DATAPATH_MODE); 3479 + 3480 + for (i = 0; i < 32; i++) { 3481 + u32 phy_id; 3482 + int j; 3483 + 3484 + for (j = 0; j < 3; j++) { 3485 + cp->phy_addr = i; 3486 + phy_id = cas_phy_read(cp, MII_PHYSID1) << 16; 3487 + phy_id |= cas_phy_read(cp, MII_PHYSID2); 3488 + if (phy_id && (phy_id != 0xFFFFFFFF)) { 3489 + cp->phy_id = phy_id; 3490 + goto done; 3491 + } 3492 + } 3493 + } 3494 + printk(KERN_ERR PFX "MII phy did not respond [%08x]\n", 3495 + readl(cp->regs + REG_MIF_STATE_MACHINE)); 3496 + return -1; 3497 + 3498 + done: 3499 + /* see if we can do gigabit */ 3500 + cfg = cas_phy_read(cp, MII_BMSR); 3501 + if ((cfg & CAS_BMSR_1000_EXTEND) && 3502 + cas_phy_read(cp, CAS_MII_1000_EXTEND)) 3503 + cp->cas_flags |= CAS_FLAG_1000MB_CAP; 3504 + return 0; 3505 + } 3506 + 3507 + /* Must be invoked under cp->lock. */ 3508 + static inline void cas_start_dma(struct cas *cp) 3509 + { 3510 + int i; 3511 + u32 val; 3512 + int txfailed = 0; 3513 + 3514 + /* enable dma */ 3515 + val = readl(cp->regs + REG_TX_CFG) | TX_CFG_DMA_EN; 3516 + writel(val, cp->regs + REG_TX_CFG); 3517 + val = readl(cp->regs + REG_RX_CFG) | RX_CFG_DMA_EN; 3518 + writel(val, cp->regs + REG_RX_CFG); 3519 + 3520 + /* enable the mac */ 3521 + val = readl(cp->regs + REG_MAC_TX_CFG) | MAC_TX_CFG_EN; 3522 + writel(val, cp->regs + REG_MAC_TX_CFG); 3523 + val = readl(cp->regs + REG_MAC_RX_CFG) | MAC_RX_CFG_EN; 3524 + writel(val, cp->regs + REG_MAC_RX_CFG); 3525 + 3526 + i = STOP_TRIES; 3527 + while (i-- > 0) { 3528 + val = readl(cp->regs + REG_MAC_TX_CFG); 3529 + if ((val & MAC_TX_CFG_EN)) 3530 + break; 3531 + udelay(10); 3532 + } 3533 + if (i < 0) txfailed = 1; 3534 + i = STOP_TRIES; 3535 + while (i-- > 0) { 3536 + val = readl(cp->regs + REG_MAC_RX_CFG); 3537 + if ((val & MAC_RX_CFG_EN)) { 3538 + if (txfailed) { 3539 + printk(KERN_ERR 3540 + "%s: enabling mac failed [tx:%08x:%08x].\n", 3541 + cp->dev->name, 3542 + readl(cp->regs + REG_MIF_STATE_MACHINE), 3543 + readl(cp->regs + REG_MAC_STATE_MACHINE)); 3544 + } 3545 + goto enable_rx_done; 3546 + } 3547 + udelay(10); 3548 + } 3549 + printk(KERN_ERR "%s: enabling mac failed [%s:%08x:%08x].\n", 3550 + cp->dev->name, 3551 + (txfailed? "tx,rx":"rx"), 3552 + readl(cp->regs + REG_MIF_STATE_MACHINE), 3553 + readl(cp->regs + REG_MAC_STATE_MACHINE)); 3554 + 3555 + enable_rx_done: 3556 + cas_unmask_intr(cp); /* enable interrupts */ 3557 + writel(RX_DESC_RINGN_SIZE(0) - 4, cp->regs + REG_RX_KICK); 3558 + writel(0, cp->regs + REG_RX_COMP_TAIL); 3559 + 3560 + if (cp->cas_flags & CAS_FLAG_REG_PLUS) { 3561 + if (N_RX_DESC_RINGS > 1) 3562 + writel(RX_DESC_RINGN_SIZE(1) - 4, 3563 + cp->regs + REG_PLUS_RX_KICK1); 3564 + 3565 + for (i = 1; i < N_RX_COMP_RINGS; i++) 3566 + writel(0, cp->regs + REG_PLUS_RX_COMPN_TAIL(i)); 3567 + } 3568 + } 3569 + 3570 + /* Must be invoked under cp->lock. */ 3571 + static void cas_read_pcs_link_mode(struct cas *cp, int *fd, int *spd, 3572 + int *pause) 3573 + { 3574 + u32 val = readl(cp->regs + REG_PCS_MII_LPA); 3575 + *fd = (val & PCS_MII_LPA_FD) ? 1 : 0; 3576 + *pause = (val & PCS_MII_LPA_SYM_PAUSE) ? 0x01 : 0x00; 3577 + if (val & PCS_MII_LPA_ASYM_PAUSE) 3578 + *pause |= 0x10; 3579 + *spd = 1000; 3580 + } 3581 + 3582 + /* Must be invoked under cp->lock. */ 3583 + static void cas_read_mii_link_mode(struct cas *cp, int *fd, int *spd, 3584 + int *pause) 3585 + { 3586 + u32 val; 3587 + 3588 + *fd = 0; 3589 + *spd = 10; 3590 + *pause = 0; 3591 + 3592 + /* use GMII registers */ 3593 + val = cas_phy_read(cp, MII_LPA); 3594 + if (val & CAS_LPA_PAUSE) 3595 + *pause = 0x01; 3596 + 3597 + if (val & CAS_LPA_ASYM_PAUSE) 3598 + *pause |= 0x10; 3599 + 3600 + if (val & LPA_DUPLEX) 3601 + *fd = 1; 3602 + if (val & LPA_100) 3603 + *spd = 100; 3604 + 3605 + if (cp->cas_flags & CAS_FLAG_1000MB_CAP) { 3606 + val = cas_phy_read(cp, CAS_MII_1000_STATUS); 3607 + if (val & (CAS_LPA_1000FULL | CAS_LPA_1000HALF)) 3608 + *spd = 1000; 3609 + if (val & CAS_LPA_1000FULL) 3610 + *fd = 1; 3611 + } 3612 + } 3613 + 3614 + /* A link-up condition has occurred, initialize and enable the 3615 + * rest of the chip. 3616 + * 3617 + * Must be invoked under cp->lock. 3618 + */ 3619 + static void cas_set_link_modes(struct cas *cp) 3620 + { 3621 + u32 val; 3622 + int full_duplex, speed, pause; 3623 + 3624 + full_duplex = 0; 3625 + speed = 10; 3626 + pause = 0; 3627 + 3628 + if (CAS_PHY_MII(cp->phy_type)) { 3629 + cas_mif_poll(cp, 0); 3630 + val = cas_phy_read(cp, MII_BMCR); 3631 + if (val & BMCR_ANENABLE) { 3632 + cas_read_mii_link_mode(cp, &full_duplex, &speed, 3633 + &pause); 3634 + } else { 3635 + if (val & BMCR_FULLDPLX) 3636 + full_duplex = 1; 3637 + 3638 + if (val & BMCR_SPEED100) 3639 + speed = 100; 3640 + else if (val & CAS_BMCR_SPEED1000) 3641 + speed = (cp->cas_flags & CAS_FLAG_1000MB_CAP) ? 3642 + 1000 : 100; 3643 + } 3644 + cas_mif_poll(cp, 1); 3645 + 3646 + } else { 3647 + val = readl(cp->regs + REG_PCS_MII_CTRL); 3648 + cas_read_pcs_link_mode(cp, &full_duplex, &speed, &pause); 3649 + if ((val & PCS_MII_AUTONEG_EN) == 0) { 3650 + if (val & PCS_MII_CTRL_DUPLEX) 3651 + full_duplex = 1; 3652 + } 3653 + } 3654 + 3655 + if (netif_msg_link(cp)) 3656 + printk(KERN_INFO "%s: Link up at %d Mbps, %s-duplex.\n", 3657 + cp->dev->name, speed, (full_duplex ? "full" : "half")); 3658 + 3659 + val = MAC_XIF_TX_MII_OUTPUT_EN | MAC_XIF_LINK_LED; 3660 + if (CAS_PHY_MII(cp->phy_type)) { 3661 + val |= MAC_XIF_MII_BUFFER_OUTPUT_EN; 3662 + if (!full_duplex) 3663 + val |= MAC_XIF_DISABLE_ECHO; 3664 + } 3665 + if (full_duplex) 3666 + val |= MAC_XIF_FDPLX_LED; 3667 + if (speed == 1000) 3668 + val |= MAC_XIF_GMII_MODE; 3669 + writel(val, cp->regs + REG_MAC_XIF_CFG); 3670 + 3671 + /* deal with carrier and collision detect. */ 3672 + val = MAC_TX_CFG_IPG_EN; 3673 + if (full_duplex) { 3674 + val |= MAC_TX_CFG_IGNORE_CARRIER; 3675 + val |= MAC_TX_CFG_IGNORE_COLL; 3676 + } else { 3677 + #ifndef USE_CSMA_CD_PROTO 3678 + val |= MAC_TX_CFG_NEVER_GIVE_UP_EN; 3679 + val |= MAC_TX_CFG_NEVER_GIVE_UP_LIM; 3680 + #endif 3681 + } 3682 + /* val now set up for REG_MAC_TX_CFG */ 3683 + 3684 + /* If gigabit and half-duplex, enable carrier extension 3685 + * mode. increase slot time to 512 bytes as well. 3686 + * else, disable it and make sure slot time is 64 bytes. 3687 + * also activate checksum bug workaround 3688 + */ 3689 + if ((speed == 1000) && !full_duplex) { 3690 + writel(val | MAC_TX_CFG_CARRIER_EXTEND, 3691 + cp->regs + REG_MAC_TX_CFG); 3692 + 3693 + val = readl(cp->regs + REG_MAC_RX_CFG); 3694 + val &= ~MAC_RX_CFG_STRIP_FCS; /* checksum workaround */ 3695 + writel(val | MAC_RX_CFG_CARRIER_EXTEND, 3696 + cp->regs + REG_MAC_RX_CFG); 3697 + 3698 + writel(0x200, cp->regs + REG_MAC_SLOT_TIME); 3699 + 3700 + cp->crc_size = 4; 3701 + /* minimum size gigabit frame at half duplex */ 3702 + cp->min_frame_size = CAS_1000MB_MIN_FRAME; 3703 + 3704 + } else { 3705 + writel(val, cp->regs + REG_MAC_TX_CFG); 3706 + 3707 + /* checksum bug workaround. don't strip FCS when in 3708 + * half-duplex mode 3709 + */ 3710 + val = readl(cp->regs + REG_MAC_RX_CFG); 3711 + if (full_duplex) { 3712 + val |= MAC_RX_CFG_STRIP_FCS; 3713 + cp->crc_size = 0; 3714 + cp->min_frame_size = CAS_MIN_MTU; 3715 + } else { 3716 + val &= ~MAC_RX_CFG_STRIP_FCS; 3717 + cp->crc_size = 4; 3718 + cp->min_frame_size = CAS_MIN_FRAME; 3719 + } 3720 + writel(val & ~MAC_RX_CFG_CARRIER_EXTEND, 3721 + cp->regs + REG_MAC_RX_CFG); 3722 + writel(0x40, cp->regs + REG_MAC_SLOT_TIME); 3723 + } 3724 + 3725 + if (netif_msg_link(cp)) { 3726 + if (pause & 0x01) { 3727 + printk(KERN_INFO "%s: Pause is enabled " 3728 + "(rxfifo: %d off: %d on: %d)\n", 3729 + cp->dev->name, 3730 + cp->rx_fifo_size, 3731 + cp->rx_pause_off, 3732 + cp->rx_pause_on); 3733 + } else if (pause & 0x10) { 3734 + printk(KERN_INFO "%s: TX pause enabled\n", 3735 + cp->dev->name); 3736 + } else { 3737 + printk(KERN_INFO "%s: Pause is disabled\n", 3738 + cp->dev->name); 3739 + } 3740 + } 3741 + 3742 + val = readl(cp->regs + REG_MAC_CTRL_CFG); 3743 + val &= ~(MAC_CTRL_CFG_SEND_PAUSE_EN | MAC_CTRL_CFG_RECV_PAUSE_EN); 3744 + if (pause) { /* symmetric or asymmetric pause */ 3745 + val |= MAC_CTRL_CFG_SEND_PAUSE_EN; 3746 + if (pause & 0x01) { /* symmetric pause */ 3747 + val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 3748 + } 3749 + } 3750 + writel(val, cp->regs + REG_MAC_CTRL_CFG); 3751 + cas_start_dma(cp); 3752 + } 3753 + 3754 + /* Must be invoked under cp->lock. */ 3755 + static void cas_init_hw(struct cas *cp, int restart_link) 3756 + { 3757 + if (restart_link) 3758 + cas_phy_init(cp); 3759 + 3760 + cas_init_pause_thresholds(cp); 3761 + cas_init_mac(cp); 3762 + cas_init_dma(cp); 3763 + 3764 + if (restart_link) { 3765 + /* Default aneg parameters */ 3766 + cp->timer_ticks = 0; 3767 + cas_begin_auto_negotiation(cp, NULL); 3768 + } else if (cp->lstate == link_up) { 3769 + cas_set_link_modes(cp); 3770 + netif_carrier_on(cp->dev); 3771 + } 3772 + } 3773 + 3774 + /* Must be invoked under cp->lock. on earlier cassini boards, 3775 + * SOFT_0 is tied to PCI reset. we use this to force a pci reset, 3776 + * let it settle out, and then restore pci state. 3777 + */ 3778 + static void cas_hard_reset(struct cas *cp) 3779 + { 3780 + writel(BIM_LOCAL_DEV_SOFT_0, cp->regs + REG_BIM_LOCAL_DEV_EN); 3781 + udelay(20); 3782 + pci_restore_state(cp->pdev); 3783 + } 3784 + 3785 + 3786 + static void cas_global_reset(struct cas *cp, int blkflag) 3787 + { 3788 + int limit; 3789 + 3790 + /* issue a global reset. don't use RSTOUT. */ 3791 + if (blkflag && !CAS_PHY_MII(cp->phy_type)) { 3792 + /* For PCS, when the blkflag is set, we should set the 3793 + * SW_REST_BLOCK_PCS_SLINK bit to prevent the results of 3794 + * the last autonegotiation from being cleared. We'll 3795 + * need some special handling if the chip is set into a 3796 + * loopback mode. 3797 + */ 3798 + writel((SW_RESET_TX | SW_RESET_RX | SW_RESET_BLOCK_PCS_SLINK), 3799 + cp->regs + REG_SW_RESET); 3800 + } else { 3801 + writel(SW_RESET_TX | SW_RESET_RX, cp->regs + REG_SW_RESET); 3802 + } 3803 + 3804 + /* need to wait at least 3ms before polling register */ 3805 + mdelay(3); 3806 + 3807 + limit = STOP_TRIES; 3808 + while (limit-- > 0) { 3809 + u32 val = readl(cp->regs + REG_SW_RESET); 3810 + if ((val & (SW_RESET_TX | SW_RESET_RX)) == 0) 3811 + goto done; 3812 + udelay(10); 3813 + } 3814 + printk(KERN_ERR "%s: sw reset failed.\n", cp->dev->name); 3815 + 3816 + done: 3817 + /* enable various BIM interrupts */ 3818 + writel(BIM_CFG_DPAR_INTR_ENABLE | BIM_CFG_RMA_INTR_ENABLE | 3819 + BIM_CFG_RTA_INTR_ENABLE, cp->regs + REG_BIM_CFG); 3820 + 3821 + /* clear out pci error status mask for handled errors. 3822 + * we don't deal with DMA counter overflows as they happen 3823 + * all the time. 3824 + */ 3825 + writel(0xFFFFFFFFU & ~(PCI_ERR_BADACK | PCI_ERR_DTRTO | 3826 + PCI_ERR_OTHER | PCI_ERR_BIM_DMA_WRITE | 3827 + PCI_ERR_BIM_DMA_READ), cp->regs + 3828 + REG_PCI_ERR_STATUS_MASK); 3829 + 3830 + /* set up for MII by default to address mac rx reset timeout 3831 + * issue 3832 + */ 3833 + writel(PCS_DATAPATH_MODE_MII, cp->regs + REG_PCS_DATAPATH_MODE); 3834 + } 3835 + 3836 + static void cas_reset(struct cas *cp, int blkflag) 3837 + { 3838 + u32 val; 3839 + 3840 + cas_mask_intr(cp); 3841 + cas_global_reset(cp, blkflag); 3842 + cas_mac_reset(cp); 3843 + cas_entropy_reset(cp); 3844 + 3845 + /* disable dma engines. */ 3846 + val = readl(cp->regs + REG_TX_CFG); 3847 + val &= ~TX_CFG_DMA_EN; 3848 + writel(val, cp->regs + REG_TX_CFG); 3849 + 3850 + val = readl(cp->regs + REG_RX_CFG); 3851 + val &= ~RX_CFG_DMA_EN; 3852 + writel(val, cp->regs + REG_RX_CFG); 3853 + 3854 + /* program header parser */ 3855 + if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) || 3856 + (CAS_HP_ALT_FIRMWARE == cas_prog_null)) { 3857 + cas_load_firmware(cp, CAS_HP_FIRMWARE); 3858 + } else { 3859 + cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE); 3860 + } 3861 + 3862 + /* clear out error registers */ 3863 + spin_lock(&cp->stat_lock[N_TX_RINGS]); 3864 + cas_clear_mac_err(cp); 3865 + spin_unlock(&cp->stat_lock[N_TX_RINGS]); 3866 + } 3867 + 3868 + /* Shut down the chip, must be called with pm_sem held. */ 3869 + static void cas_shutdown(struct cas *cp) 3870 + { 3871 + unsigned long flags; 3872 + 3873 + /* Make us not-running to avoid timers respawning */ 3874 + cp->hw_running = 0; 3875 + 3876 + del_timer_sync(&cp->link_timer); 3877 + 3878 + /* Stop the reset task */ 3879 + #if 0 3880 + while (atomic_read(&cp->reset_task_pending_mtu) || 3881 + atomic_read(&cp->reset_task_pending_spare) || 3882 + atomic_read(&cp->reset_task_pending_all)) 3883 + schedule(); 3884 + 3885 + #else 3886 + while (atomic_read(&cp->reset_task_pending)) 3887 + schedule(); 3888 + #endif 3889 + /* Actually stop the chip */ 3890 + cas_lock_all_save(cp, flags); 3891 + cas_reset(cp, 0); 3892 + if (cp->cas_flags & CAS_FLAG_SATURN) 3893 + cas_phy_powerdown(cp); 3894 + cas_unlock_all_restore(cp, flags); 3895 + } 3896 + 3897 + static int cas_change_mtu(struct net_device *dev, int new_mtu) 3898 + { 3899 + struct cas *cp = netdev_priv(dev); 3900 + 3901 + if (new_mtu < CAS_MIN_MTU || new_mtu > CAS_MAX_MTU) 3902 + return -EINVAL; 3903 + 3904 + dev->mtu = new_mtu; 3905 + if (!netif_running(dev) || !netif_device_present(dev)) 3906 + return 0; 3907 + 3908 + /* let the reset task handle it */ 3909 + #if 1 3910 + atomic_inc(&cp->reset_task_pending); 3911 + if ((cp->phy_type & CAS_PHY_SERDES)) { 3912 + atomic_inc(&cp->reset_task_pending_all); 3913 + } else { 3914 + atomic_inc(&cp->reset_task_pending_mtu); 3915 + } 3916 + schedule_work(&cp->reset_task); 3917 + #else 3918 + atomic_set(&cp->reset_task_pending, (cp->phy_type & CAS_PHY_SERDES) ? 3919 + CAS_RESET_ALL : CAS_RESET_MTU); 3920 + printk(KERN_ERR "reset called in cas_change_mtu\n"); 3921 + schedule_work(&cp->reset_task); 3922 + #endif 3923 + 3924 + flush_scheduled_work(); 3925 + return 0; 3926 + } 3927 + 3928 + static void cas_clean_txd(struct cas *cp, int ring) 3929 + { 3930 + struct cas_tx_desc *txd = cp->init_txds[ring]; 3931 + struct sk_buff *skb, **skbs = cp->tx_skbs[ring]; 3932 + u64 daddr, dlen; 3933 + int i, size; 3934 + 3935 + size = TX_DESC_RINGN_SIZE(ring); 3936 + for (i = 0; i < size; i++) { 3937 + int frag; 3938 + 3939 + if (skbs[i] == NULL) 3940 + continue; 3941 + 3942 + skb = skbs[i]; 3943 + skbs[i] = NULL; 3944 + 3945 + for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) { 3946 + int ent = i & (size - 1); 3947 + 3948 + /* first buffer is never a tiny buffer and so 3949 + * needs to be unmapped. 3950 + */ 3951 + daddr = le64_to_cpu(txd[ent].buffer); 3952 + dlen = CAS_VAL(TX_DESC_BUFLEN, 3953 + le64_to_cpu(txd[ent].control)); 3954 + pci_unmap_page(cp->pdev, daddr, dlen, 3955 + PCI_DMA_TODEVICE); 3956 + 3957 + if (frag != skb_shinfo(skb)->nr_frags) { 3958 + i++; 3959 + 3960 + /* next buffer might by a tiny buffer. 3961 + * skip past it. 3962 + */ 3963 + ent = i & (size - 1); 3964 + if (cp->tx_tiny_use[ring][ent].used) 3965 + i++; 3966 + } 3967 + } 3968 + dev_kfree_skb_any(skb); 3969 + } 3970 + 3971 + /* zero out tiny buf usage */ 3972 + memset(cp->tx_tiny_use[ring], 0, size*sizeof(*cp->tx_tiny_use[ring])); 3973 + } 3974 + 3975 + /* freed on close */ 3976 + static inline void cas_free_rx_desc(struct cas *cp, int ring) 3977 + { 3978 + cas_page_t **page = cp->rx_pages[ring]; 3979 + int i, size; 3980 + 3981 + size = RX_DESC_RINGN_SIZE(ring); 3982 + for (i = 0; i < size; i++) { 3983 + if (page[i]) { 3984 + cas_page_free(cp, page[i]); 3985 + page[i] = NULL; 3986 + } 3987 + } 3988 + } 3989 + 3990 + static void cas_free_rxds(struct cas *cp) 3991 + { 3992 + int i; 3993 + 3994 + for (i = 0; i < N_RX_DESC_RINGS; i++) 3995 + cas_free_rx_desc(cp, i); 3996 + } 3997 + 3998 + /* Must be invoked under cp->lock. */ 3999 + static void cas_clean_rings(struct cas *cp) 4000 + { 4001 + int i; 4002 + 4003 + /* need to clean all tx rings */ 4004 + memset(cp->tx_old, 0, sizeof(*cp->tx_old)*N_TX_RINGS); 4005 + memset(cp->tx_new, 0, sizeof(*cp->tx_new)*N_TX_RINGS); 4006 + for (i = 0; i < N_TX_RINGS; i++) 4007 + cas_clean_txd(cp, i); 4008 + 4009 + /* zero out init block */ 4010 + memset(cp->init_block, 0, sizeof(struct cas_init_block)); 4011 + cas_clean_rxds(cp); 4012 + cas_clean_rxcs(cp); 4013 + } 4014 + 4015 + /* allocated on open */ 4016 + static inline int cas_alloc_rx_desc(struct cas *cp, int ring) 4017 + { 4018 + cas_page_t **page = cp->rx_pages[ring]; 4019 + int size, i = 0; 4020 + 4021 + size = RX_DESC_RINGN_SIZE(ring); 4022 + for (i = 0; i < size; i++) { 4023 + if ((page[i] = cas_page_alloc(cp, GFP_KERNEL)) == NULL) 4024 + return -1; 4025 + } 4026 + return 0; 4027 + } 4028 + 4029 + static int cas_alloc_rxds(struct cas *cp) 4030 + { 4031 + int i; 4032 + 4033 + for (i = 0; i < N_RX_DESC_RINGS; i++) { 4034 + if (cas_alloc_rx_desc(cp, i) < 0) { 4035 + cas_free_rxds(cp); 4036 + return -1; 4037 + } 4038 + } 4039 + return 0; 4040 + } 4041 + 4042 + static void cas_reset_task(void *data) 4043 + { 4044 + struct cas *cp = (struct cas *) data; 4045 + #if 0 4046 + int pending = atomic_read(&cp->reset_task_pending); 4047 + #else 4048 + int pending_all = atomic_read(&cp->reset_task_pending_all); 4049 + int pending_spare = atomic_read(&cp->reset_task_pending_spare); 4050 + int pending_mtu = atomic_read(&cp->reset_task_pending_mtu); 4051 + 4052 + if (pending_all == 0 && pending_spare == 0 && pending_mtu == 0) { 4053 + /* We can have more tasks scheduled than actually 4054 + * needed. 4055 + */ 4056 + atomic_dec(&cp->reset_task_pending); 4057 + return; 4058 + } 4059 + #endif 4060 + /* The link went down, we reset the ring, but keep 4061 + * DMA stopped. Use this function for reset 4062 + * on error as well. 4063 + */ 4064 + if (cp->hw_running) { 4065 + unsigned long flags; 4066 + 4067 + /* Make sure we don't get interrupts or tx packets */ 4068 + netif_device_detach(cp->dev); 4069 + cas_lock_all_save(cp, flags); 4070 + 4071 + if (cp->opened) { 4072 + /* We call cas_spare_recover when we call cas_open. 4073 + * but we do not initialize the lists cas_spare_recover 4074 + * uses until cas_open is called. 4075 + */ 4076 + cas_spare_recover(cp, GFP_ATOMIC); 4077 + } 4078 + #if 1 4079 + /* test => only pending_spare set */ 4080 + if (!pending_all && !pending_mtu) 4081 + goto done; 4082 + #else 4083 + if (pending == CAS_RESET_SPARE) 4084 + goto done; 4085 + #endif 4086 + /* when pending == CAS_RESET_ALL, the following 4087 + * call to cas_init_hw will restart auto negotiation. 4088 + * Setting the second argument of cas_reset to 4089 + * !(pending == CAS_RESET_ALL) will set this argument 4090 + * to 1 (avoiding reinitializing the PHY for the normal 4091 + * PCS case) when auto negotiation is not restarted. 4092 + */ 4093 + #if 1 4094 + cas_reset(cp, !(pending_all > 0)); 4095 + if (cp->opened) 4096 + cas_clean_rings(cp); 4097 + cas_init_hw(cp, (pending_all > 0)); 4098 + #else 4099 + cas_reset(cp, !(pending == CAS_RESET_ALL)); 4100 + if (cp->opened) 4101 + cas_clean_rings(cp); 4102 + cas_init_hw(cp, pending == CAS_RESET_ALL); 4103 + #endif 4104 + 4105 + done: 4106 + cas_unlock_all_restore(cp, flags); 4107 + netif_device_attach(cp->dev); 4108 + } 4109 + #if 1 4110 + atomic_sub(pending_all, &cp->reset_task_pending_all); 4111 + atomic_sub(pending_spare, &cp->reset_task_pending_spare); 4112 + atomic_sub(pending_mtu, &cp->reset_task_pending_mtu); 4113 + atomic_dec(&cp->reset_task_pending); 4114 + #else 4115 + atomic_set(&cp->reset_task_pending, 0); 4116 + #endif 4117 + } 4118 + 4119 + static void cas_link_timer(unsigned long data) 4120 + { 4121 + struct cas *cp = (struct cas *) data; 4122 + int mask, pending = 0, reset = 0; 4123 + unsigned long flags; 4124 + 4125 + if (link_transition_timeout != 0 && 4126 + cp->link_transition_jiffies_valid && 4127 + ((jiffies - cp->link_transition_jiffies) > 4128 + (link_transition_timeout))) { 4129 + /* One-second counter so link-down workaround doesn't 4130 + * cause resets to occur so fast as to fool the switch 4131 + * into thinking the link is down. 4132 + */ 4133 + cp->link_transition_jiffies_valid = 0; 4134 + } 4135 + 4136 + if (!cp->hw_running) 4137 + return; 4138 + 4139 + spin_lock_irqsave(&cp->lock, flags); 4140 + cas_lock_tx(cp); 4141 + cas_entropy_gather(cp); 4142 + 4143 + /* If the link task is still pending, we just 4144 + * reschedule the link timer 4145 + */ 4146 + #if 1 4147 + if (atomic_read(&cp->reset_task_pending_all) || 4148 + atomic_read(&cp->reset_task_pending_spare) || 4149 + atomic_read(&cp->reset_task_pending_mtu)) 4150 + goto done; 4151 + #else 4152 + if (atomic_read(&cp->reset_task_pending)) 4153 + goto done; 4154 + #endif 4155 + 4156 + /* check for rx cleaning */ 4157 + if ((mask = (cp->cas_flags & CAS_FLAG_RXD_POST_MASK))) { 4158 + int i, rmask; 4159 + 4160 + for (i = 0; i < MAX_RX_DESC_RINGS; i++) { 4161 + rmask = CAS_FLAG_RXD_POST(i); 4162 + if ((mask & rmask) == 0) 4163 + continue; 4164 + 4165 + /* post_rxds will do a mod_timer */ 4166 + if (cas_post_rxds_ringN(cp, i, cp->rx_last[i]) < 0) { 4167 + pending = 1; 4168 + continue; 4169 + } 4170 + cp->cas_flags &= ~rmask; 4171 + } 4172 + } 4173 + 4174 + if (CAS_PHY_MII(cp->phy_type)) { 4175 + u16 bmsr; 4176 + cas_mif_poll(cp, 0); 4177 + bmsr = cas_phy_read(cp, MII_BMSR); 4178 + /* WTZ: Solaris driver reads this twice, but that 4179 + * may be due to the PCS case and the use of a 4180 + * common implementation. Read it twice here to be 4181 + * safe. 4182 + */ 4183 + bmsr = cas_phy_read(cp, MII_BMSR); 4184 + cas_mif_poll(cp, 1); 4185 + readl(cp->regs + REG_MIF_STATUS); /* avoid dups */ 4186 + reset = cas_mii_link_check(cp, bmsr); 4187 + } else { 4188 + reset = cas_pcs_link_check(cp); 4189 + } 4190 + 4191 + if (reset) 4192 + goto done; 4193 + 4194 + /* check for tx state machine confusion */ 4195 + if ((readl(cp->regs + REG_MAC_TX_STATUS) & MAC_TX_FRAME_XMIT) == 0) { 4196 + u32 val = readl(cp->regs + REG_MAC_STATE_MACHINE); 4197 + u32 wptr, rptr; 4198 + int tlm = CAS_VAL(MAC_SM_TLM, val); 4199 + 4200 + if (((tlm == 0x5) || (tlm == 0x3)) && 4201 + (CAS_VAL(MAC_SM_ENCAP_SM, val) == 0)) { 4202 + if (netif_msg_tx_err(cp)) 4203 + printk(KERN_DEBUG "%s: tx err: " 4204 + "MAC_STATE[%08x]\n", 4205 + cp->dev->name, val); 4206 + reset = 1; 4207 + goto done; 4208 + } 4209 + 4210 + val = readl(cp->regs + REG_TX_FIFO_PKT_CNT); 4211 + wptr = readl(cp->regs + REG_TX_FIFO_WRITE_PTR); 4212 + rptr = readl(cp->regs + REG_TX_FIFO_READ_PTR); 4213 + if ((val == 0) && (wptr != rptr)) { 4214 + if (netif_msg_tx_err(cp)) 4215 + printk(KERN_DEBUG "%s: tx err: " 4216 + "TX_FIFO[%08x:%08x:%08x]\n", 4217 + cp->dev->name, val, wptr, rptr); 4218 + reset = 1; 4219 + } 4220 + 4221 + if (reset) 4222 + cas_hard_reset(cp); 4223 + } 4224 + 4225 + done: 4226 + if (reset) { 4227 + #if 1 4228 + atomic_inc(&cp->reset_task_pending); 4229 + atomic_inc(&cp->reset_task_pending_all); 4230 + schedule_work(&cp->reset_task); 4231 + #else 4232 + atomic_set(&cp->reset_task_pending, CAS_RESET_ALL); 4233 + printk(KERN_ERR "reset called in cas_link_timer\n"); 4234 + schedule_work(&cp->reset_task); 4235 + #endif 4236 + } 4237 + 4238 + if (!pending) 4239 + mod_timer(&cp->link_timer, jiffies + CAS_LINK_TIMEOUT); 4240 + cas_unlock_tx(cp); 4241 + spin_unlock_irqrestore(&cp->lock, flags); 4242 + } 4243 + 4244 + /* tiny buffers are used to avoid target abort issues with 4245 + * older cassini's 4246 + */ 4247 + static void cas_tx_tiny_free(struct cas *cp) 4248 + { 4249 + struct pci_dev *pdev = cp->pdev; 4250 + int i; 4251 + 4252 + for (i = 0; i < N_TX_RINGS; i++) { 4253 + if (!cp->tx_tiny_bufs[i]) 4254 + continue; 4255 + 4256 + pci_free_consistent(pdev, TX_TINY_BUF_BLOCK, 4257 + cp->tx_tiny_bufs[i], 4258 + cp->tx_tiny_dvma[i]); 4259 + cp->tx_tiny_bufs[i] = NULL; 4260 + } 4261 + } 4262 + 4263 + static int cas_tx_tiny_alloc(struct cas *cp) 4264 + { 4265 + struct pci_dev *pdev = cp->pdev; 4266 + int i; 4267 + 4268 + for (i = 0; i < N_TX_RINGS; i++) { 4269 + cp->tx_tiny_bufs[i] = 4270 + pci_alloc_consistent(pdev, TX_TINY_BUF_BLOCK, 4271 + &cp->tx_tiny_dvma[i]); 4272 + if (!cp->tx_tiny_bufs[i]) { 4273 + cas_tx_tiny_free(cp); 4274 + return -1; 4275 + } 4276 + } 4277 + return 0; 4278 + } 4279 + 4280 + 4281 + static int cas_open(struct net_device *dev) 4282 + { 4283 + struct cas *cp = netdev_priv(dev); 4284 + int hw_was_up, err; 4285 + unsigned long flags; 4286 + 4287 + down(&cp->pm_sem); 4288 + 4289 + hw_was_up = cp->hw_running; 4290 + 4291 + /* The power-management semaphore protects the hw_running 4292 + * etc. state so it is safe to do this bit without cp->lock 4293 + */ 4294 + if (!cp->hw_running) { 4295 + /* Reset the chip */ 4296 + cas_lock_all_save(cp, flags); 4297 + /* We set the second arg to cas_reset to zero 4298 + * because cas_init_hw below will have its second 4299 + * argument set to non-zero, which will force 4300 + * autonegotiation to start. 4301 + */ 4302 + cas_reset(cp, 0); 4303 + cp->hw_running = 1; 4304 + cas_unlock_all_restore(cp, flags); 4305 + } 4306 + 4307 + if (cas_tx_tiny_alloc(cp) < 0) 4308 + return -ENOMEM; 4309 + 4310 + /* alloc rx descriptors */ 4311 + err = -ENOMEM; 4312 + if (cas_alloc_rxds(cp) < 0) 4313 + goto err_tx_tiny; 4314 + 4315 + /* allocate spares */ 4316 + cas_spare_init(cp); 4317 + cas_spare_recover(cp, GFP_KERNEL); 4318 + 4319 + /* We can now request the interrupt as we know it's masked 4320 + * on the controller. cassini+ has up to 4 interrupts 4321 + * that can be used, but you need to do explicit pci interrupt 4322 + * mapping to expose them 4323 + */ 4324 + if (request_irq(cp->pdev->irq, cas_interrupt, 4325 + SA_SHIRQ, dev->name, (void *) dev)) { 4326 + printk(KERN_ERR "%s: failed to request irq !\n", 4327 + cp->dev->name); 4328 + err = -EAGAIN; 4329 + goto err_spare; 4330 + } 4331 + 4332 + /* init hw */ 4333 + cas_lock_all_save(cp, flags); 4334 + cas_clean_rings(cp); 4335 + cas_init_hw(cp, !hw_was_up); 4336 + cp->opened = 1; 4337 + cas_unlock_all_restore(cp, flags); 4338 + 4339 + netif_start_queue(dev); 4340 + up(&cp->pm_sem); 4341 + return 0; 4342 + 4343 + err_spare: 4344 + cas_spare_free(cp); 4345 + cas_free_rxds(cp); 4346 + err_tx_tiny: 4347 + cas_tx_tiny_free(cp); 4348 + up(&cp->pm_sem); 4349 + return err; 4350 + } 4351 + 4352 + static int cas_close(struct net_device *dev) 4353 + { 4354 + unsigned long flags; 4355 + struct cas *cp = netdev_priv(dev); 4356 + 4357 + /* Make sure we don't get distracted by suspend/resume */ 4358 + down(&cp->pm_sem); 4359 + 4360 + netif_stop_queue(dev); 4361 + 4362 + /* Stop traffic, mark us closed */ 4363 + cas_lock_all_save(cp, flags); 4364 + cp->opened = 0; 4365 + cas_reset(cp, 0); 4366 + cas_phy_init(cp); 4367 + cas_begin_auto_negotiation(cp, NULL); 4368 + cas_clean_rings(cp); 4369 + cas_unlock_all_restore(cp, flags); 4370 + 4371 + free_irq(cp->pdev->irq, (void *) dev); 4372 + cas_spare_free(cp); 4373 + cas_free_rxds(cp); 4374 + cas_tx_tiny_free(cp); 4375 + up(&cp->pm_sem); 4376 + return 0; 4377 + } 4378 + 4379 + static struct { 4380 + const char name[ETH_GSTRING_LEN]; 4381 + } ethtool_cassini_statnames[] = { 4382 + {"collisions"}, 4383 + {"rx_bytes"}, 4384 + {"rx_crc_errors"}, 4385 + {"rx_dropped"}, 4386 + {"rx_errors"}, 4387 + {"rx_fifo_errors"}, 4388 + {"rx_frame_errors"}, 4389 + {"rx_length_errors"}, 4390 + {"rx_over_errors"}, 4391 + {"rx_packets"}, 4392 + {"tx_aborted_errors"}, 4393 + {"tx_bytes"}, 4394 + {"tx_dropped"}, 4395 + {"tx_errors"}, 4396 + {"tx_fifo_errors"}, 4397 + {"tx_packets"} 4398 + }; 4399 + #define CAS_NUM_STAT_KEYS (sizeof(ethtool_cassini_statnames)/ETH_GSTRING_LEN) 4400 + 4401 + static struct { 4402 + const int offsets; /* neg. values for 2nd arg to cas_read_phy */ 4403 + } ethtool_register_table[] = { 4404 + {-MII_BMSR}, 4405 + {-MII_BMCR}, 4406 + {REG_CAWR}, 4407 + {REG_INF_BURST}, 4408 + {REG_BIM_CFG}, 4409 + {REG_RX_CFG}, 4410 + {REG_HP_CFG}, 4411 + {REG_MAC_TX_CFG}, 4412 + {REG_MAC_RX_CFG}, 4413 + {REG_MAC_CTRL_CFG}, 4414 + {REG_MAC_XIF_CFG}, 4415 + {REG_MIF_CFG}, 4416 + {REG_PCS_CFG}, 4417 + {REG_SATURN_PCFG}, 4418 + {REG_PCS_MII_STATUS}, 4419 + {REG_PCS_STATE_MACHINE}, 4420 + {REG_MAC_COLL_EXCESS}, 4421 + {REG_MAC_COLL_LATE} 4422 + }; 4423 + #define CAS_REG_LEN (sizeof(ethtool_register_table)/sizeof(int)) 4424 + #define CAS_MAX_REGS (sizeof (u32)*CAS_REG_LEN) 4425 + 4426 + static u8 *cas_get_regs(struct cas *cp) 4427 + { 4428 + u8 *ptr = kmalloc(CAS_MAX_REGS, GFP_KERNEL); 4429 + u8 *p; 4430 + int i; 4431 + unsigned long flags; 4432 + 4433 + if (!ptr) 4434 + return NULL; 4435 + 4436 + spin_lock_irqsave(&cp->lock, flags); 4437 + for (i = 0, p = ptr; i < CAS_REG_LEN ; i ++, p += sizeof(u32)) { 4438 + u16 hval; 4439 + u32 val; 4440 + if (ethtool_register_table[i].offsets < 0) { 4441 + hval = cas_phy_read(cp, 4442 + -ethtool_register_table[i].offsets); 4443 + val = hval; 4444 + } else { 4445 + val= readl(cp->regs+ethtool_register_table[i].offsets); 4446 + } 4447 + memcpy(p, (u8 *)&val, sizeof(u32)); 4448 + } 4449 + spin_unlock_irqrestore(&cp->lock, flags); 4450 + 4451 + return ptr; 4452 + } 4453 + 4454 + static struct net_device_stats *cas_get_stats(struct net_device *dev) 4455 + { 4456 + struct cas *cp = netdev_priv(dev); 4457 + struct net_device_stats *stats = cp->net_stats; 4458 + unsigned long flags; 4459 + int i; 4460 + unsigned long tmp; 4461 + 4462 + /* we collate all of the stats into net_stats[N_TX_RING] */ 4463 + if (!cp->hw_running) 4464 + return stats + N_TX_RINGS; 4465 + 4466 + /* collect outstanding stats */ 4467 + /* WTZ: the Cassini spec gives these as 16 bit counters but 4468 + * stored in 32-bit words. Added a mask of 0xffff to be safe, 4469 + * in case the chip somehow puts any garbage in the other bits. 4470 + * Also, counter usage didn't seem to mach what Adrian did 4471 + * in the parts of the code that set these quantities. Made 4472 + * that consistent. 4473 + */ 4474 + spin_lock_irqsave(&cp->stat_lock[N_TX_RINGS], flags); 4475 + stats[N_TX_RINGS].rx_crc_errors += 4476 + readl(cp->regs + REG_MAC_FCS_ERR) & 0xffff; 4477 + stats[N_TX_RINGS].rx_frame_errors += 4478 + readl(cp->regs + REG_MAC_ALIGN_ERR) &0xffff; 4479 + stats[N_TX_RINGS].rx_length_errors += 4480 + readl(cp->regs + REG_MAC_LEN_ERR) & 0xffff; 4481 + #if 1 4482 + tmp = (readl(cp->regs + REG_MAC_COLL_EXCESS) & 0xffff) + 4483 + (readl(cp->regs + REG_MAC_COLL_LATE) & 0xffff); 4484 + stats[N_TX_RINGS].tx_aborted_errors += tmp; 4485 + stats[N_TX_RINGS].collisions += 4486 + tmp + (readl(cp->regs + REG_MAC_COLL_NORMAL) & 0xffff); 4487 + #else 4488 + stats[N_TX_RINGS].tx_aborted_errors += 4489 + readl(cp->regs + REG_MAC_COLL_EXCESS); 4490 + stats[N_TX_RINGS].collisions += readl(cp->regs + REG_MAC_COLL_EXCESS) + 4491 + readl(cp->regs + REG_MAC_COLL_LATE); 4492 + #endif 4493 + cas_clear_mac_err(cp); 4494 + 4495 + /* saved bits that are unique to ring 0 */ 4496 + spin_lock(&cp->stat_lock[0]); 4497 + stats[N_TX_RINGS].collisions += stats[0].collisions; 4498 + stats[N_TX_RINGS].rx_over_errors += stats[0].rx_over_errors; 4499 + stats[N_TX_RINGS].rx_frame_errors += stats[0].rx_frame_errors; 4500 + stats[N_TX_RINGS].rx_fifo_errors += stats[0].rx_fifo_errors; 4501 + stats[N_TX_RINGS].tx_aborted_errors += stats[0].tx_aborted_errors; 4502 + stats[N_TX_RINGS].tx_fifo_errors += stats[0].tx_fifo_errors; 4503 + spin_unlock(&cp->stat_lock[0]); 4504 + 4505 + for (i = 0; i < N_TX_RINGS; i++) { 4506 + spin_lock(&cp->stat_lock[i]); 4507 + stats[N_TX_RINGS].rx_length_errors += 4508 + stats[i].rx_length_errors; 4509 + stats[N_TX_RINGS].rx_crc_errors += stats[i].rx_crc_errors; 4510 + stats[N_TX_RINGS].rx_packets += stats[i].rx_packets; 4511 + stats[N_TX_RINGS].tx_packets += stats[i].tx_packets; 4512 + stats[N_TX_RINGS].rx_bytes += stats[i].rx_bytes; 4513 + stats[N_TX_RINGS].tx_bytes += stats[i].tx_bytes; 4514 + stats[N_TX_RINGS].rx_errors += stats[i].rx_errors; 4515 + stats[N_TX_RINGS].tx_errors += stats[i].tx_errors; 4516 + stats[N_TX_RINGS].rx_dropped += stats[i].rx_dropped; 4517 + stats[N_TX_RINGS].tx_dropped += stats[i].tx_dropped; 4518 + memset(stats + i, 0, sizeof(struct net_device_stats)); 4519 + spin_unlock(&cp->stat_lock[i]); 4520 + } 4521 + spin_unlock_irqrestore(&cp->stat_lock[N_TX_RINGS], flags); 4522 + return stats + N_TX_RINGS; 4523 + } 4524 + 4525 + 4526 + static void cas_set_multicast(struct net_device *dev) 4527 + { 4528 + struct cas *cp = netdev_priv(dev); 4529 + u32 rxcfg, rxcfg_new; 4530 + unsigned long flags; 4531 + int limit = STOP_TRIES; 4532 + 4533 + if (!cp->hw_running) 4534 + return; 4535 + 4536 + spin_lock_irqsave(&cp->lock, flags); 4537 + rxcfg = readl(cp->regs + REG_MAC_RX_CFG); 4538 + 4539 + /* disable RX MAC and wait for completion */ 4540 + writel(rxcfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG); 4541 + while (readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_EN) { 4542 + if (!limit--) 4543 + break; 4544 + udelay(10); 4545 + } 4546 + 4547 + /* disable hash filter and wait for completion */ 4548 + limit = STOP_TRIES; 4549 + rxcfg &= ~(MAC_RX_CFG_PROMISC_EN | MAC_RX_CFG_HASH_FILTER_EN); 4550 + writel(rxcfg & ~MAC_RX_CFG_EN, cp->regs + REG_MAC_RX_CFG); 4551 + while (readl(cp->regs + REG_MAC_RX_CFG) & MAC_RX_CFG_HASH_FILTER_EN) { 4552 + if (!limit--) 4553 + break; 4554 + udelay(10); 4555 + } 4556 + 4557 + /* program hash filters */ 4558 + cp->mac_rx_cfg = rxcfg_new = cas_setup_multicast(cp); 4559 + rxcfg |= rxcfg_new; 4560 + writel(rxcfg, cp->regs + REG_MAC_RX_CFG); 4561 + spin_unlock_irqrestore(&cp->lock, flags); 4562 + } 4563 + 4564 + /* Eventually add support for changing the advertisement 4565 + * on autoneg. 4566 + */ 4567 + static int cas_ethtool_ioctl(struct net_device *dev, void *ep_user) 4568 + { 4569 + struct cas *cp = netdev_priv(dev); 4570 + u16 bmcr; 4571 + int full_duplex, speed, pause; 4572 + struct ethtool_cmd ecmd; 4573 + unsigned long flags; 4574 + enum link_state linkstate = link_up; 4575 + 4576 + if (copy_from_user(&ecmd, ep_user, sizeof(ecmd))) 4577 + return -EFAULT; 4578 + 4579 + switch(ecmd.cmd) { 4580 + case ETHTOOL_GDRVINFO: { 4581 + struct ethtool_drvinfo info = { cmd: ETHTOOL_GDRVINFO }; 4582 + 4583 + strncpy(info.driver, DRV_MODULE_NAME, 4584 + ETHTOOL_BUSINFO_LEN); 4585 + strncpy(info.version, DRV_MODULE_VERSION, 4586 + ETHTOOL_BUSINFO_LEN); 4587 + info.fw_version[0] = '\0'; 4588 + strncpy(info.bus_info, pci_name(cp->pdev), 4589 + ETHTOOL_BUSINFO_LEN); 4590 + info.regdump_len = cp->casreg_len < CAS_MAX_REGS ? 4591 + cp->casreg_len : CAS_MAX_REGS; 4592 + info.n_stats = CAS_NUM_STAT_KEYS; 4593 + if (copy_to_user(ep_user, &info, sizeof(info))) 4594 + return -EFAULT; 4595 + 4596 + return 0; 4597 + } 4598 + 4599 + case ETHTOOL_GSET: 4600 + ecmd.advertising = 0; 4601 + ecmd.supported = SUPPORTED_Autoneg; 4602 + if (cp->cas_flags & CAS_FLAG_1000MB_CAP) { 4603 + ecmd.supported |= SUPPORTED_1000baseT_Full; 4604 + ecmd.advertising |= ADVERTISED_1000baseT_Full; 4605 + } 4606 + 4607 + /* Record PHY settings if HW is on. */ 4608 + spin_lock_irqsave(&cp->lock, flags); 4609 + bmcr = 0; 4610 + linkstate = cp->lstate; 4611 + if (CAS_PHY_MII(cp->phy_type)) { 4612 + ecmd.port = PORT_MII; 4613 + ecmd.transceiver = (cp->cas_flags & CAS_FLAG_SATURN) ? 4614 + XCVR_INTERNAL : XCVR_EXTERNAL; 4615 + ecmd.phy_address = cp->phy_addr; 4616 + ecmd.advertising |= ADVERTISED_TP | ADVERTISED_MII | 4617 + ADVERTISED_10baseT_Half | 4618 + ADVERTISED_10baseT_Full | 4619 + ADVERTISED_100baseT_Half | 4620 + ADVERTISED_100baseT_Full; 4621 + 4622 + ecmd.supported |= 4623 + (SUPPORTED_10baseT_Half | 4624 + SUPPORTED_10baseT_Full | 4625 + SUPPORTED_100baseT_Half | 4626 + SUPPORTED_100baseT_Full | 4627 + SUPPORTED_TP | SUPPORTED_MII); 4628 + 4629 + if (cp->hw_running) { 4630 + cas_mif_poll(cp, 0); 4631 + bmcr = cas_phy_read(cp, MII_BMCR); 4632 + cas_read_mii_link_mode(cp, &full_duplex, 4633 + &speed, &pause); 4634 + cas_mif_poll(cp, 1); 4635 + } 4636 + 4637 + } else { 4638 + ecmd.port = PORT_FIBRE; 4639 + ecmd.transceiver = XCVR_INTERNAL; 4640 + ecmd.phy_address = 0; 4641 + ecmd.supported |= SUPPORTED_FIBRE; 4642 + ecmd.advertising |= ADVERTISED_FIBRE; 4643 + 4644 + if (cp->hw_running) { 4645 + /* pcs uses the same bits as mii */ 4646 + bmcr = readl(cp->regs + REG_PCS_MII_CTRL); 4647 + cas_read_pcs_link_mode(cp, &full_duplex, 4648 + &speed, &pause); 4649 + } 4650 + } 4651 + spin_unlock_irqrestore(&cp->lock, flags); 4652 + 4653 + if (bmcr & BMCR_ANENABLE) { 4654 + ecmd.advertising |= ADVERTISED_Autoneg; 4655 + ecmd.autoneg = AUTONEG_ENABLE; 4656 + ecmd.speed = ((speed == 10) ? 4657 + SPEED_10 : 4658 + ((speed == 1000) ? 4659 + SPEED_1000 : SPEED_100)); 4660 + ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 4661 + } else { 4662 + ecmd.autoneg = AUTONEG_DISABLE; 4663 + ecmd.speed = 4664 + (bmcr & CAS_BMCR_SPEED1000) ? 4665 + SPEED_1000 : 4666 + ((bmcr & BMCR_SPEED100) ? SPEED_100: 4667 + SPEED_10); 4668 + ecmd.duplex = 4669 + (bmcr & BMCR_FULLDPLX) ? 4670 + DUPLEX_FULL : DUPLEX_HALF; 4671 + } 4672 + if (linkstate != link_up) { 4673 + /* Force these to "unknown" if the link is not up and 4674 + * autonogotiation in enabled. We can set the link 4675 + * speed to 0, but not ecmd.duplex, 4676 + * because its legal values are 0 and 1. Ethtool will 4677 + * print the value reported in parentheses after the 4678 + * word "Unknown" for unrecognized values. 4679 + * 4680 + * If in forced mode, we report the speed and duplex 4681 + * settings that we configured. 4682 + */ 4683 + if (cp->link_cntl & BMCR_ANENABLE) { 4684 + ecmd.speed = 0; 4685 + ecmd.duplex = 0xff; 4686 + } else { 4687 + ecmd.speed = SPEED_10; 4688 + if (cp->link_cntl & BMCR_SPEED100) { 4689 + ecmd.speed = SPEED_100; 4690 + } else if (cp->link_cntl & CAS_BMCR_SPEED1000) { 4691 + ecmd.speed = SPEED_1000; 4692 + } 4693 + ecmd.duplex = (cp->link_cntl & BMCR_FULLDPLX)? 4694 + DUPLEX_FULL : DUPLEX_HALF; 4695 + } 4696 + } 4697 + if (copy_to_user(ep_user, &ecmd, sizeof(ecmd))) 4698 + return -EFAULT; 4699 + return 0; 4700 + 4701 + case ETHTOOL_SSET: 4702 + if (!capable(CAP_NET_ADMIN)) 4703 + return -EPERM; 4704 + 4705 + /* Verify the settings we care about. */ 4706 + if (ecmd.autoneg != AUTONEG_ENABLE && 4707 + ecmd.autoneg != AUTONEG_DISABLE) 4708 + return -EINVAL; 4709 + 4710 + if (ecmd.autoneg == AUTONEG_DISABLE && 4711 + ((ecmd.speed != SPEED_1000 && 4712 + ecmd.speed != SPEED_100 && 4713 + ecmd.speed != SPEED_10) || 4714 + (ecmd.duplex != DUPLEX_HALF && 4715 + ecmd.duplex != DUPLEX_FULL))) 4716 + return -EINVAL; 4717 + 4718 + /* Apply settings and restart link process. */ 4719 + spin_lock_irqsave(&cp->lock, flags); 4720 + cas_begin_auto_negotiation(cp, &ecmd); 4721 + spin_unlock_irqrestore(&cp->lock, flags); 4722 + return 0; 4723 + 4724 + case ETHTOOL_NWAY_RST: 4725 + if ((cp->link_cntl & BMCR_ANENABLE) == 0) 4726 + return -EINVAL; 4727 + 4728 + /* Restart link process. */ 4729 + spin_lock_irqsave(&cp->lock, flags); 4730 + cas_begin_auto_negotiation(cp, NULL); 4731 + spin_unlock_irqrestore(&cp->lock, flags); 4732 + 4733 + return 0; 4734 + 4735 + case ETHTOOL_GWOL: 4736 + case ETHTOOL_SWOL: 4737 + break; /* doesn't exist */ 4738 + 4739 + /* get link status */ 4740 + case ETHTOOL_GLINK: { 4741 + struct ethtool_value edata = { cmd: ETHTOOL_GLINK }; 4742 + 4743 + edata.data = (cp->lstate == link_up); 4744 + if (copy_to_user(ep_user, &edata, sizeof(edata))) 4745 + return -EFAULT; 4746 + return 0; 4747 + } 4748 + 4749 + /* get message-level */ 4750 + case ETHTOOL_GMSGLVL: { 4751 + struct ethtool_value edata = { cmd: ETHTOOL_GMSGLVL }; 4752 + 4753 + edata.data = cp->msg_enable; 4754 + if (copy_to_user(ep_user, &edata, sizeof(edata))) 4755 + return -EFAULT; 4756 + return 0; 4757 + } 4758 + 4759 + /* set message-level */ 4760 + case ETHTOOL_SMSGLVL: { 4761 + struct ethtool_value edata; 4762 + 4763 + if (!capable(CAP_NET_ADMIN)) { 4764 + return (-EPERM); 4765 + } 4766 + if (copy_from_user(&edata, ep_user, sizeof(edata))) 4767 + return -EFAULT; 4768 + cp->msg_enable = edata.data; 4769 + return 0; 4770 + } 4771 + 4772 + case ETHTOOL_GREGS: { 4773 + struct ethtool_regs edata; 4774 + u8 *ptr; 4775 + int len = cp->casreg_len < CAS_MAX_REGS ? 4776 + cp->casreg_len: CAS_MAX_REGS; 4777 + 4778 + if (copy_from_user(&edata, ep_user, sizeof (edata))) 4779 + return -EFAULT; 4780 + 4781 + if (edata.len > len) 4782 + edata.len = len; 4783 + edata.version = 0; 4784 + if (copy_to_user (ep_user, &edata, sizeof(edata))) 4785 + return -EFAULT; 4786 + 4787 + /* cas_get_regs handles locks (cp->lock). */ 4788 + ptr = cas_get_regs(cp); 4789 + if (ptr == NULL) 4790 + return -ENOMEM; 4791 + if (copy_to_user(ep_user + sizeof (edata), ptr, edata.len)) 4792 + return -EFAULT; 4793 + 4794 + kfree(ptr); 4795 + return (0); 4796 + } 4797 + case ETHTOOL_GSTRINGS: { 4798 + struct ethtool_gstrings edata; 4799 + int len; 4800 + 4801 + if (copy_from_user(&edata, ep_user, sizeof(edata))) 4802 + return -EFAULT; 4803 + 4804 + len = edata.len; 4805 + switch(edata.string_set) { 4806 + case ETH_SS_STATS: 4807 + edata.len = (len < CAS_NUM_STAT_KEYS) ? 4808 + len : CAS_NUM_STAT_KEYS; 4809 + if (copy_to_user(ep_user, &edata, sizeof(edata))) 4810 + return -EFAULT; 4811 + 4812 + if (copy_to_user(ep_user + sizeof(edata), 4813 + &ethtool_cassini_statnames, 4814 + (edata.len * ETH_GSTRING_LEN))) 4815 + return -EFAULT; 4816 + return 0; 4817 + default: 4818 + return -EINVAL; 4819 + } 4820 + } 4821 + case ETHTOOL_GSTATS: { 4822 + int i = 0; 4823 + u64 *tmp; 4824 + struct ethtool_stats edata; 4825 + struct net_device_stats *stats; 4826 + int len; 4827 + 4828 + if (copy_from_user(&edata, ep_user, sizeof(edata))) 4829 + return -EFAULT; 4830 + 4831 + len = edata.n_stats; 4832 + stats = cas_get_stats(cp->dev); 4833 + edata.cmd = ETHTOOL_GSTATS; 4834 + edata.n_stats = (len < CAS_NUM_STAT_KEYS) ? 4835 + len : CAS_NUM_STAT_KEYS; 4836 + if (copy_to_user(ep_user, &edata, sizeof (edata))) 4837 + return -EFAULT; 4838 + 4839 + tmp = kmalloc(sizeof(u64)*CAS_NUM_STAT_KEYS, GFP_KERNEL); 4840 + if (tmp) { 4841 + tmp[i++] = stats->collisions; 4842 + tmp[i++] = stats->rx_bytes; 4843 + tmp[i++] = stats->rx_crc_errors; 4844 + tmp[i++] = stats->rx_dropped; 4845 + tmp[i++] = stats->rx_errors; 4846 + tmp[i++] = stats->rx_fifo_errors; 4847 + tmp[i++] = stats->rx_frame_errors; 4848 + tmp[i++] = stats->rx_length_errors; 4849 + tmp[i++] = stats->rx_over_errors; 4850 + tmp[i++] = stats->rx_packets; 4851 + tmp[i++] = stats->tx_aborted_errors; 4852 + tmp[i++] = stats->tx_bytes; 4853 + tmp[i++] = stats->tx_dropped; 4854 + tmp[i++] = stats->tx_errors; 4855 + tmp[i++] = stats->tx_fifo_errors; 4856 + tmp[i++] = stats->tx_packets; 4857 + BUG_ON(i != CAS_NUM_STAT_KEYS); 4858 + 4859 + i = copy_to_user(ep_user + sizeof(edata), 4860 + tmp, sizeof(u64)*edata.n_stats); 4861 + kfree(tmp); 4862 + } else { 4863 + return -ENOMEM; 4864 + } 4865 + if (i) 4866 + return -EFAULT; 4867 + return 0; 4868 + } 4869 + } 4870 + 4871 + return -EOPNOTSUPP; 4872 + } 4873 + 4874 + static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 4875 + { 4876 + struct cas *cp = netdev_priv(dev); 4877 + struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; 4878 + unsigned long flags; 4879 + int rc = -EOPNOTSUPP; 4880 + 4881 + /* Hold the PM semaphore while doing ioctl's or we may collide 4882 + * with open/close and power management and oops. 4883 + */ 4884 + down(&cp->pm_sem); 4885 + switch (cmd) { 4886 + case SIOCETHTOOL: 4887 + rc = cas_ethtool_ioctl(dev, ifr->ifr_data); 4888 + break; 4889 + 4890 + case SIOCGMIIPHY: /* Get address of MII PHY in use. */ 4891 + data->phy_id = cp->phy_addr; 4892 + /* Fallthrough... */ 4893 + 4894 + case SIOCGMIIREG: /* Read MII PHY register. */ 4895 + spin_lock_irqsave(&cp->lock, flags); 4896 + cas_mif_poll(cp, 0); 4897 + data->val_out = cas_phy_read(cp, data->reg_num & 0x1f); 4898 + cas_mif_poll(cp, 1); 4899 + spin_unlock_irqrestore(&cp->lock, flags); 4900 + rc = 0; 4901 + break; 4902 + 4903 + case SIOCSMIIREG: /* Write MII PHY register. */ 4904 + if (!capable(CAP_NET_ADMIN)) { 4905 + rc = -EPERM; 4906 + break; 4907 + } 4908 + spin_lock_irqsave(&cp->lock, flags); 4909 + cas_mif_poll(cp, 0); 4910 + rc = cas_phy_write(cp, data->reg_num & 0x1f, data->val_in); 4911 + cas_mif_poll(cp, 1); 4912 + spin_unlock_irqrestore(&cp->lock, flags); 4913 + break; 4914 + default: 4915 + break; 4916 + }; 4917 + 4918 + up(&cp->pm_sem); 4919 + return rc; 4920 + } 4921 + 4922 + static int __devinit cas_init_one(struct pci_dev *pdev, 4923 + const struct pci_device_id *ent) 4924 + { 4925 + static int cas_version_printed = 0; 4926 + unsigned long casreg_base, casreg_len; 4927 + struct net_device *dev; 4928 + struct cas *cp; 4929 + int i, err, pci_using_dac; 4930 + u16 pci_cmd; 4931 + u8 orig_cacheline_size = 0, cas_cacheline_size = 0; 4932 + 4933 + if (cas_version_printed++ == 0) 4934 + printk(KERN_INFO "%s", version); 4935 + 4936 + err = pci_enable_device(pdev); 4937 + if (err) { 4938 + printk(KERN_ERR PFX "Cannot enable PCI device, " 4939 + "aborting.\n"); 4940 + return err; 4941 + } 4942 + 4943 + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 4944 + printk(KERN_ERR PFX "Cannot find proper PCI device " 4945 + "base address, aborting.\n"); 4946 + err = -ENODEV; 4947 + goto err_out_disable_pdev; 4948 + } 4949 + 4950 + dev = alloc_etherdev(sizeof(*cp)); 4951 + if (!dev) { 4952 + printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); 4953 + err = -ENOMEM; 4954 + goto err_out_disable_pdev; 4955 + } 4956 + SET_MODULE_OWNER(dev); 4957 + SET_NETDEV_DEV(dev, &pdev->dev); 4958 + 4959 + err = pci_request_regions(pdev, dev->name); 4960 + if (err) { 4961 + printk(KERN_ERR PFX "Cannot obtain PCI resources, " 4962 + "aborting.\n"); 4963 + goto err_out_free_netdev; 4964 + } 4965 + pci_set_master(pdev); 4966 + 4967 + /* we must always turn on parity response or else parity 4968 + * doesn't get generated properly. disable SERR/PERR as well. 4969 + * in addition, we want to turn MWI on. 4970 + */ 4971 + pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); 4972 + pci_cmd &= ~PCI_COMMAND_SERR; 4973 + pci_cmd |= PCI_COMMAND_PARITY; 4974 + pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); 4975 + pci_set_mwi(pdev); 4976 + /* 4977 + * On some architectures, the default cache line size set 4978 + * by pci_set_mwi reduces perforamnce. We have to increase 4979 + * it for this case. To start, we'll print some configuration 4980 + * data. 4981 + */ 4982 + #if 1 4983 + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, 4984 + &orig_cacheline_size); 4985 + if (orig_cacheline_size < CAS_PREF_CACHELINE_SIZE) { 4986 + cas_cacheline_size = 4987 + (CAS_PREF_CACHELINE_SIZE < SMP_CACHE_BYTES) ? 4988 + CAS_PREF_CACHELINE_SIZE : SMP_CACHE_BYTES; 4989 + if (pci_write_config_byte(pdev, 4990 + PCI_CACHE_LINE_SIZE, 4991 + cas_cacheline_size)) { 4992 + printk(KERN_ERR PFX "Could not set PCI cache " 4993 + "line size\n"); 4994 + goto err_write_cacheline; 4995 + } 4996 + } 4997 + #endif 4998 + 4999 + 5000 + /* Configure DMA attributes. */ 5001 + if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { 5002 + pci_using_dac = 1; 5003 + err = pci_set_consistent_dma_mask(pdev, 5004 + DMA_64BIT_MASK); 5005 + if (err < 0) { 5006 + printk(KERN_ERR PFX "Unable to obtain 64-bit DMA " 5007 + "for consistent allocations\n"); 5008 + goto err_out_free_res; 5009 + } 5010 + 5011 + } else { 5012 + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); 5013 + if (err) { 5014 + printk(KERN_ERR PFX "No usable DMA configuration, " 5015 + "aborting.\n"); 5016 + goto err_out_free_res; 5017 + } 5018 + pci_using_dac = 0; 5019 + } 5020 + 5021 + casreg_base = pci_resource_start(pdev, 0); 5022 + casreg_len = pci_resource_len(pdev, 0); 5023 + 5024 + cp = netdev_priv(dev); 5025 + cp->pdev = pdev; 5026 + #if 1 5027 + /* A value of 0 indicates we never explicitly set it */ 5028 + cp->orig_cacheline_size = cas_cacheline_size ? orig_cacheline_size: 0; 5029 + #endif 5030 + cp->dev = dev; 5031 + cp->msg_enable = (cassini_debug < 0) ? CAS_DEF_MSG_ENABLE : 5032 + cassini_debug; 5033 + 5034 + cp->link_transition = LINK_TRANSITION_UNKNOWN; 5035 + cp->link_transition_jiffies_valid = 0; 5036 + 5037 + spin_lock_init(&cp->lock); 5038 + spin_lock_init(&cp->rx_inuse_lock); 5039 + spin_lock_init(&cp->rx_spare_lock); 5040 + for (i = 0; i < N_TX_RINGS; i++) { 5041 + spin_lock_init(&cp->stat_lock[i]); 5042 + spin_lock_init(&cp->tx_lock[i]); 5043 + } 5044 + spin_lock_init(&cp->stat_lock[N_TX_RINGS]); 5045 + init_MUTEX(&cp->pm_sem); 5046 + 5047 + init_timer(&cp->link_timer); 5048 + cp->link_timer.function = cas_link_timer; 5049 + cp->link_timer.data = (unsigned long) cp; 5050 + 5051 + #if 1 5052 + /* Just in case the implementation of atomic operations 5053 + * change so that an explicit initialization is necessary. 5054 + */ 5055 + atomic_set(&cp->reset_task_pending, 0); 5056 + atomic_set(&cp->reset_task_pending_all, 0); 5057 + atomic_set(&cp->reset_task_pending_spare, 0); 5058 + atomic_set(&cp->reset_task_pending_mtu, 0); 5059 + #endif 5060 + INIT_WORK(&cp->reset_task, cas_reset_task, cp); 5061 + 5062 + /* Default link parameters */ 5063 + if (link_mode >= 0 && link_mode <= 6) 5064 + cp->link_cntl = link_modes[link_mode]; 5065 + else 5066 + cp->link_cntl = BMCR_ANENABLE; 5067 + cp->lstate = link_down; 5068 + cp->link_transition = LINK_TRANSITION_LINK_DOWN; 5069 + netif_carrier_off(cp->dev); 5070 + cp->timer_ticks = 0; 5071 + 5072 + /* give us access to cassini registers */ 5073 + cp->regs = ioremap(casreg_base, casreg_len); 5074 + if (cp->regs == 0UL) { 5075 + printk(KERN_ERR PFX "Cannot map device registers, " 5076 + "aborting.\n"); 5077 + goto err_out_free_res; 5078 + } 5079 + cp->casreg_len = casreg_len; 5080 + 5081 + pci_save_state(pdev); 5082 + cas_check_pci_invariants(cp); 5083 + cas_hard_reset(cp); 5084 + cas_reset(cp, 0); 5085 + if (cas_check_invariants(cp)) 5086 + goto err_out_iounmap; 5087 + 5088 + cp->init_block = (struct cas_init_block *) 5089 + pci_alloc_consistent(pdev, sizeof(struct cas_init_block), 5090 + &cp->block_dvma); 5091 + if (!cp->init_block) { 5092 + printk(KERN_ERR PFX "Cannot allocate init block, " 5093 + "aborting.\n"); 5094 + goto err_out_iounmap; 5095 + } 5096 + 5097 + for (i = 0; i < N_TX_RINGS; i++) 5098 + cp->init_txds[i] = cp->init_block->txds[i]; 5099 + 5100 + for (i = 0; i < N_RX_DESC_RINGS; i++) 5101 + cp->init_rxds[i] = cp->init_block->rxds[i]; 5102 + 5103 + for (i = 0; i < N_RX_COMP_RINGS; i++) 5104 + cp->init_rxcs[i] = cp->init_block->rxcs[i]; 5105 + 5106 + for (i = 0; i < N_RX_FLOWS; i++) 5107 + skb_queue_head_init(&cp->rx_flows[i]); 5108 + 5109 + dev->open = cas_open; 5110 + dev->stop = cas_close; 5111 + dev->hard_start_xmit = cas_start_xmit; 5112 + dev->get_stats = cas_get_stats; 5113 + dev->set_multicast_list = cas_set_multicast; 5114 + dev->do_ioctl = cas_ioctl; 5115 + dev->tx_timeout = cas_tx_timeout; 5116 + dev->watchdog_timeo = CAS_TX_TIMEOUT; 5117 + dev->change_mtu = cas_change_mtu; 5118 + #ifdef USE_NAPI 5119 + dev->poll = cas_poll; 5120 + dev->weight = 64; 5121 + #endif 5122 + #ifdef CONFIG_NET_POLL_CONTROLLER 5123 + dev->poll_controller = cas_netpoll; 5124 + #endif 5125 + dev->irq = pdev->irq; 5126 + dev->dma = 0; 5127 + 5128 + /* Cassini features. */ 5129 + if ((cp->cas_flags & CAS_FLAG_NO_HW_CSUM) == 0) 5130 + dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; 5131 + 5132 + if (pci_using_dac) 5133 + dev->features |= NETIF_F_HIGHDMA; 5134 + 5135 + if (register_netdev(dev)) { 5136 + printk(KERN_ERR PFX "Cannot register net device, " 5137 + "aborting.\n"); 5138 + goto err_out_free_consistent; 5139 + } 5140 + 5141 + i = readl(cp->regs + REG_BIM_CFG); 5142 + printk(KERN_INFO "%s: Sun Cassini%s (%sbit/%sMHz PCI/%s) " 5143 + "Ethernet[%d] ", dev->name, 5144 + (cp->cas_flags & CAS_FLAG_REG_PLUS) ? "+" : "", 5145 + (i & BIM_CFG_32BIT) ? "32" : "64", 5146 + (i & BIM_CFG_66MHZ) ? "66" : "33", 5147 + (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq); 5148 + 5149 + for (i = 0; i < 6; i++) 5150 + printk("%2.2x%c", dev->dev_addr[i], 5151 + i == 5 ? ' ' : ':'); 5152 + printk("\n"); 5153 + 5154 + pci_set_drvdata(pdev, dev); 5155 + cp->hw_running = 1; 5156 + cas_entropy_reset(cp); 5157 + cas_phy_init(cp); 5158 + cas_begin_auto_negotiation(cp, NULL); 5159 + return 0; 5160 + 5161 + err_out_free_consistent: 5162 + pci_free_consistent(pdev, sizeof(struct cas_init_block), 5163 + cp->init_block, cp->block_dvma); 5164 + 5165 + err_out_iounmap: 5166 + down(&cp->pm_sem); 5167 + if (cp->hw_running) 5168 + cas_shutdown(cp); 5169 + up(&cp->pm_sem); 5170 + 5171 + iounmap((void *) cp->regs); 5172 + 5173 + 5174 + err_out_free_res: 5175 + pci_release_regions(pdev); 5176 + 5177 + err_write_cacheline: 5178 + /* Try to restore it in case the error occured after we 5179 + * set it. 5180 + */ 5181 + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, orig_cacheline_size); 5182 + 5183 + err_out_free_netdev: 5184 + free_netdev(dev); 5185 + 5186 + err_out_disable_pdev: 5187 + pci_disable_device(pdev); 5188 + pci_set_drvdata(pdev, NULL); 5189 + return -ENODEV; 5190 + } 5191 + 5192 + static void __devexit cas_remove_one(struct pci_dev *pdev) 5193 + { 5194 + struct net_device *dev = pci_get_drvdata(pdev); 5195 + struct cas *cp; 5196 + if (!dev) 5197 + return; 5198 + 5199 + cp = netdev_priv(dev); 5200 + unregister_netdev(dev); 5201 + 5202 + down(&cp->pm_sem); 5203 + flush_scheduled_work(); 5204 + if (cp->hw_running) 5205 + cas_shutdown(cp); 5206 + up(&cp->pm_sem); 5207 + 5208 + #if 1 5209 + if (cp->orig_cacheline_size) { 5210 + /* Restore the cache line size if we had modified 5211 + * it. 5212 + */ 5213 + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 5214 + cp->orig_cacheline_size); 5215 + } 5216 + #endif 5217 + pci_free_consistent(pdev, sizeof(struct cas_init_block), 5218 + cp->init_block, cp->block_dvma); 5219 + iounmap((void *) cp->regs); 5220 + free_netdev(dev); 5221 + pci_release_regions(pdev); 5222 + pci_disable_device(pdev); 5223 + pci_set_drvdata(pdev, NULL); 5224 + } 5225 + 5226 + #ifdef CONFIG_PM 5227 + static int cas_suspend(struct pci_dev *pdev, u32 state) 5228 + { 5229 + struct net_device *dev = pci_get_drvdata(pdev); 5230 + struct cas *cp = netdev_priv(dev); 5231 + unsigned long flags; 5232 + 5233 + /* We hold the PM semaphore during entire driver 5234 + * sleep time 5235 + */ 5236 + down(&cp->pm_sem); 5237 + 5238 + /* If the driver is opened, we stop the DMA */ 5239 + if (cp->opened) { 5240 + netif_device_detach(dev); 5241 + 5242 + cas_lock_all_save(cp, flags); 5243 + 5244 + /* We can set the second arg of cas_reset to 0 5245 + * because on resume, we'll call cas_init_hw with 5246 + * its second arg set so that autonegotiation is 5247 + * restarted. 5248 + */ 5249 + cas_reset(cp, 0); 5250 + cas_clean_rings(cp); 5251 + cas_unlock_all_restore(cp, flags); 5252 + } 5253 + 5254 + if (cp->hw_running) 5255 + cas_shutdown(cp); 5256 + 5257 + return 0; 5258 + } 5259 + 5260 + static int cas_resume(struct pci_dev *pdev) 5261 + { 5262 + struct net_device *dev = pci_get_drvdata(pdev); 5263 + struct cas *cp = netdev_priv(dev); 5264 + 5265 + printk(KERN_INFO "%s: resuming\n", dev->name); 5266 + 5267 + cas_hard_reset(cp); 5268 + if (cp->opened) { 5269 + unsigned long flags; 5270 + cas_lock_all_save(cp, flags); 5271 + cas_reset(cp, 0); 5272 + cp->hw_running = 1; 5273 + cas_clean_rings(cp); 5274 + cas_init_hw(cp, 1); 5275 + cas_unlock_all_restore(cp, flags); 5276 + 5277 + netif_device_attach(dev); 5278 + } 5279 + up(&cp->pm_sem); 5280 + return 0; 5281 + } 5282 + #endif /* CONFIG_PM */ 5283 + 5284 + static struct pci_driver cas_driver = { 5285 + .name = DRV_MODULE_NAME, 5286 + .id_table = cas_pci_tbl, 5287 + .probe = cas_init_one, 5288 + .remove = __devexit_p(cas_remove_one), 5289 + #ifdef CONFIG_PM 5290 + .suspend = cas_suspend, 5291 + .resume = cas_resume 5292 + #endif 5293 + }; 5294 + 5295 + static int __init cas_init(void) 5296 + { 5297 + if (linkdown_timeout > 0) 5298 + link_transition_timeout = linkdown_timeout * HZ; 5299 + else 5300 + link_transition_timeout = 0; 5301 + 5302 + return pci_module_init(&cas_driver); 5303 + } 5304 + 5305 + static void __exit cas_cleanup(void) 5306 + { 5307 + pci_unregister_driver(&cas_driver); 5308 + } 5309 + 5310 + module_init(cas_init); 5311 + module_exit(cas_cleanup);
+4425
drivers/net/cassini.h
··· 1 + /* $Id: cassini.h,v 1.16 2004/08/17 21:15:16 zaumen Exp $ 2 + * cassini.h: Definitions for Sun Microsystems Cassini(+) ethernet driver. 3 + * 4 + * Copyright (C) 2004 Sun Microsystems Inc. 5 + * Copyright (c) 2003 Adrian Sun (asun@darksunrising.com) 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License as 9 + * published by the Free Software Foundation; either version 2 of the 10 + * License, or (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 + * 02111-1307, USA. 21 + * 22 + * vendor id: 0x108E (Sun Microsystems, Inc.) 23 + * device id: 0xabba (Cassini) 24 + * revision ids: 0x01 = Cassini 25 + * 0x02 = Cassini rev 2 26 + * 0x10 = Cassini+ 27 + * 0x11 = Cassini+ 0.2u 28 + * 29 + * vendor id: 0x100b (National Semiconductor) 30 + * device id: 0x0035 (DP83065/Saturn) 31 + * revision ids: 0x30 = Saturn B2 32 + * 33 + * rings are all offset from 0. 34 + * 35 + * there are two clock domains: 36 + * PCI: 33/66MHz clock 37 + * chip: 125MHz clock 38 + */ 39 + 40 + #ifndef _CASSINI_H 41 + #define _CASSINI_H 42 + 43 + /* cassini register map: 2M memory mapped in 32-bit memory space accessible as 44 + * 32-bit words. there is no i/o port access. REG_ addresses are 45 + * shared between cassini and cassini+. REG_PLUS_ addresses only 46 + * appear in cassini+. REG_MINUS_ addresses only appear in cassini. 47 + */ 48 + #define CAS_ID_REV2 0x02 49 + #define CAS_ID_REVPLUS 0x10 50 + #define CAS_ID_REVPLUS02u 0x11 51 + #define CAS_ID_REVSATURNB2 0x30 52 + 53 + /** global resources **/ 54 + 55 + /* this register sets the weights for the weighted round robin arbiter. e.g., 56 + * if rx weight == 1 and tx weight == 0, rx == 2x tx transfer credit 57 + * for its next turn to access the pci bus. 58 + * map: 0x0 = x1, 0x1 = x2, 0x2 = x4, 0x3 = x8 59 + * DEFAULT: 0x0, SIZE: 5 bits 60 + */ 61 + #define REG_CAWR 0x0004 /* core arbitration weight */ 62 + #define CAWR_RX_DMA_WEIGHT_SHIFT 0 63 + #define CAWR_RX_DMA_WEIGHT_MASK 0x03 /* [0:1] */ 64 + #define CAWR_TX_DMA_WEIGHT_SHIFT 2 65 + #define CAWR_TX_DMA_WEIGHT_MASK 0x0C /* [3:2] */ 66 + #define CAWR_RR_DIS 0x10 /* [4] */ 67 + 68 + /* if enabled, BIM can send bursts across PCI bus > cacheline size. burst 69 + * sizes determined by length of packet or descriptor transfer and the 70 + * max length allowed by the target. 71 + * DEFAULT: 0x0, SIZE: 1 bit 72 + */ 73 + #define REG_INF_BURST 0x0008 /* infinite burst enable reg */ 74 + #define INF_BURST_EN 0x1 /* enable */ 75 + 76 + /* top level interrupts [0-9] are auto-cleared to 0 when the status 77 + * register is read. second level interrupts [13 - 18] are cleared at 78 + * the source. tx completion register 3 is replicated in [19 - 31] 79 + * DEFAULT: 0x00000000, SIZE: 29 bits 80 + */ 81 + #define REG_INTR_STATUS 0x000C /* interrupt status register */ 82 + #define INTR_TX_INTME 0x00000001 /* frame w/ INT ME desc bit set 83 + xferred from host queue to 84 + TX FIFO */ 85 + #define INTR_TX_ALL 0x00000002 /* all xmit frames xferred into 86 + TX FIFO. i.e., 87 + TX Kick == TX complete. if 88 + PACED_MODE set, then TX FIFO 89 + also empty */ 90 + #define INTR_TX_DONE 0x00000004 /* any frame xferred into tx 91 + FIFO */ 92 + #define INTR_TX_TAG_ERROR 0x00000008 /* TX FIFO tag framing 93 + corrupted. FATAL ERROR */ 94 + #define INTR_RX_DONE 0x00000010 /* at least 1 frame xferred 95 + from RX FIFO to host mem. 96 + RX completion reg updated. 97 + may be delayed by recv 98 + intr blanking. */ 99 + #define INTR_RX_BUF_UNAVAIL 0x00000020 /* no more receive buffers. 100 + RX Kick == RX complete */ 101 + #define INTR_RX_TAG_ERROR 0x00000040 /* RX FIFO tag framing 102 + corrupted. FATAL ERROR */ 103 + #define INTR_RX_COMP_FULL 0x00000080 /* no more room in completion 104 + ring to post descriptors. 105 + RX complete head incr to 106 + almost reach RX complete 107 + tail */ 108 + #define INTR_RX_BUF_AE 0x00000100 /* less than the 109 + programmable threshold # 110 + of free descr avail for 111 + hw use */ 112 + #define INTR_RX_COMP_AF 0x00000200 /* less than the 113 + programmable threshold # 114 + of descr spaces for hw 115 + use in completion descr 116 + ring */ 117 + #define INTR_RX_LEN_MISMATCH 0x00000400 /* len field from MAC != 118 + len of non-reassembly pkt 119 + from fifo during DMA or 120 + header parser provides TCP 121 + header and payload size > 122 + MAC packet size. 123 + FATAL ERROR */ 124 + #define INTR_SUMMARY 0x00001000 /* summary interrupt bit. this 125 + bit will be set if an interrupt 126 + generated on the pci bus. useful 127 + when driver is polling for 128 + interrupts */ 129 + #define INTR_PCS_STATUS 0x00002000 /* PCS interrupt status register */ 130 + #define INTR_TX_MAC_STATUS 0x00004000 /* TX MAC status register has at 131 + least 1 unmasked interrupt set */ 132 + #define INTR_RX_MAC_STATUS 0x00008000 /* RX MAC status register has at 133 + least 1 unmasked interrupt set */ 134 + #define INTR_MAC_CTRL_STATUS 0x00010000 /* MAC control status register has 135 + at least 1 unmasked interrupt 136 + set */ 137 + #define INTR_MIF_STATUS 0x00020000 /* MIF status register has at least 138 + 1 unmasked interrupt set */ 139 + #define INTR_PCI_ERROR_STATUS 0x00040000 /* PCI error status register in the 140 + BIF has at least 1 unmasked 141 + interrupt set */ 142 + #define INTR_TX_COMP_3_MASK 0xFFF80000 /* mask for TX completion 143 + 3 reg data */ 144 + #define INTR_TX_COMP_3_SHIFT 19 145 + #define INTR_ERROR_MASK (INTR_MIF_STATUS | INTR_PCI_ERROR_STATUS | \ 146 + INTR_PCS_STATUS | INTR_RX_LEN_MISMATCH | \ 147 + INTR_TX_MAC_STATUS | INTR_RX_MAC_STATUS | \ 148 + INTR_TX_TAG_ERROR | INTR_RX_TAG_ERROR | \ 149 + INTR_MAC_CTRL_STATUS) 150 + 151 + /* determines which status events will cause an interrupt. layout same 152 + * as REG_INTR_STATUS. 153 + * DEFAULT: 0xFFFFFFFF, SIZE: 16 bits 154 + */ 155 + #define REG_INTR_MASK 0x0010 /* Interrupt mask */ 156 + 157 + /* top level interrupt bits that are cleared during read of REG_INTR_STATUS_ALIAS. 158 + * useful when driver is polling for interrupts. layout same as REG_INTR_MASK. 159 + * DEFAULT: 0x00000000, SIZE: 12 bits 160 + */ 161 + #define REG_ALIAS_CLEAR 0x0014 /* alias clear mask 162 + (used w/ status alias) */ 163 + /* same as REG_INTR_STATUS except that only bits cleared are those selected by 164 + * REG_ALIAS_CLEAR 165 + * DEFAULT: 0x00000000, SIZE: 29 bits 166 + */ 167 + #define REG_INTR_STATUS_ALIAS 0x001C /* interrupt status alias 168 + (selective clear) */ 169 + 170 + /* DEFAULT: 0x0, SIZE: 3 bits */ 171 + #define REG_PCI_ERR_STATUS 0x1000 /* PCI error status */ 172 + #define PCI_ERR_BADACK 0x01 /* reserved in Cassini+. 173 + set if no ACK64# during ABS64 cycle 174 + in Cassini. */ 175 + #define PCI_ERR_DTRTO 0x02 /* delayed xaction timeout. set if 176 + no read retry after 2^15 clocks */ 177 + #define PCI_ERR_OTHER 0x04 /* other PCI errors */ 178 + #define PCI_ERR_BIM_DMA_WRITE 0x08 /* BIM received 0 count DMA write req. 179 + unused in Cassini. */ 180 + #define PCI_ERR_BIM_DMA_READ 0x10 /* BIM received 0 count DMA read req. 181 + unused in Cassini. */ 182 + #define PCI_ERR_BIM_DMA_TIMEOUT 0x20 /* BIM received 255 retries during 183 + DMA. unused in cassini. */ 184 + 185 + /* mask for PCI status events that will set PCI_ERR_STATUS. if cleared, event 186 + * causes an interrupt to be generated. 187 + * DEFAULT: 0x7, SIZE: 3 bits 188 + */ 189 + #define REG_PCI_ERR_STATUS_MASK 0x1004 /* PCI Error status mask */ 190 + 191 + /* used to configure PCI related parameters that are not in PCI config space. 192 + * DEFAULT: 0bxx000, SIZE: 5 bits 193 + */ 194 + #define REG_BIM_CFG 0x1008 /* BIM Configuration */ 195 + #define BIM_CFG_RESERVED0 0x001 /* reserved */ 196 + #define BIM_CFG_RESERVED1 0x002 /* reserved */ 197 + #define BIM_CFG_64BIT_DISABLE 0x004 /* disable 64-bit mode */ 198 + #define BIM_CFG_66MHZ 0x008 /* (ro) 1 = 66MHz, 0 = < 66MHz */ 199 + #define BIM_CFG_32BIT 0x010 /* (ro) 1 = 32-bit slot, 0 = 64-bit */ 200 + #define BIM_CFG_DPAR_INTR_ENABLE 0x020 /* detected parity err enable */ 201 + #define BIM_CFG_RMA_INTR_ENABLE 0x040 /* master abort intr enable */ 202 + #define BIM_CFG_RTA_INTR_ENABLE 0x080 /* target abort intr enable */ 203 + #define BIM_CFG_RESERVED2 0x100 /* reserved */ 204 + #define BIM_CFG_BIM_DISABLE 0x200 /* stop BIM DMA. use before global 205 + reset. reserved in Cassini. */ 206 + #define BIM_CFG_BIM_STATUS 0x400 /* (ro) 1 = BIM DMA suspended. 207 + reserved in Cassini. */ 208 + #define BIM_CFG_PERROR_BLOCK 0x800 /* block PERR# to pci bus. def: 0. 209 + reserved in Cassini. */ 210 + 211 + /* DEFAULT: 0x00000000, SIZE: 32 bits */ 212 + #define REG_BIM_DIAG 0x100C /* BIM Diagnostic */ 213 + #define BIM_DIAG_MSTR_SM_MASK 0x3FFFFF00 /* PCI master controller state 214 + machine bits [21:0] */ 215 + #define BIM_DIAG_BRST_SM_MASK 0x7F /* PCI burst controller state 216 + machine bits [6:0] */ 217 + 218 + /* writing to SW_RESET_TX and SW_RESET_RX will issue a global 219 + * reset. poll until TX and RX read back as 0's for completion. 220 + */ 221 + #define REG_SW_RESET 0x1010 /* Software reset */ 222 + #define SW_RESET_TX 0x00000001 /* reset TX DMA engine. poll until 223 + cleared to 0. */ 224 + #define SW_RESET_RX 0x00000002 /* reset RX DMA engine. poll until 225 + cleared to 0. */ 226 + #define SW_RESET_RSTOUT 0x00000004 /* force RSTOUT# pin active (low). 227 + resets PHY and anything else 228 + connected to RSTOUT#. RSTOUT# 229 + is also activated by local PCI 230 + reset when hot-swap is being 231 + done. */ 232 + #define SW_RESET_BLOCK_PCS_SLINK 0x00000008 /* if a global reset is done with 233 + this bit set, PCS and SLINK 234 + modules won't be reset. 235 + i.e., link won't drop. */ 236 + #define SW_RESET_BREQ_SM_MASK 0x00007F00 /* breq state machine [6:0] */ 237 + #define SW_RESET_PCIARB_SM_MASK 0x00070000 /* pci arbitration state bits: 238 + 0b000: ARB_IDLE1 239 + 0b001: ARB_IDLE2 240 + 0b010: ARB_WB_ACK 241 + 0b011: ARB_WB_WAT 242 + 0b100: ARB_RB_ACK 243 + 0b101: ARB_RB_WAT 244 + 0b110: ARB_RB_END 245 + 0b111: ARB_WB_END */ 246 + #define SW_RESET_RDPCI_SM_MASK 0x00300000 /* read pci state bits: 247 + 0b00: RD_PCI_WAT 248 + 0b01: RD_PCI_RDY 249 + 0b11: RD_PCI_ACK */ 250 + #define SW_RESET_RDARB_SM_MASK 0x00C00000 /* read arbitration state bits: 251 + 0b00: AD_IDL_RX 252 + 0b01: AD_ACK_RX 253 + 0b10: AD_ACK_TX 254 + 0b11: AD_IDL_TX */ 255 + #define SW_RESET_WRPCI_SM_MASK 0x06000000 /* write pci state bits 256 + 0b00: WR_PCI_WAT 257 + 0b01: WR_PCI_RDY 258 + 0b11: WR_PCI_ACK */ 259 + #define SW_RESET_WRARB_SM_MASK 0x38000000 /* write arbitration state bits: 260 + 0b000: ARB_IDLE1 261 + 0b001: ARB_IDLE2 262 + 0b010: ARB_TX_ACK 263 + 0b011: ARB_TX_WAT 264 + 0b100: ARB_RX_ACK 265 + 0b110: ARB_RX_WAT */ 266 + 267 + /* Cassini only. 64-bit register used to check PCI datapath. when read, 268 + * value written has both lower and upper 32-bit halves rotated to the right 269 + * one bit position. e.g., FFFFFFFF FFFFFFFF -> 7FFFFFFF 7FFFFFFF 270 + */ 271 + #define REG_MINUS_BIM_DATAPATH_TEST 0x1018 /* Cassini: BIM datapath test 272 + Cassini+: reserved */ 273 + 274 + /* output enables are provided for each device's chip select and for the rest 275 + * of the outputs from cassini to its local bus devices. two sw programmable 276 + * bits are connected to general purpus control/status bits. 277 + * DEFAULT: 0x7 278 + */ 279 + #define REG_BIM_LOCAL_DEV_EN 0x1020 /* BIM local device 280 + output EN. default: 0x7 */ 281 + #define BIM_LOCAL_DEV_PAD 0x01 /* address bus, RW signal, and 282 + OE signal output enable on the 283 + local bus interface. these 284 + are shared between both local 285 + bus devices. tristate when 0. */ 286 + #define BIM_LOCAL_DEV_PROM 0x02 /* PROM chip select */ 287 + #define BIM_LOCAL_DEV_EXT 0x04 /* secondary local bus device chip 288 + select output enable */ 289 + #define BIM_LOCAL_DEV_SOFT_0 0x08 /* sw programmable ctrl bit 0 */ 290 + #define BIM_LOCAL_DEV_SOFT_1 0x10 /* sw programmable ctrl bit 1 */ 291 + #define BIM_LOCAL_DEV_HW_RESET 0x20 /* internal hw reset. Cassini+ only. */ 292 + 293 + /* access 24 entry BIM read and write buffers. put address in REG_BIM_BUFFER_ADDR 294 + * and read/write from/to it REG_BIM_BUFFER_DATA_LOW and _DATA_HI. 295 + * _DATA_HI should be the last access of the sequence. 296 + * DEFAULT: undefined 297 + */ 298 + #define REG_BIM_BUFFER_ADDR 0x1024 /* BIM buffer address. for 299 + purposes. */ 300 + #define BIM_BUFFER_ADDR_MASK 0x3F /* index (0 - 23) of buffer */ 301 + #define BIM_BUFFER_WR_SELECT 0x40 /* write buffer access = 1 302 + read buffer access = 0 */ 303 + /* DEFAULT: undefined */ 304 + #define REG_BIM_BUFFER_DATA_LOW 0x1028 /* BIM buffer data low */ 305 + #define REG_BIM_BUFFER_DATA_HI 0x102C /* BIM buffer data high */ 306 + 307 + /* set BIM_RAM_BIST_START to start built-in self test for BIM read buffer. 308 + * bit auto-clears when done with status read from _SUMMARY and _PASS bits. 309 + */ 310 + #define REG_BIM_RAM_BIST 0x102C /* BIM RAM (read buffer) BIST 311 + control/status */ 312 + #define BIM_RAM_BIST_RD_START 0x01 /* start BIST for BIM read buffer */ 313 + #define BIM_RAM_BIST_WR_START 0x02 /* start BIST for BIM write buffer. 314 + Cassini only. reserved in 315 + Cassini+. */ 316 + #define BIM_RAM_BIST_RD_PASS 0x04 /* summary BIST pass status for read 317 + buffer. */ 318 + #define BIM_RAM_BIST_WR_PASS 0x08 /* summary BIST pass status for write 319 + buffer. Cassini only. reserved 320 + in Cassini+. */ 321 + #define BIM_RAM_BIST_RD_LOW_PASS 0x10 /* read low bank passes BIST */ 322 + #define BIM_RAM_BIST_RD_HI_PASS 0x20 /* read high bank passes BIST */ 323 + #define BIM_RAM_BIST_WR_LOW_PASS 0x40 /* write low bank passes BIST. 324 + Cassini only. reserved in 325 + Cassini+. */ 326 + #define BIM_RAM_BIST_WR_HI_PASS 0x80 /* write high bank passes BIST. 327 + Cassini only. reserved in 328 + Cassini+. */ 329 + 330 + /* ASUN: i'm not sure what this does as it's not in the spec. 331 + * DEFAULT: 0xFC 332 + */ 333 + #define REG_BIM_DIAG_MUX 0x1030 /* BIM diagnostic probe mux 334 + select register */ 335 + 336 + /* enable probe monitoring mode and select data appearing on the P_A* bus. bit 337 + * values for _SEL_HI_MASK and _SEL_LOW_MASK: 338 + * 0x0: internal probe[7:0] (pci arb state, wtc empty w, wtc full w, wtc empty w, 339 + * wtc empty r, post pci) 340 + * 0x1: internal probe[15:8] (pci wbuf comp, pci wpkt comp, pci rbuf comp, 341 + * pci rpkt comp, txdma wr req, txdma wr ack, 342 + * txdma wr rdy, txdma wr xfr done) 343 + * 0x2: internal probe[23:16] (txdma rd req, txdma rd ack, txdma rd rdy, rxdma rd, 344 + * rd arb state, rd pci state) 345 + * 0x3: internal probe[31:24] (rxdma req, rxdma ack, rxdma rdy, wrarb state, 346 + * wrpci state) 347 + * 0x4: pci io probe[7:0] 0x5: pci io probe[15:8] 348 + * 0x6: pci io probe[23:16] 0x7: pci io probe[31:24] 349 + * 0x8: pci io probe[39:32] 0x9: pci io probe[47:40] 350 + * 0xa: pci io probe[55:48] 0xb: pci io probe[63:56] 351 + * the following are not available in Cassini: 352 + * 0xc: rx probe[7:0] 0xd: tx probe[7:0] 353 + * 0xe: hp probe[7:0] 0xf: mac probe[7:0] 354 + */ 355 + #define REG_PLUS_PROBE_MUX_SELECT 0x1034 /* Cassini+: PROBE MUX SELECT */ 356 + #define PROBE_MUX_EN 0x80000000 /* allow probe signals to be 357 + driven on local bus P_A[15:0] 358 + for debugging */ 359 + #define PROBE_MUX_SUB_MUX_MASK 0x0000FF00 /* select sub module probe signals: 360 + 0x03 = mac[1:0] 361 + 0x0C = rx[1:0] 362 + 0x30 = tx[1:0] 363 + 0xC0 = hp[1:0] */ 364 + #define PROBE_MUX_SEL_HI_MASK 0x000000F0 /* select which module to appear 365 + on P_A[15:8]. see above for 366 + values. */ 367 + #define PROBE_MUX_SEL_LOW_MASK 0x0000000F /* select which module to appear 368 + on P_A[7:0]. see above for 369 + values. */ 370 + 371 + /* values mean the same thing as REG_INTR_MASK excep that it's for INTB. 372 + DEFAULT: 0x1F */ 373 + #define REG_PLUS_INTR_MASK_1 0x1038 /* Cassini+: interrupt mask 374 + register 2 for INTB */ 375 + #define REG_PLUS_INTRN_MASK(x) (REG_PLUS_INTR_MASK_1 + ((x) - 1)*16) 376 + /* bits correspond to both _MASK and _STATUS registers. _ALT corresponds to 377 + * all of the alternate (2-4) INTR registers while _1 corresponds to only 378 + * _MASK_1 and _STATUS_1 registers. 379 + * DEFAULT: 0x7 for MASK registers, 0x0 for ALIAS_CLEAR registers 380 + */ 381 + #define INTR_RX_DONE_ALT 0x01 382 + #define INTR_RX_COMP_FULL_ALT 0x02 383 + #define INTR_RX_COMP_AF_ALT 0x04 384 + #define INTR_RX_BUF_UNAVAIL_1 0x08 385 + #define INTR_RX_BUF_AE_1 0x10 /* almost empty */ 386 + #define INTRN_MASK_RX_EN 0x80 387 + #define INTRN_MASK_CLEAR_ALL (INTR_RX_DONE_ALT | \ 388 + INTR_RX_COMP_FULL_ALT | \ 389 + INTR_RX_COMP_AF_ALT | \ 390 + INTR_RX_BUF_UNAVAIL_1 | \ 391 + INTR_RX_BUF_AE_1) 392 + #define REG_PLUS_INTR_STATUS_1 0x103C /* Cassini+: interrupt status 393 + register 2 for INTB. default: 0x1F */ 394 + #define REG_PLUS_INTRN_STATUS(x) (REG_PLUS_INTR_STATUS_1 + ((x) - 1)*16) 395 + #define INTR_STATUS_ALT_INTX_EN 0x80 /* generate INTX when one of the 396 + flags are set. enables desc ring. */ 397 + 398 + #define REG_PLUS_ALIAS_CLEAR_1 0x1040 /* Cassini+: alias clear mask 399 + register 2 for INTB */ 400 + #define REG_PLUS_ALIASN_CLEAR(x) (REG_PLUS_ALIAS_CLEAR_1 + ((x) - 1)*16) 401 + 402 + #define REG_PLUS_INTR_STATUS_ALIAS_1 0x1044 /* Cassini+: interrupt status 403 + register alias 2 for INTB */ 404 + #define REG_PLUS_INTRN_STATUS_ALIAS(x) (REG_PLUS_INTR_STATUS_ALIAS_1 + ((x) - 1)*16) 405 + 406 + #define REG_SATURN_PCFG 0x106c /* pin configuration register for 407 + integrated macphy */ 408 + 409 + #define SATURN_PCFG_TLA 0x00000001 /* 1 = phy actled */ 410 + #define SATURN_PCFG_FLA 0x00000002 /* 1 = phy link10led */ 411 + #define SATURN_PCFG_CLA 0x00000004 /* 1 = phy link100led */ 412 + #define SATURN_PCFG_LLA 0x00000008 /* 1 = phy link1000led */ 413 + #define SATURN_PCFG_RLA 0x00000010 /* 1 = phy duplexled */ 414 + #define SATURN_PCFG_PDS 0x00000020 /* phy debug mode. 415 + 0 = normal */ 416 + #define SATURN_PCFG_MTP 0x00000080 /* test point select */ 417 + #define SATURN_PCFG_GMO 0x00000100 /* GMII observe. 1 = 418 + GMII on SERDES pins for 419 + monitoring. */ 420 + #define SATURN_PCFG_FSI 0x00000200 /* 1 = freeze serdes/gmii. all 421 + pins configed as outputs. 422 + for power saving when using 423 + internal phy. */ 424 + #define SATURN_PCFG_LAD 0x00000800 /* 0 = mac core led ctrl 425 + polarity from strapping 426 + value. 427 + 1 = mac core led ctrl 428 + polarity active low. */ 429 + 430 + 431 + /** transmit dma registers **/ 432 + #define MAX_TX_RINGS_SHIFT 2 433 + #define MAX_TX_RINGS (1 << MAX_TX_RINGS_SHIFT) 434 + #define MAX_TX_RINGS_MASK (MAX_TX_RINGS - 1) 435 + 436 + /* TX configuration. 437 + * descr ring sizes size = 32 * (1 << n), n < 9. e.g., 0x8 = 8k. default: 0x8 438 + * DEFAULT: 0x3F000001 439 + */ 440 + #define REG_TX_CFG 0x2004 /* TX config */ 441 + #define TX_CFG_DMA_EN 0x00000001 /* enable TX DMA. if cleared, DMA 442 + will stop after xfer of current 443 + buffer has been completed. */ 444 + #define TX_CFG_FIFO_PIO_SEL 0x00000002 /* TX DMA FIFO can be 445 + accessed w/ FIFO addr 446 + and data registers. 447 + TX DMA should be 448 + disabled. */ 449 + #define TX_CFG_DESC_RING0_MASK 0x0000003C /* # desc entries in 450 + ring 1. */ 451 + #define TX_CFG_DESC_RING0_SHIFT 2 452 + #define TX_CFG_DESC_RINGN_MASK(a) (TX_CFG_DESC_RING0_MASK << (a)*4) 453 + #define TX_CFG_DESC_RINGN_SHIFT(a) (TX_CFG_DESC_RING0_SHIFT + (a)*4) 454 + #define TX_CFG_PACED_MODE 0x00100000 /* TX_ALL only set after 455 + TX FIFO becomes empty. 456 + if 0, TX_ALL set 457 + if descr queue empty. */ 458 + #define TX_CFG_DMA_RDPIPE_DIS 0x01000000 /* always set to 1 */ 459 + #define TX_CFG_COMPWB_Q1 0x02000000 /* completion writeback happens at 460 + the end of every packet kicked 461 + through Q1. */ 462 + #define TX_CFG_COMPWB_Q2 0x04000000 /* completion writeback happens at 463 + the end of every packet kicked 464 + through Q2. */ 465 + #define TX_CFG_COMPWB_Q3 0x08000000 /* completion writeback happens at 466 + the end of every packet kicked 467 + through Q3 */ 468 + #define TX_CFG_COMPWB_Q4 0x10000000 /* completion writeback happens at 469 + the end of every packet kicked 470 + through Q4 */ 471 + #define TX_CFG_INTR_COMPWB_DIS 0x20000000 /* disable pre-interrupt completion 472 + writeback */ 473 + #define TX_CFG_CTX_SEL_MASK 0xC0000000 /* selects tx test port 474 + connection 475 + 0b00: tx mac req, 476 + tx mac retry req, 477 + tx ack and tx tag. 478 + 0b01: txdma rd req, 479 + txdma rd ack, 480 + txdma rd rdy, 481 + txdma rd type0 482 + 0b11: txdma wr req, 483 + txdma wr ack, 484 + txdma wr rdy, 485 + txdma wr xfr done. */ 486 + #define TX_CFG_CTX_SEL_SHIFT 30 487 + 488 + /* 11-bit counters that point to next location in FIFO to be loaded/retrieved. 489 + * used for diagnostics only. 490 + */ 491 + #define REG_TX_FIFO_WRITE_PTR 0x2014 /* TX FIFO write pointer */ 492 + #define REG_TX_FIFO_SHADOW_WRITE_PTR 0x2018 /* TX FIFO shadow write 493 + pointer. temp hold reg. 494 + diagnostics only. */ 495 + #define REG_TX_FIFO_READ_PTR 0x201C /* TX FIFO read pointer */ 496 + #define REG_TX_FIFO_SHADOW_READ_PTR 0x2020 /* TX FIFO shadow read 497 + pointer */ 498 + 499 + /* (ro) 11-bit up/down counter w/ # of frames currently in TX FIFO */ 500 + #define REG_TX_FIFO_PKT_CNT 0x2024 /* TX FIFO packet counter */ 501 + 502 + /* current state of all state machines in TX */ 503 + #define REG_TX_SM_1 0x2028 /* TX state machine reg #1 */ 504 + #define TX_SM_1_CHAIN_MASK 0x000003FF /* chaining state machine */ 505 + #define TX_SM_1_CSUM_MASK 0x00000C00 /* checksum state machine */ 506 + #define TX_SM_1_FIFO_LOAD_MASK 0x0003F000 /* FIFO load state machine. 507 + = 0x01 when TX disabled. */ 508 + #define TX_SM_1_FIFO_UNLOAD_MASK 0x003C0000 /* FIFO unload state machine */ 509 + #define TX_SM_1_CACHE_MASK 0x03C00000 /* desc. prefetch cache controller 510 + state machine */ 511 + #define TX_SM_1_CBQ_ARB_MASK 0xF8000000 /* CBQ arbiter state machine */ 512 + 513 + #define REG_TX_SM_2 0x202C /* TX state machine reg #2 */ 514 + #define TX_SM_2_COMP_WB_MASK 0x07 /* completion writeback sm */ 515 + #define TX_SM_2_SUB_LOAD_MASK 0x38 /* sub load state machine */ 516 + #define TX_SM_2_KICK_MASK 0xC0 /* kick state machine */ 517 + 518 + /* 64-bit pointer to the transmit data buffer. only the 50 LSB are incremented 519 + * while the upper 23 bits are taken from the TX descriptor 520 + */ 521 + #define REG_TX_DATA_PTR_LOW 0x2030 /* TX data pointer low */ 522 + #define REG_TX_DATA_PTR_HI 0x2034 /* TX data pointer high */ 523 + 524 + /* 13 bit registers written by driver w/ descriptor value that follows 525 + * last valid xmit descriptor. kick # and complete # values are used by 526 + * the xmit dma engine to control tx descr fetching. if > 1 valid 527 + * tx descr is available within the cache line being read, cassini will 528 + * internally cache up to 4 of them. 0 on reset. _KICK = rw, _COMP = ro. 529 + */ 530 + #define REG_TX_KICK0 0x2038 /* TX kick reg #1 */ 531 + #define REG_TX_KICKN(x) (REG_TX_KICK0 + (x)*4) 532 + #define REG_TX_COMP0 0x2048 /* TX completion reg #1 */ 533 + #define REG_TX_COMPN(x) (REG_TX_COMP0 + (x)*4) 534 + 535 + /* values of TX_COMPLETE_1-4 are written. each completion register 536 + * is 2bytes in size and contiguous. 8B allocation w/ 8B alignment. 537 + * NOTE: completion reg values are only written back prior to TX_INTME and 538 + * TX_ALL interrupts. at all other times, the most up-to-date index values 539 + * should be obtained from the REG_TX_COMPLETE_# registers. 540 + * here's the layout: 541 + * offset from base addr completion # byte 542 + * 0 TX_COMPLETE_1_MSB 543 + * 1 TX_COMPLETE_1_LSB 544 + * 2 TX_COMPLETE_2_MSB 545 + * 3 TX_COMPLETE_2_LSB 546 + * 4 TX_COMPLETE_3_MSB 547 + * 5 TX_COMPLETE_3_LSB 548 + * 6 TX_COMPLETE_4_MSB 549 + * 7 TX_COMPLETE_4_LSB 550 + */ 551 + #define TX_COMPWB_SIZE 8 552 + #define REG_TX_COMPWB_DB_LOW 0x2058 /* TX completion write back 553 + base low */ 554 + #define REG_TX_COMPWB_DB_HI 0x205C /* TX completion write back 555 + base high */ 556 + #define TX_COMPWB_MSB_MASK 0x00000000000000FFULL 557 + #define TX_COMPWB_MSB_SHIFT 0 558 + #define TX_COMPWB_LSB_MASK 0x000000000000FF00ULL 559 + #define TX_COMPWB_LSB_SHIFT 8 560 + #define TX_COMPWB_NEXT(x) ((x) >> 16) 561 + 562 + /* 53 MSB used as base address. 11 LSB assumed to be 0. TX desc pointer must 563 + * be 2KB-aligned. */ 564 + #define REG_TX_DB0_LOW 0x2060 /* TX descriptor base low #1 */ 565 + #define REG_TX_DB0_HI 0x2064 /* TX descriptor base hi #1 */ 566 + #define REG_TX_DBN_LOW(x) (REG_TX_DB0_LOW + (x)*8) 567 + #define REG_TX_DBN_HI(x) (REG_TX_DB0_HI + (x)*8) 568 + 569 + /* 16-bit registers hold weights for the weighted round-robin of the 570 + * four CBQ TX descr rings. weights correspond to # bytes xferred from 571 + * host to TXFIFO in a round of WRR arbitration. can be set 572 + * dynamically with new weights set upon completion of the current 573 + * packet transfer from host memory to TXFIFO. a dummy write to any of 574 + * these registers causes a queue1 pre-emption with all historical bw 575 + * deficit data reset to 0 (useful when congestion requires a 576 + * pre-emption/re-allocation of network bandwidth 577 + */ 578 + #define REG_TX_MAXBURST_0 0x2080 /* TX MaxBurst #1 */ 579 + #define REG_TX_MAXBURST_1 0x2084 /* TX MaxBurst #2 */ 580 + #define REG_TX_MAXBURST_2 0x2088 /* TX MaxBurst #3 */ 581 + #define REG_TX_MAXBURST_3 0x208C /* TX MaxBurst #4 */ 582 + 583 + /* diagnostics access to any TX FIFO location. every access is 65 584 + * bits. _DATA_LOW = 32 LSB, _DATA_HI_T1/T0 = 32 MSB. _TAG = tag bit. 585 + * writing _DATA_HI_T0 sets tag bit low, writing _DATA_HI_T1 sets tag 586 + * bit high. TX_FIFO_PIO_SEL must be set for TX FIFO PIO access. if 587 + * TX FIFO data integrity is desired, TX DMA should be 588 + * disabled. _DATA_HI_Tx should be the last access of the sequence. 589 + */ 590 + #define REG_TX_FIFO_ADDR 0x2104 /* TX FIFO address */ 591 + #define REG_TX_FIFO_TAG 0x2108 /* TX FIFO tag */ 592 + #define REG_TX_FIFO_DATA_LOW 0x210C /* TX FIFO data low */ 593 + #define REG_TX_FIFO_DATA_HI_T1 0x2110 /* TX FIFO data high t1 */ 594 + #define REG_TX_FIFO_DATA_HI_T0 0x2114 /* TX FIFO data high t0 */ 595 + #define REG_TX_FIFO_SIZE 0x2118 /* (ro) TX FIFO size = 0x090 = 9KB */ 596 + 597 + /* 9-bit register controls BIST of TX FIFO. bit set indicates that the BIST 598 + * passed for the specified memory 599 + */ 600 + #define REG_TX_RAMBIST 0x211C /* TX RAMBIST control/status */ 601 + #define TX_RAMBIST_STATE 0x01C0 /* progress state of RAMBIST 602 + controller state machine */ 603 + #define TX_RAMBIST_RAM33A_PASS 0x0020 /* RAM33A passed */ 604 + #define TX_RAMBIST_RAM32A_PASS 0x0010 /* RAM32A passed */ 605 + #define TX_RAMBIST_RAM33B_PASS 0x0008 /* RAM33B passed */ 606 + #define TX_RAMBIST_RAM32B_PASS 0x0004 /* RAM32B passed */ 607 + #define TX_RAMBIST_SUMMARY 0x0002 /* all RAM passed */ 608 + #define TX_RAMBIST_START 0x0001 /* write 1 to start BIST. self 609 + clears on completion. */ 610 + 611 + /** receive dma registers **/ 612 + #define MAX_RX_DESC_RINGS 2 613 + #define MAX_RX_COMP_RINGS 4 614 + 615 + /* receive DMA channel configuration. default: 0x80910 616 + * free ring size = (1 << n)*32 -> [32 - 8k] 617 + * completion ring size = (1 << n)*128 -> [128 - 32k], n < 9 618 + * DEFAULT: 0x80910 619 + */ 620 + #define REG_RX_CFG 0x4000 /* RX config */ 621 + #define RX_CFG_DMA_EN 0x00000001 /* enable RX DMA. 0 stops 622 + channel as soon as current 623 + frame xfer has completed. 624 + driver should disable MAC 625 + for 200ms before disabling 626 + RX */ 627 + #define RX_CFG_DESC_RING_MASK 0x0000001E /* # desc entries in RX 628 + free desc ring. 629 + def: 0x8 = 8k */ 630 + #define RX_CFG_DESC_RING_SHIFT 1 631 + #define RX_CFG_COMP_RING_MASK 0x000001E0 /* # desc entries in RX complete 632 + ring. def: 0x8 = 32k */ 633 + #define RX_CFG_COMP_RING_SHIFT 5 634 + #define RX_CFG_BATCH_DIS 0x00000200 /* disable receive desc 635 + batching. def: 0x0 = 636 + enabled */ 637 + #define RX_CFG_SWIVEL_MASK 0x00001C00 /* byte offset of the 1st 638 + data byte of the packet 639 + w/in 8 byte boundares. 640 + this swivels the data 641 + DMA'ed to header 642 + buffers, jumbo buffers 643 + when header split is not 644 + requested and MTU sized 645 + buffers. def: 0x2 */ 646 + #define RX_CFG_SWIVEL_SHIFT 10 647 + 648 + /* cassini+ only */ 649 + #define RX_CFG_DESC_RING1_MASK 0x000F0000 /* # of desc entries in 650 + RX free desc ring 2. 651 + def: 0x8 = 8k */ 652 + #define RX_CFG_DESC_RING1_SHIFT 16 653 + 654 + 655 + /* the page size register allows cassini chips to do the following with 656 + * received data: 657 + * [--------------------------------------------------------------] page 658 + * [off][buf1][pad][off][buf2][pad][off][buf3][pad][off][buf4][pad] 659 + * |--------------| = PAGE_SIZE_BUFFER_STRIDE 660 + * page = PAGE_SIZE 661 + * offset = PAGE_SIZE_MTU_OFF 662 + * for the above example, MTU_BUFFER_COUNT = 4. 663 + * NOTE: as is apparent, you need to ensure that the following holds: 664 + * MTU_BUFFER_COUNT <= PAGE_SIZE/PAGE_SIZE_BUFFER_STRIDE 665 + * DEFAULT: 0x48002002 (8k pages) 666 + */ 667 + #define REG_RX_PAGE_SIZE 0x4004 /* RX page size */ 668 + #define RX_PAGE_SIZE_MASK 0x00000003 /* size of pages pointed to 669 + by receive descriptors. 670 + if jumbo buffers are 671 + supported the page size 672 + should not be < 8k. 673 + 0b00 = 2k, 0b01 = 4k 674 + 0b10 = 8k, 0b11 = 16k 675 + DEFAULT: 8k */ 676 + #define RX_PAGE_SIZE_SHIFT 0 677 + #define RX_PAGE_SIZE_MTU_COUNT_MASK 0x00007800 /* # of MTU buffers the hw 678 + packs into a page. 679 + DEFAULT: 4 */ 680 + #define RX_PAGE_SIZE_MTU_COUNT_SHIFT 11 681 + #define RX_PAGE_SIZE_MTU_STRIDE_MASK 0x18000000 /* # of bytes that separate 682 + each MTU buffer + 683 + offset from each 684 + other. 685 + 0b00 = 1k, 0b01 = 2k 686 + 0b10 = 4k, 0b11 = 8k 687 + DEFAULT: 0x1 */ 688 + #define RX_PAGE_SIZE_MTU_STRIDE_SHIFT 27 689 + #define RX_PAGE_SIZE_MTU_OFF_MASK 0xC0000000 /* offset in each page that 690 + hw writes the MTU buffer 691 + into. 692 + 0b00 = 0, 693 + 0b01 = 64 bytes 694 + 0b10 = 96, 0b11 = 128 695 + DEFAULT: 0x1 */ 696 + #define RX_PAGE_SIZE_MTU_OFF_SHIFT 30 697 + 698 + /* 11-bit counter points to next location in RX FIFO to be loaded/read. 699 + * shadow write pointers enable retries in case of early receive aborts. 700 + * DEFAULT: 0x0. generated on 64-bit boundaries. 701 + */ 702 + #define REG_RX_FIFO_WRITE_PTR 0x4008 /* RX FIFO write pointer */ 703 + #define REG_RX_FIFO_READ_PTR 0x400C /* RX FIFO read pointer */ 704 + #define REG_RX_IPP_FIFO_SHADOW_WRITE_PTR 0x4010 /* RX IPP FIFO shadow write 705 + pointer */ 706 + #define REG_RX_IPP_FIFO_SHADOW_READ_PTR 0x4014 /* RX IPP FIFO shadow read 707 + pointer */ 708 + #define REG_RX_IPP_FIFO_READ_PTR 0x400C /* RX IPP FIFO read 709 + pointer. (8-bit counter) */ 710 + 711 + /* current state of RX DMA state engines + other info 712 + * DEFAULT: 0x0 713 + */ 714 + #define REG_RX_DEBUG 0x401C /* RX debug */ 715 + #define RX_DEBUG_LOAD_STATE_MASK 0x0000000F /* load state machine w/ MAC: 716 + 0x0 = idle, 0x1 = load_bop 717 + 0x2 = load 1, 0x3 = load 2 718 + 0x4 = load 3, 0x5 = load 4 719 + 0x6 = last detect 720 + 0x7 = wait req 721 + 0x8 = wait req statuss 1st 722 + 0x9 = load st 723 + 0xa = bubble mac 724 + 0xb = error */ 725 + #define RX_DEBUG_LM_STATE_MASK 0x00000070 /* load state machine w/ HP and 726 + RX FIFO: 727 + 0x0 = idle, 0x1 = hp xfr 728 + 0x2 = wait hp ready 729 + 0x3 = wait flow code 730 + 0x4 = fifo xfer 731 + 0x5 = make status 732 + 0x6 = csum ready 733 + 0x7 = error */ 734 + #define RX_DEBUG_FC_STATE_MASK 0x000000180 /* flow control state machine 735 + w/ MAC: 736 + 0x0 = idle 737 + 0x1 = wait xoff ack 738 + 0x2 = wait xon 739 + 0x3 = wait xon ack */ 740 + #define RX_DEBUG_DATA_STATE_MASK 0x000001E00 /* unload data state machine 741 + states: 742 + 0x0 = idle data 743 + 0x1 = header begin 744 + 0x2 = xfer header 745 + 0x3 = xfer header ld 746 + 0x4 = mtu begin 747 + 0x5 = xfer mtu 748 + 0x6 = xfer mtu ld 749 + 0x7 = jumbo begin 750 + 0x8 = xfer jumbo 751 + 0x9 = xfer jumbo ld 752 + 0xa = reas begin 753 + 0xb = xfer reas 754 + 0xc = flush tag 755 + 0xd = xfer reas ld 756 + 0xe = error 757 + 0xf = bubble idle */ 758 + #define RX_DEBUG_DESC_STATE_MASK 0x0001E000 /* unload desc state machine 759 + states: 760 + 0x0 = idle desc 761 + 0x1 = wait ack 762 + 0x9 = wait ack 2 763 + 0x2 = fetch desc 1 764 + 0xa = fetch desc 2 765 + 0x3 = load ptrs 766 + 0x4 = wait dma 767 + 0x5 = wait ack batch 768 + 0x6 = post batch 769 + 0x7 = xfr done */ 770 + #define RX_DEBUG_INTR_READ_PTR_MASK 0x30000000 /* interrupt read ptr of the 771 + interrupt queue */ 772 + #define RX_DEBUG_INTR_WRITE_PTR_MASK 0xC0000000 /* interrupt write pointer 773 + of the interrupt queue */ 774 + 775 + /* flow control frames are emmitted using two PAUSE thresholds: 776 + * XOFF PAUSE uses pause time value pre-programmed in the Send PAUSE MAC reg 777 + * XON PAUSE uses a pause time of 0. granularity of threshold is 64bytes. 778 + * PAUSE thresholds defined in terms of FIFO occupancy and may be translated 779 + * into FIFO vacancy using RX_FIFO_SIZE. setting ON will trigger XON frames 780 + * when FIFO reaches 0. OFF threshold should not be > size of RX FIFO. max 781 + * value is is 0x6F. 782 + * DEFAULT: 0x00078 783 + */ 784 + #define REG_RX_PAUSE_THRESH 0x4020 /* RX pause thresholds */ 785 + #define RX_PAUSE_THRESH_QUANTUM 64 786 + #define RX_PAUSE_THRESH_OFF_MASK 0x000001FF /* XOFF PAUSE emitted when 787 + RX FIFO occupancy > 788 + value*64B */ 789 + #define RX_PAUSE_THRESH_OFF_SHIFT 0 790 + #define RX_PAUSE_THRESH_ON_MASK 0x001FF000 /* XON PAUSE emitted after 791 + emitting XOFF PAUSE when RX 792 + FIFO occupancy falls below 793 + this value*64B. must be 794 + < XOFF threshold. if = 795 + RX_FIFO_SIZE< XON frames are 796 + never emitted. */ 797 + #define RX_PAUSE_THRESH_ON_SHIFT 12 798 + 799 + /* 13-bit register used to control RX desc fetching and intr generation. if 4+ 800 + * valid RX descriptors are available, Cassini will read 4 at a time. 801 + * writing N means that all desc up to *but* excluding N are available. N must 802 + * be a multiple of 4 (N % 4 = 0). first desc should be cache-line aligned. 803 + * DEFAULT: 0 on reset 804 + */ 805 + #define REG_RX_KICK 0x4024 /* RX kick reg */ 806 + 807 + /* 8KB aligned 64-bit pointer to the base of the RX free/completion rings. 808 + * lower 13 bits of the low register are hard-wired to 0. 809 + */ 810 + #define REG_RX_DB_LOW 0x4028 /* RX descriptor ring 811 + base low */ 812 + #define REG_RX_DB_HI 0x402C /* RX descriptor ring 813 + base hi */ 814 + #define REG_RX_CB_LOW 0x4030 /* RX completion ring 815 + base low */ 816 + #define REG_RX_CB_HI 0x4034 /* RX completion ring 817 + base hi */ 818 + /* 13-bit register indicate desc used by cassini for receive frames. used 819 + * for diagnostic purposes. 820 + * DEFAULT: 0 on reset 821 + */ 822 + #define REG_RX_COMP 0x4038 /* (ro) RX completion */ 823 + 824 + /* HEAD and TAIL are used to control RX desc posting and interrupt 825 + * generation. hw moves the head register to pass ownership to sw. sw 826 + * moves the tail register to pass ownership back to hw. to give all 827 + * entries to hw, set TAIL = HEAD. if HEAD and TAIL indicate that no 828 + * more entries are available, DMA will pause and an interrupt will be 829 + * generated to indicate no more entries are available. sw can use 830 + * this interrupt to reduce the # of times it must update the 831 + * completion tail register. 832 + * DEFAULT: 0 on reset 833 + */ 834 + #define REG_RX_COMP_HEAD 0x403C /* RX completion head */ 835 + #define REG_RX_COMP_TAIL 0x4040 /* RX completion tail */ 836 + 837 + /* values used for receive interrupt blanking. loaded each time the ISR is read 838 + * DEFAULT: 0x00000000 839 + */ 840 + #define REG_RX_BLANK 0x4044 /* RX blanking register 841 + for ISR read */ 842 + #define RX_BLANK_INTR_PKT_MASK 0x000001FF /* RX_DONE intr asserted if 843 + this many sets of completion 844 + writebacks (up to 2 packets) 845 + occur since the last time 846 + the ISR was read. 0 = no 847 + packet blanking */ 848 + #define RX_BLANK_INTR_PKT_SHIFT 0 849 + #define RX_BLANK_INTR_TIME_MASK 0x3FFFF000 /* RX_DONE interrupt asserted 850 + if that many clocks were 851 + counted since last time the 852 + ISR was read. 853 + each count is 512 core 854 + clocks (125MHz). 0 = no 855 + time blanking */ 856 + #define RX_BLANK_INTR_TIME_SHIFT 12 857 + 858 + /* values used for interrupt generation based on threshold values of how 859 + * many free desc and completion entries are available for hw use. 860 + * DEFAULT: 0x00000000 861 + */ 862 + #define REG_RX_AE_THRESH 0x4048 /* RX almost empty 863 + thresholds */ 864 + #define RX_AE_THRESH_FREE_MASK 0x00001FFF /* RX_BUF_AE will be 865 + generated if # desc 866 + avail for hw use <= 867 + # */ 868 + #define RX_AE_THRESH_FREE_SHIFT 0 869 + #define RX_AE_THRESH_COMP_MASK 0x0FFFE000 /* RX_COMP_AE will be 870 + generated if # of 871 + completion entries 872 + avail for hw use <= 873 + # */ 874 + #define RX_AE_THRESH_COMP_SHIFT 13 875 + 876 + /* probabilities for random early drop (RED) thresholds on a FIFO threshold 877 + * basis. probability should increase when the FIFO level increases. control 878 + * packets are never dropped and not counted in stats. probability programmed 879 + * on a 12.5% granularity. e.g., 0x1 = 1/8 packets dropped. 880 + * DEFAULT: 0x00000000 881 + */ 882 + #define REG_RX_RED 0x404C /* RX random early detect enable */ 883 + #define RX_RED_4K_6K_FIFO_MASK 0x000000FF /* 4KB < FIFO thresh < 6KB */ 884 + #define RX_RED_6K_8K_FIFO_MASK 0x0000FF00 /* 6KB < FIFO thresh < 8KB */ 885 + #define RX_RED_8K_10K_FIFO_MASK 0x00FF0000 /* 8KB < FIFO thresh < 10KB */ 886 + #define RX_RED_10K_12K_FIFO_MASK 0xFF000000 /* 10KB < FIFO thresh < 12KB */ 887 + 888 + /* FIFO fullness levels for RX FIFO, RX control FIFO, and RX IPP FIFO. 889 + * RX control FIFO = # of packets in RX FIFO. 890 + * DEFAULT: 0x0 891 + */ 892 + #define REG_RX_FIFO_FULLNESS 0x4050 /* (ro) RX FIFO fullness */ 893 + #define RX_FIFO_FULLNESS_RX_FIFO_MASK 0x3FF80000 /* level w/ 8B granularity */ 894 + #define RX_FIFO_FULLNESS_IPP_FIFO_MASK 0x0007FF00 /* level w/ 8B granularity */ 895 + #define RX_FIFO_FULLNESS_RX_PKT_MASK 0x000000FF /* # packets in RX FIFO */ 896 + #define REG_RX_IPP_PACKET_COUNT 0x4054 /* RX IPP packet counter */ 897 + #define REG_RX_WORK_DMA_PTR_LOW 0x4058 /* RX working DMA ptr low */ 898 + #define REG_RX_WORK_DMA_PTR_HI 0x405C /* RX working DMA ptr 899 + high */ 900 + 901 + /* BIST testing ro RX FIFO, RX control FIFO, and RX IPP FIFO. only RX BIST 902 + * START/COMPLETE is writeable. START will clear when the BIST has completed 903 + * checking all 17 RAMS. 904 + * DEFAULT: 0bxxxx xxxxx xxxx xxxx xxxx x000 0000 0000 00x0 905 + */ 906 + #define REG_RX_BIST 0x4060 /* (ro) RX BIST */ 907 + #define RX_BIST_32A_PASS 0x80000000 /* RX FIFO 32A passed */ 908 + #define RX_BIST_33A_PASS 0x40000000 /* RX FIFO 33A passed */ 909 + #define RX_BIST_32B_PASS 0x20000000 /* RX FIFO 32B passed */ 910 + #define RX_BIST_33B_PASS 0x10000000 /* RX FIFO 33B passed */ 911 + #define RX_BIST_32C_PASS 0x08000000 /* RX FIFO 32C passed */ 912 + #define RX_BIST_33C_PASS 0x04000000 /* RX FIFO 33C passed */ 913 + #define RX_BIST_IPP_32A_PASS 0x02000000 /* RX IPP FIFO 33B passed */ 914 + #define RX_BIST_IPP_33A_PASS 0x01000000 /* RX IPP FIFO 33A passed */ 915 + #define RX_BIST_IPP_32B_PASS 0x00800000 /* RX IPP FIFO 32B passed */ 916 + #define RX_BIST_IPP_33B_PASS 0x00400000 /* RX IPP FIFO 33B passed */ 917 + #define RX_BIST_IPP_32C_PASS 0x00200000 /* RX IPP FIFO 32C passed */ 918 + #define RX_BIST_IPP_33C_PASS 0x00100000 /* RX IPP FIFO 33C passed */ 919 + #define RX_BIST_CTRL_32_PASS 0x00800000 /* RX CTRL FIFO 32 passed */ 920 + #define RX_BIST_CTRL_33_PASS 0x00400000 /* RX CTRL FIFO 33 passed */ 921 + #define RX_BIST_REAS_26A_PASS 0x00200000 /* RX Reas 26A passed */ 922 + #define RX_BIST_REAS_26B_PASS 0x00100000 /* RX Reas 26B passed */ 923 + #define RX_BIST_REAS_27_PASS 0x00080000 /* RX Reas 27 passed */ 924 + #define RX_BIST_STATE_MASK 0x00078000 /* BIST state machine */ 925 + #define RX_BIST_SUMMARY 0x00000002 /* when BIST complete, 926 + summary pass bit 927 + contains AND of BIST 928 + results of all 16 929 + RAMS */ 930 + #define RX_BIST_START 0x00000001 /* write 1 to start 931 + BIST. self clears 932 + on completion. */ 933 + 934 + /* next location in RX CTRL FIFO that will be loaded w/ data from RX IPP/read 935 + * from to retrieve packet control info. 936 + * DEFAULT: 0 937 + */ 938 + #define REG_RX_CTRL_FIFO_WRITE_PTR 0x4064 /* (ro) RX control FIFO 939 + write ptr */ 940 + #define REG_RX_CTRL_FIFO_READ_PTR 0x4068 /* (ro) RX control FIFO read 941 + ptr */ 942 + 943 + /* receive interrupt blanking. loaded each time interrupt alias register is 944 + * read. 945 + * DEFAULT: 0x0 946 + */ 947 + #define REG_RX_BLANK_ALIAS_READ 0x406C /* RX blanking register for 948 + alias read */ 949 + #define RX_BAR_INTR_PACKET_MASK 0x000001FF /* assert RX_DONE if # 950 + completion writebacks 951 + > # since last ISR 952 + read. 0 = no 953 + blanking. up to 2 954 + packets per 955 + completion wb. */ 956 + #define RX_BAR_INTR_TIME_MASK 0x3FFFF000 /* assert RX_DONE if # 957 + clocks > # since last 958 + ISR read. each count 959 + is 512 core clocks 960 + (125MHz). 0 = no 961 + blanking. */ 962 + 963 + /* diagnostic access to RX FIFO. 32 LSB accessed via DATA_LOW. 32 MSB accessed 964 + * via DATA_HI_T0 or DATA_HI_T1. TAG reads the tag bit. writing HI_T0 965 + * will unset the tag bit while writing HI_T1 will set the tag bit. to reset 966 + * to normal operation after diagnostics, write to address location 0x0. 967 + * RX_DMA_EN bit must be set to 0x0 for RX FIFO PIO access. DATA_HI should 968 + * be the last write access of a write sequence. 969 + * DEFAULT: undefined 970 + */ 971 + #define REG_RX_FIFO_ADDR 0x4080 /* RX FIFO address */ 972 + #define REG_RX_FIFO_TAG 0x4084 /* RX FIFO tag */ 973 + #define REG_RX_FIFO_DATA_LOW 0x4088 /* RX FIFO data low */ 974 + #define REG_RX_FIFO_DATA_HI_T0 0x408C /* RX FIFO data high T0 */ 975 + #define REG_RX_FIFO_DATA_HI_T1 0x4090 /* RX FIFO data high T1 */ 976 + 977 + /* diagnostic assess to RX CTRL FIFO. 8-bit FIFO_ADDR holds address of 978 + * 81 bit control entry and 6 bit flow id. LOW and MID are both 32-bit 979 + * accesses. HI is 7-bits with 6-bit flow id and 1 bit control 980 + * word. RX_DMA_EN must be 0 for RX CTRL FIFO PIO access. DATA_HI 981 + * should be last write access of the write sequence. 982 + * DEFAULT: undefined 983 + */ 984 + #define REG_RX_CTRL_FIFO_ADDR 0x4094 /* RX Control FIFO and 985 + Batching FIFO addr */ 986 + #define REG_RX_CTRL_FIFO_DATA_LOW 0x4098 /* RX Control FIFO data 987 + low */ 988 + #define REG_RX_CTRL_FIFO_DATA_MID 0x409C /* RX Control FIFO data 989 + mid */ 990 + #define REG_RX_CTRL_FIFO_DATA_HI 0x4100 /* RX Control FIFO data 991 + hi and flow id */ 992 + #define RX_CTRL_FIFO_DATA_HI_CTRL 0x0001 /* upper bit of ctrl word */ 993 + #define RX_CTRL_FIFO_DATA_HI_FLOW_MASK 0x007E /* flow id */ 994 + 995 + /* diagnostic access to RX IPP FIFO. same semantics as RX_FIFO. 996 + * DEFAULT: undefined 997 + */ 998 + #define REG_RX_IPP_FIFO_ADDR 0x4104 /* RX IPP FIFO address */ 999 + #define REG_RX_IPP_FIFO_TAG 0x4108 /* RX IPP FIFO tag */ 1000 + #define REG_RX_IPP_FIFO_DATA_LOW 0x410C /* RX IPP FIFO data low */ 1001 + #define REG_RX_IPP_FIFO_DATA_HI_T0 0x4110 /* RX IPP FIFO data high 1002 + T0 */ 1003 + #define REG_RX_IPP_FIFO_DATA_HI_T1 0x4114 /* RX IPP FIFO data high 1004 + T1 */ 1005 + 1006 + /* 64-bit pointer to receive data buffer in host memory used for headers and 1007 + * small packets. MSB in high register. loaded by DMA state machine and 1008 + * increments as DMA writes receive data. only 50 LSB are incremented. top 1009 + * 13 bits taken from RX descriptor. 1010 + * DEFAULT: undefined 1011 + */ 1012 + #define REG_RX_HEADER_PAGE_PTR_LOW 0x4118 /* (ro) RX header page ptr 1013 + low */ 1014 + #define REG_RX_HEADER_PAGE_PTR_HI 0x411C /* (ro) RX header page ptr 1015 + high */ 1016 + #define REG_RX_MTU_PAGE_PTR_LOW 0x4120 /* (ro) RX MTU page pointer 1017 + low */ 1018 + #define REG_RX_MTU_PAGE_PTR_HI 0x4124 /* (ro) RX MTU page pointer 1019 + high */ 1020 + 1021 + /* PIO diagnostic access to RX reassembly DMA Table RAM. 6-bit register holds 1022 + * one of 64 79-bit locations in the RX Reassembly DMA table and the addr of 1023 + * one of the 64 byte locations in the Batching table. LOW holds 32 LSB. 1024 + * MID holds the next 32 LSB. HIGH holds the 15 MSB. RX_DMA_EN must be set 1025 + * to 0 for PIO access. DATA_HIGH should be last write of write sequence. 1026 + * layout: 1027 + * reassmbl ptr [78:15] | reassmbl index [14:1] | reassmbl entry valid [0] 1028 + * DEFAULT: undefined 1029 + */ 1030 + #define REG_RX_TABLE_ADDR 0x4128 /* RX reassembly DMA table 1031 + address */ 1032 + #define RX_TABLE_ADDR_MASK 0x0000003F /* address mask */ 1033 + 1034 + #define REG_RX_TABLE_DATA_LOW 0x412C /* RX reassembly DMA table 1035 + data low */ 1036 + #define REG_RX_TABLE_DATA_MID 0x4130 /* RX reassembly DMA table 1037 + data mid */ 1038 + #define REG_RX_TABLE_DATA_HI 0x4134 /* RX reassembly DMA table 1039 + data high */ 1040 + 1041 + /* cassini+ only */ 1042 + /* 8KB aligned 64-bit pointer to base of RX rings. lower 13 bits hardwired to 1043 + * 0. same semantics as primary desc/complete rings. 1044 + */ 1045 + #define REG_PLUS_RX_DB1_LOW 0x4200 /* RX descriptor ring 1046 + 2 base low */ 1047 + #define REG_PLUS_RX_DB1_HI 0x4204 /* RX descriptor ring 1048 + 2 base high */ 1049 + #define REG_PLUS_RX_CB1_LOW 0x4208 /* RX completion ring 1050 + 2 base low. 4 total */ 1051 + #define REG_PLUS_RX_CB1_HI 0x420C /* RX completion ring 1052 + 2 base high. 4 total */ 1053 + #define REG_PLUS_RX_CBN_LOW(x) (REG_PLUS_RX_CB1_LOW + 8*((x) - 1)) 1054 + #define REG_PLUS_RX_CBN_HI(x) (REG_PLUS_RX_CB1_HI + 8*((x) - 1)) 1055 + #define REG_PLUS_RX_KICK1 0x4220 /* RX Kick 2 register */ 1056 + #define REG_PLUS_RX_COMP1 0x4224 /* (ro) RX completion 2 1057 + reg */ 1058 + #define REG_PLUS_RX_COMP1_HEAD 0x4228 /* (ro) RX completion 2 1059 + head reg. 4 total. */ 1060 + #define REG_PLUS_RX_COMP1_TAIL 0x422C /* RX completion 2 1061 + tail reg. 4 total. */ 1062 + #define REG_PLUS_RX_COMPN_HEAD(x) (REG_PLUS_RX_COMP1_HEAD + 8*((x) - 1)) 1063 + #define REG_PLUS_RX_COMPN_TAIL(x) (REG_PLUS_RX_COMP1_TAIL + 8*((x) - 1)) 1064 + #define REG_PLUS_RX_AE1_THRESH 0x4240 /* RX almost empty 2 1065 + thresholds */ 1066 + #define RX_AE1_THRESH_FREE_MASK RX_AE_THRESH_FREE_MASK 1067 + #define RX_AE1_THRESH_FREE_SHIFT RX_AE_THRESH_FREE_SHIFT 1068 + 1069 + /** header parser registers **/ 1070 + 1071 + /* RX parser configuration register. 1072 + * DEFAULT: 0x1651004 1073 + */ 1074 + #define REG_HP_CFG 0x4140 /* header parser 1075 + configuration reg */ 1076 + #define HP_CFG_PARSE_EN 0x00000001 /* enab header parsing */ 1077 + #define HP_CFG_NUM_CPU_MASK 0x000000FC /* # processors 1078 + 0 = 64. 0x3f = 63 */ 1079 + #define HP_CFG_NUM_CPU_SHIFT 2 1080 + #define HP_CFG_SYN_INC_MASK 0x00000100 /* SYN bit won't increment 1081 + TCP seq # by one when 1082 + stored in FDBM */ 1083 + #define HP_CFG_TCP_THRESH_MASK 0x000FFE00 /* # bytes of TCP data 1084 + needed to be considered 1085 + for reassembly */ 1086 + #define HP_CFG_TCP_THRESH_SHIFT 9 1087 + 1088 + /* access to RX Instruction RAM. 5-bit register/counter holds addr 1089 + * of 39 bit entry to be read/written. 32 LSB in _DATA_LOW. 7 MSB in _DATA_HI. 1090 + * RX_DMA_EN must be 0 for RX instr PIO access. DATA_HI should be last access 1091 + * of sequence. 1092 + * DEFAULT: undefined 1093 + */ 1094 + #define REG_HP_INSTR_RAM_ADDR 0x4144 /* HP instruction RAM 1095 + address */ 1096 + #define HP_INSTR_RAM_ADDR_MASK 0x01F /* 5-bit mask */ 1097 + #define REG_HP_INSTR_RAM_DATA_LOW 0x4148 /* HP instruction RAM 1098 + data low */ 1099 + #define HP_INSTR_RAM_LOW_OUTMASK_MASK 0x0000FFFF 1100 + #define HP_INSTR_RAM_LOW_OUTMASK_SHIFT 0 1101 + #define HP_INSTR_RAM_LOW_OUTSHIFT_MASK 0x000F0000 1102 + #define HP_INSTR_RAM_LOW_OUTSHIFT_SHIFT 16 1103 + #define HP_INSTR_RAM_LOW_OUTEN_MASK 0x00300000 1104 + #define HP_INSTR_RAM_LOW_OUTEN_SHIFT 20 1105 + #define HP_INSTR_RAM_LOW_OUTARG_MASK 0xFFC00000 1106 + #define HP_INSTR_RAM_LOW_OUTARG_SHIFT 22 1107 + #define REG_HP_INSTR_RAM_DATA_MID 0x414C /* HP instruction RAM 1108 + data mid */ 1109 + #define HP_INSTR_RAM_MID_OUTARG_MASK 0x00000003 1110 + #define HP_INSTR_RAM_MID_OUTARG_SHIFT 0 1111 + #define HP_INSTR_RAM_MID_OUTOP_MASK 0x0000003C 1112 + #define HP_INSTR_RAM_MID_OUTOP_SHIFT 2 1113 + #define HP_INSTR_RAM_MID_FNEXT_MASK 0x000007C0 1114 + #define HP_INSTR_RAM_MID_FNEXT_SHIFT 6 1115 + #define HP_INSTR_RAM_MID_FOFF_MASK 0x0003F800 1116 + #define HP_INSTR_RAM_MID_FOFF_SHIFT 11 1117 + #define HP_INSTR_RAM_MID_SNEXT_MASK 0x007C0000 1118 + #define HP_INSTR_RAM_MID_SNEXT_SHIFT 18 1119 + #define HP_INSTR_RAM_MID_SOFF_MASK 0x3F800000 1120 + #define HP_INSTR_RAM_MID_SOFF_SHIFT 23 1121 + #define HP_INSTR_RAM_MID_OP_MASK 0xC0000000 1122 + #define HP_INSTR_RAM_MID_OP_SHIFT 30 1123 + #define REG_HP_INSTR_RAM_DATA_HI 0x4150 /* HP instruction RAM 1124 + data high */ 1125 + #define HP_INSTR_RAM_HI_VAL_MASK 0x0000FFFF 1126 + #define HP_INSTR_RAM_HI_VAL_SHIFT 0 1127 + #define HP_INSTR_RAM_HI_MASK_MASK 0xFFFF0000 1128 + #define HP_INSTR_RAM_HI_MASK_SHIFT 16 1129 + 1130 + /* PIO access into RX Header parser data RAM and flow database. 1131 + * 11-bit register. Data fills the LSB portion of bus if less than 32 bits. 1132 + * DATA_RAM: write RAM_FDB_DATA with index to access DATA_RAM. 1133 + * RAM bytes = 4*(x - 1) + [3:0]. e.g., 0 -> [3:0], 31 -> [123:120] 1134 + * FLOWDB: write DATA_RAM_FDB register and then read/write FDB1-12 to access 1135 + * flow database. 1136 + * RX_DMA_EN must be 0 for RX parser RAM PIO access. RX Parser RAM data reg 1137 + * should be the last write access of the write sequence. 1138 + * DEFAULT: undefined 1139 + */ 1140 + #define REG_HP_DATA_RAM_FDB_ADDR 0x4154 /* HP data and FDB 1141 + RAM address */ 1142 + #define HP_DATA_RAM_FDB_DATA_MASK 0x001F /* select 1 of 86 byte 1143 + locations in header 1144 + parser data ram to 1145 + read/write */ 1146 + #define HP_DATA_RAM_FDB_FDB_MASK 0x3F00 /* 1 of 64 353-bit locations 1147 + in the flow database */ 1148 + #define REG_HP_DATA_RAM_DATA 0x4158 /* HP data RAM data */ 1149 + 1150 + /* HP flow database registers: 1 - 12, 0x415C - 0x4188, 4 8-bit bytes 1151 + * FLOW_DB(1) = IP_SA[127:96], FLOW_DB(2) = IP_SA[95:64] 1152 + * FLOW_DB(3) = IP_SA[63:32], FLOW_DB(4) = IP_SA[31:0] 1153 + * FLOW_DB(5) = IP_DA[127:96], FLOW_DB(6) = IP_DA[95:64] 1154 + * FLOW_DB(7) = IP_DA[63:32], FLOW_DB(8) = IP_DA[31:0] 1155 + * FLOW_DB(9) = {TCP_SP[15:0],TCP_DP[15:0]} 1156 + * FLOW_DB(10) = bit 0 has value for flow valid 1157 + * FLOW_DB(11) = TCP_SEQ[63:32], FLOW_DB(12) = TCP_SEQ[31:0] 1158 + */ 1159 + #define REG_HP_FLOW_DB0 0x415C /* HP flow database 1 reg */ 1160 + #define REG_HP_FLOW_DBN(x) (REG_HP_FLOW_DB0 + (x)*4) 1161 + 1162 + /* diagnostics for RX Header Parser block. 1163 + * ASUN: the header parser state machine register is used for diagnostics 1164 + * purposes. however, the spec doesn't have any details on it. 1165 + */ 1166 + #define REG_HP_STATE_MACHINE 0x418C /* (ro) HP state machine */ 1167 + #define REG_HP_STATUS0 0x4190 /* (ro) HP status 1 */ 1168 + #define HP_STATUS0_SAP_MASK 0xFFFF0000 /* SAP */ 1169 + #define HP_STATUS0_L3_OFF_MASK 0x0000FE00 /* L3 offset */ 1170 + #define HP_STATUS0_LB_CPUNUM_MASK 0x000001F8 /* load balancing CPU 1171 + number */ 1172 + #define HP_STATUS0_HRP_OPCODE_MASK 0x00000007 /* HRP opcode */ 1173 + 1174 + #define REG_HP_STATUS1 0x4194 /* (ro) HP status 2 */ 1175 + #define HP_STATUS1_ACCUR2_MASK 0xE0000000 /* accu R2[6:4] */ 1176 + #define HP_STATUS1_FLOWID_MASK 0x1F800000 /* flow id */ 1177 + #define HP_STATUS1_TCP_OFF_MASK 0x007F0000 /* tcp payload offset */ 1178 + #define HP_STATUS1_TCP_SIZE_MASK 0x0000FFFF /* tcp payload size */ 1179 + 1180 + #define REG_HP_STATUS2 0x4198 /* (ro) HP status 3 */ 1181 + #define HP_STATUS2_ACCUR2_MASK 0xF0000000 /* accu R2[3:0] */ 1182 + #define HP_STATUS2_CSUM_OFF_MASK 0x07F00000 /* checksum start 1183 + start offset */ 1184 + #define HP_STATUS2_ACCUR1_MASK 0x000FE000 /* accu R1 */ 1185 + #define HP_STATUS2_FORCE_DROP 0x00001000 /* force drop */ 1186 + #define HP_STATUS2_BWO_REASSM 0x00000800 /* batching w/o 1187 + reassembly */ 1188 + #define HP_STATUS2_JH_SPLIT_EN 0x00000400 /* jumbo header split 1189 + enable */ 1190 + #define HP_STATUS2_FORCE_TCP_NOCHECK 0x00000200 /* force tcp no payload 1191 + check */ 1192 + #define HP_STATUS2_DATA_MASK_ZERO 0x00000100 /* mask of data length 1193 + equal to zero */ 1194 + #define HP_STATUS2_FORCE_TCP_CHECK 0x00000080 /* force tcp payload 1195 + chk */ 1196 + #define HP_STATUS2_MASK_TCP_THRESH 0x00000040 /* mask of payload 1197 + threshold */ 1198 + #define HP_STATUS2_NO_ASSIST 0x00000020 /* no assist */ 1199 + #define HP_STATUS2_CTRL_PACKET_FLAG 0x00000010 /* control packet flag */ 1200 + #define HP_STATUS2_TCP_FLAG_CHECK 0x00000008 /* tcp flag check */ 1201 + #define HP_STATUS2_SYN_FLAG 0x00000004 /* syn flag */ 1202 + #define HP_STATUS2_TCP_CHECK 0x00000002 /* tcp payload chk */ 1203 + #define HP_STATUS2_TCP_NOCHECK 0x00000001 /* tcp no payload chk */ 1204 + 1205 + /* BIST for header parser(HP) and flow database memories (FDBM). set _START 1206 + * to start BIST. controller clears _START on completion. _START can also 1207 + * be cleared to force termination of BIST. a bit set indicates that that 1208 + * memory passed its BIST. 1209 + */ 1210 + #define REG_HP_RAM_BIST 0x419C /* HP RAM BIST reg */ 1211 + #define HP_RAM_BIST_HP_DATA_PASS 0x80000000 /* HP data ram */ 1212 + #define HP_RAM_BIST_HP_INSTR0_PASS 0x40000000 /* HP instr ram 0 */ 1213 + #define HP_RAM_BIST_HP_INSTR1_PASS 0x20000000 /* HP instr ram 1 */ 1214 + #define HP_RAM_BIST_HP_INSTR2_PASS 0x10000000 /* HP instr ram 2 */ 1215 + #define HP_RAM_BIST_FDBM_AGE0_PASS 0x08000000 /* FDBM aging RAM0 */ 1216 + #define HP_RAM_BIST_FDBM_AGE1_PASS 0x04000000 /* FDBM aging RAM1 */ 1217 + #define HP_RAM_BIST_FDBM_FLOWID00_PASS 0x02000000 /* FDBM flowid RAM0 1218 + bank 0 */ 1219 + #define HP_RAM_BIST_FDBM_FLOWID10_PASS 0x01000000 /* FDBM flowid RAM1 1220 + bank 0 */ 1221 + #define HP_RAM_BIST_FDBM_FLOWID20_PASS 0x00800000 /* FDBM flowid RAM2 1222 + bank 0 */ 1223 + #define HP_RAM_BIST_FDBM_FLOWID30_PASS 0x00400000 /* FDBM flowid RAM3 1224 + bank 0 */ 1225 + #define HP_RAM_BIST_FDBM_FLOWID01_PASS 0x00200000 /* FDBM flowid RAM0 1226 + bank 1 */ 1227 + #define HP_RAM_BIST_FDBM_FLOWID11_PASS 0x00100000 /* FDBM flowid RAM1 1228 + bank 2 */ 1229 + #define HP_RAM_BIST_FDBM_FLOWID21_PASS 0x00080000 /* FDBM flowid RAM2 1230 + bank 1 */ 1231 + #define HP_RAM_BIST_FDBM_FLOWID31_PASS 0x00040000 /* FDBM flowid RAM3 1232 + bank 1 */ 1233 + #define HP_RAM_BIST_FDBM_TCPSEQ_PASS 0x00020000 /* FDBM tcp sequence 1234 + RAM */ 1235 + #define HP_RAM_BIST_SUMMARY 0x00000002 /* all BIST tests */ 1236 + #define HP_RAM_BIST_START 0x00000001 /* start/stop BIST */ 1237 + 1238 + 1239 + /** MAC registers. **/ 1240 + /* reset bits are set using a PIO write and self-cleared after the command 1241 + * execution has completed. 1242 + */ 1243 + #define REG_MAC_TX_RESET 0x6000 /* TX MAC software reset 1244 + command (default: 0x0) */ 1245 + #define REG_MAC_RX_RESET 0x6004 /* RX MAC software reset 1246 + command (default: 0x0) */ 1247 + /* execute a pause flow control frame transmission 1248 + DEFAULT: 0x0XXXX */ 1249 + #define REG_MAC_SEND_PAUSE 0x6008 /* send pause command reg */ 1250 + #define MAC_SEND_PAUSE_TIME_MASK 0x0000FFFF /* value of pause time 1251 + to be sent on network 1252 + in units of slot 1253 + times */ 1254 + #define MAC_SEND_PAUSE_SEND 0x00010000 /* send pause flow ctrl 1255 + frame on network */ 1256 + 1257 + /* bit set indicates that event occurred. auto-cleared when status register 1258 + * is read and have corresponding mask bits in mask register. events will 1259 + * trigger an interrupt if the corresponding mask bit is 0. 1260 + * status register default: 0x00000000 1261 + * mask register default = 0xFFFFFFFF on reset 1262 + */ 1263 + #define REG_MAC_TX_STATUS 0x6010 /* TX MAC status reg */ 1264 + #define MAC_TX_FRAME_XMIT 0x0001 /* successful frame 1265 + transmision */ 1266 + #define MAC_TX_UNDERRUN 0x0002 /* terminated frame 1267 + transmission due to 1268 + data starvation in the 1269 + xmit data path */ 1270 + #define MAC_TX_MAX_PACKET_ERR 0x0004 /* frame exceeds max allowed 1271 + length passed to TX MAC 1272 + by the DMA engine */ 1273 + #define MAC_TX_COLL_NORMAL 0x0008 /* rollover of the normal 1274 + collision counter */ 1275 + #define MAC_TX_COLL_EXCESS 0x0010 /* rollover of the excessive 1276 + collision counter */ 1277 + #define MAC_TX_COLL_LATE 0x0020 /* rollover of the late 1278 + collision counter */ 1279 + #define MAC_TX_COLL_FIRST 0x0040 /* rollover of the first 1280 + collision counter */ 1281 + #define MAC_TX_DEFER_TIMER 0x0080 /* rollover of the defer 1282 + timer */ 1283 + #define MAC_TX_PEAK_ATTEMPTS 0x0100 /* rollover of the peak 1284 + attempts counter */ 1285 + 1286 + #define REG_MAC_RX_STATUS 0x6014 /* RX MAC status reg */ 1287 + #define MAC_RX_FRAME_RECV 0x0001 /* successful receipt of 1288 + a frame */ 1289 + #define MAC_RX_OVERFLOW 0x0002 /* dropped frame due to 1290 + RX FIFO overflow */ 1291 + #define MAC_RX_FRAME_COUNT 0x0004 /* rollover of receive frame 1292 + counter */ 1293 + #define MAC_RX_ALIGN_ERR 0x0008 /* rollover of alignment 1294 + error counter */ 1295 + #define MAC_RX_CRC_ERR 0x0010 /* rollover of crc error 1296 + counter */ 1297 + #define MAC_RX_LEN_ERR 0x0020 /* rollover of length 1298 + error counter */ 1299 + #define MAC_RX_VIOL_ERR 0x0040 /* rollover of code 1300 + violation error */ 1301 + 1302 + /* DEFAULT: 0xXXXX0000 on reset */ 1303 + #define REG_MAC_CTRL_STATUS 0x6018 /* MAC control status reg */ 1304 + #define MAC_CTRL_PAUSE_RECEIVED 0x00000001 /* successful 1305 + reception of a 1306 + pause control 1307 + frame */ 1308 + #define MAC_CTRL_PAUSE_STATE 0x00000002 /* MAC has made a 1309 + transition from 1310 + "not paused" to 1311 + "paused" */ 1312 + #define MAC_CTRL_NOPAUSE_STATE 0x00000004 /* MAC has made a 1313 + transition from 1314 + "paused" to "not 1315 + paused" */ 1316 + #define MAC_CTRL_PAUSE_TIME_MASK 0xFFFF0000 /* value of pause time 1317 + operand that was 1318 + received in the last 1319 + pause flow control 1320 + frame */ 1321 + 1322 + /* layout identical to TX MAC[8:0] */ 1323 + #define REG_MAC_TX_MASK 0x6020 /* TX MAC mask reg */ 1324 + /* layout identical to RX MAC[6:0] */ 1325 + #define REG_MAC_RX_MASK 0x6024 /* RX MAC mask reg */ 1326 + /* layout identical to CTRL MAC[2:0] */ 1327 + #define REG_MAC_CTRL_MASK 0x6028 /* MAC control mask reg */ 1328 + 1329 + /* to ensure proper operation, CFG_EN must be cleared to 0 and a delay 1330 + * imposed before writes to other bits in the TX_MAC_CFG register or any of 1331 + * the MAC parameters is performed. delay dependent upon time required to 1332 + * transmit a maximum size frame (= MAC_FRAMESIZE_MAX*8/Mbps). e.g., 1333 + * the delay for a 1518-byte frame on a 100Mbps network is 125us. 1334 + * alternatively, just poll TX_CFG_EN until it reads back as 0. 1335 + * NOTE: on half-duplex 1Gbps, TX_CFG_CARRIER_EXTEND and 1336 + * RX_CFG_CARRIER_EXTEND should be set and the SLOT_TIME register should 1337 + * be 0x200 (slot time of 512 bytes) 1338 + */ 1339 + #define REG_MAC_TX_CFG 0x6030 /* TX MAC config reg */ 1340 + #define MAC_TX_CFG_EN 0x0001 /* enable TX MAC. 0 will 1341 + force TXMAC state 1342 + machine to remain in 1343 + idle state or to 1344 + transition to idle state 1345 + on completion of an 1346 + ongoing packet. */ 1347 + #define MAC_TX_CFG_IGNORE_CARRIER 0x0002 /* disable CSMA/CD deferral 1348 + process. set to 1 when 1349 + full duplex and 0 when 1350 + half duplex */ 1351 + #define MAC_TX_CFG_IGNORE_COLL 0x0004 /* disable CSMA/CD backoff 1352 + algorithm. set to 1 when 1353 + full duplex and 0 when 1354 + half duplex */ 1355 + #define MAC_TX_CFG_IPG_EN 0x0008 /* enable extension of the 1356 + Rx-to-TX IPG. after 1357 + receiving a frame, TX 1358 + MAC will reset its 1359 + deferral process to 1360 + carrier sense for the 1361 + amount of time = IPG0 + 1362 + IPG1 and commit to 1363 + transmission for time 1364 + specified in IPG2. when 1365 + 0 or when xmitting frames 1366 + back-to-pack (Tx-to-Tx 1367 + IPG), TX MAC ignores 1368 + IPG0 and will only use 1369 + IPG1 for deferral time. 1370 + IPG2 still used. */ 1371 + #define MAC_TX_CFG_NEVER_GIVE_UP_EN 0x0010 /* TX MAC will not easily 1372 + give up on frame 1373 + xmission. if backoff 1374 + algorithm reaches the 1375 + ATTEMPT_LIMIT, it will 1376 + clear attempts counter 1377 + and continue trying to 1378 + send the frame as 1379 + specified by 1380 + GIVE_UP_LIM. when 0, 1381 + TX MAC will execute 1382 + standard CSMA/CD prot. */ 1383 + #define MAC_TX_CFG_NEVER_GIVE_UP_LIM 0x0020 /* when set, TX MAC will 1384 + continue to try to xmit 1385 + until successful. when 1386 + 0, TX MAC will continue 1387 + to try xmitting until 1388 + successful or backoff 1389 + algorithm reaches 1390 + ATTEMPT_LIMIT*16 */ 1391 + #define MAC_TX_CFG_NO_BACKOFF 0x0040 /* modify CSMA/CD to disable 1392 + backoff algorithm. TX 1393 + MAC will not back off 1394 + after a xmission attempt 1395 + that resulted in a 1396 + collision. */ 1397 + #define MAC_TX_CFG_SLOW_DOWN 0x0080 /* modify CSMA/CD so that 1398 + deferral process is reset 1399 + in response to carrier 1400 + sense during the entire 1401 + duration of IPG. TX MAC 1402 + will only commit to frame 1403 + xmission after frame 1404 + xmission has actually 1405 + begun. */ 1406 + #define MAC_TX_CFG_NO_FCS 0x0100 /* TX MAC will not generate 1407 + CRC for all xmitted 1408 + packets. when clear, CRC 1409 + generation is dependent 1410 + upon NO_CRC bit in the 1411 + xmit control word from 1412 + TX DMA */ 1413 + #define MAC_TX_CFG_CARRIER_EXTEND 0x0200 /* enables xmit part of the 1414 + carrier extension 1415 + feature. this allows for 1416 + longer collision domains 1417 + by extending the carrier 1418 + and collision window 1419 + from the end of FCS until 1420 + the end of the slot time 1421 + if necessary. Required 1422 + for half-duplex at 1Gbps, 1423 + clear otherwise. */ 1424 + 1425 + /* when CRC is not stripped, reassembly packets will not contain the CRC. 1426 + * these will be stripped by HRP because it reassembles layer 4 data, and the 1427 + * CRC is layer 2. however, non-reassembly packets will still contain the CRC 1428 + * when passed to the host. to ensure proper operation, need to wait 3.2ms 1429 + * after clearing RX_CFG_EN before writing to any other RX MAC registers 1430 + * or other MAC parameters. alternatively, poll RX_CFG_EN until it clears 1431 + * to 0. similary, HASH_FILTER_EN and ADDR_FILTER_EN have the same 1432 + * restrictions as CFG_EN. 1433 + */ 1434 + #define REG_MAC_RX_CFG 0x6034 /* RX MAC config reg */ 1435 + #define MAC_RX_CFG_EN 0x0001 /* enable RX MAC */ 1436 + #define MAC_RX_CFG_STRIP_PAD 0x0002 /* always program to 0. 1437 + feature not supported */ 1438 + #define MAC_RX_CFG_STRIP_FCS 0x0004 /* RX MAC will strip the 1439 + last 4 bytes of a 1440 + received frame. */ 1441 + #define MAC_RX_CFG_PROMISC_EN 0x0008 /* promiscuous mode */ 1442 + #define MAC_RX_CFG_PROMISC_GROUP_EN 0x0010 /* accept all valid 1443 + multicast frames (group 1444 + bit in DA field set) */ 1445 + #define MAC_RX_CFG_HASH_FILTER_EN 0x0020 /* use hash table to filter 1446 + multicast addresses */ 1447 + #define MAC_RX_CFG_ADDR_FILTER_EN 0x0040 /* cause RX MAC to use 1448 + address filtering regs 1449 + to filter both unicast 1450 + and multicast 1451 + addresses */ 1452 + #define MAC_RX_CFG_DISABLE_DISCARD 0x0080 /* pass errored frames to 1453 + RX DMA by setting BAD 1454 + bit but not Abort bit 1455 + in the status. CRC, 1456 + framing, and length errs 1457 + will not increment 1458 + error counters. frames 1459 + which don't match dest 1460 + addr will be passed up 1461 + w/ BAD bit set. */ 1462 + #define MAC_RX_CFG_CARRIER_EXTEND 0x0100 /* enable reception of 1463 + packet bursts generated 1464 + by carrier extension 1465 + with packet bursting 1466 + senders. only applies 1467 + to half-duplex 1Gbps */ 1468 + 1469 + /* DEFAULT: 0x0 */ 1470 + #define REG_MAC_CTRL_CFG 0x6038 /* MAC control config reg */ 1471 + #define MAC_CTRL_CFG_SEND_PAUSE_EN 0x0001 /* respond to requests for 1472 + sending pause flow ctrl 1473 + frames */ 1474 + #define MAC_CTRL_CFG_RECV_PAUSE_EN 0x0002 /* respond to received 1475 + pause flow ctrl frames */ 1476 + #define MAC_CTRL_CFG_PASS_CTRL 0x0004 /* pass valid MAC ctrl 1477 + packets to RX DMA */ 1478 + 1479 + /* to ensure proper operation, a global initialization sequence should be 1480 + * performed when a loopback config is entered or exited. if programmed after 1481 + * a hw or global sw reset, RX/TX MAC software reset and initialization 1482 + * should be done to ensure stable clocking. 1483 + * DEFAULT: 0x0 1484 + */ 1485 + #define REG_MAC_XIF_CFG 0x603C /* XIF config reg */ 1486 + #define MAC_XIF_TX_MII_OUTPUT_EN 0x0001 /* enable output drivers 1487 + on MII xmit bus */ 1488 + #define MAC_XIF_MII_INT_LOOPBACK 0x0002 /* loopback GMII xmit data 1489 + path to GMII recv data 1490 + path. phy mode register 1491 + clock selection must be 1492 + set to GMII mode and 1493 + GMII_MODE should be set 1494 + to 1. in loopback mode, 1495 + REFCLK will drive the 1496 + entire mac core. 0 for 1497 + normal operation. */ 1498 + #define MAC_XIF_DISABLE_ECHO 0x0004 /* disables receive data 1499 + path during packet 1500 + xmission. clear to 0 1501 + in any full duplex mode, 1502 + in any loopback mode, 1503 + or in half-duplex SERDES 1504 + or SLINK modes. set when 1505 + in half-duplex when 1506 + using external phy. */ 1507 + #define MAC_XIF_GMII_MODE 0x0008 /* MAC operates with GMII 1508 + clocks and datapath */ 1509 + #define MAC_XIF_MII_BUFFER_OUTPUT_EN 0x0010 /* MII_BUF_EN pin. enable 1510 + external tristate buffer 1511 + on the MII receive 1512 + bus. */ 1513 + #define MAC_XIF_LINK_LED 0x0020 /* LINKLED# active (low) */ 1514 + #define MAC_XIF_FDPLX_LED 0x0040 /* FDPLXLED# active (low) */ 1515 + 1516 + #define REG_MAC_IPG0 0x6040 /* inter-packet gap0 reg. 1517 + recommended: 0x00 */ 1518 + #define REG_MAC_IPG1 0x6044 /* inter-packet gap1 reg 1519 + recommended: 0x08 */ 1520 + #define REG_MAC_IPG2 0x6048 /* inter-packet gap2 reg 1521 + recommended: 0x04 */ 1522 + #define REG_MAC_SLOT_TIME 0x604C /* slot time reg 1523 + recommended: 0x40 */ 1524 + #define REG_MAC_FRAMESIZE_MIN 0x6050 /* min frame size reg 1525 + recommended: 0x40 */ 1526 + 1527 + /* FRAMESIZE_MAX holds both the max frame size as well as the max burst size. 1528 + * recommended value: 0x2000.05EE 1529 + */ 1530 + #define REG_MAC_FRAMESIZE_MAX 0x6054 /* max frame size reg */ 1531 + #define MAC_FRAMESIZE_MAX_BURST_MASK 0x3FFF0000 /* max burst size */ 1532 + #define MAC_FRAMESIZE_MAX_BURST_SHIFT 16 1533 + #define MAC_FRAMESIZE_MAX_FRAME_MASK 0x00007FFF /* max frame size */ 1534 + #define MAC_FRAMESIZE_MAX_FRAME_SHIFT 0 1535 + #define REG_MAC_PA_SIZE 0x6058 /* PA size reg. number of 1536 + preamble bytes that the 1537 + TX MAC will xmit at the 1538 + beginning of each frame 1539 + value should be 2 or 1540 + greater. recommended 1541 + value: 0x07 */ 1542 + #define REG_MAC_JAM_SIZE 0x605C /* jam size reg. duration 1543 + of jam in units of media 1544 + byte time. recommended 1545 + value: 0x04 */ 1546 + #define REG_MAC_ATTEMPT_LIMIT 0x6060 /* attempt limit reg. # 1547 + of attempts TX MAC will 1548 + make to xmit a frame 1549 + before it resets its 1550 + attempts counter. after 1551 + the limit has been 1552 + reached, TX MAC may or 1553 + may not drop the frame 1554 + dependent upon value 1555 + in TX_MAC_CFG. 1556 + recommended 1557 + value: 0x10 */ 1558 + #define REG_MAC_CTRL_TYPE 0x6064 /* MAC control type reg. 1559 + type field of a MAC 1560 + ctrl frame. recommended 1561 + value: 0x8808 */ 1562 + 1563 + /* mac address registers: 0 - 44, 0x6080 - 0x6130, 4 8-bit bytes. 1564 + * register contains comparison 1565 + * 0 16 MSB of primary MAC addr [47:32] of DA field 1566 + * 1 16 middle bits "" [31:16] of DA field 1567 + * 2 16 LSB "" [15:0] of DA field 1568 + * 3*x 16MSB of alt MAC addr 1-15 [47:32] of DA field 1569 + * 4*x 16 middle bits "" [31:16] 1570 + * 5*x 16 LSB "" [15:0] 1571 + * 42 16 MSB of MAC CTRL addr [47:32] of DA. 1572 + * 43 16 middle bits "" [31:16] 1573 + * 44 16 LSB "" [15:0] 1574 + * MAC CTRL addr must be the reserved multicast addr for MAC CTRL frames. 1575 + * if there is a match, MAC will set the bit for alternative address 1576 + * filter pass [15] 1577 + 1578 + * here is the map of registers given MAC address notation: a:b:c:d:e:f 1579 + * ab cd ef 1580 + * primary addr reg 2 reg 1 reg 0 1581 + * alt addr 1 reg 5 reg 4 reg 3 1582 + * alt addr x reg 5*x reg 4*x reg 3*x 1583 + * ctrl addr reg 44 reg 43 reg 42 1584 + */ 1585 + #define REG_MAC_ADDR0 0x6080 /* MAC address 0 reg */ 1586 + #define REG_MAC_ADDRN(x) (REG_MAC_ADDR0 + (x)*4) 1587 + #define REG_MAC_ADDR_FILTER0 0x614C /* address filter 0 reg 1588 + [47:32] */ 1589 + #define REG_MAC_ADDR_FILTER1 0x6150 /* address filter 1 reg 1590 + [31:16] */ 1591 + #define REG_MAC_ADDR_FILTER2 0x6154 /* address filter 2 reg 1592 + [15:0] */ 1593 + #define REG_MAC_ADDR_FILTER2_1_MASK 0x6158 /* address filter 2 and 1 1594 + mask reg. 8-bit reg 1595 + contains nibble mask for 1596 + reg 2 and 1. */ 1597 + #define REG_MAC_ADDR_FILTER0_MASK 0x615C /* address filter 0 mask 1598 + reg */ 1599 + 1600 + /* hash table registers: 0 - 15, 0x6160 - 0x619C, 4 8-bit bytes 1601 + * 16-bit registers contain bits of the hash table. 1602 + * reg x -> [16*(15 - x) + 15 : 16*(15 - x)]. 1603 + * e.g., 15 -> [15:0], 0 -> [255:240] 1604 + */ 1605 + #define REG_MAC_HASH_TABLE0 0x6160 /* hash table 0 reg */ 1606 + #define REG_MAC_HASH_TABLEN(x) (REG_MAC_HASH_TABLE0 + (x)*4) 1607 + 1608 + /* statistics registers. these registers generate an interrupt on 1609 + * overflow. recommended initialization: 0x0000. most are 16-bits except 1610 + * for PEAK_ATTEMPTS register which is 8 bits. 1611 + */ 1612 + #define REG_MAC_COLL_NORMAL 0x61A0 /* normal collision 1613 + counter. */ 1614 + #define REG_MAC_COLL_FIRST 0x61A4 /* first attempt 1615 + successful collision 1616 + counter */ 1617 + #define REG_MAC_COLL_EXCESS 0x61A8 /* excessive collision 1618 + counter */ 1619 + #define REG_MAC_COLL_LATE 0x61AC /* late collision counter */ 1620 + #define REG_MAC_TIMER_DEFER 0x61B0 /* defer timer. time base 1621 + is the media byte 1622 + clock/256 */ 1623 + #define REG_MAC_ATTEMPTS_PEAK 0x61B4 /* peak attempts reg */ 1624 + #define REG_MAC_RECV_FRAME 0x61B8 /* receive frame counter */ 1625 + #define REG_MAC_LEN_ERR 0x61BC /* length error counter */ 1626 + #define REG_MAC_ALIGN_ERR 0x61C0 /* alignment error counter */ 1627 + #define REG_MAC_FCS_ERR 0x61C4 /* FCS error counter */ 1628 + #define REG_MAC_RX_CODE_ERR 0x61C8 /* RX code violation 1629 + error counter */ 1630 + 1631 + /* misc registers */ 1632 + #define REG_MAC_RANDOM_SEED 0x61CC /* random number seed reg. 1633 + 10-bit register used as a 1634 + seed for the random number 1635 + generator for the CSMA/CD 1636 + backoff algorithm. only 1637 + programmed after power-on 1638 + reset and should be a 1639 + random value which has a 1640 + high likelihood of being 1641 + unique for each MAC 1642 + attached to a network 1643 + segment (e.g., 10 LSB of 1644 + MAC address) */ 1645 + 1646 + /* ASUN: there's a PAUSE_TIMER (ro) described, but it's not in the address 1647 + * map 1648 + */ 1649 + 1650 + /* 27-bit register has the current state for key state machines in the MAC */ 1651 + #define REG_MAC_STATE_MACHINE 0x61D0 /* (ro) state machine reg */ 1652 + #define MAC_SM_RLM_MASK 0x07800000 1653 + #define MAC_SM_RLM_SHIFT 23 1654 + #define MAC_SM_RX_FC_MASK 0x00700000 1655 + #define MAC_SM_RX_FC_SHIFT 20 1656 + #define MAC_SM_TLM_MASK 0x000F0000 1657 + #define MAC_SM_TLM_SHIFT 16 1658 + #define MAC_SM_ENCAP_SM_MASK 0x0000F000 1659 + #define MAC_SM_ENCAP_SM_SHIFT 12 1660 + #define MAC_SM_TX_REQ_MASK 0x00000C00 1661 + #define MAC_SM_TX_REQ_SHIFT 10 1662 + #define MAC_SM_TX_FC_MASK 0x000003C0 1663 + #define MAC_SM_TX_FC_SHIFT 6 1664 + #define MAC_SM_FIFO_WRITE_SEL_MASK 0x00000038 1665 + #define MAC_SM_FIFO_WRITE_SEL_SHIFT 3 1666 + #define MAC_SM_TX_FIFO_EMPTY_MASK 0x00000007 1667 + #define MAC_SM_TX_FIFO_EMPTY_SHIFT 0 1668 + 1669 + /** MIF registers. the MIF can be programmed in either bit-bang or 1670 + * frame mode. 1671 + **/ 1672 + #define REG_MIF_BIT_BANG_CLOCK 0x6200 /* MIF bit-bang clock. 1673 + 1 -> 0 will generate a 1674 + rising edge. 0 -> 1 will 1675 + generate a falling edge. */ 1676 + #define REG_MIF_BIT_BANG_DATA 0x6204 /* MIF bit-bang data. 1-bit 1677 + register generates data */ 1678 + #define REG_MIF_BIT_BANG_OUTPUT_EN 0x6208 /* MIF bit-bang output 1679 + enable. enable when 1680 + xmitting data from MIF to 1681 + transceiver. */ 1682 + 1683 + /* 32-bit register serves as an instruction register when the MIF is 1684 + * programmed in frame mode. load this register w/ a valid instruction 1685 + * (as per IEEE 802.3u MII spec). poll this register to check for instruction 1686 + * execution completion. during a read operation, this register will also 1687 + * contain the 16-bit data returned by the tranceiver. unless specified 1688 + * otherwise, fields are considered "don't care" when polling for 1689 + * completion. 1690 + */ 1691 + #define REG_MIF_FRAME 0x620C /* MIF frame/output reg */ 1692 + #define MIF_FRAME_START_MASK 0xC0000000 /* start of frame. 1693 + load w/ 01 when 1694 + issuing an instr */ 1695 + #define MIF_FRAME_ST 0x40000000 /* STart of frame */ 1696 + #define MIF_FRAME_OPCODE_MASK 0x30000000 /* opcode. 01 for a 1697 + write. 10 for a 1698 + read */ 1699 + #define MIF_FRAME_OP_READ 0x20000000 /* read OPcode */ 1700 + #define MIF_FRAME_OP_WRITE 0x10000000 /* write OPcode */ 1701 + #define MIF_FRAME_PHY_ADDR_MASK 0x0F800000 /* phy address. when 1702 + issuing an instr, 1703 + this field should be 1704 + loaded w/ the XCVR 1705 + addr */ 1706 + #define MIF_FRAME_PHY_ADDR_SHIFT 23 1707 + #define MIF_FRAME_REG_ADDR_MASK 0x007C0000 /* register address. 1708 + when issuing an instr, 1709 + addr of register 1710 + to be read/written */ 1711 + #define MIF_FRAME_REG_ADDR_SHIFT 18 1712 + #define MIF_FRAME_TURN_AROUND_MSB 0x00020000 /* turn around, MSB. 1713 + when issuing an instr, 1714 + set this bit to 1 */ 1715 + #define MIF_FRAME_TURN_AROUND_LSB 0x00010000 /* turn around, LSB. 1716 + when issuing an instr, 1717 + set this bit to 0. 1718 + when polling for 1719 + completion, 1 means 1720 + that instr execution 1721 + has been completed */ 1722 + #define MIF_FRAME_DATA_MASK 0x0000FFFF /* instruction payload 1723 + load with 16-bit data 1724 + to be written in 1725 + transceiver reg for a 1726 + write. doesn't matter 1727 + in a read. when 1728 + polling for 1729 + completion, field is 1730 + "don't care" for write 1731 + and 16-bit data 1732 + returned by the 1733 + transceiver for a 1734 + read (if valid bit 1735 + is set) */ 1736 + #define REG_MIF_CFG 0x6210 /* MIF config reg */ 1737 + #define MIF_CFG_PHY_SELECT 0x0001 /* 1 -> select MDIO_1 1738 + 0 -> select MDIO_0 */ 1739 + #define MIF_CFG_POLL_EN 0x0002 /* enable polling 1740 + mechanism. if set, 1741 + BB_MODE should be 0 */ 1742 + #define MIF_CFG_BB_MODE 0x0004 /* 1 -> bit-bang mode 1743 + 0 -> frame mode */ 1744 + #define MIF_CFG_POLL_REG_MASK 0x00F8 /* register address to be 1745 + used by polling mode. 1746 + only meaningful if POLL_EN 1747 + is set to 1 */ 1748 + #define MIF_CFG_POLL_REG_SHIFT 3 1749 + #define MIF_CFG_MDIO_0 0x0100 /* (ro) dual purpose. 1750 + when MDIO_0 is idle, 1751 + 1 -> tranceiver is 1752 + connected to MDIO_0. 1753 + when MIF is communicating 1754 + w/ MDIO_0 in bit-bang 1755 + mode, this bit indicates 1756 + the incoming bit stream 1757 + during a read op */ 1758 + #define MIF_CFG_MDIO_1 0x0200 /* (ro) dual purpose. 1759 + when MDIO_1 is idle, 1760 + 1 -> transceiver is 1761 + connected to MDIO_1. 1762 + when MIF is communicating 1763 + w/ MDIO_1 in bit-bang 1764 + mode, this bit indicates 1765 + the incoming bit stream 1766 + during a read op */ 1767 + #define MIF_CFG_POLL_PHY_MASK 0x7C00 /* tranceiver address to 1768 + be polled */ 1769 + #define MIF_CFG_POLL_PHY_SHIFT 10 1770 + 1771 + /* 16-bit register used to determine which bits in the POLL_STATUS portion of 1772 + * the MIF_STATUS register will cause an interrupt. if a mask bit is 0, 1773 + * corresponding bit of the POLL_STATUS will generate a MIF interrupt when 1774 + * set. DEFAULT: 0xFFFF 1775 + */ 1776 + #define REG_MIF_MASK 0x6214 /* MIF mask reg */ 1777 + 1778 + /* 32-bit register used when in poll mode. auto-cleared after being read */ 1779 + #define REG_MIF_STATUS 0x6218 /* MIF status reg */ 1780 + #define MIF_STATUS_POLL_DATA_MASK 0xFFFF0000 /* poll data contains 1781 + the "latest image" 1782 + update of the XCVR 1783 + reg being read */ 1784 + #define MIF_STATUS_POLL_DATA_SHIFT 16 1785 + #define MIF_STATUS_POLL_STATUS_MASK 0x0000FFFF /* poll status indicates 1786 + which bits in the 1787 + POLL_DATA field have 1788 + changed since the 1789 + MIF_STATUS reg was 1790 + last read */ 1791 + #define MIF_STATUS_POLL_STATUS_SHIFT 0 1792 + 1793 + /* 7-bit register has current state for all state machines in the MIF */ 1794 + #define REG_MIF_STATE_MACHINE 0x621C /* MIF state machine reg */ 1795 + #define MIF_SM_CONTROL_MASK 0x07 /* control state machine 1796 + state */ 1797 + #define MIF_SM_EXECUTION_MASK 0x60 /* execution state machine 1798 + state */ 1799 + 1800 + /** PCS/Serialink. the following registers are equivalent to the standard 1801 + * MII management registers except that they're directly mapped in 1802 + * Cassini's register space. 1803 + **/ 1804 + 1805 + /* the auto-negotiation enable bit should be programmed the same at 1806 + * the link partner as in the local device to enable auto-negotiation to 1807 + * complete. when that bit is reprogrammed, auto-neg/manual config is 1808 + * restarted automatically. 1809 + * DEFAULT: 0x1040 1810 + */ 1811 + #define REG_PCS_MII_CTRL 0x9000 /* PCS MII control reg */ 1812 + #define PCS_MII_CTRL_1000_SEL 0x0040 /* reads 1. ignored on 1813 + writes */ 1814 + #define PCS_MII_CTRL_COLLISION_TEST 0x0080 /* COL signal at the PCS 1815 + to MAC interface is 1816 + activated regardless 1817 + of activity */ 1818 + #define PCS_MII_CTRL_DUPLEX 0x0100 /* forced 0x0. PCS 1819 + behaviour same for 1820 + half and full dplx */ 1821 + #define PCS_MII_RESTART_AUTONEG 0x0200 /* self clearing. 1822 + restart auto- 1823 + negotiation */ 1824 + #define PCS_MII_ISOLATE 0x0400 /* read as 0. ignored 1825 + on writes */ 1826 + #define PCS_MII_POWER_DOWN 0x0800 /* read as 0. ignored 1827 + on writes */ 1828 + #define PCS_MII_AUTONEG_EN 0x1000 /* default 1. PCS goes 1829 + through automatic 1830 + link config before it 1831 + can be used. when 0, 1832 + link can be used 1833 + w/out any link config 1834 + phase */ 1835 + #define PCS_MII_10_100_SEL 0x2000 /* read as 0. ignored on 1836 + writes */ 1837 + #define PCS_MII_RESET 0x8000 /* reset PCS. self-clears 1838 + when done */ 1839 + 1840 + /* DEFAULT: 0x0108 */ 1841 + #define REG_PCS_MII_STATUS 0x9004 /* PCS MII status reg */ 1842 + #define PCS_MII_STATUS_EXTEND_CAP 0x0001 /* reads 0 */ 1843 + #define PCS_MII_STATUS_JABBER_DETECT 0x0002 /* reads 0 */ 1844 + #define PCS_MII_STATUS_LINK_STATUS 0x0004 /* 1 -> link up. 1845 + 0 -> link down. 0 is 1846 + latched so that 0 is 1847 + kept until read. read 1848 + 2x to determine if the 1849 + link has gone up again */ 1850 + #define PCS_MII_STATUS_AUTONEG_ABLE 0x0008 /* reads 1 (able to perform 1851 + auto-neg) */ 1852 + #define PCS_MII_STATUS_REMOTE_FAULT 0x0010 /* 1 -> remote fault detected 1853 + from received link code 1854 + word. only valid after 1855 + auto-neg completed */ 1856 + #define PCS_MII_STATUS_AUTONEG_COMP 0x0020 /* 1 -> auto-negotiation 1857 + completed 1858 + 0 -> auto-negotiation not 1859 + completed */ 1860 + #define PCS_MII_STATUS_EXTEND_STATUS 0x0100 /* reads as 1. used as an 1861 + indication that this is 1862 + a 1000 Base-X PHY. writes 1863 + to it are ignored */ 1864 + 1865 + /* used during auto-negotiation. 1866 + * DEFAULT: 0x00E0 1867 + */ 1868 + #define REG_PCS_MII_ADVERT 0x9008 /* PCS MII advertisement 1869 + reg */ 1870 + #define PCS_MII_ADVERT_FD 0x0020 /* advertise full duplex 1871 + 1000 Base-X */ 1872 + #define PCS_MII_ADVERT_HD 0x0040 /* advertise half-duplex 1873 + 1000 Base-X */ 1874 + #define PCS_MII_ADVERT_SYM_PAUSE 0x0080 /* advertise PAUSE 1875 + symmetric capability */ 1876 + #define PCS_MII_ADVERT_ASYM_PAUSE 0x0100 /* advertises PAUSE 1877 + asymmetric capability */ 1878 + #define PCS_MII_ADVERT_RF_MASK 0x3000 /* remote fault. write bit13 1879 + to optionally indicate to 1880 + link partner that chip is 1881 + going off-line. bit12 will 1882 + get set when signal 1883 + detect == FAIL and will 1884 + remain set until 1885 + successful negotiation */ 1886 + #define PCS_MII_ADVERT_ACK 0x4000 /* (ro) */ 1887 + #define PCS_MII_ADVERT_NEXT_PAGE 0x8000 /* (ro) forced 0x0 */ 1888 + 1889 + /* contents updated as a result of autonegotiation. layout and definitions 1890 + * identical to PCS_MII_ADVERT 1891 + */ 1892 + #define REG_PCS_MII_LPA 0x900C /* PCS MII link partner 1893 + ability reg */ 1894 + #define PCS_MII_LPA_FD PCS_MII_ADVERT_FD 1895 + #define PCS_MII_LPA_HD PCS_MII_ADVERT_HD 1896 + #define PCS_MII_LPA_SYM_PAUSE PCS_MII_ADVERT_SYM_PAUSE 1897 + #define PCS_MII_LPA_ASYM_PAUSE PCS_MII_ADVERT_ASYM_PAUSE 1898 + #define PCS_MII_LPA_RF_MASK PCS_MII_ADVERT_RF_MASK 1899 + #define PCS_MII_LPA_ACK PCS_MII_ADVERT_ACK 1900 + #define PCS_MII_LPA_NEXT_PAGE PCS_MII_ADVERT_NEXT_PAGE 1901 + 1902 + /* DEFAULT: 0x0 */ 1903 + #define REG_PCS_CFG 0x9010 /* PCS config reg */ 1904 + #define PCS_CFG_EN 0x01 /* enable PCS. must be 1905 + 0 when modifying 1906 + PCS_MII_ADVERT */ 1907 + #define PCS_CFG_SD_OVERRIDE 0x02 /* sets signal detect to 1908 + OK. bit is 1909 + non-resettable */ 1910 + #define PCS_CFG_SD_ACTIVE_LOW 0x04 /* changes interpretation 1911 + of optical signal to make 1912 + signal detect okay when 1913 + signal is low */ 1914 + #define PCS_CFG_JITTER_STUDY_MASK 0x18 /* used to make jitter 1915 + measurements. a single 1916 + code group is xmitted 1917 + regularly. 1918 + 0x0 = normal operation 1919 + 0x1 = high freq test 1920 + pattern, D21.5 1921 + 0x2 = low freq test 1922 + pattern, K28.7 1923 + 0x3 = reserved */ 1924 + #define PCS_CFG_10MS_TIMER_OVERRIDE 0x20 /* shortens 10-20ms auto- 1925 + negotiation timer to 1926 + a few cycles for test 1927 + purposes */ 1928 + 1929 + /* used for diagnostic purposes. bits 20-22 autoclear on read */ 1930 + #define REG_PCS_STATE_MACHINE 0x9014 /* (ro) PCS state machine 1931 + and diagnostic reg */ 1932 + #define PCS_SM_TX_STATE_MASK 0x0000000F /* 0 and 1 indicate 1933 + xmission of idle. 1934 + otherwise, xmission of 1935 + a packet */ 1936 + #define PCS_SM_RX_STATE_MASK 0x000000F0 /* 0 indicates reception 1937 + of idle. otherwise, 1938 + reception of packet */ 1939 + #define PCS_SM_WORD_SYNC_STATE_MASK 0x00000700 /* 0 indicates loss of 1940 + sync */ 1941 + #define PCS_SM_SEQ_DETECT_STATE_MASK 0x00001800 /* cycling through 0-3 1942 + indicates reception of 1943 + Config codes. cycling 1944 + through 0-1 indicates 1945 + reception of idles */ 1946 + #define PCS_SM_LINK_STATE_MASK 0x0001E000 1947 + #define SM_LINK_STATE_UP 0x00016000 /* link state is up */ 1948 + 1949 + #define PCS_SM_LOSS_LINK_C 0x00100000 /* loss of link due to 1950 + recept of Config 1951 + codes */ 1952 + #define PCS_SM_LOSS_LINK_SYNC 0x00200000 /* loss of link due to 1953 + loss of sync */ 1954 + #define PCS_SM_LOSS_SIGNAL_DETECT 0x00400000 /* signal detect goes 1955 + from OK to FAIL. bit29 1956 + will also be set if 1957 + this is set */ 1958 + #define PCS_SM_NO_LINK_BREAKLINK 0x01000000 /* link not up due to 1959 + receipt of breaklink 1960 + C codes from partner. 1961 + C codes w/ 0 content 1962 + received triggering 1963 + start/restart of 1964 + autonegotiation. 1965 + should be sent for 1966 + no longer than 20ms */ 1967 + #define PCS_SM_NO_LINK_SERDES 0x02000000 /* serdes being 1968 + initialized. see serdes 1969 + state reg */ 1970 + #define PCS_SM_NO_LINK_C 0x04000000 /* C codes not stable or 1971 + not received */ 1972 + #define PCS_SM_NO_LINK_SYNC 0x08000000 /* word sync not 1973 + achieved */ 1974 + #define PCS_SM_NO_LINK_WAIT_C 0x10000000 /* waiting for C codes 1975 + w/ ack bit set */ 1976 + #define PCS_SM_NO_LINK_NO_IDLE 0x20000000 /* link partner continues 1977 + to send C codes 1978 + instead of idle 1979 + symbols or pkt data */ 1980 + 1981 + /* this register indicates interrupt changes in specific PCS MII status bits. 1982 + * PCS_INT may be masked at the ISR level. only a single bit is implemented 1983 + * for link status change. 1984 + */ 1985 + #define REG_PCS_INTR_STATUS 0x9018 /* PCS interrupt status */ 1986 + #define PCS_INTR_STATUS_LINK_CHANGE 0x04 /* link status has changed 1987 + since last read */ 1988 + 1989 + /* control which network interface is used. no more than one bit should 1990 + * be set. 1991 + * DEFAULT: none 1992 + */ 1993 + #define REG_PCS_DATAPATH_MODE 0x9050 /* datapath mode reg */ 1994 + #define PCS_DATAPATH_MODE_MII 0x00 /* PCS is not used and 1995 + MII/GMII is selected. 1996 + selection between MII and 1997 + GMII is controlled by 1998 + XIF_CFG */ 1999 + #define PCS_DATAPATH_MODE_SERDES 0x02 /* PCS is used via the 2000 + 10-bit interface */ 2001 + 2002 + /* input to serdes chip or serialink block */ 2003 + #define REG_PCS_SERDES_CTRL 0x9054 /* serdes control reg */ 2004 + #define PCS_SERDES_CTRL_LOOPBACK 0x01 /* enable loopback on 2005 + serdes interface */ 2006 + #define PCS_SERDES_CTRL_SYNCD_EN 0x02 /* enable sync carrier 2007 + detection. should be 2008 + 0x0 for normal 2009 + operation */ 2010 + #define PCS_SERDES_CTRL_LOCKREF 0x04 /* frequency-lock RBC[0:1] 2011 + to REFCLK when set. 2012 + when clear, receiver 2013 + clock locks to incoming 2014 + serial data */ 2015 + 2016 + /* multiplex test outputs into the PROM address (PA_3 through PA_0) pins. 2017 + * should be 0x0 for normal operations. 2018 + * 0b000 normal operation, PROM address[3:0] selected 2019 + * 0b001 rxdma req, rxdma ack, rxdma ready, rxdma read 2020 + * 0b010 rxmac req, rx ack, rx tag, rx clk shared 2021 + * 0b011 txmac req, tx ack, tx tag, tx retry req 2022 + * 0b100 tx tp3, tx tp2, tx tp1, tx tp0 2023 + * 0b101 R period RX, R period TX, R period HP, R period BIM 2024 + * DEFAULT: 0x0 2025 + */ 2026 + #define REG_PCS_SHARED_OUTPUT_SEL 0x9058 /* shared output select */ 2027 + #define PCS_SOS_PROM_ADDR_MASK 0x0007 2028 + 2029 + /* used for diagnostics. this register indicates progress of the SERDES 2030 + * boot up. 2031 + * 0b00 undergoing reset 2032 + * 0b01 waiting 500us while lockrefn is asserted 2033 + * 0b10 waiting for comma detect 2034 + * 0b11 receive data is synchronized 2035 + * DEFAULT: 0x0 2036 + */ 2037 + #define REG_PCS_SERDES_STATE 0x905C /* (ro) serdes state */ 2038 + #define PCS_SERDES_STATE_MASK 0x03 2039 + 2040 + /* used for diagnostics. indicates number of packets transmitted or received. 2041 + * counters rollover w/out generating an interrupt. 2042 + * DEFAULT: 0x0 2043 + */ 2044 + #define REG_PCS_PACKET_COUNT 0x9060 /* (ro) PCS packet counter */ 2045 + #define PCS_PACKET_COUNT_TX 0x000007FF /* pkts xmitted by PCS */ 2046 + #define PCS_PACKET_COUNT_RX 0x07FF0000 /* pkts recvd by PCS 2047 + whether they 2048 + encountered an error 2049 + or not */ 2050 + 2051 + /** LocalBus Devices. the following provides run-time access to the 2052 + * Cassini's PROM 2053 + ***/ 2054 + #define REG_EXPANSION_ROM_RUN_START 0x100000 /* expansion rom run time 2055 + access */ 2056 + #define REG_EXPANSION_ROM_RUN_END 0x17FFFF 2057 + 2058 + #define REG_SECOND_LOCALBUS_START 0x180000 /* secondary local bus 2059 + device */ 2060 + #define REG_SECOND_LOCALBUS_END 0x1FFFFF 2061 + 2062 + /* entropy device */ 2063 + #define REG_ENTROPY_START REG_SECOND_LOCALBUS_START 2064 + #define REG_ENTROPY_DATA (REG_ENTROPY_START + 0x00) 2065 + #define REG_ENTROPY_STATUS (REG_ENTROPY_START + 0x04) 2066 + #define ENTROPY_STATUS_DRDY 0x01 2067 + #define ENTROPY_STATUS_BUSY 0x02 2068 + #define ENTROPY_STATUS_CIPHER 0x04 2069 + #define ENTROPY_STATUS_BYPASS_MASK 0x18 2070 + #define REG_ENTROPY_MODE (REG_ENTROPY_START + 0x05) 2071 + #define ENTROPY_MODE_KEY_MASK 0x07 2072 + #define ENTROPY_MODE_ENCRYPT 0x40 2073 + #define REG_ENTROPY_RAND_REG (REG_ENTROPY_START + 0x06) 2074 + #define REG_ENTROPY_RESET (REG_ENTROPY_START + 0x07) 2075 + #define ENTROPY_RESET_DES_IO 0x01 2076 + #define ENTROPY_RESET_STC_MODE 0x02 2077 + #define ENTROPY_RESET_KEY_CACHE 0x04 2078 + #define ENTROPY_RESET_IV 0x08 2079 + #define REG_ENTROPY_IV (REG_ENTROPY_START + 0x08) 2080 + #define REG_ENTROPY_KEY0 (REG_ENTROPY_START + 0x10) 2081 + #define REG_ENTROPY_KEYN(x) (REG_ENTROPY_KEY0 + 4*(x)) 2082 + 2083 + /* phys of interest w/ their special mii registers */ 2084 + #define PHY_LUCENT_B0 0x00437421 2085 + #define LUCENT_MII_REG 0x1F 2086 + 2087 + #define PHY_NS_DP83065 0x20005c78 2088 + #define DP83065_MII_MEM 0x16 2089 + #define DP83065_MII_REGD 0x1D 2090 + #define DP83065_MII_REGE 0x1E 2091 + 2092 + #define PHY_BROADCOM_5411 0x00206071 2093 + #define PHY_BROADCOM_B0 0x00206050 2094 + #define BROADCOM_MII_REG4 0x14 2095 + #define BROADCOM_MII_REG5 0x15 2096 + #define BROADCOM_MII_REG7 0x17 2097 + #define BROADCOM_MII_REG8 0x18 2098 + 2099 + #define CAS_MII_ANNPTR 0x07 2100 + #define CAS_MII_ANNPRR 0x08 2101 + #define CAS_MII_1000_CTRL 0x09 2102 + #define CAS_MII_1000_STATUS 0x0A 2103 + #define CAS_MII_1000_EXTEND 0x0F 2104 + 2105 + #define CAS_BMSR_1000_EXTEND 0x0100 /* supports 1000Base-T extended status */ 2106 + /* 2107 + * if autoneg is disabled, here's the table: 2108 + * BMCR_SPEED100 = 100Mbps 2109 + * BMCR_SPEED1000 = 1000Mbps 2110 + * ~(BMCR_SPEED100 | BMCR_SPEED1000) = 10Mbps 2111 + */ 2112 + #define CAS_BMCR_SPEED1000 0x0040 /* Select 1000Mbps */ 2113 + 2114 + #define CAS_ADVERTISE_1000HALF 0x0100 2115 + #define CAS_ADVERTISE_1000FULL 0x0200 2116 + #define CAS_ADVERTISE_PAUSE 0x0400 2117 + #define CAS_ADVERTISE_ASYM_PAUSE 0x0800 2118 + 2119 + /* regular lpa register */ 2120 + #define CAS_LPA_PAUSE CAS_ADVERTISE_PAUSE 2121 + #define CAS_LPA_ASYM_PAUSE CAS_ADVERTISE_ASYM_PAUSE 2122 + 2123 + /* 1000_STATUS register */ 2124 + #define CAS_LPA_1000HALF 0x0400 2125 + #define CAS_LPA_1000FULL 0x0800 2126 + 2127 + #define CAS_EXTEND_1000XFULL 0x8000 2128 + #define CAS_EXTEND_1000XHALF 0x4000 2129 + #define CAS_EXTEND_1000TFULL 0x2000 2130 + #define CAS_EXTEND_1000THALF 0x1000 2131 + 2132 + /* cassini header parser firmware */ 2133 + typedef struct cas_hp_inst { 2134 + const char *note; 2135 + 2136 + u16 mask, val; 2137 + 2138 + u8 op; 2139 + u8 soff, snext; /* if match succeeds, new offset and match */ 2140 + u8 foff, fnext; /* if match fails, new offset and match */ 2141 + /* output info */ 2142 + u8 outop; /* output opcode */ 2143 + 2144 + u16 outarg; /* output argument */ 2145 + u8 outenab; /* output enable: 0 = not, 1 = if match 2146 + 2 = if !match, 3 = always */ 2147 + u8 outshift; /* barrel shift right, 4 bits */ 2148 + u16 outmask; 2149 + } cas_hp_inst_t; 2150 + 2151 + /* comparison */ 2152 + #define OP_EQ 0 /* packet == value */ 2153 + #define OP_LT 1 /* packet < value */ 2154 + #define OP_GT 2 /* packet > value */ 2155 + #define OP_NP 3 /* new packet */ 2156 + 2157 + /* output opcodes */ 2158 + #define CL_REG 0 2159 + #define LD_FID 1 2160 + #define LD_SEQ 2 2161 + #define LD_CTL 3 2162 + #define LD_SAP 4 2163 + #define LD_R1 5 2164 + #define LD_L3 6 2165 + #define LD_SUM 7 2166 + #define LD_HDR 8 2167 + #define IM_FID 9 2168 + #define IM_SEQ 10 2169 + #define IM_SAP 11 2170 + #define IM_R1 12 2171 + #define IM_CTL 13 2172 + #define LD_LEN 14 2173 + #define ST_FLG 15 2174 + 2175 + /* match setp #s for IP4TCP4 */ 2176 + #define S1_PCKT 0 2177 + #define S1_VLAN 1 2178 + #define S1_CFI 2 2179 + #define S1_8023 3 2180 + #define S1_LLC 4 2181 + #define S1_LLCc 5 2182 + #define S1_IPV4 6 2183 + #define S1_IPV4c 7 2184 + #define S1_IPV4F 8 2185 + #define S1_TCP44 9 2186 + #define S1_IPV6 10 2187 + #define S1_IPV6L 11 2188 + #define S1_IPV6c 12 2189 + #define S1_TCP64 13 2190 + #define S1_TCPSQ 14 2191 + #define S1_TCPFG 15 2192 + #define S1_TCPHL 16 2193 + #define S1_TCPHc 17 2194 + #define S1_CLNP 18 2195 + #define S1_CLNP2 19 2196 + #define S1_DROP 20 2197 + #define S2_HTTP 21 2198 + #define S1_ESP4 22 2199 + #define S1_AH4 23 2200 + #define S1_ESP6 24 2201 + #define S1_AH6 25 2202 + 2203 + #define CAS_PROG_IP46TCP4_PREAMBLE \ 2204 + { "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0, S1_PCKT, \ 2205 + CL_REG, 0x3ff, 1, 0x0, 0x0000}, \ 2206 + { "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023, \ 2207 + IM_CTL, 0x00a, 3, 0x0, 0xffff}, \ 2208 + { "CFI?", 0x1000, 0x1000, OP_EQ, 0, S1_DROP, 1, S1_8023, \ 2209 + CL_REG, 0x000, 0, 0x0, 0x0000}, \ 2210 + { "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4, \ 2211 + CL_REG, 0x000, 0, 0x0, 0x0000}, \ 2212 + { "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S1_CLNP, \ 2213 + CL_REG, 0x000, 0, 0x0, 0x0000}, \ 2214 + { "LLCc?", 0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S1_CLNP, \ 2215 + CL_REG, 0x000, 0, 0x0, 0x0000}, \ 2216 + { "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6, \ 2217 + LD_SAP, 0x100, 3, 0x0, 0xffff}, \ 2218 + { "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S1_CLNP, \ 2219 + LD_SUM, 0x00a, 1, 0x0, 0x0000}, \ 2220 + { "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S1_CLNP, \ 2221 + LD_LEN, 0x03e, 1, 0x0, 0xffff}, \ 2222 + { "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S1_TCPSQ, 0, S1_CLNP, \ 2223 + LD_FID, 0x182, 1, 0x0, 0xffff}, /* FID IP4&TCP src+dst */ \ 2224 + { "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S1_IPV6L, 0, S1_CLNP, \ 2225 + LD_SUM, 0x015, 1, 0x0, 0x0000}, \ 2226 + { "IPV6 len", 0xf000, 0x6000, OP_EQ, 0, S1_IPV6c, 0, S1_CLNP, \ 2227 + IM_R1, 0x128, 1, 0x0, 0xffff}, \ 2228 + { "IPV6 cont?", 0x0000, 0x0000, OP_EQ, 3, S1_TCP64, 0, S1_CLNP, \ 2229 + LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */ \ 2230 + { "TCP64?", 0xff00, 0x0600, OP_EQ, 18, S1_TCPSQ, 0, S1_CLNP, \ 2231 + LD_LEN, 0x03f, 1, 0x0, 0xffff} 2232 + 2233 + #ifdef USE_HP_IP46TCP4 2234 + static cas_hp_inst_t cas_prog_ip46tcp4tab[] = { 2235 + CAS_PROG_IP46TCP4_PREAMBLE, 2236 + { "TCP seq", /* DADDR should point to dest port */ 2237 + 0x0000, 0x0000, OP_EQ, 0, S1_TCPFG, 4, S1_TCPFG, LD_SEQ, 2238 + 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */ 2239 + { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHL, 0, 2240 + S1_TCPHL, ST_FLG, 0x045, 3, 0x0, 0x002f}, /* Load TCP flags */ 2241 + { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, 2242 + S1_TCPHc, LD_R1, 0x205, 3, 0xB, 0xf000}, 2243 + { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, 2244 + S1_PCKT, LD_HDR, 0x0ff, 3, 0x0, 0xffff}, 2245 + { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2, 2246 + IM_CTL, 0x001, 3, 0x0, 0x0001}, 2247 + { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2248 + IM_CTL, 0x000, 0, 0x0, 0x0000}, 2249 + { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2250 + IM_CTL, 0x080, 3, 0x0, 0xffff}, 2251 + { NULL }, 2252 + }; 2253 + #ifdef HP_IP46TCP4_DEFAULT 2254 + #define CAS_HP_FIRMWARE cas_prog_ip46tcp4tab 2255 + #endif 2256 + #endif 2257 + 2258 + /* 2259 + * Alternate table load which excludes HTTP server traffic from reassembly. 2260 + * It is substantially similar to the basic table, with one extra state 2261 + * and a few extra compares. */ 2262 + #ifdef USE_HP_IP46TCP4NOHTTP 2263 + static cas_hp_inst_t cas_prog_ip46tcp4nohttptab[] = { 2264 + CAS_PROG_IP46TCP4_PREAMBLE, 2265 + { "TCP seq", /* DADDR should point to dest port */ 2266 + 0xFFFF, 0x0080, OP_EQ, 0, S2_HTTP, 0, S1_TCPFG, LD_SEQ, 2267 + 0x081, 3, 0x0, 0xffff} , /* Load TCP seq # */ 2268 + { "TCP control flags", 0xFFFF, 0x8080, OP_EQ, 0, S2_HTTP, 0, 2269 + S1_TCPHL, ST_FLG, 0x145, 2, 0x0, 0x002f, }, /* Load TCP flags */ 2270 + { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, S1_TCPHc, 2271 + LD_R1, 0x205, 3, 0xB, 0xf000}, 2272 + { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2273 + LD_HDR, 0x0ff, 3, 0x0, 0xffff}, 2274 + { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2, 2275 + IM_CTL, 0x001, 3, 0x0, 0x0001}, 2276 + { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2277 + CL_REG, 0x002, 3, 0x0, 0x0000}, 2278 + { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2279 + IM_CTL, 0x080, 3, 0x0, 0xffff}, 2280 + { "No HTTP", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2281 + IM_CTL, 0x044, 3, 0x0, 0xffff}, 2282 + { NULL }, 2283 + }; 2284 + #ifdef HP_IP46TCP4NOHTTP_DEFAULT 2285 + #define CAS_HP_FIRMWARE cas_prog_ip46tcp4nohttptab 2286 + #endif 2287 + #endif 2288 + 2289 + /* match step #s for IP4FRAG */ 2290 + #define S3_IPV6c 11 2291 + #define S3_TCP64 12 2292 + #define S3_TCPSQ 13 2293 + #define S3_TCPFG 14 2294 + #define S3_TCPHL 15 2295 + #define S3_TCPHc 16 2296 + #define S3_FRAG 17 2297 + #define S3_FOFF 18 2298 + #define S3_CLNP 19 2299 + 2300 + #ifdef USE_HP_IP4FRAG 2301 + static cas_hp_inst_t cas_prog_ip4fragtab[] = { 2302 + { "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0, S1_PCKT, 2303 + CL_REG, 0x3ff, 1, 0x0, 0x0000}, 2304 + { "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023, 2305 + IM_CTL, 0x00a, 3, 0x0, 0xffff}, 2306 + { "CFI?", 0x1000, 0x1000, OP_EQ, 0, S3_CLNP, 1, S1_8023, 2307 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2308 + { "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4, 2309 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2310 + { "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S3_CLNP, 2311 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2312 + { "LLCc?",0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S3_CLNP, 2313 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2314 + { "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6, 2315 + LD_SAP, 0x100, 3, 0x0, 0xffff}, 2316 + { "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S3_CLNP, 2317 + LD_SUM, 0x00a, 1, 0x0, 0x0000}, 2318 + { "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S3_FRAG, 2319 + LD_LEN, 0x03e, 3, 0x0, 0xffff}, 2320 + { "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S3_TCPSQ, 0, S3_CLNP, 2321 + LD_FID, 0x182, 3, 0x0, 0xffff}, /* FID IP4&TCP src+dst */ 2322 + { "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S3_IPV6c, 0, S3_CLNP, 2323 + LD_SUM, 0x015, 1, 0x0, 0x0000}, 2324 + { "IPV6 cont?", 0xf000, 0x6000, OP_EQ, 3, S3_TCP64, 0, S3_CLNP, 2325 + LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */ 2326 + { "TCP64?", 0xff00, 0x0600, OP_EQ, 18, S3_TCPSQ, 0, S3_CLNP, 2327 + LD_LEN, 0x03f, 1, 0x0, 0xffff}, 2328 + { "TCP seq", /* DADDR should point to dest port */ 2329 + 0x0000, 0x0000, OP_EQ, 0, S3_TCPFG, 4, S3_TCPFG, LD_SEQ, 2330 + 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */ 2331 + { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S3_TCPHL, 0, 2332 + S3_TCPHL, ST_FLG, 0x045, 3, 0x0, 0x002f}, /* Load TCP flags */ 2333 + { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S3_TCPHc, 0, S3_TCPHc, 2334 + LD_R1, 0x205, 3, 0xB, 0xf000}, 2335 + { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2336 + LD_HDR, 0x0ff, 3, 0x0, 0xffff}, 2337 + { "IP4 Fragment", 0x0000, 0x0000, OP_EQ, 0, S3_FOFF, 0, S3_FOFF, 2338 + LD_FID, 0x103, 3, 0x0, 0xffff}, /* FID IP4 src+dst */ 2339 + { "IP4 frag offset", 0x0000, 0x0000, OP_EQ, 0, S3_FOFF, 0, S3_FOFF, 2340 + LD_SEQ, 0x040, 1, 0xD, 0xfff8}, 2341 + { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2342 + IM_CTL, 0x001, 3, 0x0, 0x0001}, 2343 + { NULL }, 2344 + }; 2345 + #ifdef HP_IP4FRAG_DEFAULT 2346 + #define CAS_HP_FIRMWARE cas_prog_ip4fragtab 2347 + #endif 2348 + #endif 2349 + 2350 + /* 2351 + * Alternate table which does batching without reassembly 2352 + */ 2353 + #ifdef USE_HP_IP46TCP4BATCH 2354 + static cas_hp_inst_t cas_prog_ip46tcp4batchtab[] = { 2355 + CAS_PROG_IP46TCP4_PREAMBLE, 2356 + { "TCP seq", /* DADDR should point to dest port */ 2357 + 0x0000, 0x0000, OP_EQ, 0, S1_TCPFG, 0, S1_TCPFG, LD_SEQ, 2358 + 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */ 2359 + { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHL, 0, 2360 + S1_TCPHL, ST_FLG, 0x000, 3, 0x0, 0x0000}, /* Load TCP flags */ 2361 + { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, 2362 + S1_TCPHc, LD_R1, 0x205, 3, 0xB, 0xf000}, 2363 + { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, 2364 + S1_PCKT, IM_CTL, 0x040, 3, 0x0, 0xffff}, /* set batch bit */ 2365 + { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2366 + IM_CTL, 0x001, 3, 0x0, 0x0001}, 2367 + { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, 2368 + S1_PCKT, IM_CTL, 0x080, 3, 0x0, 0xffff}, 2369 + { NULL }, 2370 + }; 2371 + #ifdef HP_IP46TCP4BATCH_DEFAULT 2372 + #define CAS_HP_FIRMWARE cas_prog_ip46tcp4batchtab 2373 + #endif 2374 + #endif 2375 + 2376 + /* Workaround for Cassini rev2 descriptor corruption problem. 2377 + * Does batching without reassembly, and sets the SAP to a known 2378 + * data pattern for all packets. 2379 + */ 2380 + #ifdef USE_HP_WORKAROUND 2381 + static cas_hp_inst_t cas_prog_workaroundtab[] = { 2382 + { "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0, 2383 + S1_PCKT, CL_REG, 0x3ff, 1, 0x0, 0x0000} , 2384 + { "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023, 2385 + IM_CTL, 0x04a, 3, 0x0, 0xffff}, 2386 + { "CFI?", 0x1000, 0x1000, OP_EQ, 0, S1_CLNP, 1, S1_8023, 2387 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2388 + { "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4, 2389 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2390 + { "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S1_CLNP, 2391 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2392 + { "LLCc?", 0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S1_CLNP, 2393 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2394 + { "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6, 2395 + IM_SAP, 0x6AE, 3, 0x0, 0xffff}, 2396 + { "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S1_CLNP, 2397 + LD_SUM, 0x00a, 1, 0x0, 0x0000}, 2398 + { "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S1_CLNP, 2399 + LD_LEN, 0x03e, 1, 0x0, 0xffff}, 2400 + { "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S1_TCPSQ, 0, S1_CLNP, 2401 + LD_FID, 0x182, 3, 0x0, 0xffff}, /* FID IP4&TCP src+dst */ 2402 + { "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S1_IPV6L, 0, S1_CLNP, 2403 + LD_SUM, 0x015, 1, 0x0, 0x0000}, 2404 + { "IPV6 len", 0xf000, 0x6000, OP_EQ, 0, S1_IPV6c, 0, S1_CLNP, 2405 + IM_R1, 0x128, 1, 0x0, 0xffff}, 2406 + { "IPV6 cont?", 0x0000, 0x0000, OP_EQ, 3, S1_TCP64, 0, S1_CLNP, 2407 + LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */ 2408 + { "TCP64?", 0xff00, 0x0600, OP_EQ, 18, S1_TCPSQ, 0, S1_CLNP, 2409 + LD_LEN, 0x03f, 1, 0x0, 0xffff}, 2410 + { "TCP seq", /* DADDR should point to dest port */ 2411 + 0x0000, 0x0000, OP_EQ, 0, S1_TCPFG, 4, S1_TCPFG, LD_SEQ, 2412 + 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */ 2413 + { "TCP control flags", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHL, 0, 2414 + S1_TCPHL, ST_FLG, 0x045, 3, 0x0, 0x002f}, /* Load TCP flags */ 2415 + { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, S1_TCPHc, 2416 + LD_R1, 0x205, 3, 0xB, 0xf000}, 2417 + { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, 2418 + S1_PCKT, LD_HDR, 0x0ff, 3, 0x0, 0xffff}, 2419 + { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2, 2420 + IM_SAP, 0x6AE, 3, 0x0, 0xffff} , 2421 + { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2422 + IM_CTL, 0x001, 3, 0x0, 0x0001}, 2423 + { NULL }, 2424 + }; 2425 + #ifdef HP_WORKAROUND_DEFAULT 2426 + #define CAS_HP_FIRMWARE cas_prog_workaroundtab 2427 + #endif 2428 + #endif 2429 + 2430 + #ifdef USE_HP_ENCRYPT 2431 + static cas_hp_inst_t cas_prog_encryptiontab[] = { 2432 + { "packet arrival?", 0xffff, 0x0000, OP_NP, 6, S1_VLAN, 0, 2433 + S1_PCKT, CL_REG, 0x3ff, 1, 0x0, 0x0000}, 2434 + { "VLAN?", 0xffff, 0x8100, OP_EQ, 1, S1_CFI, 0, S1_8023, 2435 + IM_CTL, 0x00a, 3, 0x0, 0xffff}, 2436 + #if 0 2437 + //"CFI?", /* 02 FIND CFI and If FIND go to S1_DROP */ 2438 + //0x1000, 0x1000, OP_EQ, 0, S1_DROP, 1, S1_8023, CL_REG, 0x000, 0, 0x0, 0x00 2439 + 00, 2440 + #endif 2441 + { "CFI?", /* FIND CFI and If FIND go to CleanUP1 (ignore and send to host) */ 2442 + 0x1000, 0x1000, OP_EQ, 0, S1_CLNP, 1, S1_8023, 2443 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2444 + { "8023?", 0xffff, 0x0600, OP_LT, 1, S1_LLC, 0, S1_IPV4, 2445 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2446 + { "LLC?", 0xffff, 0xaaaa, OP_EQ, 1, S1_LLCc, 0, S1_CLNP, 2447 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2448 + { "LLCc?", 0xff00, 0x0300, OP_EQ, 2, S1_IPV4, 0, S1_CLNP, 2449 + CL_REG, 0x000, 0, 0x0, 0x0000}, 2450 + { "IPV4?", 0xffff, 0x0800, OP_EQ, 1, S1_IPV4c, 0, S1_IPV6, 2451 + LD_SAP, 0x100, 3, 0x0, 0xffff}, 2452 + { "IPV4 cont?", 0xff00, 0x4500, OP_EQ, 3, S1_IPV4F, 0, S1_CLNP, 2453 + LD_SUM, 0x00a, 1, 0x0, 0x0000}, 2454 + { "IPV4 frag?", 0x3fff, 0x0000, OP_EQ, 1, S1_TCP44, 0, S1_CLNP, 2455 + LD_LEN, 0x03e, 1, 0x0, 0xffff}, 2456 + { "TCP44?", 0x00ff, 0x0006, OP_EQ, 7, S1_TCPSQ, 0, S1_ESP4, 2457 + LD_FID, 0x182, 1, 0x0, 0xffff}, /* FID IP4&TCP src+dst */ 2458 + { "IPV6?", 0xffff, 0x86dd, OP_EQ, 1, S1_IPV6L, 0, S1_CLNP, 2459 + LD_SUM, 0x015, 1, 0x0, 0x0000}, 2460 + { "IPV6 len", 0xf000, 0x6000, OP_EQ, 0, S1_IPV6c, 0, S1_CLNP, 2461 + IM_R1, 0x128, 1, 0x0, 0xffff}, 2462 + { "IPV6 cont?", 0x0000, 0x0000, OP_EQ, 3, S1_TCP64, 0, S1_CLNP, 2463 + LD_FID, 0x484, 1, 0x0, 0xffff}, /* FID IP6&TCP src+dst */ 2464 + { "TCP64?", 2465 + #if 0 2466 + //@@@0xff00, 0x0600, OP_EQ, 18, S1_TCPSQ, 0, S1_ESP6, LD_LEN, 0x03f, 1, 0x0, 0xffff, 2467 + #endif 2468 + 0xff00, 0x0600, OP_EQ, 12, S1_TCPSQ, 0, S1_ESP6, LD_LEN, 2469 + 0x03f, 1, 0x0, 0xffff}, 2470 + { "TCP seq", /* 14:DADDR should point to dest port */ 2471 + 0xFFFF, 0x0080, OP_EQ, 0, S2_HTTP, 0, S1_TCPFG, LD_SEQ, 2472 + 0x081, 3, 0x0, 0xffff}, /* Load TCP seq # */ 2473 + { "TCP control flags", 0xFFFF, 0x8080, OP_EQ, 0, S2_HTTP, 0, 2474 + S1_TCPHL, ST_FLG, 0x145, 2, 0x0, 0x002f}, /* Load TCP flags */ 2475 + { "TCP length", 0x0000, 0x0000, OP_EQ, 0, S1_TCPHc, 0, S1_TCPHc, 2476 + LD_R1, 0x205, 3, 0xB, 0xf000} , 2477 + { "TCP length cont", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, 2478 + S1_PCKT, LD_HDR, 0x0ff, 3, 0x0, 0xffff}, 2479 + { "Cleanup", 0x0000, 0x0000, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP2, 2480 + IM_CTL, 0x001, 3, 0x0, 0x0001}, 2481 + { "Cleanup 2", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2482 + CL_REG, 0x002, 3, 0x0, 0x0000}, 2483 + { "Drop packet", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2484 + IM_CTL, 0x080, 3, 0x0, 0xffff}, 2485 + { "No HTTP", 0x0000, 0x0000, OP_EQ, 0, S1_PCKT, 0, S1_PCKT, 2486 + IM_CTL, 0x044, 3, 0x0, 0xffff}, 2487 + { "IPV4 ESP encrypted?", /* S1_ESP4 */ 2488 + 0x00ff, 0x0032, OP_EQ, 0, S1_CLNP2, 0, S1_AH4, IM_CTL, 2489 + 0x021, 1, 0x0, 0xffff}, 2490 + { "IPV4 AH encrypted?", /* S1_AH4 */ 2491 + 0x00ff, 0x0033, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP, IM_CTL, 2492 + 0x021, 1, 0x0, 0xffff}, 2493 + { "IPV6 ESP encrypted?", /* S1_ESP6 */ 2494 + #if 0 2495 + //@@@0x00ff, 0x0032, OP_EQ, 0, S1_CLNP2, 0, S1_AH6, IM_CTL, 0x021, 1, 0x0, 0xffff, 2496 + #endif 2497 + 0xff00, 0x3200, OP_EQ, 0, S1_CLNP2, 0, S1_AH6, IM_CTL, 2498 + 0x021, 1, 0x0, 0xffff}, 2499 + { "IPV6 AH encrypted?", /* S1_AH6 */ 2500 + #if 0 2501 + //@@@0x00ff, 0x0033, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP, IM_CTL, 0x021, 1, 0x0, 0xffff, 2502 + #endif 2503 + 0xff00, 0x3300, OP_EQ, 0, S1_CLNP2, 0, S1_CLNP, IM_CTL, 2504 + 0x021, 1, 0x0, 0xffff}, 2505 + { NULL }, 2506 + }; 2507 + #ifdef HP_ENCRYPT_DEFAULT 2508 + #define CAS_HP_FIRMWARE cas_prog_encryptiontab 2509 + #endif 2510 + #endif 2511 + 2512 + static cas_hp_inst_t cas_prog_null[] = { {NULL} }; 2513 + #ifdef HP_NULL_DEFAULT 2514 + #define CAS_HP_FIRMWARE cas_prog_null 2515 + #endif 2516 + 2517 + /* firmware patch for NS_DP83065 */ 2518 + typedef struct cas_saturn_patch { 2519 + u16 addr; 2520 + u16 val; 2521 + } cas_saturn_patch_t; 2522 + 2523 + #if 1 2524 + cas_saturn_patch_t cas_saturn_patch[] = { 2525 + {0x8200, 0x007e}, {0x8201, 0x0082}, {0x8202, 0x0009}, 2526 + {0x8203, 0x0000}, {0x8204, 0x0000}, {0x8205, 0x0000}, 2527 + {0x8206, 0x0000}, {0x8207, 0x0000}, {0x8208, 0x0000}, 2528 + {0x8209, 0x008e}, {0x820a, 0x008e}, {0x820b, 0x00ff}, 2529 + {0x820c, 0x00ce}, {0x820d, 0x0082}, {0x820e, 0x0025}, 2530 + {0x820f, 0x00ff}, {0x8210, 0x0001}, {0x8211, 0x000f}, 2531 + {0x8212, 0x00ce}, {0x8213, 0x0084}, {0x8214, 0x0026}, 2532 + {0x8215, 0x00ff}, {0x8216, 0x0001}, {0x8217, 0x0011}, 2533 + {0x8218, 0x00ce}, {0x8219, 0x0085}, {0x821a, 0x003d}, 2534 + {0x821b, 0x00df}, {0x821c, 0x00e5}, {0x821d, 0x0086}, 2535 + {0x821e, 0x0039}, {0x821f, 0x00b7}, {0x8220, 0x008f}, 2536 + {0x8221, 0x00f8}, {0x8222, 0x007e}, {0x8223, 0x00c3}, 2537 + {0x8224, 0x00c2}, {0x8225, 0x0096}, {0x8226, 0x0047}, 2538 + {0x8227, 0x0084}, {0x8228, 0x00f3}, {0x8229, 0x008a}, 2539 + {0x822a, 0x0000}, {0x822b, 0x0097}, {0x822c, 0x0047}, 2540 + {0x822d, 0x00ce}, {0x822e, 0x0082}, {0x822f, 0x0033}, 2541 + {0x8230, 0x00ff}, {0x8231, 0x0001}, {0x8232, 0x000f}, 2542 + {0x8233, 0x0096}, {0x8234, 0x0046}, {0x8235, 0x0084}, 2543 + {0x8236, 0x000c}, {0x8237, 0x0081}, {0x8238, 0x0004}, 2544 + {0x8239, 0x0027}, {0x823a, 0x000b}, {0x823b, 0x0096}, 2545 + {0x823c, 0x0046}, {0x823d, 0x0084}, {0x823e, 0x000c}, 2546 + {0x823f, 0x0081}, {0x8240, 0x0008}, {0x8241, 0x0027}, 2547 + {0x8242, 0x0057}, {0x8243, 0x007e}, {0x8244, 0x0084}, 2548 + {0x8245, 0x0025}, {0x8246, 0x0096}, {0x8247, 0x0047}, 2549 + {0x8248, 0x0084}, {0x8249, 0x00f3}, {0x824a, 0x008a}, 2550 + {0x824b, 0x0004}, {0x824c, 0x0097}, {0x824d, 0x0047}, 2551 + {0x824e, 0x00ce}, {0x824f, 0x0082}, {0x8250, 0x0054}, 2552 + {0x8251, 0x00ff}, {0x8252, 0x0001}, {0x8253, 0x000f}, 2553 + {0x8254, 0x0096}, {0x8255, 0x0046}, {0x8256, 0x0084}, 2554 + {0x8257, 0x000c}, {0x8258, 0x0081}, {0x8259, 0x0004}, 2555 + {0x825a, 0x0026}, {0x825b, 0x0038}, {0x825c, 0x00b6}, 2556 + {0x825d, 0x0012}, {0x825e, 0x0020}, {0x825f, 0x0084}, 2557 + {0x8260, 0x0020}, {0x8261, 0x0026}, {0x8262, 0x0003}, 2558 + {0x8263, 0x007e}, {0x8264, 0x0084}, {0x8265, 0x0025}, 2559 + {0x8266, 0x0096}, {0x8267, 0x007b}, {0x8268, 0x00d6}, 2560 + {0x8269, 0x007c}, {0x826a, 0x00fe}, {0x826b, 0x008f}, 2561 + {0x826c, 0x0056}, {0x826d, 0x00bd}, {0x826e, 0x00f7}, 2562 + {0x826f, 0x00b6}, {0x8270, 0x00fe}, {0x8271, 0x008f}, 2563 + {0x8272, 0x004e}, {0x8273, 0x00bd}, {0x8274, 0x00ec}, 2564 + {0x8275, 0x008e}, {0x8276, 0x00bd}, {0x8277, 0x00fa}, 2565 + {0x8278, 0x00f7}, {0x8279, 0x00bd}, {0x827a, 0x00f7}, 2566 + {0x827b, 0x0028}, {0x827c, 0x00ce}, {0x827d, 0x0082}, 2567 + {0x827e, 0x0082}, {0x827f, 0x00ff}, {0x8280, 0x0001}, 2568 + {0x8281, 0x000f}, {0x8282, 0x0096}, {0x8283, 0x0046}, 2569 + {0x8284, 0x0084}, {0x8285, 0x000c}, {0x8286, 0x0081}, 2570 + {0x8287, 0x0004}, {0x8288, 0x0026}, {0x8289, 0x000a}, 2571 + {0x828a, 0x00b6}, {0x828b, 0x0012}, {0x828c, 0x0020}, 2572 + {0x828d, 0x0084}, {0x828e, 0x0020}, {0x828f, 0x0027}, 2573 + {0x8290, 0x00b5}, {0x8291, 0x007e}, {0x8292, 0x0084}, 2574 + {0x8293, 0x0025}, {0x8294, 0x00bd}, {0x8295, 0x00f7}, 2575 + {0x8296, 0x001f}, {0x8297, 0x007e}, {0x8298, 0x0084}, 2576 + {0x8299, 0x001f}, {0x829a, 0x0096}, {0x829b, 0x0047}, 2577 + {0x829c, 0x0084}, {0x829d, 0x00f3}, {0x829e, 0x008a}, 2578 + {0x829f, 0x0008}, {0x82a0, 0x0097}, {0x82a1, 0x0047}, 2579 + {0x82a2, 0x00de}, {0x82a3, 0x00e1}, {0x82a4, 0x00ad}, 2580 + {0x82a5, 0x0000}, {0x82a6, 0x00ce}, {0x82a7, 0x0082}, 2581 + {0x82a8, 0x00af}, {0x82a9, 0x00ff}, {0x82aa, 0x0001}, 2582 + {0x82ab, 0x000f}, {0x82ac, 0x007e}, {0x82ad, 0x0084}, 2583 + {0x82ae, 0x0025}, {0x82af, 0x0096}, {0x82b0, 0x0041}, 2584 + {0x82b1, 0x0085}, {0x82b2, 0x0010}, {0x82b3, 0x0026}, 2585 + {0x82b4, 0x0006}, {0x82b5, 0x0096}, {0x82b6, 0x0023}, 2586 + {0x82b7, 0x0085}, {0x82b8, 0x0040}, {0x82b9, 0x0027}, 2587 + {0x82ba, 0x0006}, {0x82bb, 0x00bd}, {0x82bc, 0x00ed}, 2588 + {0x82bd, 0x0000}, {0x82be, 0x007e}, {0x82bf, 0x0083}, 2589 + {0x82c0, 0x00a2}, {0x82c1, 0x00de}, {0x82c2, 0x0042}, 2590 + {0x82c3, 0x00bd}, {0x82c4, 0x00eb}, {0x82c5, 0x008e}, 2591 + {0x82c6, 0x0096}, {0x82c7, 0x0024}, {0x82c8, 0x0084}, 2592 + {0x82c9, 0x0008}, {0x82ca, 0x0027}, {0x82cb, 0x0003}, 2593 + {0x82cc, 0x007e}, {0x82cd, 0x0083}, {0x82ce, 0x00df}, 2594 + {0x82cf, 0x0096}, {0x82d0, 0x007b}, {0x82d1, 0x00d6}, 2595 + {0x82d2, 0x007c}, {0x82d3, 0x00fe}, {0x82d4, 0x008f}, 2596 + {0x82d5, 0x0056}, {0x82d6, 0x00bd}, {0x82d7, 0x00f7}, 2597 + {0x82d8, 0x00b6}, {0x82d9, 0x00fe}, {0x82da, 0x008f}, 2598 + {0x82db, 0x0050}, {0x82dc, 0x00bd}, {0x82dd, 0x00ec}, 2599 + {0x82de, 0x008e}, {0x82df, 0x00bd}, {0x82e0, 0x00fa}, 2600 + {0x82e1, 0x00f7}, {0x82e2, 0x0086}, {0x82e3, 0x0011}, 2601 + {0x82e4, 0x00c6}, {0x82e5, 0x0049}, {0x82e6, 0x00bd}, 2602 + {0x82e7, 0x00e4}, {0x82e8, 0x0012}, {0x82e9, 0x00ce}, 2603 + {0x82ea, 0x0082}, {0x82eb, 0x00ef}, {0x82ec, 0x00ff}, 2604 + {0x82ed, 0x0001}, {0x82ee, 0x000f}, {0x82ef, 0x0096}, 2605 + {0x82f0, 0x0046}, {0x82f1, 0x0084}, {0x82f2, 0x000c}, 2606 + {0x82f3, 0x0081}, {0x82f4, 0x0000}, {0x82f5, 0x0027}, 2607 + {0x82f6, 0x0017}, {0x82f7, 0x00c6}, {0x82f8, 0x0049}, 2608 + {0x82f9, 0x00bd}, {0x82fa, 0x00e4}, {0x82fb, 0x0091}, 2609 + {0x82fc, 0x0024}, {0x82fd, 0x000d}, {0x82fe, 0x00b6}, 2610 + {0x82ff, 0x0012}, {0x8300, 0x0020}, {0x8301, 0x0085}, 2611 + {0x8302, 0x0020}, {0x8303, 0x0026}, {0x8304, 0x000c}, 2612 + {0x8305, 0x00ce}, {0x8306, 0x0082}, {0x8307, 0x00c1}, 2613 + {0x8308, 0x00ff}, {0x8309, 0x0001}, {0x830a, 0x000f}, 2614 + {0x830b, 0x007e}, {0x830c, 0x0084}, {0x830d, 0x0025}, 2615 + {0x830e, 0x007e}, {0x830f, 0x0084}, {0x8310, 0x0016}, 2616 + {0x8311, 0x00fe}, {0x8312, 0x008f}, {0x8313, 0x0052}, 2617 + {0x8314, 0x00bd}, {0x8315, 0x00ec}, {0x8316, 0x008e}, 2618 + {0x8317, 0x00bd}, {0x8318, 0x00fa}, {0x8319, 0x00f7}, 2619 + {0x831a, 0x0086}, {0x831b, 0x006a}, {0x831c, 0x00c6}, 2620 + {0x831d, 0x0049}, {0x831e, 0x00bd}, {0x831f, 0x00e4}, 2621 + {0x8320, 0x0012}, {0x8321, 0x00ce}, {0x8322, 0x0083}, 2622 + {0x8323, 0x0027}, {0x8324, 0x00ff}, {0x8325, 0x0001}, 2623 + {0x8326, 0x000f}, {0x8327, 0x0096}, {0x8328, 0x0046}, 2624 + {0x8329, 0x0084}, {0x832a, 0x000c}, {0x832b, 0x0081}, 2625 + {0x832c, 0x0000}, {0x832d, 0x0027}, {0x832e, 0x000a}, 2626 + {0x832f, 0x00c6}, {0x8330, 0x0049}, {0x8331, 0x00bd}, 2627 + {0x8332, 0x00e4}, {0x8333, 0x0091}, {0x8334, 0x0025}, 2628 + {0x8335, 0x0006}, {0x8336, 0x007e}, {0x8337, 0x0084}, 2629 + {0x8338, 0x0025}, {0x8339, 0x007e}, {0x833a, 0x0084}, 2630 + {0x833b, 0x0016}, {0x833c, 0x00b6}, {0x833d, 0x0018}, 2631 + {0x833e, 0x0070}, {0x833f, 0x00bb}, {0x8340, 0x0019}, 2632 + {0x8341, 0x0070}, {0x8342, 0x002a}, {0x8343, 0x0004}, 2633 + {0x8344, 0x0081}, {0x8345, 0x00af}, {0x8346, 0x002e}, 2634 + {0x8347, 0x0019}, {0x8348, 0x0096}, {0x8349, 0x007b}, 2635 + {0x834a, 0x00f6}, {0x834b, 0x0020}, {0x834c, 0x0007}, 2636 + {0x834d, 0x00fa}, {0x834e, 0x0020}, {0x834f, 0x0027}, 2637 + {0x8350, 0x00c4}, {0x8351, 0x0038}, {0x8352, 0x0081}, 2638 + {0x8353, 0x0038}, {0x8354, 0x0027}, {0x8355, 0x000b}, 2639 + {0x8356, 0x00f6}, {0x8357, 0x0020}, {0x8358, 0x0007}, 2640 + {0x8359, 0x00fa}, {0x835a, 0x0020}, {0x835b, 0x0027}, 2641 + {0x835c, 0x00cb}, {0x835d, 0x0008}, {0x835e, 0x007e}, 2642 + {0x835f, 0x0082}, {0x8360, 0x00d3}, {0x8361, 0x00bd}, 2643 + {0x8362, 0x00f7}, {0x8363, 0x0066}, {0x8364, 0x0086}, 2644 + {0x8365, 0x0074}, {0x8366, 0x00c6}, {0x8367, 0x0049}, 2645 + {0x8368, 0x00bd}, {0x8369, 0x00e4}, {0x836a, 0x0012}, 2646 + {0x836b, 0x00ce}, {0x836c, 0x0083}, {0x836d, 0x0071}, 2647 + {0x836e, 0x00ff}, {0x836f, 0x0001}, {0x8370, 0x000f}, 2648 + {0x8371, 0x0096}, {0x8372, 0x0046}, {0x8373, 0x0084}, 2649 + {0x8374, 0x000c}, {0x8375, 0x0081}, {0x8376, 0x0008}, 2650 + {0x8377, 0x0026}, {0x8378, 0x000a}, {0x8379, 0x00c6}, 2651 + {0x837a, 0x0049}, {0x837b, 0x00bd}, {0x837c, 0x00e4}, 2652 + {0x837d, 0x0091}, {0x837e, 0x0025}, {0x837f, 0x0006}, 2653 + {0x8380, 0x007e}, {0x8381, 0x0084}, {0x8382, 0x0025}, 2654 + {0x8383, 0x007e}, {0x8384, 0x0084}, {0x8385, 0x0016}, 2655 + {0x8386, 0x00bd}, {0x8387, 0x00f7}, {0x8388, 0x003e}, 2656 + {0x8389, 0x0026}, {0x838a, 0x000e}, {0x838b, 0x00bd}, 2657 + {0x838c, 0x00e5}, {0x838d, 0x0009}, {0x838e, 0x0026}, 2658 + {0x838f, 0x0006}, {0x8390, 0x00ce}, {0x8391, 0x0082}, 2659 + {0x8392, 0x00c1}, {0x8393, 0x00ff}, {0x8394, 0x0001}, 2660 + {0x8395, 0x000f}, {0x8396, 0x007e}, {0x8397, 0x0084}, 2661 + {0x8398, 0x0025}, {0x8399, 0x00fe}, {0x839a, 0x008f}, 2662 + {0x839b, 0x0054}, {0x839c, 0x00bd}, {0x839d, 0x00ec}, 2663 + {0x839e, 0x008e}, {0x839f, 0x00bd}, {0x83a0, 0x00fa}, 2664 + {0x83a1, 0x00f7}, {0x83a2, 0x00bd}, {0x83a3, 0x00f7}, 2665 + {0x83a4, 0x0033}, {0x83a5, 0x0086}, {0x83a6, 0x000f}, 2666 + {0x83a7, 0x00c6}, {0x83a8, 0x0051}, {0x83a9, 0x00bd}, 2667 + {0x83aa, 0x00e4}, {0x83ab, 0x0012}, {0x83ac, 0x00ce}, 2668 + {0x83ad, 0x0083}, {0x83ae, 0x00b2}, {0x83af, 0x00ff}, 2669 + {0x83b0, 0x0001}, {0x83b1, 0x000f}, {0x83b2, 0x0096}, 2670 + {0x83b3, 0x0046}, {0x83b4, 0x0084}, {0x83b5, 0x000c}, 2671 + {0x83b6, 0x0081}, {0x83b7, 0x0008}, {0x83b8, 0x0026}, 2672 + {0x83b9, 0x005c}, {0x83ba, 0x00b6}, {0x83bb, 0x0012}, 2673 + {0x83bc, 0x0020}, {0x83bd, 0x0084}, {0x83be, 0x003f}, 2674 + {0x83bf, 0x0081}, {0x83c0, 0x003a}, {0x83c1, 0x0027}, 2675 + {0x83c2, 0x001c}, {0x83c3, 0x0096}, {0x83c4, 0x0023}, 2676 + {0x83c5, 0x0085}, {0x83c6, 0x0040}, {0x83c7, 0x0027}, 2677 + {0x83c8, 0x0003}, {0x83c9, 0x007e}, {0x83ca, 0x0084}, 2678 + {0x83cb, 0x0025}, {0x83cc, 0x00c6}, {0x83cd, 0x0051}, 2679 + {0x83ce, 0x00bd}, {0x83cf, 0x00e4}, {0x83d0, 0x0091}, 2680 + {0x83d1, 0x0025}, {0x83d2, 0x0003}, {0x83d3, 0x007e}, 2681 + {0x83d4, 0x0084}, {0x83d5, 0x0025}, {0x83d6, 0x00ce}, 2682 + {0x83d7, 0x0082}, {0x83d8, 0x00c1}, {0x83d9, 0x00ff}, 2683 + {0x83da, 0x0001}, {0x83db, 0x000f}, {0x83dc, 0x007e}, 2684 + {0x83dd, 0x0084}, {0x83de, 0x0025}, {0x83df, 0x00bd}, 2685 + {0x83e0, 0x00f8}, {0x83e1, 0x0037}, {0x83e2, 0x007c}, 2686 + {0x83e3, 0x0000}, {0x83e4, 0x007a}, {0x83e5, 0x00ce}, 2687 + {0x83e6, 0x0083}, {0x83e7, 0x00ee}, {0x83e8, 0x00ff}, 2688 + {0x83e9, 0x0001}, {0x83ea, 0x000f}, {0x83eb, 0x007e}, 2689 + {0x83ec, 0x0084}, {0x83ed, 0x0025}, {0x83ee, 0x0096}, 2690 + {0x83ef, 0x0046}, {0x83f0, 0x0084}, {0x83f1, 0x000c}, 2691 + {0x83f2, 0x0081}, {0x83f3, 0x0008}, {0x83f4, 0x0026}, 2692 + {0x83f5, 0x0020}, {0x83f6, 0x0096}, {0x83f7, 0x0024}, 2693 + {0x83f8, 0x0084}, {0x83f9, 0x0008}, {0x83fa, 0x0026}, 2694 + {0x83fb, 0x0029}, {0x83fc, 0x00b6}, {0x83fd, 0x0018}, 2695 + {0x83fe, 0x0082}, {0x83ff, 0x00bb}, {0x8400, 0x0019}, 2696 + {0x8401, 0x0082}, {0x8402, 0x00b1}, {0x8403, 0x0001}, 2697 + {0x8404, 0x003b}, {0x8405, 0x0022}, {0x8406, 0x0009}, 2698 + {0x8407, 0x00b6}, {0x8408, 0x0012}, {0x8409, 0x0020}, 2699 + {0x840a, 0x0084}, {0x840b, 0x0037}, {0x840c, 0x0081}, 2700 + {0x840d, 0x0032}, {0x840e, 0x0027}, {0x840f, 0x0015}, 2701 + {0x8410, 0x00bd}, {0x8411, 0x00f8}, {0x8412, 0x0044}, 2702 + {0x8413, 0x007e}, {0x8414, 0x0082}, {0x8415, 0x00c1}, 2703 + {0x8416, 0x00bd}, {0x8417, 0x00f7}, {0x8418, 0x001f}, 2704 + {0x8419, 0x00bd}, {0x841a, 0x00f8}, {0x841b, 0x0044}, 2705 + {0x841c, 0x00bd}, {0x841d, 0x00fc}, {0x841e, 0x0029}, 2706 + {0x841f, 0x00ce}, {0x8420, 0x0082}, {0x8421, 0x0025}, 2707 + {0x8422, 0x00ff}, {0x8423, 0x0001}, {0x8424, 0x000f}, 2708 + {0x8425, 0x0039}, {0x8426, 0x0096}, {0x8427, 0x0047}, 2709 + {0x8428, 0x0084}, {0x8429, 0x00fc}, {0x842a, 0x008a}, 2710 + {0x842b, 0x0000}, {0x842c, 0x0097}, {0x842d, 0x0047}, 2711 + {0x842e, 0x00ce}, {0x842f, 0x0084}, {0x8430, 0x0034}, 2712 + {0x8431, 0x00ff}, {0x8432, 0x0001}, {0x8433, 0x0011}, 2713 + {0x8434, 0x0096}, {0x8435, 0x0046}, {0x8436, 0x0084}, 2714 + {0x8437, 0x0003}, {0x8438, 0x0081}, {0x8439, 0x0002}, 2715 + {0x843a, 0x0027}, {0x843b, 0x0003}, {0x843c, 0x007e}, 2716 + {0x843d, 0x0085}, {0x843e, 0x001e}, {0x843f, 0x0096}, 2717 + {0x8440, 0x0047}, {0x8441, 0x0084}, {0x8442, 0x00fc}, 2718 + {0x8443, 0x008a}, {0x8444, 0x0002}, {0x8445, 0x0097}, 2719 + {0x8446, 0x0047}, {0x8447, 0x00de}, {0x8448, 0x00e1}, 2720 + {0x8449, 0x00ad}, {0x844a, 0x0000}, {0x844b, 0x0086}, 2721 + {0x844c, 0x0001}, {0x844d, 0x00b7}, {0x844e, 0x0012}, 2722 + {0x844f, 0x0051}, {0x8450, 0x00bd}, {0x8451, 0x00f7}, 2723 + {0x8452, 0x0014}, {0x8453, 0x00b6}, {0x8454, 0x0010}, 2724 + {0x8455, 0x0031}, {0x8456, 0x0084}, {0x8457, 0x00fd}, 2725 + {0x8458, 0x00b7}, {0x8459, 0x0010}, {0x845a, 0x0031}, 2726 + {0x845b, 0x00bd}, {0x845c, 0x00f8}, {0x845d, 0x001e}, 2727 + {0x845e, 0x0096}, {0x845f, 0x0081}, {0x8460, 0x00d6}, 2728 + {0x8461, 0x0082}, {0x8462, 0x00fe}, {0x8463, 0x008f}, 2729 + {0x8464, 0x005a}, {0x8465, 0x00bd}, {0x8466, 0x00f7}, 2730 + {0x8467, 0x00b6}, {0x8468, 0x00fe}, {0x8469, 0x008f}, 2731 + {0x846a, 0x005c}, {0x846b, 0x00bd}, {0x846c, 0x00ec}, 2732 + {0x846d, 0x008e}, {0x846e, 0x00bd}, {0x846f, 0x00fa}, 2733 + {0x8470, 0x00f7}, {0x8471, 0x0086}, {0x8472, 0x0008}, 2734 + {0x8473, 0x00d6}, {0x8474, 0x0000}, {0x8475, 0x00c5}, 2735 + {0x8476, 0x0010}, {0x8477, 0x0026}, {0x8478, 0x0002}, 2736 + {0x8479, 0x008b}, {0x847a, 0x0020}, {0x847b, 0x00c6}, 2737 + {0x847c, 0x0051}, {0x847d, 0x00bd}, {0x847e, 0x00e4}, 2738 + {0x847f, 0x0012}, {0x8480, 0x00ce}, {0x8481, 0x0084}, 2739 + {0x8482, 0x0086}, {0x8483, 0x00ff}, {0x8484, 0x0001}, 2740 + {0x8485, 0x0011}, {0x8486, 0x0096}, {0x8487, 0x0046}, 2741 + {0x8488, 0x0084}, {0x8489, 0x0003}, {0x848a, 0x0081}, 2742 + {0x848b, 0x0002}, {0x848c, 0x0027}, {0x848d, 0x0003}, 2743 + {0x848e, 0x007e}, {0x848f, 0x0085}, {0x8490, 0x000f}, 2744 + {0x8491, 0x00c6}, {0x8492, 0x0051}, {0x8493, 0x00bd}, 2745 + {0x8494, 0x00e4}, {0x8495, 0x0091}, {0x8496, 0x0025}, 2746 + {0x8497, 0x0003}, {0x8498, 0x007e}, {0x8499, 0x0085}, 2747 + {0x849a, 0x001e}, {0x849b, 0x0096}, {0x849c, 0x0044}, 2748 + {0x849d, 0x0085}, {0x849e, 0x0010}, {0x849f, 0x0026}, 2749 + {0x84a0, 0x000a}, {0x84a1, 0x00b6}, {0x84a2, 0x0012}, 2750 + {0x84a3, 0x0050}, {0x84a4, 0x00ba}, {0x84a5, 0x0001}, 2751 + {0x84a6, 0x003c}, {0x84a7, 0x0085}, {0x84a8, 0x0010}, 2752 + {0x84a9, 0x0027}, {0x84aa, 0x00a8}, {0x84ab, 0x00bd}, 2753 + {0x84ac, 0x00f7}, {0x84ad, 0x0066}, {0x84ae, 0x00ce}, 2754 + {0x84af, 0x0084}, {0x84b0, 0x00b7}, {0x84b1, 0x00ff}, 2755 + {0x84b2, 0x0001}, {0x84b3, 0x0011}, {0x84b4, 0x007e}, 2756 + {0x84b5, 0x0085}, {0x84b6, 0x001e}, {0x84b7, 0x0096}, 2757 + {0x84b8, 0x0046}, {0x84b9, 0x0084}, {0x84ba, 0x0003}, 2758 + {0x84bb, 0x0081}, {0x84bc, 0x0002}, {0x84bd, 0x0026}, 2759 + {0x84be, 0x0050}, {0x84bf, 0x00b6}, {0x84c0, 0x0012}, 2760 + {0x84c1, 0x0030}, {0x84c2, 0x0084}, {0x84c3, 0x0003}, 2761 + {0x84c4, 0x0081}, {0x84c5, 0x0001}, {0x84c6, 0x0027}, 2762 + {0x84c7, 0x0003}, {0x84c8, 0x007e}, {0x84c9, 0x0085}, 2763 + {0x84ca, 0x001e}, {0x84cb, 0x0096}, {0x84cc, 0x0044}, 2764 + {0x84cd, 0x0085}, {0x84ce, 0x0010}, {0x84cf, 0x0026}, 2765 + {0x84d0, 0x0013}, {0x84d1, 0x00b6}, {0x84d2, 0x0012}, 2766 + {0x84d3, 0x0050}, {0x84d4, 0x00ba}, {0x84d5, 0x0001}, 2767 + {0x84d6, 0x003c}, {0x84d7, 0x0085}, {0x84d8, 0x0010}, 2768 + {0x84d9, 0x0026}, {0x84da, 0x0009}, {0x84db, 0x00ce}, 2769 + {0x84dc, 0x0084}, {0x84dd, 0x0053}, {0x84de, 0x00ff}, 2770 + {0x84df, 0x0001}, {0x84e0, 0x0011}, {0x84e1, 0x007e}, 2771 + {0x84e2, 0x0085}, {0x84e3, 0x001e}, {0x84e4, 0x00b6}, 2772 + {0x84e5, 0x0010}, {0x84e6, 0x0031}, {0x84e7, 0x008a}, 2773 + {0x84e8, 0x0002}, {0x84e9, 0x00b7}, {0x84ea, 0x0010}, 2774 + {0x84eb, 0x0031}, {0x84ec, 0x00bd}, {0x84ed, 0x0085}, 2775 + {0x84ee, 0x001f}, {0x84ef, 0x00bd}, {0x84f0, 0x00f8}, 2776 + {0x84f1, 0x0037}, {0x84f2, 0x007c}, {0x84f3, 0x0000}, 2777 + {0x84f4, 0x0080}, {0x84f5, 0x00ce}, {0x84f6, 0x0084}, 2778 + {0x84f7, 0x00fe}, {0x84f8, 0x00ff}, {0x84f9, 0x0001}, 2779 + {0x84fa, 0x0011}, {0x84fb, 0x007e}, {0x84fc, 0x0085}, 2780 + {0x84fd, 0x001e}, {0x84fe, 0x0096}, {0x84ff, 0x0046}, 2781 + {0x8500, 0x0084}, {0x8501, 0x0003}, {0x8502, 0x0081}, 2782 + {0x8503, 0x0002}, {0x8504, 0x0026}, {0x8505, 0x0009}, 2783 + {0x8506, 0x00b6}, {0x8507, 0x0012}, {0x8508, 0x0030}, 2784 + {0x8509, 0x0084}, {0x850a, 0x0003}, {0x850b, 0x0081}, 2785 + {0x850c, 0x0001}, {0x850d, 0x0027}, {0x850e, 0x000f}, 2786 + {0x850f, 0x00bd}, {0x8510, 0x00f8}, {0x8511, 0x0044}, 2787 + {0x8512, 0x00bd}, {0x8513, 0x00f7}, {0x8514, 0x000b}, 2788 + {0x8515, 0x00bd}, {0x8516, 0x00fc}, {0x8517, 0x0029}, 2789 + {0x8518, 0x00ce}, {0x8519, 0x0084}, {0x851a, 0x0026}, 2790 + {0x851b, 0x00ff}, {0x851c, 0x0001}, {0x851d, 0x0011}, 2791 + {0x851e, 0x0039}, {0x851f, 0x00d6}, {0x8520, 0x0022}, 2792 + {0x8521, 0x00c4}, {0x8522, 0x000f}, {0x8523, 0x00b6}, 2793 + {0x8524, 0x0012}, {0x8525, 0x0030}, {0x8526, 0x00ba}, 2794 + {0x8527, 0x0012}, {0x8528, 0x0032}, {0x8529, 0x0084}, 2795 + {0x852a, 0x0004}, {0x852b, 0x0027}, {0x852c, 0x000d}, 2796 + {0x852d, 0x0096}, {0x852e, 0x0022}, {0x852f, 0x0085}, 2797 + {0x8530, 0x0004}, {0x8531, 0x0027}, {0x8532, 0x0005}, 2798 + {0x8533, 0x00ca}, {0x8534, 0x0010}, {0x8535, 0x007e}, 2799 + {0x8536, 0x0085}, {0x8537, 0x003a}, {0x8538, 0x00ca}, 2800 + {0x8539, 0x0020}, {0x853a, 0x00d7}, {0x853b, 0x0022}, 2801 + {0x853c, 0x0039}, {0x853d, 0x0086}, {0x853e, 0x0000}, 2802 + {0x853f, 0x0097}, {0x8540, 0x0083}, {0x8541, 0x0018}, 2803 + {0x8542, 0x00ce}, {0x8543, 0x001c}, {0x8544, 0x0000}, 2804 + {0x8545, 0x00bd}, {0x8546, 0x00eb}, {0x8547, 0x0046}, 2805 + {0x8548, 0x0096}, {0x8549, 0x0057}, {0x854a, 0x0085}, 2806 + {0x854b, 0x0001}, {0x854c, 0x0027}, {0x854d, 0x0002}, 2807 + {0x854e, 0x004f}, {0x854f, 0x0039}, {0x8550, 0x0085}, 2808 + {0x8551, 0x0002}, {0x8552, 0x0027}, {0x8553, 0x0001}, 2809 + {0x8554, 0x0039}, {0x8555, 0x007f}, {0x8556, 0x008f}, 2810 + {0x8557, 0x007d}, {0x8558, 0x0086}, {0x8559, 0x0004}, 2811 + {0x855a, 0x00b7}, {0x855b, 0x0012}, {0x855c, 0x0004}, 2812 + {0x855d, 0x0086}, {0x855e, 0x0008}, {0x855f, 0x00b7}, 2813 + {0x8560, 0x0012}, {0x8561, 0x0007}, {0x8562, 0x0086}, 2814 + {0x8563, 0x0010}, {0x8564, 0x00b7}, {0x8565, 0x0012}, 2815 + {0x8566, 0x000c}, {0x8567, 0x0086}, {0x8568, 0x0007}, 2816 + {0x8569, 0x00b7}, {0x856a, 0x0012}, {0x856b, 0x0006}, 2817 + {0x856c, 0x00b6}, {0x856d, 0x008f}, {0x856e, 0x007d}, 2818 + {0x856f, 0x00b7}, {0x8570, 0x0012}, {0x8571, 0x0070}, 2819 + {0x8572, 0x0086}, {0x8573, 0x0001}, {0x8574, 0x00ba}, 2820 + {0x8575, 0x0012}, {0x8576, 0x0004}, {0x8577, 0x00b7}, 2821 + {0x8578, 0x0012}, {0x8579, 0x0004}, {0x857a, 0x0001}, 2822 + {0x857b, 0x0001}, {0x857c, 0x0001}, {0x857d, 0x0001}, 2823 + {0x857e, 0x0001}, {0x857f, 0x0001}, {0x8580, 0x00b6}, 2824 + {0x8581, 0x0012}, {0x8582, 0x0004}, {0x8583, 0x0084}, 2825 + {0x8584, 0x00fe}, {0x8585, 0x008a}, {0x8586, 0x0002}, 2826 + {0x8587, 0x00b7}, {0x8588, 0x0012}, {0x8589, 0x0004}, 2827 + {0x858a, 0x0001}, {0x858b, 0x0001}, {0x858c, 0x0001}, 2828 + {0x858d, 0x0001}, {0x858e, 0x0001}, {0x858f, 0x0001}, 2829 + {0x8590, 0x0086}, {0x8591, 0x00fd}, {0x8592, 0x00b4}, 2830 + {0x8593, 0x0012}, {0x8594, 0x0004}, {0x8595, 0x00b7}, 2831 + {0x8596, 0x0012}, {0x8597, 0x0004}, {0x8598, 0x00b6}, 2832 + {0x8599, 0x0012}, {0x859a, 0x0000}, {0x859b, 0x0084}, 2833 + {0x859c, 0x0008}, {0x859d, 0x0081}, {0x859e, 0x0008}, 2834 + {0x859f, 0x0027}, {0x85a0, 0x0016}, {0x85a1, 0x00b6}, 2835 + {0x85a2, 0x008f}, {0x85a3, 0x007d}, {0x85a4, 0x0081}, 2836 + {0x85a5, 0x000c}, {0x85a6, 0x0027}, {0x85a7, 0x0008}, 2837 + {0x85a8, 0x008b}, {0x85a9, 0x0004}, {0x85aa, 0x00b7}, 2838 + {0x85ab, 0x008f}, {0x85ac, 0x007d}, {0x85ad, 0x007e}, 2839 + {0x85ae, 0x0085}, {0x85af, 0x006c}, {0x85b0, 0x0086}, 2840 + {0x85b1, 0x0003}, {0x85b2, 0x0097}, {0x85b3, 0x0040}, 2841 + {0x85b4, 0x007e}, {0x85b5, 0x0089}, {0x85b6, 0x006e}, 2842 + {0x85b7, 0x0086}, {0x85b8, 0x0007}, {0x85b9, 0x00b7}, 2843 + {0x85ba, 0x0012}, {0x85bb, 0x0006}, {0x85bc, 0x005f}, 2844 + {0x85bd, 0x00f7}, {0x85be, 0x008f}, {0x85bf, 0x0082}, 2845 + {0x85c0, 0x005f}, {0x85c1, 0x00f7}, {0x85c2, 0x008f}, 2846 + {0x85c3, 0x007f}, {0x85c4, 0x00f7}, {0x85c5, 0x008f}, 2847 + {0x85c6, 0x0070}, {0x85c7, 0x00f7}, {0x85c8, 0x008f}, 2848 + {0x85c9, 0x0071}, {0x85ca, 0x00f7}, {0x85cb, 0x008f}, 2849 + {0x85cc, 0x0072}, {0x85cd, 0x00f7}, {0x85ce, 0x008f}, 2850 + {0x85cf, 0x0073}, {0x85d0, 0x00f7}, {0x85d1, 0x008f}, 2851 + {0x85d2, 0x0074}, {0x85d3, 0x00f7}, {0x85d4, 0x008f}, 2852 + {0x85d5, 0x0075}, {0x85d6, 0x00f7}, {0x85d7, 0x008f}, 2853 + {0x85d8, 0x0076}, {0x85d9, 0x00f7}, {0x85da, 0x008f}, 2854 + {0x85db, 0x0077}, {0x85dc, 0x00f7}, {0x85dd, 0x008f}, 2855 + {0x85de, 0x0078}, {0x85df, 0x00f7}, {0x85e0, 0x008f}, 2856 + {0x85e1, 0x0079}, {0x85e2, 0x00f7}, {0x85e3, 0x008f}, 2857 + {0x85e4, 0x007a}, {0x85e5, 0x00f7}, {0x85e6, 0x008f}, 2858 + {0x85e7, 0x007b}, {0x85e8, 0x00b6}, {0x85e9, 0x0012}, 2859 + {0x85ea, 0x0004}, {0x85eb, 0x008a}, {0x85ec, 0x0010}, 2860 + {0x85ed, 0x00b7}, {0x85ee, 0x0012}, {0x85ef, 0x0004}, 2861 + {0x85f0, 0x0086}, {0x85f1, 0x00e4}, {0x85f2, 0x00b7}, 2862 + {0x85f3, 0x0012}, {0x85f4, 0x0070}, {0x85f5, 0x00b7}, 2863 + {0x85f6, 0x0012}, {0x85f7, 0x0007}, {0x85f8, 0x00f7}, 2864 + {0x85f9, 0x0012}, {0x85fa, 0x0005}, {0x85fb, 0x00f7}, 2865 + {0x85fc, 0x0012}, {0x85fd, 0x0009}, {0x85fe, 0x0086}, 2866 + {0x85ff, 0x0008}, {0x8600, 0x00ba}, {0x8601, 0x0012}, 2867 + {0x8602, 0x0004}, {0x8603, 0x00b7}, {0x8604, 0x0012}, 2868 + {0x8605, 0x0004}, {0x8606, 0x0086}, {0x8607, 0x00f7}, 2869 + {0x8608, 0x00b4}, {0x8609, 0x0012}, {0x860a, 0x0004}, 2870 + {0x860b, 0x00b7}, {0x860c, 0x0012}, {0x860d, 0x0004}, 2871 + {0x860e, 0x0001}, {0x860f, 0x0001}, {0x8610, 0x0001}, 2872 + {0x8611, 0x0001}, {0x8612, 0x0001}, {0x8613, 0x0001}, 2873 + {0x8614, 0x00b6}, {0x8615, 0x0012}, {0x8616, 0x0008}, 2874 + {0x8617, 0x0027}, {0x8618, 0x007f}, {0x8619, 0x0081}, 2875 + {0x861a, 0x0080}, {0x861b, 0x0026}, {0x861c, 0x000b}, 2876 + {0x861d, 0x0086}, {0x861e, 0x0008}, {0x861f, 0x00ce}, 2877 + {0x8620, 0x008f}, {0x8621, 0x0079}, {0x8622, 0x00bd}, 2878 + {0x8623, 0x0089}, {0x8624, 0x007b}, {0x8625, 0x007e}, 2879 + {0x8626, 0x0086}, {0x8627, 0x008e}, {0x8628, 0x0081}, 2880 + {0x8629, 0x0040}, {0x862a, 0x0026}, {0x862b, 0x000b}, 2881 + {0x862c, 0x0086}, {0x862d, 0x0004}, {0x862e, 0x00ce}, 2882 + {0x862f, 0x008f}, {0x8630, 0x0076}, {0x8631, 0x00bd}, 2883 + {0x8632, 0x0089}, {0x8633, 0x007b}, {0x8634, 0x007e}, 2884 + {0x8635, 0x0086}, {0x8636, 0x008e}, {0x8637, 0x0081}, 2885 + {0x8638, 0x0020}, {0x8639, 0x0026}, {0x863a, 0x000b}, 2886 + {0x863b, 0x0086}, {0x863c, 0x0002}, {0x863d, 0x00ce}, 2887 + {0x863e, 0x008f}, {0x863f, 0x0073}, {0x8640, 0x00bd}, 2888 + {0x8641, 0x0089}, {0x8642, 0x007b}, {0x8643, 0x007e}, 2889 + {0x8644, 0x0086}, {0x8645, 0x008e}, {0x8646, 0x0081}, 2890 + {0x8647, 0x0010}, {0x8648, 0x0026}, {0x8649, 0x000b}, 2891 + {0x864a, 0x0086}, {0x864b, 0x0001}, {0x864c, 0x00ce}, 2892 + {0x864d, 0x008f}, {0x864e, 0x0070}, {0x864f, 0x00bd}, 2893 + {0x8650, 0x0089}, {0x8651, 0x007b}, {0x8652, 0x007e}, 2894 + {0x8653, 0x0086}, {0x8654, 0x008e}, {0x8655, 0x0081}, 2895 + {0x8656, 0x0008}, {0x8657, 0x0026}, {0x8658, 0x000b}, 2896 + {0x8659, 0x0086}, {0x865a, 0x0008}, {0x865b, 0x00ce}, 2897 + {0x865c, 0x008f}, {0x865d, 0x0079}, {0x865e, 0x00bd}, 2898 + {0x865f, 0x0089}, {0x8660, 0x007f}, {0x8661, 0x007e}, 2899 + {0x8662, 0x0086}, {0x8663, 0x008e}, {0x8664, 0x0081}, 2900 + {0x8665, 0x0004}, {0x8666, 0x0026}, {0x8667, 0x000b}, 2901 + {0x8668, 0x0086}, {0x8669, 0x0004}, {0x866a, 0x00ce}, 2902 + {0x866b, 0x008f}, {0x866c, 0x0076}, {0x866d, 0x00bd}, 2903 + {0x866e, 0x0089}, {0x866f, 0x007f}, {0x8670, 0x007e}, 2904 + {0x8671, 0x0086}, {0x8672, 0x008e}, {0x8673, 0x0081}, 2905 + {0x8674, 0x0002}, {0x8675, 0x0026}, {0x8676, 0x000b}, 2906 + {0x8677, 0x008a}, {0x8678, 0x0002}, {0x8679, 0x00ce}, 2907 + {0x867a, 0x008f}, {0x867b, 0x0073}, {0x867c, 0x00bd}, 2908 + {0x867d, 0x0089}, {0x867e, 0x007f}, {0x867f, 0x007e}, 2909 + {0x8680, 0x0086}, {0x8681, 0x008e}, {0x8682, 0x0081}, 2910 + {0x8683, 0x0001}, {0x8684, 0x0026}, {0x8685, 0x0008}, 2911 + {0x8686, 0x0086}, {0x8687, 0x0001}, {0x8688, 0x00ce}, 2912 + {0x8689, 0x008f}, {0x868a, 0x0070}, {0x868b, 0x00bd}, 2913 + {0x868c, 0x0089}, {0x868d, 0x007f}, {0x868e, 0x00b6}, 2914 + {0x868f, 0x008f}, {0x8690, 0x007f}, {0x8691, 0x0081}, 2915 + {0x8692, 0x000f}, {0x8693, 0x0026}, {0x8694, 0x0003}, 2916 + {0x8695, 0x007e}, {0x8696, 0x0087}, {0x8697, 0x0047}, 2917 + {0x8698, 0x00b6}, {0x8699, 0x0012}, {0x869a, 0x0009}, 2918 + {0x869b, 0x0084}, {0x869c, 0x0003}, {0x869d, 0x0081}, 2919 + {0x869e, 0x0003}, {0x869f, 0x0027}, {0x86a0, 0x0006}, 2920 + {0x86a1, 0x007c}, {0x86a2, 0x0012}, {0x86a3, 0x0009}, 2921 + {0x86a4, 0x007e}, {0x86a5, 0x0085}, {0x86a6, 0x00fe}, 2922 + {0x86a7, 0x00b6}, {0x86a8, 0x0012}, {0x86a9, 0x0006}, 2923 + {0x86aa, 0x0084}, {0x86ab, 0x0007}, {0x86ac, 0x0081}, 2924 + {0x86ad, 0x0007}, {0x86ae, 0x0027}, {0x86af, 0x0008}, 2925 + {0x86b0, 0x008b}, {0x86b1, 0x0001}, {0x86b2, 0x00b7}, 2926 + {0x86b3, 0x0012}, {0x86b4, 0x0006}, {0x86b5, 0x007e}, 2927 + {0x86b6, 0x0086}, {0x86b7, 0x00d5}, {0x86b8, 0x00b6}, 2928 + {0x86b9, 0x008f}, {0x86ba, 0x0082}, {0x86bb, 0x0026}, 2929 + {0x86bc, 0x000a}, {0x86bd, 0x007c}, {0x86be, 0x008f}, 2930 + {0x86bf, 0x0082}, {0x86c0, 0x004f}, {0x86c1, 0x00b7}, 2931 + {0x86c2, 0x0012}, {0x86c3, 0x0006}, {0x86c4, 0x007e}, 2932 + {0x86c5, 0x0085}, {0x86c6, 0x00c0}, {0x86c7, 0x00b6}, 2933 + {0x86c8, 0x0012}, {0x86c9, 0x0006}, {0x86ca, 0x0084}, 2934 + {0x86cb, 0x003f}, {0x86cc, 0x0081}, {0x86cd, 0x003f}, 2935 + {0x86ce, 0x0027}, {0x86cf, 0x0010}, {0x86d0, 0x008b}, 2936 + {0x86d1, 0x0008}, {0x86d2, 0x00b7}, {0x86d3, 0x0012}, 2937 + {0x86d4, 0x0006}, {0x86d5, 0x00b6}, {0x86d6, 0x0012}, 2938 + {0x86d7, 0x0009}, {0x86d8, 0x0084}, {0x86d9, 0x00fc}, 2939 + {0x86da, 0x00b7}, {0x86db, 0x0012}, {0x86dc, 0x0009}, 2940 + {0x86dd, 0x007e}, {0x86de, 0x0085}, {0x86df, 0x00fe}, 2941 + {0x86e0, 0x00ce}, {0x86e1, 0x008f}, {0x86e2, 0x0070}, 2942 + {0x86e3, 0x0018}, {0x86e4, 0x00ce}, {0x86e5, 0x008f}, 2943 + {0x86e6, 0x0084}, {0x86e7, 0x00c6}, {0x86e8, 0x000c}, 2944 + {0x86e9, 0x00bd}, {0x86ea, 0x0089}, {0x86eb, 0x006f}, 2945 + {0x86ec, 0x00ce}, {0x86ed, 0x008f}, {0x86ee, 0x0084}, 2946 + {0x86ef, 0x0018}, {0x86f0, 0x00ce}, {0x86f1, 0x008f}, 2947 + {0x86f2, 0x0070}, {0x86f3, 0x00c6}, {0x86f4, 0x000c}, 2948 + {0x86f5, 0x00bd}, {0x86f6, 0x0089}, {0x86f7, 0x006f}, 2949 + {0x86f8, 0x00d6}, {0x86f9, 0x0083}, {0x86fa, 0x00c1}, 2950 + {0x86fb, 0x004f}, {0x86fc, 0x002d}, {0x86fd, 0x0003}, 2951 + {0x86fe, 0x007e}, {0x86ff, 0x0087}, {0x8700, 0x0040}, 2952 + {0x8701, 0x00b6}, {0x8702, 0x008f}, {0x8703, 0x007f}, 2953 + {0x8704, 0x0081}, {0x8705, 0x0007}, {0x8706, 0x0027}, 2954 + {0x8707, 0x000f}, {0x8708, 0x0081}, {0x8709, 0x000b}, 2955 + {0x870a, 0x0027}, {0x870b, 0x0015}, {0x870c, 0x0081}, 2956 + {0x870d, 0x000d}, {0x870e, 0x0027}, {0x870f, 0x001b}, 2957 + {0x8710, 0x0081}, {0x8711, 0x000e}, {0x8712, 0x0027}, 2958 + {0x8713, 0x0021}, {0x8714, 0x007e}, {0x8715, 0x0087}, 2959 + {0x8716, 0x0040}, {0x8717, 0x00f7}, {0x8718, 0x008f}, 2960 + {0x8719, 0x007b}, {0x871a, 0x0086}, {0x871b, 0x0002}, 2961 + {0x871c, 0x00b7}, {0x871d, 0x008f}, {0x871e, 0x007a}, 2962 + {0x871f, 0x0020}, {0x8720, 0x001c}, {0x8721, 0x00f7}, 2963 + {0x8722, 0x008f}, {0x8723, 0x0078}, {0x8724, 0x0086}, 2964 + {0x8725, 0x0002}, {0x8726, 0x00b7}, {0x8727, 0x008f}, 2965 + {0x8728, 0x0077}, {0x8729, 0x0020}, {0x872a, 0x0012}, 2966 + {0x872b, 0x00f7}, {0x872c, 0x008f}, {0x872d, 0x0075}, 2967 + {0x872e, 0x0086}, {0x872f, 0x0002}, {0x8730, 0x00b7}, 2968 + {0x8731, 0x008f}, {0x8732, 0x0074}, {0x8733, 0x0020}, 2969 + {0x8734, 0x0008}, {0x8735, 0x00f7}, {0x8736, 0x008f}, 2970 + {0x8737, 0x0072}, {0x8738, 0x0086}, {0x8739, 0x0002}, 2971 + {0x873a, 0x00b7}, {0x873b, 0x008f}, {0x873c, 0x0071}, 2972 + {0x873d, 0x007e}, {0x873e, 0x0087}, {0x873f, 0x0047}, 2973 + {0x8740, 0x0086}, {0x8741, 0x0004}, {0x8742, 0x0097}, 2974 + {0x8743, 0x0040}, {0x8744, 0x007e}, {0x8745, 0x0089}, 2975 + {0x8746, 0x006e}, {0x8747, 0x00ce}, {0x8748, 0x008f}, 2976 + {0x8749, 0x0072}, {0x874a, 0x00bd}, {0x874b, 0x0089}, 2977 + {0x874c, 0x00f7}, {0x874d, 0x00ce}, {0x874e, 0x008f}, 2978 + {0x874f, 0x0075}, {0x8750, 0x00bd}, {0x8751, 0x0089}, 2979 + {0x8752, 0x00f7}, {0x8753, 0x00ce}, {0x8754, 0x008f}, 2980 + {0x8755, 0x0078}, {0x8756, 0x00bd}, {0x8757, 0x0089}, 2981 + {0x8758, 0x00f7}, {0x8759, 0x00ce}, {0x875a, 0x008f}, 2982 + {0x875b, 0x007b}, {0x875c, 0x00bd}, {0x875d, 0x0089}, 2983 + {0x875e, 0x00f7}, {0x875f, 0x004f}, {0x8760, 0x00b7}, 2984 + {0x8761, 0x008f}, {0x8762, 0x007d}, {0x8763, 0x00b7}, 2985 + {0x8764, 0x008f}, {0x8765, 0x0081}, {0x8766, 0x00b6}, 2986 + {0x8767, 0x008f}, {0x8768, 0x0072}, {0x8769, 0x0027}, 2987 + {0x876a, 0x0047}, {0x876b, 0x007c}, {0x876c, 0x008f}, 2988 + {0x876d, 0x007d}, {0x876e, 0x00b6}, {0x876f, 0x008f}, 2989 + {0x8770, 0x0075}, {0x8771, 0x0027}, {0x8772, 0x003f}, 2990 + {0x8773, 0x007c}, {0x8774, 0x008f}, {0x8775, 0x007d}, 2991 + {0x8776, 0x00b6}, {0x8777, 0x008f}, {0x8778, 0x0078}, 2992 + {0x8779, 0x0027}, {0x877a, 0x0037}, {0x877b, 0x007c}, 2993 + {0x877c, 0x008f}, {0x877d, 0x007d}, {0x877e, 0x00b6}, 2994 + {0x877f, 0x008f}, {0x8780, 0x007b}, {0x8781, 0x0027}, 2995 + {0x8782, 0x002f}, {0x8783, 0x007f}, {0x8784, 0x008f}, 2996 + {0x8785, 0x007d}, {0x8786, 0x007c}, {0x8787, 0x008f}, 2997 + {0x8788, 0x0081}, {0x8789, 0x007a}, {0x878a, 0x008f}, 2998 + {0x878b, 0x0072}, {0x878c, 0x0027}, {0x878d, 0x001b}, 2999 + {0x878e, 0x007c}, {0x878f, 0x008f}, {0x8790, 0x007d}, 3000 + {0x8791, 0x007a}, {0x8792, 0x008f}, {0x8793, 0x0075}, 3001 + {0x8794, 0x0027}, {0x8795, 0x0016}, {0x8796, 0x007c}, 3002 + {0x8797, 0x008f}, {0x8798, 0x007d}, {0x8799, 0x007a}, 3003 + {0x879a, 0x008f}, {0x879b, 0x0078}, {0x879c, 0x0027}, 3004 + {0x879d, 0x0011}, {0x879e, 0x007c}, {0x879f, 0x008f}, 3005 + {0x87a0, 0x007d}, {0x87a1, 0x007a}, {0x87a2, 0x008f}, 3006 + {0x87a3, 0x007b}, {0x87a4, 0x0027}, {0x87a5, 0x000c}, 3007 + {0x87a6, 0x007e}, {0x87a7, 0x0087}, {0x87a8, 0x0083}, 3008 + {0x87a9, 0x007a}, {0x87aa, 0x008f}, {0x87ab, 0x0075}, 3009 + {0x87ac, 0x007a}, {0x87ad, 0x008f}, {0x87ae, 0x0078}, 3010 + {0x87af, 0x007a}, {0x87b0, 0x008f}, {0x87b1, 0x007b}, 3011 + {0x87b2, 0x00ce}, {0x87b3, 0x00c1}, {0x87b4, 0x00fc}, 3012 + {0x87b5, 0x00f6}, {0x87b6, 0x008f}, {0x87b7, 0x007d}, 3013 + {0x87b8, 0x003a}, {0x87b9, 0x00a6}, {0x87ba, 0x0000}, 3014 + {0x87bb, 0x00b7}, {0x87bc, 0x0012}, {0x87bd, 0x0070}, 3015 + {0x87be, 0x00b6}, {0x87bf, 0x008f}, {0x87c0, 0x0072}, 3016 + {0x87c1, 0x0026}, {0x87c2, 0x0003}, {0x87c3, 0x007e}, 3017 + {0x87c4, 0x0087}, {0x87c5, 0x00fa}, {0x87c6, 0x00b6}, 3018 + {0x87c7, 0x008f}, {0x87c8, 0x0075}, {0x87c9, 0x0026}, 3019 + {0x87ca, 0x000a}, {0x87cb, 0x0018}, {0x87cc, 0x00ce}, 3020 + {0x87cd, 0x008f}, {0x87ce, 0x0073}, {0x87cf, 0x00bd}, 3021 + {0x87d0, 0x0089}, {0x87d1, 0x00d5}, {0x87d2, 0x007e}, 3022 + {0x87d3, 0x0087}, {0x87d4, 0x00fa}, {0x87d5, 0x00b6}, 3023 + {0x87d6, 0x008f}, {0x87d7, 0x0078}, {0x87d8, 0x0026}, 3024 + {0x87d9, 0x000a}, {0x87da, 0x0018}, {0x87db, 0x00ce}, 3025 + {0x87dc, 0x008f}, {0x87dd, 0x0076}, {0x87de, 0x00bd}, 3026 + {0x87df, 0x0089}, {0x87e0, 0x00d5}, {0x87e1, 0x007e}, 3027 + {0x87e2, 0x0087}, {0x87e3, 0x00fa}, {0x87e4, 0x00b6}, 3028 + {0x87e5, 0x008f}, {0x87e6, 0x007b}, {0x87e7, 0x0026}, 3029 + {0x87e8, 0x000a}, {0x87e9, 0x0018}, {0x87ea, 0x00ce}, 3030 + {0x87eb, 0x008f}, {0x87ec, 0x0079}, {0x87ed, 0x00bd}, 3031 + {0x87ee, 0x0089}, {0x87ef, 0x00d5}, {0x87f0, 0x007e}, 3032 + {0x87f1, 0x0087}, {0x87f2, 0x00fa}, {0x87f3, 0x0086}, 3033 + {0x87f4, 0x0005}, {0x87f5, 0x0097}, {0x87f6, 0x0040}, 3034 + {0x87f7, 0x007e}, {0x87f8, 0x0089}, {0x87f9, 0x0000}, 3035 + {0x87fa, 0x00b6}, {0x87fb, 0x008f}, {0x87fc, 0x0075}, 3036 + {0x87fd, 0x0081}, {0x87fe, 0x0007}, {0x87ff, 0x002e}, 3037 + {0x8800, 0x00f2}, {0x8801, 0x00f6}, {0x8802, 0x0012}, 3038 + {0x8803, 0x0006}, {0x8804, 0x00c4}, {0x8805, 0x00f8}, 3039 + {0x8806, 0x001b}, {0x8807, 0x00b7}, {0x8808, 0x0012}, 3040 + {0x8809, 0x0006}, {0x880a, 0x00b6}, {0x880b, 0x008f}, 3041 + {0x880c, 0x0078}, {0x880d, 0x0081}, {0x880e, 0x0007}, 3042 + {0x880f, 0x002e}, {0x8810, 0x00e2}, {0x8811, 0x0048}, 3043 + {0x8812, 0x0048}, {0x8813, 0x0048}, {0x8814, 0x00f6}, 3044 + {0x8815, 0x0012}, {0x8816, 0x0006}, {0x8817, 0x00c4}, 3045 + {0x8818, 0x00c7}, {0x8819, 0x001b}, {0x881a, 0x00b7}, 3046 + {0x881b, 0x0012}, {0x881c, 0x0006}, {0x881d, 0x00b6}, 3047 + {0x881e, 0x008f}, {0x881f, 0x007b}, {0x8820, 0x0081}, 3048 + {0x8821, 0x0007}, {0x8822, 0x002e}, {0x8823, 0x00cf}, 3049 + {0x8824, 0x00f6}, {0x8825, 0x0012}, {0x8826, 0x0005}, 3050 + {0x8827, 0x00c4}, {0x8828, 0x00f8}, {0x8829, 0x001b}, 3051 + {0x882a, 0x00b7}, {0x882b, 0x0012}, {0x882c, 0x0005}, 3052 + {0x882d, 0x0086}, {0x882e, 0x0000}, {0x882f, 0x00f6}, 3053 + {0x8830, 0x008f}, {0x8831, 0x0071}, {0x8832, 0x00bd}, 3054 + {0x8833, 0x0089}, {0x8834, 0x0094}, {0x8835, 0x0086}, 3055 + {0x8836, 0x0001}, {0x8837, 0x00f6}, {0x8838, 0x008f}, 3056 + {0x8839, 0x0074}, {0x883a, 0x00bd}, {0x883b, 0x0089}, 3057 + {0x883c, 0x0094}, {0x883d, 0x0086}, {0x883e, 0x0002}, 3058 + {0x883f, 0x00f6}, {0x8840, 0x008f}, {0x8841, 0x0077}, 3059 + {0x8842, 0x00bd}, {0x8843, 0x0089}, {0x8844, 0x0094}, 3060 + {0x8845, 0x0086}, {0x8846, 0x0003}, {0x8847, 0x00f6}, 3061 + {0x8848, 0x008f}, {0x8849, 0x007a}, {0x884a, 0x00bd}, 3062 + {0x884b, 0x0089}, {0x884c, 0x0094}, {0x884d, 0x00ce}, 3063 + {0x884e, 0x008f}, {0x884f, 0x0070}, {0x8850, 0x00a6}, 3064 + {0x8851, 0x0001}, {0x8852, 0x0081}, {0x8853, 0x0001}, 3065 + {0x8854, 0x0027}, {0x8855, 0x0007}, {0x8856, 0x0081}, 3066 + {0x8857, 0x0003}, {0x8858, 0x0027}, {0x8859, 0x0003}, 3067 + {0x885a, 0x007e}, {0x885b, 0x0088}, {0x885c, 0x0066}, 3068 + {0x885d, 0x00a6}, {0x885e, 0x0000}, {0x885f, 0x00b8}, 3069 + {0x8860, 0x008f}, {0x8861, 0x0081}, {0x8862, 0x0084}, 3070 + {0x8863, 0x0001}, {0x8864, 0x0026}, {0x8865, 0x000b}, 3071 + {0x8866, 0x008c}, {0x8867, 0x008f}, {0x8868, 0x0079}, 3072 + {0x8869, 0x002c}, {0x886a, 0x000e}, {0x886b, 0x0008}, 3073 + {0x886c, 0x0008}, {0x886d, 0x0008}, {0x886e, 0x007e}, 3074 + {0x886f, 0x0088}, {0x8870, 0x0050}, {0x8871, 0x00b6}, 3075 + {0x8872, 0x0012}, {0x8873, 0x0004}, {0x8874, 0x008a}, 3076 + {0x8875, 0x0040}, {0x8876, 0x00b7}, {0x8877, 0x0012}, 3077 + {0x8878, 0x0004}, {0x8879, 0x00b6}, {0x887a, 0x0012}, 3078 + {0x887b, 0x0004}, {0x887c, 0x0084}, {0x887d, 0x00fb}, 3079 + {0x887e, 0x0084}, {0x887f, 0x00ef}, {0x8880, 0x00b7}, 3080 + {0x8881, 0x0012}, {0x8882, 0x0004}, {0x8883, 0x00b6}, 3081 + {0x8884, 0x0012}, {0x8885, 0x0007}, {0x8886, 0x0036}, 3082 + {0x8887, 0x00b6}, {0x8888, 0x008f}, {0x8889, 0x007c}, 3083 + {0x888a, 0x0048}, {0x888b, 0x0048}, {0x888c, 0x00b7}, 3084 + {0x888d, 0x0012}, {0x888e, 0x0007}, {0x888f, 0x0086}, 3085 + {0x8890, 0x0001}, {0x8891, 0x00ba}, {0x8892, 0x0012}, 3086 + {0x8893, 0x0004}, {0x8894, 0x00b7}, {0x8895, 0x0012}, 3087 + {0x8896, 0x0004}, {0x8897, 0x0001}, {0x8898, 0x0001}, 3088 + {0x8899, 0x0001}, {0x889a, 0x0001}, {0x889b, 0x0001}, 3089 + {0x889c, 0x0001}, {0x889d, 0x0086}, {0x889e, 0x00fe}, 3090 + {0x889f, 0x00b4}, {0x88a0, 0x0012}, {0x88a1, 0x0004}, 3091 + {0x88a2, 0x00b7}, {0x88a3, 0x0012}, {0x88a4, 0x0004}, 3092 + {0x88a5, 0x0086}, {0x88a6, 0x0002}, {0x88a7, 0x00ba}, 3093 + {0x88a8, 0x0012}, {0x88a9, 0x0004}, {0x88aa, 0x00b7}, 3094 + {0x88ab, 0x0012}, {0x88ac, 0x0004}, {0x88ad, 0x0086}, 3095 + {0x88ae, 0x00fd}, {0x88af, 0x00b4}, {0x88b0, 0x0012}, 3096 + {0x88b1, 0x0004}, {0x88b2, 0x00b7}, {0x88b3, 0x0012}, 3097 + {0x88b4, 0x0004}, {0x88b5, 0x0032}, {0x88b6, 0x00b7}, 3098 + {0x88b7, 0x0012}, {0x88b8, 0x0007}, {0x88b9, 0x00b6}, 3099 + {0x88ba, 0x0012}, {0x88bb, 0x0000}, {0x88bc, 0x0084}, 3100 + {0x88bd, 0x0008}, {0x88be, 0x0081}, {0x88bf, 0x0008}, 3101 + {0x88c0, 0x0027}, {0x88c1, 0x000f}, {0x88c2, 0x007c}, 3102 + {0x88c3, 0x0082}, {0x88c4, 0x0008}, {0x88c5, 0x0026}, 3103 + {0x88c6, 0x0007}, {0x88c7, 0x0086}, {0x88c8, 0x0076}, 3104 + {0x88c9, 0x0097}, {0x88ca, 0x0040}, {0x88cb, 0x007e}, 3105 + {0x88cc, 0x0089}, {0x88cd, 0x006e}, {0x88ce, 0x007e}, 3106 + {0x88cf, 0x0086}, {0x88d0, 0x00ec}, {0x88d1, 0x00b6}, 3107 + {0x88d2, 0x008f}, {0x88d3, 0x007f}, {0x88d4, 0x0081}, 3108 + {0x88d5, 0x000f}, {0x88d6, 0x0027}, {0x88d7, 0x003c}, 3109 + {0x88d8, 0x00bd}, {0x88d9, 0x00e6}, {0x88da, 0x00c7}, 3110 + {0x88db, 0x00b7}, {0x88dc, 0x0012}, {0x88dd, 0x000d}, 3111 + {0x88de, 0x00bd}, {0x88df, 0x00e6}, {0x88e0, 0x00cb}, 3112 + {0x88e1, 0x00b6}, {0x88e2, 0x0012}, {0x88e3, 0x0004}, 3113 + {0x88e4, 0x008a}, {0x88e5, 0x0020}, {0x88e6, 0x00b7}, 3114 + {0x88e7, 0x0012}, {0x88e8, 0x0004}, {0x88e9, 0x00ce}, 3115 + {0x88ea, 0x00ff}, {0x88eb, 0x00ff}, {0x88ec, 0x00b6}, 3116 + {0x88ed, 0x0012}, {0x88ee, 0x0000}, {0x88ef, 0x0081}, 3117 + {0x88f0, 0x000c}, {0x88f1, 0x0026}, {0x88f2, 0x0005}, 3118 + {0x88f3, 0x0009}, {0x88f4, 0x0026}, {0x88f5, 0x00f6}, 3119 + {0x88f6, 0x0027}, {0x88f7, 0x001c}, {0x88f8, 0x00b6}, 3120 + {0x88f9, 0x0012}, {0x88fa, 0x0004}, {0x88fb, 0x0084}, 3121 + {0x88fc, 0x00df}, {0x88fd, 0x00b7}, {0x88fe, 0x0012}, 3122 + {0x88ff, 0x0004}, {0x8900, 0x0096}, {0x8901, 0x0083}, 3123 + {0x8902, 0x0081}, {0x8903, 0x0007}, {0x8904, 0x002c}, 3124 + {0x8905, 0x0005}, {0x8906, 0x007c}, {0x8907, 0x0000}, 3125 + {0x8908, 0x0083}, {0x8909, 0x0020}, {0x890a, 0x0006}, 3126 + {0x890b, 0x0096}, {0x890c, 0x0083}, {0x890d, 0x008b}, 3127 + {0x890e, 0x0008}, {0x890f, 0x0097}, {0x8910, 0x0083}, 3128 + {0x8911, 0x007e}, {0x8912, 0x0085}, {0x8913, 0x0041}, 3129 + {0x8914, 0x007f}, {0x8915, 0x008f}, {0x8916, 0x007e}, 3130 + {0x8917, 0x0086}, {0x8918, 0x0080}, {0x8919, 0x00b7}, 3131 + {0x891a, 0x0012}, {0x891b, 0x000c}, {0x891c, 0x0086}, 3132 + {0x891d, 0x0001}, {0x891e, 0x00b7}, {0x891f, 0x008f}, 3133 + {0x8920, 0x007d}, {0x8921, 0x00b6}, {0x8922, 0x0012}, 3134 + {0x8923, 0x000c}, {0x8924, 0x0084}, {0x8925, 0x007f}, 3135 + {0x8926, 0x00b7}, {0x8927, 0x0012}, {0x8928, 0x000c}, 3136 + {0x8929, 0x008a}, {0x892a, 0x0080}, {0x892b, 0x00b7}, 3137 + {0x892c, 0x0012}, {0x892d, 0x000c}, {0x892e, 0x0086}, 3138 + {0x892f, 0x000a}, {0x8930, 0x00bd}, {0x8931, 0x008a}, 3139 + {0x8932, 0x0006}, {0x8933, 0x00b6}, {0x8934, 0x0012}, 3140 + {0x8935, 0x000a}, {0x8936, 0x002a}, {0x8937, 0x0009}, 3141 + {0x8938, 0x00b6}, {0x8939, 0x0012}, {0x893a, 0x000c}, 3142 + {0x893b, 0x00ba}, {0x893c, 0x008f}, {0x893d, 0x007d}, 3143 + {0x893e, 0x00b7}, {0x893f, 0x0012}, {0x8940, 0x000c}, 3144 + {0x8941, 0x00b6}, {0x8942, 0x008f}, {0x8943, 0x007e}, 3145 + {0x8944, 0x0081}, {0x8945, 0x0060}, {0x8946, 0x0027}, 3146 + {0x8947, 0x001a}, {0x8948, 0x008b}, {0x8949, 0x0020}, 3147 + {0x894a, 0x00b7}, {0x894b, 0x008f}, {0x894c, 0x007e}, 3148 + {0x894d, 0x00b6}, {0x894e, 0x0012}, {0x894f, 0x000c}, 3149 + {0x8950, 0x0084}, {0x8951, 0x009f}, {0x8952, 0x00ba}, 3150 + {0x8953, 0x008f}, {0x8954, 0x007e}, {0x8955, 0x00b7}, 3151 + {0x8956, 0x0012}, {0x8957, 0x000c}, {0x8958, 0x00b6}, 3152 + {0x8959, 0x008f}, {0x895a, 0x007d}, {0x895b, 0x0048}, 3153 + {0x895c, 0x00b7}, {0x895d, 0x008f}, {0x895e, 0x007d}, 3154 + {0x895f, 0x007e}, {0x8960, 0x0089}, {0x8961, 0x0021}, 3155 + {0x8962, 0x00b6}, {0x8963, 0x0012}, {0x8964, 0x0004}, 3156 + {0x8965, 0x008a}, {0x8966, 0x0020}, {0x8967, 0x00b7}, 3157 + {0x8968, 0x0012}, {0x8969, 0x0004}, {0x896a, 0x00bd}, 3158 + {0x896b, 0x008a}, {0x896c, 0x000a}, {0x896d, 0x004f}, 3159 + {0x896e, 0x0039}, {0x896f, 0x00a6}, {0x8970, 0x0000}, 3160 + {0x8971, 0x0018}, {0x8972, 0x00a7}, {0x8973, 0x0000}, 3161 + {0x8974, 0x0008}, {0x8975, 0x0018}, {0x8976, 0x0008}, 3162 + {0x8977, 0x005a}, {0x8978, 0x0026}, {0x8979, 0x00f5}, 3163 + {0x897a, 0x0039}, {0x897b, 0x0036}, {0x897c, 0x006c}, 3164 + {0x897d, 0x0000}, {0x897e, 0x0032}, {0x897f, 0x00ba}, 3165 + {0x8980, 0x008f}, {0x8981, 0x007f}, {0x8982, 0x00b7}, 3166 + {0x8983, 0x008f}, {0x8984, 0x007f}, {0x8985, 0x00b6}, 3167 + {0x8986, 0x0012}, {0x8987, 0x0009}, {0x8988, 0x0084}, 3168 + {0x8989, 0x0003}, {0x898a, 0x00a7}, {0x898b, 0x0001}, 3169 + {0x898c, 0x00b6}, {0x898d, 0x0012}, {0x898e, 0x0006}, 3170 + {0x898f, 0x0084}, {0x8990, 0x003f}, {0x8991, 0x00a7}, 3171 + {0x8992, 0x0002}, {0x8993, 0x0039}, {0x8994, 0x0036}, 3172 + {0x8995, 0x0086}, {0x8996, 0x0003}, {0x8997, 0x00b7}, 3173 + {0x8998, 0x008f}, {0x8999, 0x0080}, {0x899a, 0x0032}, 3174 + {0x899b, 0x00c1}, {0x899c, 0x0000}, {0x899d, 0x0026}, 3175 + {0x899e, 0x0006}, {0x899f, 0x00b7}, {0x89a0, 0x008f}, 3176 + {0x89a1, 0x007c}, {0x89a2, 0x007e}, {0x89a3, 0x0089}, 3177 + {0x89a4, 0x00c9}, {0x89a5, 0x00c1}, {0x89a6, 0x0001}, 3178 + {0x89a7, 0x0027}, {0x89a8, 0x0018}, {0x89a9, 0x00c1}, 3179 + {0x89aa, 0x0002}, {0x89ab, 0x0027}, {0x89ac, 0x000c}, 3180 + {0x89ad, 0x00c1}, {0x89ae, 0x0003}, {0x89af, 0x0027}, 3181 + {0x89b0, 0x0000}, {0x89b1, 0x00f6}, {0x89b2, 0x008f}, 3182 + {0x89b3, 0x0080}, {0x89b4, 0x0005}, {0x89b5, 0x0005}, 3183 + {0x89b6, 0x00f7}, {0x89b7, 0x008f}, {0x89b8, 0x0080}, 3184 + {0x89b9, 0x00f6}, {0x89ba, 0x008f}, {0x89bb, 0x0080}, 3185 + {0x89bc, 0x0005}, {0x89bd, 0x0005}, {0x89be, 0x00f7}, 3186 + {0x89bf, 0x008f}, {0x89c0, 0x0080}, {0x89c1, 0x00f6}, 3187 + {0x89c2, 0x008f}, {0x89c3, 0x0080}, {0x89c4, 0x0005}, 3188 + {0x89c5, 0x0005}, {0x89c6, 0x00f7}, {0x89c7, 0x008f}, 3189 + {0x89c8, 0x0080}, {0x89c9, 0x00f6}, {0x89ca, 0x008f}, 3190 + {0x89cb, 0x0080}, {0x89cc, 0x0053}, {0x89cd, 0x00f4}, 3191 + {0x89ce, 0x0012}, {0x89cf, 0x0007}, {0x89d0, 0x001b}, 3192 + {0x89d1, 0x00b7}, {0x89d2, 0x0012}, {0x89d3, 0x0007}, 3193 + {0x89d4, 0x0039}, {0x89d5, 0x00ce}, {0x89d6, 0x008f}, 3194 + {0x89d7, 0x0070}, {0x89d8, 0x00a6}, {0x89d9, 0x0000}, 3195 + {0x89da, 0x0018}, {0x89db, 0x00e6}, {0x89dc, 0x0000}, 3196 + {0x89dd, 0x0018}, {0x89de, 0x00a7}, {0x89df, 0x0000}, 3197 + {0x89e0, 0x00e7}, {0x89e1, 0x0000}, {0x89e2, 0x00a6}, 3198 + {0x89e3, 0x0001}, {0x89e4, 0x0018}, {0x89e5, 0x00e6}, 3199 + {0x89e6, 0x0001}, {0x89e7, 0x0018}, {0x89e8, 0x00a7}, 3200 + {0x89e9, 0x0001}, {0x89ea, 0x00e7}, {0x89eb, 0x0001}, 3201 + {0x89ec, 0x00a6}, {0x89ed, 0x0002}, {0x89ee, 0x0018}, 3202 + {0x89ef, 0x00e6}, {0x89f0, 0x0002}, {0x89f1, 0x0018}, 3203 + {0x89f2, 0x00a7}, {0x89f3, 0x0002}, {0x89f4, 0x00e7}, 3204 + {0x89f5, 0x0002}, {0x89f6, 0x0039}, {0x89f7, 0x00a6}, 3205 + {0x89f8, 0x0000}, {0x89f9, 0x0084}, {0x89fa, 0x0007}, 3206 + {0x89fb, 0x00e6}, {0x89fc, 0x0000}, {0x89fd, 0x00c4}, 3207 + {0x89fe, 0x0038}, {0x89ff, 0x0054}, {0x8a00, 0x0054}, 3208 + {0x8a01, 0x0054}, {0x8a02, 0x001b}, {0x8a03, 0x00a7}, 3209 + {0x8a04, 0x0000}, {0x8a05, 0x0039}, {0x8a06, 0x004a}, 3210 + {0x8a07, 0x0026}, {0x8a08, 0x00fd}, {0x8a09, 0x0039}, 3211 + {0x8a0a, 0x0096}, {0x8a0b, 0x0022}, {0x8a0c, 0x0084}, 3212 + {0x8a0d, 0x000f}, {0x8a0e, 0x0097}, {0x8a0f, 0x0022}, 3213 + {0x8a10, 0x0086}, {0x8a11, 0x0001}, {0x8a12, 0x00b7}, 3214 + {0x8a13, 0x008f}, {0x8a14, 0x0070}, {0x8a15, 0x00b6}, 3215 + {0x8a16, 0x0012}, {0x8a17, 0x0007}, {0x8a18, 0x00b7}, 3216 + {0x8a19, 0x008f}, {0x8a1a, 0x0071}, {0x8a1b, 0x00f6}, 3217 + {0x8a1c, 0x0012}, {0x8a1d, 0x000c}, {0x8a1e, 0x00c4}, 3218 + {0x8a1f, 0x000f}, {0x8a20, 0x00c8}, {0x8a21, 0x000f}, 3219 + {0x8a22, 0x00f7}, {0x8a23, 0x008f}, {0x8a24, 0x0072}, 3220 + {0x8a25, 0x00f6}, {0x8a26, 0x008f}, {0x8a27, 0x0072}, 3221 + {0x8a28, 0x00b6}, {0x8a29, 0x008f}, {0x8a2a, 0x0071}, 3222 + {0x8a2b, 0x0084}, {0x8a2c, 0x0003}, {0x8a2d, 0x0027}, 3223 + {0x8a2e, 0x0014}, {0x8a2f, 0x0081}, {0x8a30, 0x0001}, 3224 + {0x8a31, 0x0027}, {0x8a32, 0x001c}, {0x8a33, 0x0081}, 3225 + {0x8a34, 0x0002}, {0x8a35, 0x0027}, {0x8a36, 0x0024}, 3226 + {0x8a37, 0x00f4}, {0x8a38, 0x008f}, {0x8a39, 0x0070}, 3227 + {0x8a3a, 0x0027}, {0x8a3b, 0x002a}, {0x8a3c, 0x0096}, 3228 + {0x8a3d, 0x0022}, {0x8a3e, 0x008a}, {0x8a3f, 0x0080}, 3229 + {0x8a40, 0x007e}, {0x8a41, 0x008a}, {0x8a42, 0x0064}, 3230 + {0x8a43, 0x00f4}, {0x8a44, 0x008f}, {0x8a45, 0x0070}, 3231 + {0x8a46, 0x0027}, {0x8a47, 0x001e}, {0x8a48, 0x0096}, 3232 + {0x8a49, 0x0022}, {0x8a4a, 0x008a}, {0x8a4b, 0x0010}, 3233 + {0x8a4c, 0x007e}, {0x8a4d, 0x008a}, {0x8a4e, 0x0064}, 3234 + {0x8a4f, 0x00f4}, {0x8a50, 0x008f}, {0x8a51, 0x0070}, 3235 + {0x8a52, 0x0027}, {0x8a53, 0x0012}, {0x8a54, 0x0096}, 3236 + {0x8a55, 0x0022}, {0x8a56, 0x008a}, {0x8a57, 0x0020}, 3237 + {0x8a58, 0x007e}, {0x8a59, 0x008a}, {0x8a5a, 0x0064}, 3238 + {0x8a5b, 0x00f4}, {0x8a5c, 0x008f}, {0x8a5d, 0x0070}, 3239 + {0x8a5e, 0x0027}, {0x8a5f, 0x0006}, {0x8a60, 0x0096}, 3240 + {0x8a61, 0x0022}, {0x8a62, 0x008a}, {0x8a63, 0x0040}, 3241 + {0x8a64, 0x0097}, {0x8a65, 0x0022}, {0x8a66, 0x0074}, 3242 + {0x8a67, 0x008f}, {0x8a68, 0x0071}, {0x8a69, 0x0074}, 3243 + {0x8a6a, 0x008f}, {0x8a6b, 0x0071}, {0x8a6c, 0x0078}, 3244 + {0x8a6d, 0x008f}, {0x8a6e, 0x0070}, {0x8a6f, 0x00b6}, 3245 + {0x8a70, 0x008f}, {0x8a71, 0x0070}, {0x8a72, 0x0085}, 3246 + {0x8a73, 0x0010}, {0x8a74, 0x0027}, {0x8a75, 0x00af}, 3247 + {0x8a76, 0x00d6}, {0x8a77, 0x0022}, {0x8a78, 0x00c4}, 3248 + {0x8a79, 0x0010}, {0x8a7a, 0x0058}, {0x8a7b, 0x00b6}, 3249 + {0x8a7c, 0x0012}, {0x8a7d, 0x0070}, {0x8a7e, 0x0081}, 3250 + {0x8a7f, 0x00e4}, {0x8a80, 0x0027}, {0x8a81, 0x0036}, 3251 + {0x8a82, 0x0081}, {0x8a83, 0x00e1}, {0x8a84, 0x0026}, 3252 + {0x8a85, 0x000c}, {0x8a86, 0x0096}, {0x8a87, 0x0022}, 3253 + {0x8a88, 0x0084}, {0x8a89, 0x0020}, {0x8a8a, 0x0044}, 3254 + {0x8a8b, 0x001b}, {0x8a8c, 0x00d6}, {0x8a8d, 0x0022}, 3255 + {0x8a8e, 0x00c4}, {0x8a8f, 0x00cf}, {0x8a90, 0x0020}, 3256 + {0x8a91, 0x0023}, {0x8a92, 0x0058}, {0x8a93, 0x0081}, 3257 + {0x8a94, 0x00c6}, {0x8a95, 0x0026}, {0x8a96, 0x000d}, 3258 + {0x8a97, 0x0096}, {0x8a98, 0x0022}, {0x8a99, 0x0084}, 3259 + {0x8a9a, 0x0040}, {0x8a9b, 0x0044}, {0x8a9c, 0x0044}, 3260 + {0x8a9d, 0x001b}, {0x8a9e, 0x00d6}, {0x8a9f, 0x0022}, 3261 + {0x8aa0, 0x00c4}, {0x8aa1, 0x00af}, {0x8aa2, 0x0020}, 3262 + {0x8aa3, 0x0011}, {0x8aa4, 0x0058}, {0x8aa5, 0x0081}, 3263 + {0x8aa6, 0x0027}, {0x8aa7, 0x0026}, {0x8aa8, 0x000f}, 3264 + {0x8aa9, 0x0096}, {0x8aaa, 0x0022}, {0x8aab, 0x0084}, 3265 + {0x8aac, 0x0080}, {0x8aad, 0x0044}, {0x8aae, 0x0044}, 3266 + {0x8aaf, 0x0044}, {0x8ab0, 0x001b}, {0x8ab1, 0x00d6}, 3267 + {0x8ab2, 0x0022}, {0x8ab3, 0x00c4}, {0x8ab4, 0x006f}, 3268 + {0x8ab5, 0x001b}, {0x8ab6, 0x0097}, {0x8ab7, 0x0022}, 3269 + {0x8ab8, 0x0039}, {0x8ab9, 0x0027}, {0x8aba, 0x000c}, 3270 + {0x8abb, 0x007c}, {0x8abc, 0x0082}, {0x8abd, 0x0006}, 3271 + {0x8abe, 0x00bd}, {0x8abf, 0x00d9}, {0x8ac0, 0x00ed}, 3272 + {0x8ac1, 0x00b6}, {0x8ac2, 0x0082}, {0x8ac3, 0x0007}, 3273 + {0x8ac4, 0x007e}, {0x8ac5, 0x008a}, {0x8ac6, 0x00b9}, 3274 + {0x8ac7, 0x007f}, {0x8ac8, 0x0082}, {0x8ac9, 0x0006}, 3275 + {0x8aca, 0x0039}, { 0x0, 0x0 } 3276 + }; 3277 + #else 3278 + cas_saturn_patch_t cas_saturn_patch[] = { 3279 + {0x8200, 0x007e}, {0x8201, 0x0082}, {0x8202, 0x0009}, 3280 + {0x8203, 0x0000}, {0x8204, 0x0000}, {0x8205, 0x0000}, 3281 + {0x8206, 0x0000}, {0x8207, 0x0000}, {0x8208, 0x0000}, 3282 + {0x8209, 0x008e}, {0x820a, 0x008e}, {0x820b, 0x00ff}, 3283 + {0x820c, 0x00ce}, {0x820d, 0x0082}, {0x820e, 0x0025}, 3284 + {0x820f, 0x00ff}, {0x8210, 0x0001}, {0x8211, 0x000f}, 3285 + {0x8212, 0x00ce}, {0x8213, 0x0084}, {0x8214, 0x0026}, 3286 + {0x8215, 0x00ff}, {0x8216, 0x0001}, {0x8217, 0x0011}, 3287 + {0x8218, 0x00ce}, {0x8219, 0x0085}, {0x821a, 0x003d}, 3288 + {0x821b, 0x00df}, {0x821c, 0x00e5}, {0x821d, 0x0086}, 3289 + {0x821e, 0x0039}, {0x821f, 0x00b7}, {0x8220, 0x008f}, 3290 + {0x8221, 0x00f8}, {0x8222, 0x007e}, {0x8223, 0x00c3}, 3291 + {0x8224, 0x00c2}, {0x8225, 0x0096}, {0x8226, 0x0047}, 3292 + {0x8227, 0x0084}, {0x8228, 0x00f3}, {0x8229, 0x008a}, 3293 + {0x822a, 0x0000}, {0x822b, 0x0097}, {0x822c, 0x0047}, 3294 + {0x822d, 0x00ce}, {0x822e, 0x0082}, {0x822f, 0x0033}, 3295 + {0x8230, 0x00ff}, {0x8231, 0x0001}, {0x8232, 0x000f}, 3296 + {0x8233, 0x0096}, {0x8234, 0x0046}, {0x8235, 0x0084}, 3297 + {0x8236, 0x000c}, {0x8237, 0x0081}, {0x8238, 0x0004}, 3298 + {0x8239, 0x0027}, {0x823a, 0x000b}, {0x823b, 0x0096}, 3299 + {0x823c, 0x0046}, {0x823d, 0x0084}, {0x823e, 0x000c}, 3300 + {0x823f, 0x0081}, {0x8240, 0x0008}, {0x8241, 0x0027}, 3301 + {0x8242, 0x0057}, {0x8243, 0x007e}, {0x8244, 0x0084}, 3302 + {0x8245, 0x0025}, {0x8246, 0x0096}, {0x8247, 0x0047}, 3303 + {0x8248, 0x0084}, {0x8249, 0x00f3}, {0x824a, 0x008a}, 3304 + {0x824b, 0x0004}, {0x824c, 0x0097}, {0x824d, 0x0047}, 3305 + {0x824e, 0x00ce}, {0x824f, 0x0082}, {0x8250, 0x0054}, 3306 + {0x8251, 0x00ff}, {0x8252, 0x0001}, {0x8253, 0x000f}, 3307 + {0x8254, 0x0096}, {0x8255, 0x0046}, {0x8256, 0x0084}, 3308 + {0x8257, 0x000c}, {0x8258, 0x0081}, {0x8259, 0x0004}, 3309 + {0x825a, 0x0026}, {0x825b, 0x0038}, {0x825c, 0x00b6}, 3310 + {0x825d, 0x0012}, {0x825e, 0x0020}, {0x825f, 0x0084}, 3311 + {0x8260, 0x0020}, {0x8261, 0x0026}, {0x8262, 0x0003}, 3312 + {0x8263, 0x007e}, {0x8264, 0x0084}, {0x8265, 0x0025}, 3313 + {0x8266, 0x0096}, {0x8267, 0x007b}, {0x8268, 0x00d6}, 3314 + {0x8269, 0x007c}, {0x826a, 0x00fe}, {0x826b, 0x008f}, 3315 + {0x826c, 0x0056}, {0x826d, 0x00bd}, {0x826e, 0x00f7}, 3316 + {0x826f, 0x00b6}, {0x8270, 0x00fe}, {0x8271, 0x008f}, 3317 + {0x8272, 0x004e}, {0x8273, 0x00bd}, {0x8274, 0x00ec}, 3318 + {0x8275, 0x008e}, {0x8276, 0x00bd}, {0x8277, 0x00fa}, 3319 + {0x8278, 0x00f7}, {0x8279, 0x00bd}, {0x827a, 0x00f7}, 3320 + {0x827b, 0x0028}, {0x827c, 0x00ce}, {0x827d, 0x0082}, 3321 + {0x827e, 0x0082}, {0x827f, 0x00ff}, {0x8280, 0x0001}, 3322 + {0x8281, 0x000f}, {0x8282, 0x0096}, {0x8283, 0x0046}, 3323 + {0x8284, 0x0084}, {0x8285, 0x000c}, {0x8286, 0x0081}, 3324 + {0x8287, 0x0004}, {0x8288, 0x0026}, {0x8289, 0x000a}, 3325 + {0x828a, 0x00b6}, {0x828b, 0x0012}, {0x828c, 0x0020}, 3326 + {0x828d, 0x0084}, {0x828e, 0x0020}, {0x828f, 0x0027}, 3327 + {0x8290, 0x00b5}, {0x8291, 0x007e}, {0x8292, 0x0084}, 3328 + {0x8293, 0x0025}, {0x8294, 0x00bd}, {0x8295, 0x00f7}, 3329 + {0x8296, 0x001f}, {0x8297, 0x007e}, {0x8298, 0x0084}, 3330 + {0x8299, 0x001f}, {0x829a, 0x0096}, {0x829b, 0x0047}, 3331 + {0x829c, 0x0084}, {0x829d, 0x00f3}, {0x829e, 0x008a}, 3332 + {0x829f, 0x0008}, {0x82a0, 0x0097}, {0x82a1, 0x0047}, 3333 + {0x82a2, 0x00de}, {0x82a3, 0x00e1}, {0x82a4, 0x00ad}, 3334 + {0x82a5, 0x0000}, {0x82a6, 0x00ce}, {0x82a7, 0x0082}, 3335 + {0x82a8, 0x00af}, {0x82a9, 0x00ff}, {0x82aa, 0x0001}, 3336 + {0x82ab, 0x000f}, {0x82ac, 0x007e}, {0x82ad, 0x0084}, 3337 + {0x82ae, 0x0025}, {0x82af, 0x0096}, {0x82b0, 0x0041}, 3338 + {0x82b1, 0x0085}, {0x82b2, 0x0010}, {0x82b3, 0x0026}, 3339 + {0x82b4, 0x0006}, {0x82b5, 0x0096}, {0x82b6, 0x0023}, 3340 + {0x82b7, 0x0085}, {0x82b8, 0x0040}, {0x82b9, 0x0027}, 3341 + {0x82ba, 0x0006}, {0x82bb, 0x00bd}, {0x82bc, 0x00ed}, 3342 + {0x82bd, 0x0000}, {0x82be, 0x007e}, {0x82bf, 0x0083}, 3343 + {0x82c0, 0x00a2}, {0x82c1, 0x00de}, {0x82c2, 0x0042}, 3344 + {0x82c3, 0x00bd}, {0x82c4, 0x00eb}, {0x82c5, 0x008e}, 3345 + {0x82c6, 0x0096}, {0x82c7, 0x0024}, {0x82c8, 0x0084}, 3346 + {0x82c9, 0x0008}, {0x82ca, 0x0027}, {0x82cb, 0x0003}, 3347 + {0x82cc, 0x007e}, {0x82cd, 0x0083}, {0x82ce, 0x00df}, 3348 + {0x82cf, 0x0096}, {0x82d0, 0x007b}, {0x82d1, 0x00d6}, 3349 + {0x82d2, 0x007c}, {0x82d3, 0x00fe}, {0x82d4, 0x008f}, 3350 + {0x82d5, 0x0056}, {0x82d6, 0x00bd}, {0x82d7, 0x00f7}, 3351 + {0x82d8, 0x00b6}, {0x82d9, 0x00fe}, {0x82da, 0x008f}, 3352 + {0x82db, 0x0050}, {0x82dc, 0x00bd}, {0x82dd, 0x00ec}, 3353 + {0x82de, 0x008e}, {0x82df, 0x00bd}, {0x82e0, 0x00fa}, 3354 + {0x82e1, 0x00f7}, {0x82e2, 0x0086}, {0x82e3, 0x0011}, 3355 + {0x82e4, 0x00c6}, {0x82e5, 0x0049}, {0x82e6, 0x00bd}, 3356 + {0x82e7, 0x00e4}, {0x82e8, 0x0012}, {0x82e9, 0x00ce}, 3357 + {0x82ea, 0x0082}, {0x82eb, 0x00ef}, {0x82ec, 0x00ff}, 3358 + {0x82ed, 0x0001}, {0x82ee, 0x000f}, {0x82ef, 0x0096}, 3359 + {0x82f0, 0x0046}, {0x82f1, 0x0084}, {0x82f2, 0x000c}, 3360 + {0x82f3, 0x0081}, {0x82f4, 0x0000}, {0x82f5, 0x0027}, 3361 + {0x82f6, 0x0017}, {0x82f7, 0x00c6}, {0x82f8, 0x0049}, 3362 + {0x82f9, 0x00bd}, {0x82fa, 0x00e4}, {0x82fb, 0x0091}, 3363 + {0x82fc, 0x0024}, {0x82fd, 0x000d}, {0x82fe, 0x00b6}, 3364 + {0x82ff, 0x0012}, {0x8300, 0x0020}, {0x8301, 0x0085}, 3365 + {0x8302, 0x0020}, {0x8303, 0x0026}, {0x8304, 0x000c}, 3366 + {0x8305, 0x00ce}, {0x8306, 0x0082}, {0x8307, 0x00c1}, 3367 + {0x8308, 0x00ff}, {0x8309, 0x0001}, {0x830a, 0x000f}, 3368 + {0x830b, 0x007e}, {0x830c, 0x0084}, {0x830d, 0x0025}, 3369 + {0x830e, 0x007e}, {0x830f, 0x0084}, {0x8310, 0x0016}, 3370 + {0x8311, 0x00fe}, {0x8312, 0x008f}, {0x8313, 0x0052}, 3371 + {0x8314, 0x00bd}, {0x8315, 0x00ec}, {0x8316, 0x008e}, 3372 + {0x8317, 0x00bd}, {0x8318, 0x00fa}, {0x8319, 0x00f7}, 3373 + {0x831a, 0x0086}, {0x831b, 0x006a}, {0x831c, 0x00c6}, 3374 + {0x831d, 0x0049}, {0x831e, 0x00bd}, {0x831f, 0x00e4}, 3375 + {0x8320, 0x0012}, {0x8321, 0x00ce}, {0x8322, 0x0083}, 3376 + {0x8323, 0x0027}, {0x8324, 0x00ff}, {0x8325, 0x0001}, 3377 + {0x8326, 0x000f}, {0x8327, 0x0096}, {0x8328, 0x0046}, 3378 + {0x8329, 0x0084}, {0x832a, 0x000c}, {0x832b, 0x0081}, 3379 + {0x832c, 0x0000}, {0x832d, 0x0027}, {0x832e, 0x000a}, 3380 + {0x832f, 0x00c6}, {0x8330, 0x0049}, {0x8331, 0x00bd}, 3381 + {0x8332, 0x00e4}, {0x8333, 0x0091}, {0x8334, 0x0025}, 3382 + {0x8335, 0x0006}, {0x8336, 0x007e}, {0x8337, 0x0084}, 3383 + {0x8338, 0x0025}, {0x8339, 0x007e}, {0x833a, 0x0084}, 3384 + {0x833b, 0x0016}, {0x833c, 0x00b6}, {0x833d, 0x0018}, 3385 + {0x833e, 0x0070}, {0x833f, 0x00bb}, {0x8340, 0x0019}, 3386 + {0x8341, 0x0070}, {0x8342, 0x002a}, {0x8343, 0x0004}, 3387 + {0x8344, 0x0081}, {0x8345, 0x00af}, {0x8346, 0x002e}, 3388 + {0x8347, 0x0019}, {0x8348, 0x0096}, {0x8349, 0x007b}, 3389 + {0x834a, 0x00f6}, {0x834b, 0x0020}, {0x834c, 0x0007}, 3390 + {0x834d, 0x00fa}, {0x834e, 0x0020}, {0x834f, 0x0027}, 3391 + {0x8350, 0x00c4}, {0x8351, 0x0038}, {0x8352, 0x0081}, 3392 + {0x8353, 0x0038}, {0x8354, 0x0027}, {0x8355, 0x000b}, 3393 + {0x8356, 0x00f6}, {0x8357, 0x0020}, {0x8358, 0x0007}, 3394 + {0x8359, 0x00fa}, {0x835a, 0x0020}, {0x835b, 0x0027}, 3395 + {0x835c, 0x00cb}, {0x835d, 0x0008}, {0x835e, 0x007e}, 3396 + {0x835f, 0x0082}, {0x8360, 0x00d3}, {0x8361, 0x00bd}, 3397 + {0x8362, 0x00f7}, {0x8363, 0x0066}, {0x8364, 0x0086}, 3398 + {0x8365, 0x0074}, {0x8366, 0x00c6}, {0x8367, 0x0049}, 3399 + {0x8368, 0x00bd}, {0x8369, 0x00e4}, {0x836a, 0x0012}, 3400 + {0x836b, 0x00ce}, {0x836c, 0x0083}, {0x836d, 0x0071}, 3401 + {0x836e, 0x00ff}, {0x836f, 0x0001}, {0x8370, 0x000f}, 3402 + {0x8371, 0x0096}, {0x8372, 0x0046}, {0x8373, 0x0084}, 3403 + {0x8374, 0x000c}, {0x8375, 0x0081}, {0x8376, 0x0008}, 3404 + {0x8377, 0x0026}, {0x8378, 0x000a}, {0x8379, 0x00c6}, 3405 + {0x837a, 0x0049}, {0x837b, 0x00bd}, {0x837c, 0x00e4}, 3406 + {0x837d, 0x0091}, {0x837e, 0x0025}, {0x837f, 0x0006}, 3407 + {0x8380, 0x007e}, {0x8381, 0x0084}, {0x8382, 0x0025}, 3408 + {0x8383, 0x007e}, {0x8384, 0x0084}, {0x8385, 0x0016}, 3409 + {0x8386, 0x00bd}, {0x8387, 0x00f7}, {0x8388, 0x003e}, 3410 + {0x8389, 0x0026}, {0x838a, 0x000e}, {0x838b, 0x00bd}, 3411 + {0x838c, 0x00e5}, {0x838d, 0x0009}, {0x838e, 0x0026}, 3412 + {0x838f, 0x0006}, {0x8390, 0x00ce}, {0x8391, 0x0082}, 3413 + {0x8392, 0x00c1}, {0x8393, 0x00ff}, {0x8394, 0x0001}, 3414 + {0x8395, 0x000f}, {0x8396, 0x007e}, {0x8397, 0x0084}, 3415 + {0x8398, 0x0025}, {0x8399, 0x00fe}, {0x839a, 0x008f}, 3416 + {0x839b, 0x0054}, {0x839c, 0x00bd}, {0x839d, 0x00ec}, 3417 + {0x839e, 0x008e}, {0x839f, 0x00bd}, {0x83a0, 0x00fa}, 3418 + {0x83a1, 0x00f7}, {0x83a2, 0x00bd}, {0x83a3, 0x00f7}, 3419 + {0x83a4, 0x0033}, {0x83a5, 0x0086}, {0x83a6, 0x000f}, 3420 + {0x83a7, 0x00c6}, {0x83a8, 0x0051}, {0x83a9, 0x00bd}, 3421 + {0x83aa, 0x00e4}, {0x83ab, 0x0012}, {0x83ac, 0x00ce}, 3422 + {0x83ad, 0x0083}, {0x83ae, 0x00b2}, {0x83af, 0x00ff}, 3423 + {0x83b0, 0x0001}, {0x83b1, 0x000f}, {0x83b2, 0x0096}, 3424 + {0x83b3, 0x0046}, {0x83b4, 0x0084}, {0x83b5, 0x000c}, 3425 + {0x83b6, 0x0081}, {0x83b7, 0x0008}, {0x83b8, 0x0026}, 3426 + {0x83b9, 0x005c}, {0x83ba, 0x00b6}, {0x83bb, 0x0012}, 3427 + {0x83bc, 0x0020}, {0x83bd, 0x0084}, {0x83be, 0x003f}, 3428 + {0x83bf, 0x0081}, {0x83c0, 0x003a}, {0x83c1, 0x0027}, 3429 + {0x83c2, 0x001c}, {0x83c3, 0x0096}, {0x83c4, 0x0023}, 3430 + {0x83c5, 0x0085}, {0x83c6, 0x0040}, {0x83c7, 0x0027}, 3431 + {0x83c8, 0x0003}, {0x83c9, 0x007e}, {0x83ca, 0x0084}, 3432 + {0x83cb, 0x0025}, {0x83cc, 0x00c6}, {0x83cd, 0x0051}, 3433 + {0x83ce, 0x00bd}, {0x83cf, 0x00e4}, {0x83d0, 0x0091}, 3434 + {0x83d1, 0x0025}, {0x83d2, 0x0003}, {0x83d3, 0x007e}, 3435 + {0x83d4, 0x0084}, {0x83d5, 0x0025}, {0x83d6, 0x00ce}, 3436 + {0x83d7, 0x0082}, {0x83d8, 0x00c1}, {0x83d9, 0x00ff}, 3437 + {0x83da, 0x0001}, {0x83db, 0x000f}, {0x83dc, 0x007e}, 3438 + {0x83dd, 0x0084}, {0x83de, 0x0025}, {0x83df, 0x00bd}, 3439 + {0x83e0, 0x00f8}, {0x83e1, 0x0037}, {0x83e2, 0x007c}, 3440 + {0x83e3, 0x0000}, {0x83e4, 0x007a}, {0x83e5, 0x00ce}, 3441 + {0x83e6, 0x0083}, {0x83e7, 0x00ee}, {0x83e8, 0x00ff}, 3442 + {0x83e9, 0x0001}, {0x83ea, 0x000f}, {0x83eb, 0x007e}, 3443 + {0x83ec, 0x0084}, {0x83ed, 0x0025}, {0x83ee, 0x0096}, 3444 + {0x83ef, 0x0046}, {0x83f0, 0x0084}, {0x83f1, 0x000c}, 3445 + {0x83f2, 0x0081}, {0x83f3, 0x0008}, {0x83f4, 0x0026}, 3446 + {0x83f5, 0x0020}, {0x83f6, 0x0096}, {0x83f7, 0x0024}, 3447 + {0x83f8, 0x0084}, {0x83f9, 0x0008}, {0x83fa, 0x0026}, 3448 + {0x83fb, 0x0029}, {0x83fc, 0x00b6}, {0x83fd, 0x0018}, 3449 + {0x83fe, 0x0082}, {0x83ff, 0x00bb}, {0x8400, 0x0019}, 3450 + {0x8401, 0x0082}, {0x8402, 0x00b1}, {0x8403, 0x0001}, 3451 + {0x8404, 0x003b}, {0x8405, 0x0022}, {0x8406, 0x0009}, 3452 + {0x8407, 0x00b6}, {0x8408, 0x0012}, {0x8409, 0x0020}, 3453 + {0x840a, 0x0084}, {0x840b, 0x0037}, {0x840c, 0x0081}, 3454 + {0x840d, 0x0032}, {0x840e, 0x0027}, {0x840f, 0x0015}, 3455 + {0x8410, 0x00bd}, {0x8411, 0x00f8}, {0x8412, 0x0044}, 3456 + {0x8413, 0x007e}, {0x8414, 0x0082}, {0x8415, 0x00c1}, 3457 + {0x8416, 0x00bd}, {0x8417, 0x00f7}, {0x8418, 0x001f}, 3458 + {0x8419, 0x00bd}, {0x841a, 0x00f8}, {0x841b, 0x0044}, 3459 + {0x841c, 0x00bd}, {0x841d, 0x00fc}, {0x841e, 0x0029}, 3460 + {0x841f, 0x00ce}, {0x8420, 0x0082}, {0x8421, 0x0025}, 3461 + {0x8422, 0x00ff}, {0x8423, 0x0001}, {0x8424, 0x000f}, 3462 + {0x8425, 0x0039}, {0x8426, 0x0096}, {0x8427, 0x0047}, 3463 + {0x8428, 0x0084}, {0x8429, 0x00fc}, {0x842a, 0x008a}, 3464 + {0x842b, 0x0000}, {0x842c, 0x0097}, {0x842d, 0x0047}, 3465 + {0x842e, 0x00ce}, {0x842f, 0x0084}, {0x8430, 0x0034}, 3466 + {0x8431, 0x00ff}, {0x8432, 0x0001}, {0x8433, 0x0011}, 3467 + {0x8434, 0x0096}, {0x8435, 0x0046}, {0x8436, 0x0084}, 3468 + {0x8437, 0x0003}, {0x8438, 0x0081}, {0x8439, 0x0002}, 3469 + {0x843a, 0x0027}, {0x843b, 0x0003}, {0x843c, 0x007e}, 3470 + {0x843d, 0x0085}, {0x843e, 0x001e}, {0x843f, 0x0096}, 3471 + {0x8440, 0x0047}, {0x8441, 0x0084}, {0x8442, 0x00fc}, 3472 + {0x8443, 0x008a}, {0x8444, 0x0002}, {0x8445, 0x0097}, 3473 + {0x8446, 0x0047}, {0x8447, 0x00de}, {0x8448, 0x00e1}, 3474 + {0x8449, 0x00ad}, {0x844a, 0x0000}, {0x844b, 0x0086}, 3475 + {0x844c, 0x0001}, {0x844d, 0x00b7}, {0x844e, 0x0012}, 3476 + {0x844f, 0x0051}, {0x8450, 0x00bd}, {0x8451, 0x00f7}, 3477 + {0x8452, 0x0014}, {0x8453, 0x00b6}, {0x8454, 0x0010}, 3478 + {0x8455, 0x0031}, {0x8456, 0x0084}, {0x8457, 0x00fd}, 3479 + {0x8458, 0x00b7}, {0x8459, 0x0010}, {0x845a, 0x0031}, 3480 + {0x845b, 0x00bd}, {0x845c, 0x00f8}, {0x845d, 0x001e}, 3481 + {0x845e, 0x0096}, {0x845f, 0x0081}, {0x8460, 0x00d6}, 3482 + {0x8461, 0x0082}, {0x8462, 0x00fe}, {0x8463, 0x008f}, 3483 + {0x8464, 0x005a}, {0x8465, 0x00bd}, {0x8466, 0x00f7}, 3484 + {0x8467, 0x00b6}, {0x8468, 0x00fe}, {0x8469, 0x008f}, 3485 + {0x846a, 0x005c}, {0x846b, 0x00bd}, {0x846c, 0x00ec}, 3486 + {0x846d, 0x008e}, {0x846e, 0x00bd}, {0x846f, 0x00fa}, 3487 + {0x8470, 0x00f7}, {0x8471, 0x0086}, {0x8472, 0x0008}, 3488 + {0x8473, 0x00d6}, {0x8474, 0x0000}, {0x8475, 0x00c5}, 3489 + {0x8476, 0x0010}, {0x8477, 0x0026}, {0x8478, 0x0002}, 3490 + {0x8479, 0x008b}, {0x847a, 0x0020}, {0x847b, 0x00c6}, 3491 + {0x847c, 0x0051}, {0x847d, 0x00bd}, {0x847e, 0x00e4}, 3492 + {0x847f, 0x0012}, {0x8480, 0x00ce}, {0x8481, 0x0084}, 3493 + {0x8482, 0x0086}, {0x8483, 0x00ff}, {0x8484, 0x0001}, 3494 + {0x8485, 0x0011}, {0x8486, 0x0096}, {0x8487, 0x0046}, 3495 + {0x8488, 0x0084}, {0x8489, 0x0003}, {0x848a, 0x0081}, 3496 + {0x848b, 0x0002}, {0x848c, 0x0027}, {0x848d, 0x0003}, 3497 + {0x848e, 0x007e}, {0x848f, 0x0085}, {0x8490, 0x000f}, 3498 + {0x8491, 0x00c6}, {0x8492, 0x0051}, {0x8493, 0x00bd}, 3499 + {0x8494, 0x00e4}, {0x8495, 0x0091}, {0x8496, 0x0025}, 3500 + {0x8497, 0x0003}, {0x8498, 0x007e}, {0x8499, 0x0085}, 3501 + {0x849a, 0x001e}, {0x849b, 0x0096}, {0x849c, 0x0044}, 3502 + {0x849d, 0x0085}, {0x849e, 0x0010}, {0x849f, 0x0026}, 3503 + {0x84a0, 0x000a}, {0x84a1, 0x00b6}, {0x84a2, 0x0012}, 3504 + {0x84a3, 0x0050}, {0x84a4, 0x00ba}, {0x84a5, 0x0001}, 3505 + {0x84a6, 0x003c}, {0x84a7, 0x0085}, {0x84a8, 0x0010}, 3506 + {0x84a9, 0x0027}, {0x84aa, 0x00a8}, {0x84ab, 0x00bd}, 3507 + {0x84ac, 0x00f7}, {0x84ad, 0x0066}, {0x84ae, 0x00ce}, 3508 + {0x84af, 0x0084}, {0x84b0, 0x00b7}, {0x84b1, 0x00ff}, 3509 + {0x84b2, 0x0001}, {0x84b3, 0x0011}, {0x84b4, 0x007e}, 3510 + {0x84b5, 0x0085}, {0x84b6, 0x001e}, {0x84b7, 0x0096}, 3511 + {0x84b8, 0x0046}, {0x84b9, 0x0084}, {0x84ba, 0x0003}, 3512 + {0x84bb, 0x0081}, {0x84bc, 0x0002}, {0x84bd, 0x0026}, 3513 + {0x84be, 0x0050}, {0x84bf, 0x00b6}, {0x84c0, 0x0012}, 3514 + {0x84c1, 0x0030}, {0x84c2, 0x0084}, {0x84c3, 0x0003}, 3515 + {0x84c4, 0x0081}, {0x84c5, 0x0001}, {0x84c6, 0x0027}, 3516 + {0x84c7, 0x0003}, {0x84c8, 0x007e}, {0x84c9, 0x0085}, 3517 + {0x84ca, 0x001e}, {0x84cb, 0x0096}, {0x84cc, 0x0044}, 3518 + {0x84cd, 0x0085}, {0x84ce, 0x0010}, {0x84cf, 0x0026}, 3519 + {0x84d0, 0x0013}, {0x84d1, 0x00b6}, {0x84d2, 0x0012}, 3520 + {0x84d3, 0x0050}, {0x84d4, 0x00ba}, {0x84d5, 0x0001}, 3521 + {0x84d6, 0x003c}, {0x84d7, 0x0085}, {0x84d8, 0x0010}, 3522 + {0x84d9, 0x0026}, {0x84da, 0x0009}, {0x84db, 0x00ce}, 3523 + {0x84dc, 0x0084}, {0x84dd, 0x0053}, {0x84de, 0x00ff}, 3524 + {0x84df, 0x0001}, {0x84e0, 0x0011}, {0x84e1, 0x007e}, 3525 + {0x84e2, 0x0085}, {0x84e3, 0x001e}, {0x84e4, 0x00b6}, 3526 + {0x84e5, 0x0010}, {0x84e6, 0x0031}, {0x84e7, 0x008a}, 3527 + {0x84e8, 0x0002}, {0x84e9, 0x00b7}, {0x84ea, 0x0010}, 3528 + {0x84eb, 0x0031}, {0x84ec, 0x00bd}, {0x84ed, 0x0085}, 3529 + {0x84ee, 0x001f}, {0x84ef, 0x00bd}, {0x84f0, 0x00f8}, 3530 + {0x84f1, 0x0037}, {0x84f2, 0x007c}, {0x84f3, 0x0000}, 3531 + {0x84f4, 0x0080}, {0x84f5, 0x00ce}, {0x84f6, 0x0084}, 3532 + {0x84f7, 0x00fe}, {0x84f8, 0x00ff}, {0x84f9, 0x0001}, 3533 + {0x84fa, 0x0011}, {0x84fb, 0x007e}, {0x84fc, 0x0085}, 3534 + {0x84fd, 0x001e}, {0x84fe, 0x0096}, {0x84ff, 0x0046}, 3535 + {0x8500, 0x0084}, {0x8501, 0x0003}, {0x8502, 0x0081}, 3536 + {0x8503, 0x0002}, {0x8504, 0x0026}, {0x8505, 0x0009}, 3537 + {0x8506, 0x00b6}, {0x8507, 0x0012}, {0x8508, 0x0030}, 3538 + {0x8509, 0x0084}, {0x850a, 0x0003}, {0x850b, 0x0081}, 3539 + {0x850c, 0x0001}, {0x850d, 0x0027}, {0x850e, 0x000f}, 3540 + {0x850f, 0x00bd}, {0x8510, 0x00f8}, {0x8511, 0x0044}, 3541 + {0x8512, 0x00bd}, {0x8513, 0x00f7}, {0x8514, 0x000b}, 3542 + {0x8515, 0x00bd}, {0x8516, 0x00fc}, {0x8517, 0x0029}, 3543 + {0x8518, 0x00ce}, {0x8519, 0x0084}, {0x851a, 0x0026}, 3544 + {0x851b, 0x00ff}, {0x851c, 0x0001}, {0x851d, 0x0011}, 3545 + {0x851e, 0x0039}, {0x851f, 0x00d6}, {0x8520, 0x0022}, 3546 + {0x8521, 0x00c4}, {0x8522, 0x000f}, {0x8523, 0x00b6}, 3547 + {0x8524, 0x0012}, {0x8525, 0x0030}, {0x8526, 0x00ba}, 3548 + {0x8527, 0x0012}, {0x8528, 0x0032}, {0x8529, 0x0084}, 3549 + {0x852a, 0x0004}, {0x852b, 0x0027}, {0x852c, 0x000d}, 3550 + {0x852d, 0x0096}, {0x852e, 0x0022}, {0x852f, 0x0085}, 3551 + {0x8530, 0x0004}, {0x8531, 0x0027}, {0x8532, 0x0005}, 3552 + {0x8533, 0x00ca}, {0x8534, 0x0010}, {0x8535, 0x007e}, 3553 + {0x8536, 0x0085}, {0x8537, 0x003a}, {0x8538, 0x00ca}, 3554 + {0x8539, 0x0020}, {0x853a, 0x00d7}, {0x853b, 0x0022}, 3555 + {0x853c, 0x0039}, {0x853d, 0x0086}, {0x853e, 0x0000}, 3556 + {0x853f, 0x0097}, {0x8540, 0x0083}, {0x8541, 0x0018}, 3557 + {0x8542, 0x00ce}, {0x8543, 0x001c}, {0x8544, 0x0000}, 3558 + {0x8545, 0x00bd}, {0x8546, 0x00eb}, {0x8547, 0x0046}, 3559 + {0x8548, 0x0096}, {0x8549, 0x0057}, {0x854a, 0x0085}, 3560 + {0x854b, 0x0001}, {0x854c, 0x0027}, {0x854d, 0x0002}, 3561 + {0x854e, 0x004f}, {0x854f, 0x0039}, {0x8550, 0x0085}, 3562 + {0x8551, 0x0002}, {0x8552, 0x0027}, {0x8553, 0x0001}, 3563 + {0x8554, 0x0039}, {0x8555, 0x007f}, {0x8556, 0x008f}, 3564 + {0x8557, 0x007d}, {0x8558, 0x0086}, {0x8559, 0x0004}, 3565 + {0x855a, 0x00b7}, {0x855b, 0x0012}, {0x855c, 0x0004}, 3566 + {0x855d, 0x0086}, {0x855e, 0x0008}, {0x855f, 0x00b7}, 3567 + {0x8560, 0x0012}, {0x8561, 0x0007}, {0x8562, 0x0086}, 3568 + {0x8563, 0x0010}, {0x8564, 0x00b7}, {0x8565, 0x0012}, 3569 + {0x8566, 0x000c}, {0x8567, 0x0086}, {0x8568, 0x0007}, 3570 + {0x8569, 0x00b7}, {0x856a, 0x0012}, {0x856b, 0x0006}, 3571 + {0x856c, 0x00b6}, {0x856d, 0x008f}, {0x856e, 0x007d}, 3572 + {0x856f, 0x00b7}, {0x8570, 0x0012}, {0x8571, 0x0070}, 3573 + {0x8572, 0x0086}, {0x8573, 0x0001}, {0x8574, 0x00ba}, 3574 + {0x8575, 0x0012}, {0x8576, 0x0004}, {0x8577, 0x00b7}, 3575 + {0x8578, 0x0012}, {0x8579, 0x0004}, {0x857a, 0x0001}, 3576 + {0x857b, 0x0001}, {0x857c, 0x0001}, {0x857d, 0x0001}, 3577 + {0x857e, 0x0001}, {0x857f, 0x0001}, {0x8580, 0x00b6}, 3578 + {0x8581, 0x0012}, {0x8582, 0x0004}, {0x8583, 0x0084}, 3579 + {0x8584, 0x00fe}, {0x8585, 0x008a}, {0x8586, 0x0002}, 3580 + {0x8587, 0x00b7}, {0x8588, 0x0012}, {0x8589, 0x0004}, 3581 + {0x858a, 0x0001}, {0x858b, 0x0001}, {0x858c, 0x0001}, 3582 + {0x858d, 0x0001}, {0x858e, 0x0001}, {0x858f, 0x0001}, 3583 + {0x8590, 0x0086}, {0x8591, 0x00fd}, {0x8592, 0x00b4}, 3584 + {0x8593, 0x0012}, {0x8594, 0x0004}, {0x8595, 0x00b7}, 3585 + {0x8596, 0x0012}, {0x8597, 0x0004}, {0x8598, 0x00b6}, 3586 + {0x8599, 0x0012}, {0x859a, 0x0000}, {0x859b, 0x0084}, 3587 + {0x859c, 0x0008}, {0x859d, 0x0081}, {0x859e, 0x0008}, 3588 + {0x859f, 0x0027}, {0x85a0, 0x0016}, {0x85a1, 0x00b6}, 3589 + {0x85a2, 0x008f}, {0x85a3, 0x007d}, {0x85a4, 0x0081}, 3590 + {0x85a5, 0x000c}, {0x85a6, 0x0027}, {0x85a7, 0x0008}, 3591 + {0x85a8, 0x008b}, {0x85a9, 0x0004}, {0x85aa, 0x00b7}, 3592 + {0x85ab, 0x008f}, {0x85ac, 0x007d}, {0x85ad, 0x007e}, 3593 + {0x85ae, 0x0085}, {0x85af, 0x006c}, {0x85b0, 0x0086}, 3594 + {0x85b1, 0x0003}, {0x85b2, 0x0097}, {0x85b3, 0x0040}, 3595 + {0x85b4, 0x007e}, {0x85b5, 0x0089}, {0x85b6, 0x006e}, 3596 + {0x85b7, 0x0086}, {0x85b8, 0x0007}, {0x85b9, 0x00b7}, 3597 + {0x85ba, 0x0012}, {0x85bb, 0x0006}, {0x85bc, 0x005f}, 3598 + {0x85bd, 0x00f7}, {0x85be, 0x008f}, {0x85bf, 0x0082}, 3599 + {0x85c0, 0x005f}, {0x85c1, 0x00f7}, {0x85c2, 0x008f}, 3600 + {0x85c3, 0x007f}, {0x85c4, 0x00f7}, {0x85c5, 0x008f}, 3601 + {0x85c6, 0x0070}, {0x85c7, 0x00f7}, {0x85c8, 0x008f}, 3602 + {0x85c9, 0x0071}, {0x85ca, 0x00f7}, {0x85cb, 0x008f}, 3603 + {0x85cc, 0x0072}, {0x85cd, 0x00f7}, {0x85ce, 0x008f}, 3604 + {0x85cf, 0x0073}, {0x85d0, 0x00f7}, {0x85d1, 0x008f}, 3605 + {0x85d2, 0x0074}, {0x85d3, 0x00f7}, {0x85d4, 0x008f}, 3606 + {0x85d5, 0x0075}, {0x85d6, 0x00f7}, {0x85d7, 0x008f}, 3607 + {0x85d8, 0x0076}, {0x85d9, 0x00f7}, {0x85da, 0x008f}, 3608 + {0x85db, 0x0077}, {0x85dc, 0x00f7}, {0x85dd, 0x008f}, 3609 + {0x85de, 0x0078}, {0x85df, 0x00f7}, {0x85e0, 0x008f}, 3610 + {0x85e1, 0x0079}, {0x85e2, 0x00f7}, {0x85e3, 0x008f}, 3611 + {0x85e4, 0x007a}, {0x85e5, 0x00f7}, {0x85e6, 0x008f}, 3612 + {0x85e7, 0x007b}, {0x85e8, 0x00b6}, {0x85e9, 0x0012}, 3613 + {0x85ea, 0x0004}, {0x85eb, 0x008a}, {0x85ec, 0x0010}, 3614 + {0x85ed, 0x00b7}, {0x85ee, 0x0012}, {0x85ef, 0x0004}, 3615 + {0x85f0, 0x0086}, {0x85f1, 0x00e4}, {0x85f2, 0x00b7}, 3616 + {0x85f3, 0x0012}, {0x85f4, 0x0070}, {0x85f5, 0x00b7}, 3617 + {0x85f6, 0x0012}, {0x85f7, 0x0007}, {0x85f8, 0x00f7}, 3618 + {0x85f9, 0x0012}, {0x85fa, 0x0005}, {0x85fb, 0x00f7}, 3619 + {0x85fc, 0x0012}, {0x85fd, 0x0009}, {0x85fe, 0x0086}, 3620 + {0x85ff, 0x0008}, {0x8600, 0x00ba}, {0x8601, 0x0012}, 3621 + {0x8602, 0x0004}, {0x8603, 0x00b7}, {0x8604, 0x0012}, 3622 + {0x8605, 0x0004}, {0x8606, 0x0086}, {0x8607, 0x00f7}, 3623 + {0x8608, 0x00b4}, {0x8609, 0x0012}, {0x860a, 0x0004}, 3624 + {0x860b, 0x00b7}, {0x860c, 0x0012}, {0x860d, 0x0004}, 3625 + {0x860e, 0x0001}, {0x860f, 0x0001}, {0x8610, 0x0001}, 3626 + {0x8611, 0x0001}, {0x8612, 0x0001}, {0x8613, 0x0001}, 3627 + {0x8614, 0x00b6}, {0x8615, 0x0012}, {0x8616, 0x0008}, 3628 + {0x8617, 0x0027}, {0x8618, 0x007f}, {0x8619, 0x0081}, 3629 + {0x861a, 0x0080}, {0x861b, 0x0026}, {0x861c, 0x000b}, 3630 + {0x861d, 0x0086}, {0x861e, 0x0008}, {0x861f, 0x00ce}, 3631 + {0x8620, 0x008f}, {0x8621, 0x0079}, {0x8622, 0x00bd}, 3632 + {0x8623, 0x0089}, {0x8624, 0x007b}, {0x8625, 0x007e}, 3633 + {0x8626, 0x0086}, {0x8627, 0x008e}, {0x8628, 0x0081}, 3634 + {0x8629, 0x0040}, {0x862a, 0x0026}, {0x862b, 0x000b}, 3635 + {0x862c, 0x0086}, {0x862d, 0x0004}, {0x862e, 0x00ce}, 3636 + {0x862f, 0x008f}, {0x8630, 0x0076}, {0x8631, 0x00bd}, 3637 + {0x8632, 0x0089}, {0x8633, 0x007b}, {0x8634, 0x007e}, 3638 + {0x8635, 0x0086}, {0x8636, 0x008e}, {0x8637, 0x0081}, 3639 + {0x8638, 0x0020}, {0x8639, 0x0026}, {0x863a, 0x000b}, 3640 + {0x863b, 0x0086}, {0x863c, 0x0002}, {0x863d, 0x00ce}, 3641 + {0x863e, 0x008f}, {0x863f, 0x0073}, {0x8640, 0x00bd}, 3642 + {0x8641, 0x0089}, {0x8642, 0x007b}, {0x8643, 0x007e}, 3643 + {0x8644, 0x0086}, {0x8645, 0x008e}, {0x8646, 0x0081}, 3644 + {0x8647, 0x0010}, {0x8648, 0x0026}, {0x8649, 0x000b}, 3645 + {0x864a, 0x0086}, {0x864b, 0x0001}, {0x864c, 0x00ce}, 3646 + {0x864d, 0x008f}, {0x864e, 0x0070}, {0x864f, 0x00bd}, 3647 + {0x8650, 0x0089}, {0x8651, 0x007b}, {0x8652, 0x007e}, 3648 + {0x8653, 0x0086}, {0x8654, 0x008e}, {0x8655, 0x0081}, 3649 + {0x8656, 0x0008}, {0x8657, 0x0026}, {0x8658, 0x000b}, 3650 + {0x8659, 0x0086}, {0x865a, 0x0008}, {0x865b, 0x00ce}, 3651 + {0x865c, 0x008f}, {0x865d, 0x0079}, {0x865e, 0x00bd}, 3652 + {0x865f, 0x0089}, {0x8660, 0x007f}, {0x8661, 0x007e}, 3653 + {0x8662, 0x0086}, {0x8663, 0x008e}, {0x8664, 0x0081}, 3654 + {0x8665, 0x0004}, {0x8666, 0x0026}, {0x8667, 0x000b}, 3655 + {0x8668, 0x0086}, {0x8669, 0x0004}, {0x866a, 0x00ce}, 3656 + {0x866b, 0x008f}, {0x866c, 0x0076}, {0x866d, 0x00bd}, 3657 + {0x866e, 0x0089}, {0x866f, 0x007f}, {0x8670, 0x007e}, 3658 + {0x8671, 0x0086}, {0x8672, 0x008e}, {0x8673, 0x0081}, 3659 + {0x8674, 0x0002}, {0x8675, 0x0026}, {0x8676, 0x000b}, 3660 + {0x8677, 0x008a}, {0x8678, 0x0002}, {0x8679, 0x00ce}, 3661 + {0x867a, 0x008f}, {0x867b, 0x0073}, {0x867c, 0x00bd}, 3662 + {0x867d, 0x0089}, {0x867e, 0x007f}, {0x867f, 0x007e}, 3663 + {0x8680, 0x0086}, {0x8681, 0x008e}, {0x8682, 0x0081}, 3664 + {0x8683, 0x0001}, {0x8684, 0x0026}, {0x8685, 0x0008}, 3665 + {0x8686, 0x0086}, {0x8687, 0x0001}, {0x8688, 0x00ce}, 3666 + {0x8689, 0x008f}, {0x868a, 0x0070}, {0x868b, 0x00bd}, 3667 + {0x868c, 0x0089}, {0x868d, 0x007f}, {0x868e, 0x00b6}, 3668 + {0x868f, 0x008f}, {0x8690, 0x007f}, {0x8691, 0x0081}, 3669 + {0x8692, 0x000f}, {0x8693, 0x0026}, {0x8694, 0x0003}, 3670 + {0x8695, 0x007e}, {0x8696, 0x0087}, {0x8697, 0x0047}, 3671 + {0x8698, 0x00b6}, {0x8699, 0x0012}, {0x869a, 0x0009}, 3672 + {0x869b, 0x0084}, {0x869c, 0x0003}, {0x869d, 0x0081}, 3673 + {0x869e, 0x0003}, {0x869f, 0x0027}, {0x86a0, 0x0006}, 3674 + {0x86a1, 0x007c}, {0x86a2, 0x0012}, {0x86a3, 0x0009}, 3675 + {0x86a4, 0x007e}, {0x86a5, 0x0085}, {0x86a6, 0x00fe}, 3676 + {0x86a7, 0x00b6}, {0x86a8, 0x0012}, {0x86a9, 0x0006}, 3677 + {0x86aa, 0x0084}, {0x86ab, 0x0007}, {0x86ac, 0x0081}, 3678 + {0x86ad, 0x0007}, {0x86ae, 0x0027}, {0x86af, 0x0008}, 3679 + {0x86b0, 0x008b}, {0x86b1, 0x0001}, {0x86b2, 0x00b7}, 3680 + {0x86b3, 0x0012}, {0x86b4, 0x0006}, {0x86b5, 0x007e}, 3681 + {0x86b6, 0x0086}, {0x86b7, 0x00d5}, {0x86b8, 0x00b6}, 3682 + {0x86b9, 0x008f}, {0x86ba, 0x0082}, {0x86bb, 0x0026}, 3683 + {0x86bc, 0x000a}, {0x86bd, 0x007c}, {0x86be, 0x008f}, 3684 + {0x86bf, 0x0082}, {0x86c0, 0x004f}, {0x86c1, 0x00b7}, 3685 + {0x86c2, 0x0012}, {0x86c3, 0x0006}, {0x86c4, 0x007e}, 3686 + {0x86c5, 0x0085}, {0x86c6, 0x00c0}, {0x86c7, 0x00b6}, 3687 + {0x86c8, 0x0012}, {0x86c9, 0x0006}, {0x86ca, 0x0084}, 3688 + {0x86cb, 0x003f}, {0x86cc, 0x0081}, {0x86cd, 0x003f}, 3689 + {0x86ce, 0x0027}, {0x86cf, 0x0010}, {0x86d0, 0x008b}, 3690 + {0x86d1, 0x0008}, {0x86d2, 0x00b7}, {0x86d3, 0x0012}, 3691 + {0x86d4, 0x0006}, {0x86d5, 0x00b6}, {0x86d6, 0x0012}, 3692 + {0x86d7, 0x0009}, {0x86d8, 0x0084}, {0x86d9, 0x00fc}, 3693 + {0x86da, 0x00b7}, {0x86db, 0x0012}, {0x86dc, 0x0009}, 3694 + {0x86dd, 0x007e}, {0x86de, 0x0085}, {0x86df, 0x00fe}, 3695 + {0x86e0, 0x00ce}, {0x86e1, 0x008f}, {0x86e2, 0x0070}, 3696 + {0x86e3, 0x0018}, {0x86e4, 0x00ce}, {0x86e5, 0x008f}, 3697 + {0x86e6, 0x0084}, {0x86e7, 0x00c6}, {0x86e8, 0x000c}, 3698 + {0x86e9, 0x00bd}, {0x86ea, 0x0089}, {0x86eb, 0x006f}, 3699 + {0x86ec, 0x00ce}, {0x86ed, 0x008f}, {0x86ee, 0x0084}, 3700 + {0x86ef, 0x0018}, {0x86f0, 0x00ce}, {0x86f1, 0x008f}, 3701 + {0x86f2, 0x0070}, {0x86f3, 0x00c6}, {0x86f4, 0x000c}, 3702 + {0x86f5, 0x00bd}, {0x86f6, 0x0089}, {0x86f7, 0x006f}, 3703 + {0x86f8, 0x00d6}, {0x86f9, 0x0083}, {0x86fa, 0x00c1}, 3704 + {0x86fb, 0x004f}, {0x86fc, 0x002d}, {0x86fd, 0x0003}, 3705 + {0x86fe, 0x007e}, {0x86ff, 0x0087}, {0x8700, 0x0040}, 3706 + {0x8701, 0x00b6}, {0x8702, 0x008f}, {0x8703, 0x007f}, 3707 + {0x8704, 0x0081}, {0x8705, 0x0007}, {0x8706, 0x0027}, 3708 + {0x8707, 0x000f}, {0x8708, 0x0081}, {0x8709, 0x000b}, 3709 + {0x870a, 0x0027}, {0x870b, 0x0015}, {0x870c, 0x0081}, 3710 + {0x870d, 0x000d}, {0x870e, 0x0027}, {0x870f, 0x001b}, 3711 + {0x8710, 0x0081}, {0x8711, 0x000e}, {0x8712, 0x0027}, 3712 + {0x8713, 0x0021}, {0x8714, 0x007e}, {0x8715, 0x0087}, 3713 + {0x8716, 0x0040}, {0x8717, 0x00f7}, {0x8718, 0x008f}, 3714 + {0x8719, 0x007b}, {0x871a, 0x0086}, {0x871b, 0x0002}, 3715 + {0x871c, 0x00b7}, {0x871d, 0x008f}, {0x871e, 0x007a}, 3716 + {0x871f, 0x0020}, {0x8720, 0x001c}, {0x8721, 0x00f7}, 3717 + {0x8722, 0x008f}, {0x8723, 0x0078}, {0x8724, 0x0086}, 3718 + {0x8725, 0x0002}, {0x8726, 0x00b7}, {0x8727, 0x008f}, 3719 + {0x8728, 0x0077}, {0x8729, 0x0020}, {0x872a, 0x0012}, 3720 + {0x872b, 0x00f7}, {0x872c, 0x008f}, {0x872d, 0x0075}, 3721 + {0x872e, 0x0086}, {0x872f, 0x0002}, {0x8730, 0x00b7}, 3722 + {0x8731, 0x008f}, {0x8732, 0x0074}, {0x8733, 0x0020}, 3723 + {0x8734, 0x0008}, {0x8735, 0x00f7}, {0x8736, 0x008f}, 3724 + {0x8737, 0x0072}, {0x8738, 0x0086}, {0x8739, 0x0002}, 3725 + {0x873a, 0x00b7}, {0x873b, 0x008f}, {0x873c, 0x0071}, 3726 + {0x873d, 0x007e}, {0x873e, 0x0087}, {0x873f, 0x0047}, 3727 + {0x8740, 0x0086}, {0x8741, 0x0004}, {0x8742, 0x0097}, 3728 + {0x8743, 0x0040}, {0x8744, 0x007e}, {0x8745, 0x0089}, 3729 + {0x8746, 0x006e}, {0x8747, 0x00ce}, {0x8748, 0x008f}, 3730 + {0x8749, 0x0072}, {0x874a, 0x00bd}, {0x874b, 0x0089}, 3731 + {0x874c, 0x00f7}, {0x874d, 0x00ce}, {0x874e, 0x008f}, 3732 + {0x874f, 0x0075}, {0x8750, 0x00bd}, {0x8751, 0x0089}, 3733 + {0x8752, 0x00f7}, {0x8753, 0x00ce}, {0x8754, 0x008f}, 3734 + {0x8755, 0x0078}, {0x8756, 0x00bd}, {0x8757, 0x0089}, 3735 + {0x8758, 0x00f7}, {0x8759, 0x00ce}, {0x875a, 0x008f}, 3736 + {0x875b, 0x007b}, {0x875c, 0x00bd}, {0x875d, 0x0089}, 3737 + {0x875e, 0x00f7}, {0x875f, 0x004f}, {0x8760, 0x00b7}, 3738 + {0x8761, 0x008f}, {0x8762, 0x007d}, {0x8763, 0x00b7}, 3739 + {0x8764, 0x008f}, {0x8765, 0x0081}, {0x8766, 0x00b6}, 3740 + {0x8767, 0x008f}, {0x8768, 0x0072}, {0x8769, 0x0027}, 3741 + {0x876a, 0x0047}, {0x876b, 0x007c}, {0x876c, 0x008f}, 3742 + {0x876d, 0x007d}, {0x876e, 0x00b6}, {0x876f, 0x008f}, 3743 + {0x8770, 0x0075}, {0x8771, 0x0027}, {0x8772, 0x003f}, 3744 + {0x8773, 0x007c}, {0x8774, 0x008f}, {0x8775, 0x007d}, 3745 + {0x8776, 0x00b6}, {0x8777, 0x008f}, {0x8778, 0x0078}, 3746 + {0x8779, 0x0027}, {0x877a, 0x0037}, {0x877b, 0x007c}, 3747 + {0x877c, 0x008f}, {0x877d, 0x007d}, {0x877e, 0x00b6}, 3748 + {0x877f, 0x008f}, {0x8780, 0x007b}, {0x8781, 0x0027}, 3749 + {0x8782, 0x002f}, {0x8783, 0x007f}, {0x8784, 0x008f}, 3750 + {0x8785, 0x007d}, {0x8786, 0x007c}, {0x8787, 0x008f}, 3751 + {0x8788, 0x0081}, {0x8789, 0x007a}, {0x878a, 0x008f}, 3752 + {0x878b, 0x0072}, {0x878c, 0x0027}, {0x878d, 0x001b}, 3753 + {0x878e, 0x007c}, {0x878f, 0x008f}, {0x8790, 0x007d}, 3754 + {0x8791, 0x007a}, {0x8792, 0x008f}, {0x8793, 0x0075}, 3755 + {0x8794, 0x0027}, {0x8795, 0x0016}, {0x8796, 0x007c}, 3756 + {0x8797, 0x008f}, {0x8798, 0x007d}, {0x8799, 0x007a}, 3757 + {0x879a, 0x008f}, {0x879b, 0x0078}, {0x879c, 0x0027}, 3758 + {0x879d, 0x0011}, {0x879e, 0x007c}, {0x879f, 0x008f}, 3759 + {0x87a0, 0x007d}, {0x87a1, 0x007a}, {0x87a2, 0x008f}, 3760 + {0x87a3, 0x007b}, {0x87a4, 0x0027}, {0x87a5, 0x000c}, 3761 + {0x87a6, 0x007e}, {0x87a7, 0x0087}, {0x87a8, 0x0083}, 3762 + {0x87a9, 0x007a}, {0x87aa, 0x008f}, {0x87ab, 0x0075}, 3763 + {0x87ac, 0x007a}, {0x87ad, 0x008f}, {0x87ae, 0x0078}, 3764 + {0x87af, 0x007a}, {0x87b0, 0x008f}, {0x87b1, 0x007b}, 3765 + {0x87b2, 0x00ce}, {0x87b3, 0x00c1}, {0x87b4, 0x00fc}, 3766 + {0x87b5, 0x00f6}, {0x87b6, 0x008f}, {0x87b7, 0x007d}, 3767 + {0x87b8, 0x003a}, {0x87b9, 0x00a6}, {0x87ba, 0x0000}, 3768 + {0x87bb, 0x00b7}, {0x87bc, 0x0012}, {0x87bd, 0x0070}, 3769 + {0x87be, 0x00b6}, {0x87bf, 0x008f}, {0x87c0, 0x0072}, 3770 + {0x87c1, 0x0026}, {0x87c2, 0x0003}, {0x87c3, 0x007e}, 3771 + {0x87c4, 0x0087}, {0x87c5, 0x00fa}, {0x87c6, 0x00b6}, 3772 + {0x87c7, 0x008f}, {0x87c8, 0x0075}, {0x87c9, 0x0026}, 3773 + {0x87ca, 0x000a}, {0x87cb, 0x0018}, {0x87cc, 0x00ce}, 3774 + {0x87cd, 0x008f}, {0x87ce, 0x0073}, {0x87cf, 0x00bd}, 3775 + {0x87d0, 0x0089}, {0x87d1, 0x00d5}, {0x87d2, 0x007e}, 3776 + {0x87d3, 0x0087}, {0x87d4, 0x00fa}, {0x87d5, 0x00b6}, 3777 + {0x87d6, 0x008f}, {0x87d7, 0x0078}, {0x87d8, 0x0026}, 3778 + {0x87d9, 0x000a}, {0x87da, 0x0018}, {0x87db, 0x00ce}, 3779 + {0x87dc, 0x008f}, {0x87dd, 0x0076}, {0x87de, 0x00bd}, 3780 + {0x87df, 0x0089}, {0x87e0, 0x00d5}, {0x87e1, 0x007e}, 3781 + {0x87e2, 0x0087}, {0x87e3, 0x00fa}, {0x87e4, 0x00b6}, 3782 + {0x87e5, 0x008f}, {0x87e6, 0x007b}, {0x87e7, 0x0026}, 3783 + {0x87e8, 0x000a}, {0x87e9, 0x0018}, {0x87ea, 0x00ce}, 3784 + {0x87eb, 0x008f}, {0x87ec, 0x0079}, {0x87ed, 0x00bd}, 3785 + {0x87ee, 0x0089}, {0x87ef, 0x00d5}, {0x87f0, 0x007e}, 3786 + {0x87f1, 0x0087}, {0x87f2, 0x00fa}, {0x87f3, 0x0086}, 3787 + {0x87f4, 0x0005}, {0x87f5, 0x0097}, {0x87f6, 0x0040}, 3788 + {0x87f7, 0x007e}, {0x87f8, 0x0089}, {0x87f9, 0x006e}, 3789 + {0x87fa, 0x00b6}, {0x87fb, 0x008f}, {0x87fc, 0x0075}, 3790 + {0x87fd, 0x0081}, {0x87fe, 0x0007}, {0x87ff, 0x002e}, 3791 + {0x8800, 0x00f2}, {0x8801, 0x00f6}, {0x8802, 0x0012}, 3792 + {0x8803, 0x0006}, {0x8804, 0x00c4}, {0x8805, 0x00f8}, 3793 + {0x8806, 0x001b}, {0x8807, 0x00b7}, {0x8808, 0x0012}, 3794 + {0x8809, 0x0006}, {0x880a, 0x00b6}, {0x880b, 0x008f}, 3795 + {0x880c, 0x0078}, {0x880d, 0x0081}, {0x880e, 0x0007}, 3796 + {0x880f, 0x002e}, {0x8810, 0x00e2}, {0x8811, 0x0048}, 3797 + {0x8812, 0x0048}, {0x8813, 0x0048}, {0x8814, 0x00f6}, 3798 + {0x8815, 0x0012}, {0x8816, 0x0006}, {0x8817, 0x00c4}, 3799 + {0x8818, 0x00c7}, {0x8819, 0x001b}, {0x881a, 0x00b7}, 3800 + {0x881b, 0x0012}, {0x881c, 0x0006}, {0x881d, 0x00b6}, 3801 + {0x881e, 0x008f}, {0x881f, 0x007b}, {0x8820, 0x0081}, 3802 + {0x8821, 0x0007}, {0x8822, 0x002e}, {0x8823, 0x00cf}, 3803 + {0x8824, 0x00f6}, {0x8825, 0x0012}, {0x8826, 0x0005}, 3804 + {0x8827, 0x00c4}, {0x8828, 0x00f8}, {0x8829, 0x001b}, 3805 + {0x882a, 0x00b7}, {0x882b, 0x0012}, {0x882c, 0x0005}, 3806 + {0x882d, 0x0086}, {0x882e, 0x0000}, {0x882f, 0x00f6}, 3807 + {0x8830, 0x008f}, {0x8831, 0x0071}, {0x8832, 0x00bd}, 3808 + {0x8833, 0x0089}, {0x8834, 0x0094}, {0x8835, 0x0086}, 3809 + {0x8836, 0x0001}, {0x8837, 0x00f6}, {0x8838, 0x008f}, 3810 + {0x8839, 0x0074}, {0x883a, 0x00bd}, {0x883b, 0x0089}, 3811 + {0x883c, 0x0094}, {0x883d, 0x0086}, {0x883e, 0x0002}, 3812 + {0x883f, 0x00f6}, {0x8840, 0x008f}, {0x8841, 0x0077}, 3813 + {0x8842, 0x00bd}, {0x8843, 0x0089}, {0x8844, 0x0094}, 3814 + {0x8845, 0x0086}, {0x8846, 0x0003}, {0x8847, 0x00f6}, 3815 + {0x8848, 0x008f}, {0x8849, 0x007a}, {0x884a, 0x00bd}, 3816 + {0x884b, 0x0089}, {0x884c, 0x0094}, {0x884d, 0x00ce}, 3817 + {0x884e, 0x008f}, {0x884f, 0x0070}, {0x8850, 0x00a6}, 3818 + {0x8851, 0x0001}, {0x8852, 0x0081}, {0x8853, 0x0001}, 3819 + {0x8854, 0x0027}, {0x8855, 0x0007}, {0x8856, 0x0081}, 3820 + {0x8857, 0x0003}, {0x8858, 0x0027}, {0x8859, 0x0003}, 3821 + {0x885a, 0x007e}, {0x885b, 0x0088}, {0x885c, 0x0066}, 3822 + {0x885d, 0x00a6}, {0x885e, 0x0000}, {0x885f, 0x00b8}, 3823 + {0x8860, 0x008f}, {0x8861, 0x0081}, {0x8862, 0x0084}, 3824 + {0x8863, 0x0001}, {0x8864, 0x0026}, {0x8865, 0x000b}, 3825 + {0x8866, 0x008c}, {0x8867, 0x008f}, {0x8868, 0x0079}, 3826 + {0x8869, 0x002c}, {0x886a, 0x000e}, {0x886b, 0x0008}, 3827 + {0x886c, 0x0008}, {0x886d, 0x0008}, {0x886e, 0x007e}, 3828 + {0x886f, 0x0088}, {0x8870, 0x0050}, {0x8871, 0x00b6}, 3829 + {0x8872, 0x0012}, {0x8873, 0x0004}, {0x8874, 0x008a}, 3830 + {0x8875, 0x0040}, {0x8876, 0x00b7}, {0x8877, 0x0012}, 3831 + {0x8878, 0x0004}, {0x8879, 0x00b6}, {0x887a, 0x0012}, 3832 + {0x887b, 0x0004}, {0x887c, 0x0084}, {0x887d, 0x00fb}, 3833 + {0x887e, 0x0084}, {0x887f, 0x00ef}, {0x8880, 0x00b7}, 3834 + {0x8881, 0x0012}, {0x8882, 0x0004}, {0x8883, 0x00b6}, 3835 + {0x8884, 0x0012}, {0x8885, 0x0007}, {0x8886, 0x0036}, 3836 + {0x8887, 0x00b6}, {0x8888, 0x008f}, {0x8889, 0x007c}, 3837 + {0x888a, 0x0048}, {0x888b, 0x0048}, {0x888c, 0x00b7}, 3838 + {0x888d, 0x0012}, {0x888e, 0x0007}, {0x888f, 0x0086}, 3839 + {0x8890, 0x0001}, {0x8891, 0x00ba}, {0x8892, 0x0012}, 3840 + {0x8893, 0x0004}, {0x8894, 0x00b7}, {0x8895, 0x0012}, 3841 + {0x8896, 0x0004}, {0x8897, 0x0001}, {0x8898, 0x0001}, 3842 + {0x8899, 0x0001}, {0x889a, 0x0001}, {0x889b, 0x0001}, 3843 + {0x889c, 0x0001}, {0x889d, 0x0086}, {0x889e, 0x00fe}, 3844 + {0x889f, 0x00b4}, {0x88a0, 0x0012}, {0x88a1, 0x0004}, 3845 + {0x88a2, 0x00b7}, {0x88a3, 0x0012}, {0x88a4, 0x0004}, 3846 + {0x88a5, 0x0086}, {0x88a6, 0x0002}, {0x88a7, 0x00ba}, 3847 + {0x88a8, 0x0012}, {0x88a9, 0x0004}, {0x88aa, 0x00b7}, 3848 + {0x88ab, 0x0012}, {0x88ac, 0x0004}, {0x88ad, 0x0086}, 3849 + {0x88ae, 0x00fd}, {0x88af, 0x00b4}, {0x88b0, 0x0012}, 3850 + {0x88b1, 0x0004}, {0x88b2, 0x00b7}, {0x88b3, 0x0012}, 3851 + {0x88b4, 0x0004}, {0x88b5, 0x0032}, {0x88b6, 0x00b7}, 3852 + {0x88b7, 0x0012}, {0x88b8, 0x0007}, {0x88b9, 0x00b6}, 3853 + {0x88ba, 0x0012}, {0x88bb, 0x0000}, {0x88bc, 0x0084}, 3854 + {0x88bd, 0x0008}, {0x88be, 0x0081}, {0x88bf, 0x0008}, 3855 + {0x88c0, 0x0027}, {0x88c1, 0x000f}, {0x88c2, 0x007c}, 3856 + {0x88c3, 0x0082}, {0x88c4, 0x0008}, {0x88c5, 0x0026}, 3857 + {0x88c6, 0x0007}, {0x88c7, 0x0086}, {0x88c8, 0x0076}, 3858 + {0x88c9, 0x0097}, {0x88ca, 0x0040}, {0x88cb, 0x007e}, 3859 + {0x88cc, 0x0089}, {0x88cd, 0x006e}, {0x88ce, 0x007e}, 3860 + {0x88cf, 0x0086}, {0x88d0, 0x00ec}, {0x88d1, 0x00b6}, 3861 + {0x88d2, 0x008f}, {0x88d3, 0x007f}, {0x88d4, 0x0081}, 3862 + {0x88d5, 0x000f}, {0x88d6, 0x0027}, {0x88d7, 0x003c}, 3863 + {0x88d8, 0x00bd}, {0x88d9, 0x00e6}, {0x88da, 0x00c7}, 3864 + {0x88db, 0x00b7}, {0x88dc, 0x0012}, {0x88dd, 0x000d}, 3865 + {0x88de, 0x00bd}, {0x88df, 0x00e6}, {0x88e0, 0x00cb}, 3866 + {0x88e1, 0x00b6}, {0x88e2, 0x0012}, {0x88e3, 0x0004}, 3867 + {0x88e4, 0x008a}, {0x88e5, 0x0020}, {0x88e6, 0x00b7}, 3868 + {0x88e7, 0x0012}, {0x88e8, 0x0004}, {0x88e9, 0x00ce}, 3869 + {0x88ea, 0x00ff}, {0x88eb, 0x00ff}, {0x88ec, 0x00b6}, 3870 + {0x88ed, 0x0012}, {0x88ee, 0x0000}, {0x88ef, 0x0081}, 3871 + {0x88f0, 0x000c}, {0x88f1, 0x0026}, {0x88f2, 0x0005}, 3872 + {0x88f3, 0x0009}, {0x88f4, 0x0026}, {0x88f5, 0x00f6}, 3873 + {0x88f6, 0x0027}, {0x88f7, 0x001c}, {0x88f8, 0x00b6}, 3874 + {0x88f9, 0x0012}, {0x88fa, 0x0004}, {0x88fb, 0x0084}, 3875 + {0x88fc, 0x00df}, {0x88fd, 0x00b7}, {0x88fe, 0x0012}, 3876 + {0x88ff, 0x0004}, {0x8900, 0x0096}, {0x8901, 0x0083}, 3877 + {0x8902, 0x0081}, {0x8903, 0x0007}, {0x8904, 0x002c}, 3878 + {0x8905, 0x0005}, {0x8906, 0x007c}, {0x8907, 0x0000}, 3879 + {0x8908, 0x0083}, {0x8909, 0x0020}, {0x890a, 0x0006}, 3880 + {0x890b, 0x0096}, {0x890c, 0x0083}, {0x890d, 0x008b}, 3881 + {0x890e, 0x0008}, {0x890f, 0x0097}, {0x8910, 0x0083}, 3882 + {0x8911, 0x007e}, {0x8912, 0x0085}, {0x8913, 0x0041}, 3883 + {0x8914, 0x007f}, {0x8915, 0x008f}, {0x8916, 0x007e}, 3884 + {0x8917, 0x0086}, {0x8918, 0x0080}, {0x8919, 0x00b7}, 3885 + {0x891a, 0x0012}, {0x891b, 0x000c}, {0x891c, 0x0086}, 3886 + {0x891d, 0x0001}, {0x891e, 0x00b7}, {0x891f, 0x008f}, 3887 + {0x8920, 0x007d}, {0x8921, 0x00b6}, {0x8922, 0x0012}, 3888 + {0x8923, 0x000c}, {0x8924, 0x0084}, {0x8925, 0x007f}, 3889 + {0x8926, 0x00b7}, {0x8927, 0x0012}, {0x8928, 0x000c}, 3890 + {0x8929, 0x008a}, {0x892a, 0x0080}, {0x892b, 0x00b7}, 3891 + {0x892c, 0x0012}, {0x892d, 0x000c}, {0x892e, 0x0086}, 3892 + {0x892f, 0x000a}, {0x8930, 0x00bd}, {0x8931, 0x008a}, 3893 + {0x8932, 0x0006}, {0x8933, 0x00b6}, {0x8934, 0x0012}, 3894 + {0x8935, 0x000a}, {0x8936, 0x002a}, {0x8937, 0x0009}, 3895 + {0x8938, 0x00b6}, {0x8939, 0x0012}, {0x893a, 0x000c}, 3896 + {0x893b, 0x00ba}, {0x893c, 0x008f}, {0x893d, 0x007d}, 3897 + {0x893e, 0x00b7}, {0x893f, 0x0012}, {0x8940, 0x000c}, 3898 + {0x8941, 0x00b6}, {0x8942, 0x008f}, {0x8943, 0x007e}, 3899 + {0x8944, 0x0081}, {0x8945, 0x0060}, {0x8946, 0x0027}, 3900 + {0x8947, 0x001a}, {0x8948, 0x008b}, {0x8949, 0x0020}, 3901 + {0x894a, 0x00b7}, {0x894b, 0x008f}, {0x894c, 0x007e}, 3902 + {0x894d, 0x00b6}, {0x894e, 0x0012}, {0x894f, 0x000c}, 3903 + {0x8950, 0x0084}, {0x8951, 0x009f}, {0x8952, 0x00ba}, 3904 + {0x8953, 0x008f}, {0x8954, 0x007e}, {0x8955, 0x00b7}, 3905 + {0x8956, 0x0012}, {0x8957, 0x000c}, {0x8958, 0x00b6}, 3906 + {0x8959, 0x008f}, {0x895a, 0x007d}, {0x895b, 0x0048}, 3907 + {0x895c, 0x00b7}, {0x895d, 0x008f}, {0x895e, 0x007d}, 3908 + {0x895f, 0x007e}, {0x8960, 0x0089}, {0x8961, 0x0021}, 3909 + {0x8962, 0x00b6}, {0x8963, 0x0012}, {0x8964, 0x0004}, 3910 + {0x8965, 0x008a}, {0x8966, 0x0020}, {0x8967, 0x00b7}, 3911 + {0x8968, 0x0012}, {0x8969, 0x0004}, {0x896a, 0x00bd}, 3912 + {0x896b, 0x008a}, {0x896c, 0x000a}, {0x896d, 0x004f}, 3913 + {0x896e, 0x0039}, {0x896f, 0x00a6}, {0x8970, 0x0000}, 3914 + {0x8971, 0x0018}, {0x8972, 0x00a7}, {0x8973, 0x0000}, 3915 + {0x8974, 0x0008}, {0x8975, 0x0018}, {0x8976, 0x0008}, 3916 + {0x8977, 0x005a}, {0x8978, 0x0026}, {0x8979, 0x00f5}, 3917 + {0x897a, 0x0039}, {0x897b, 0x0036}, {0x897c, 0x006c}, 3918 + {0x897d, 0x0000}, {0x897e, 0x0032}, {0x897f, 0x00ba}, 3919 + {0x8980, 0x008f}, {0x8981, 0x007f}, {0x8982, 0x00b7}, 3920 + {0x8983, 0x008f}, {0x8984, 0x007f}, {0x8985, 0x00b6}, 3921 + {0x8986, 0x0012}, {0x8987, 0x0009}, {0x8988, 0x0084}, 3922 + {0x8989, 0x0003}, {0x898a, 0x00a7}, {0x898b, 0x0001}, 3923 + {0x898c, 0x00b6}, {0x898d, 0x0012}, {0x898e, 0x0006}, 3924 + {0x898f, 0x0084}, {0x8990, 0x003f}, {0x8991, 0x00a7}, 3925 + {0x8992, 0x0002}, {0x8993, 0x0039}, {0x8994, 0x0036}, 3926 + {0x8995, 0x0086}, {0x8996, 0x0003}, {0x8997, 0x00b7}, 3927 + {0x8998, 0x008f}, {0x8999, 0x0080}, {0x899a, 0x0032}, 3928 + {0x899b, 0x00c1}, {0x899c, 0x0000}, {0x899d, 0x0026}, 3929 + {0x899e, 0x0006}, {0x899f, 0x00b7}, {0x89a0, 0x008f}, 3930 + {0x89a1, 0x007c}, {0x89a2, 0x007e}, {0x89a3, 0x0089}, 3931 + {0x89a4, 0x00c9}, {0x89a5, 0x00c1}, {0x89a6, 0x0001}, 3932 + {0x89a7, 0x0027}, {0x89a8, 0x0018}, {0x89a9, 0x00c1}, 3933 + {0x89aa, 0x0002}, {0x89ab, 0x0027}, {0x89ac, 0x000c}, 3934 + {0x89ad, 0x00c1}, {0x89ae, 0x0003}, {0x89af, 0x0027}, 3935 + {0x89b0, 0x0000}, {0x89b1, 0x00f6}, {0x89b2, 0x008f}, 3936 + {0x89b3, 0x0080}, {0x89b4, 0x0005}, {0x89b5, 0x0005}, 3937 + {0x89b6, 0x00f7}, {0x89b7, 0x008f}, {0x89b8, 0x0080}, 3938 + {0x89b9, 0x00f6}, {0x89ba, 0x008f}, {0x89bb, 0x0080}, 3939 + {0x89bc, 0x0005}, {0x89bd, 0x0005}, {0x89be, 0x00f7}, 3940 + {0x89bf, 0x008f}, {0x89c0, 0x0080}, {0x89c1, 0x00f6}, 3941 + {0x89c2, 0x008f}, {0x89c3, 0x0080}, {0x89c4, 0x0005}, 3942 + {0x89c5, 0x0005}, {0x89c6, 0x00f7}, {0x89c7, 0x008f}, 3943 + {0x89c8, 0x0080}, {0x89c9, 0x00f6}, {0x89ca, 0x008f}, 3944 + {0x89cb, 0x0080}, {0x89cc, 0x0053}, {0x89cd, 0x00f4}, 3945 + {0x89ce, 0x0012}, {0x89cf, 0x0007}, {0x89d0, 0x001b}, 3946 + {0x89d1, 0x00b7}, {0x89d2, 0x0012}, {0x89d3, 0x0007}, 3947 + {0x89d4, 0x0039}, {0x89d5, 0x00ce}, {0x89d6, 0x008f}, 3948 + {0x89d7, 0x0070}, {0x89d8, 0x00a6}, {0x89d9, 0x0000}, 3949 + {0x89da, 0x0018}, {0x89db, 0x00e6}, {0x89dc, 0x0000}, 3950 + {0x89dd, 0x0018}, {0x89de, 0x00a7}, {0x89df, 0x0000}, 3951 + {0x89e0, 0x00e7}, {0x89e1, 0x0000}, {0x89e2, 0x00a6}, 3952 + {0x89e3, 0x0001}, {0x89e4, 0x0018}, {0x89e5, 0x00e6}, 3953 + {0x89e6, 0x0001}, {0x89e7, 0x0018}, {0x89e8, 0x00a7}, 3954 + {0x89e9, 0x0001}, {0x89ea, 0x00e7}, {0x89eb, 0x0001}, 3955 + {0x89ec, 0x00a6}, {0x89ed, 0x0002}, {0x89ee, 0x0018}, 3956 + {0x89ef, 0x00e6}, {0x89f0, 0x0002}, {0x89f1, 0x0018}, 3957 + {0x89f2, 0x00a7}, {0x89f3, 0x0002}, {0x89f4, 0x00e7}, 3958 + {0x89f5, 0x0002}, {0x89f6, 0x0039}, {0x89f7, 0x00a6}, 3959 + {0x89f8, 0x0000}, {0x89f9, 0x0084}, {0x89fa, 0x0007}, 3960 + {0x89fb, 0x00e6}, {0x89fc, 0x0000}, {0x89fd, 0x00c4}, 3961 + {0x89fe, 0x0038}, {0x89ff, 0x0054}, {0x8a00, 0x0054}, 3962 + {0x8a01, 0x0054}, {0x8a02, 0x001b}, {0x8a03, 0x00a7}, 3963 + {0x8a04, 0x0000}, {0x8a05, 0x0039}, {0x8a06, 0x004a}, 3964 + {0x8a07, 0x0026}, {0x8a08, 0x00fd}, {0x8a09, 0x0039}, 3965 + {0x8a0a, 0x0096}, {0x8a0b, 0x0022}, {0x8a0c, 0x0084}, 3966 + {0x8a0d, 0x000f}, {0x8a0e, 0x0097}, {0x8a0f, 0x0022}, 3967 + {0x8a10, 0x0086}, {0x8a11, 0x0001}, {0x8a12, 0x00b7}, 3968 + {0x8a13, 0x008f}, {0x8a14, 0x0070}, {0x8a15, 0x00b6}, 3969 + {0x8a16, 0x0012}, {0x8a17, 0x0007}, {0x8a18, 0x00b7}, 3970 + {0x8a19, 0x008f}, {0x8a1a, 0x0071}, {0x8a1b, 0x00f6}, 3971 + {0x8a1c, 0x0012}, {0x8a1d, 0x000c}, {0x8a1e, 0x00c4}, 3972 + {0x8a1f, 0x000f}, {0x8a20, 0x00c8}, {0x8a21, 0x000f}, 3973 + {0x8a22, 0x00f7}, {0x8a23, 0x008f}, {0x8a24, 0x0072}, 3974 + {0x8a25, 0x00f6}, {0x8a26, 0x008f}, {0x8a27, 0x0072}, 3975 + {0x8a28, 0x00b6}, {0x8a29, 0x008f}, {0x8a2a, 0x0071}, 3976 + {0x8a2b, 0x0084}, {0x8a2c, 0x0003}, {0x8a2d, 0x0027}, 3977 + {0x8a2e, 0x0014}, {0x8a2f, 0x0081}, {0x8a30, 0x0001}, 3978 + {0x8a31, 0x0027}, {0x8a32, 0x001c}, {0x8a33, 0x0081}, 3979 + {0x8a34, 0x0002}, {0x8a35, 0x0027}, {0x8a36, 0x0024}, 3980 + {0x8a37, 0x00f4}, {0x8a38, 0x008f}, {0x8a39, 0x0070}, 3981 + {0x8a3a, 0x0027}, {0x8a3b, 0x002a}, {0x8a3c, 0x0096}, 3982 + {0x8a3d, 0x0022}, {0x8a3e, 0x008a}, {0x8a3f, 0x0080}, 3983 + {0x8a40, 0x007e}, {0x8a41, 0x008a}, {0x8a42, 0x0064}, 3984 + {0x8a43, 0x00f4}, {0x8a44, 0x008f}, {0x8a45, 0x0070}, 3985 + {0x8a46, 0x0027}, {0x8a47, 0x001e}, {0x8a48, 0x0096}, 3986 + {0x8a49, 0x0022}, {0x8a4a, 0x008a}, {0x8a4b, 0x0010}, 3987 + {0x8a4c, 0x007e}, {0x8a4d, 0x008a}, {0x8a4e, 0x0064}, 3988 + {0x8a4f, 0x00f4}, {0x8a50, 0x008f}, {0x8a51, 0x0070}, 3989 + {0x8a52, 0x0027}, {0x8a53, 0x0012}, {0x8a54, 0x0096}, 3990 + {0x8a55, 0x0022}, {0x8a56, 0x008a}, {0x8a57, 0x0020}, 3991 + {0x8a58, 0x007e}, {0x8a59, 0x008a}, {0x8a5a, 0x0064}, 3992 + {0x8a5b, 0x00f4}, {0x8a5c, 0x008f}, {0x8a5d, 0x0070}, 3993 + {0x8a5e, 0x0027}, {0x8a5f, 0x0006}, {0x8a60, 0x0096}, 3994 + {0x8a61, 0x0022}, {0x8a62, 0x008a}, {0x8a63, 0x0040}, 3995 + {0x8a64, 0x0097}, {0x8a65, 0x0022}, {0x8a66, 0x0074}, 3996 + {0x8a67, 0x008f}, {0x8a68, 0x0071}, {0x8a69, 0x0074}, 3997 + {0x8a6a, 0x008f}, {0x8a6b, 0x0071}, {0x8a6c, 0x0078}, 3998 + {0x8a6d, 0x008f}, {0x8a6e, 0x0070}, {0x8a6f, 0x00b6}, 3999 + {0x8a70, 0x008f}, {0x8a71, 0x0070}, {0x8a72, 0x0085}, 4000 + {0x8a73, 0x0010}, {0x8a74, 0x0027}, {0x8a75, 0x00af}, 4001 + {0x8a76, 0x00d6}, {0x8a77, 0x0022}, {0x8a78, 0x00c4}, 4002 + {0x8a79, 0x0010}, {0x8a7a, 0x0058}, {0x8a7b, 0x00b6}, 4003 + {0x8a7c, 0x0012}, {0x8a7d, 0x0070}, {0x8a7e, 0x0081}, 4004 + {0x8a7f, 0x00e4}, {0x8a80, 0x0027}, {0x8a81, 0x0036}, 4005 + {0x8a82, 0x0081}, {0x8a83, 0x00e1}, {0x8a84, 0x0026}, 4006 + {0x8a85, 0x000c}, {0x8a86, 0x0096}, {0x8a87, 0x0022}, 4007 + {0x8a88, 0x0084}, {0x8a89, 0x0020}, {0x8a8a, 0x0044}, 4008 + {0x8a8b, 0x001b}, {0x8a8c, 0x00d6}, {0x8a8d, 0x0022}, 4009 + {0x8a8e, 0x00c4}, {0x8a8f, 0x00cf}, {0x8a90, 0x0020}, 4010 + {0x8a91, 0x0023}, {0x8a92, 0x0058}, {0x8a93, 0x0081}, 4011 + {0x8a94, 0x00c6}, {0x8a95, 0x0026}, {0x8a96, 0x000d}, 4012 + {0x8a97, 0x0096}, {0x8a98, 0x0022}, {0x8a99, 0x0084}, 4013 + {0x8a9a, 0x0040}, {0x8a9b, 0x0044}, {0x8a9c, 0x0044}, 4014 + {0x8a9d, 0x001b}, {0x8a9e, 0x00d6}, {0x8a9f, 0x0022}, 4015 + {0x8aa0, 0x00c4}, {0x8aa1, 0x00af}, {0x8aa2, 0x0020}, 4016 + {0x8aa3, 0x0011}, {0x8aa4, 0x0058}, {0x8aa5, 0x0081}, 4017 + {0x8aa6, 0x0027}, {0x8aa7, 0x0026}, {0x8aa8, 0x000f}, 4018 + {0x8aa9, 0x0096}, {0x8aaa, 0x0022}, {0x8aab, 0x0084}, 4019 + {0x8aac, 0x0080}, {0x8aad, 0x0044}, {0x8aae, 0x0044}, 4020 + {0x8aaf, 0x0044}, {0x8ab0, 0x001b}, {0x8ab1, 0x00d6}, 4021 + {0x8ab2, 0x0022}, {0x8ab3, 0x00c4}, {0x8ab4, 0x006f}, 4022 + {0x8ab5, 0x001b}, {0x8ab6, 0x0097}, {0x8ab7, 0x0022}, 4023 + {0x8ab8, 0x0039}, {0x8ab9, 0x0027}, {0x8aba, 0x000c}, 4024 + {0x8abb, 0x007c}, {0x8abc, 0x0082}, {0x8abd, 0x0006}, 4025 + {0x8abe, 0x00bd}, {0x8abf, 0x00d9}, {0x8ac0, 0x00ed}, 4026 + {0x8ac1, 0x00b6}, {0x8ac2, 0x0082}, {0x8ac3, 0x0007}, 4027 + {0x8ac4, 0x007e}, {0x8ac5, 0x008a}, {0x8ac6, 0x00b9}, 4028 + {0x8ac7, 0x007f}, {0x8ac8, 0x0082}, {0x8ac9, 0x0006}, 4029 + {0x8aca, 0x0039}, { 0x0, 0x0 } 4030 + }; 4031 + #endif 4032 + 4033 + 4034 + /* phy types */ 4035 + #define CAS_PHY_UNKNOWN 0x00 4036 + #define CAS_PHY_SERDES 0x01 4037 + #define CAS_PHY_MII_MDIO0 0x02 4038 + #define CAS_PHY_MII_MDIO1 0x04 4039 + #define CAS_PHY_MII(x) ((x) & (CAS_PHY_MII_MDIO0 | CAS_PHY_MII_MDIO1)) 4040 + 4041 + /* _RING_INDEX is the index for the ring sizes to be used. _RING_SIZE 4042 + * is the actual size. the default index for the various rings is 4043 + * 8. NOTE: there a bunch of alignment constraints for the rings. to 4044 + * deal with that, i just allocate rings to create the desired 4045 + * alignment. here are the constraints: 4046 + * RX DESC and COMP rings must be 8KB aligned 4047 + * TX DESC must be 2KB aligned. 4048 + * if you change the numbers, be cognizant of how the alignment will change 4049 + * in INIT_BLOCK as well. 4050 + */ 4051 + 4052 + #define DESC_RING_I_TO_S(x) (32*(1 << (x))) 4053 + #define COMP_RING_I_TO_S(x) (128*(1 << (x))) 4054 + #define TX_DESC_RING_INDEX 4 /* 512 = 8k */ 4055 + #define RX_DESC_RING_INDEX 4 /* 512 = 8k */ 4056 + #define RX_COMP_RING_INDEX 4 /* 2048 = 64k: should be 4x rx ring size */ 4057 + 4058 + #if (TX_DESC_RING_INDEX > 8) || (TX_DESC_RING_INDEX < 0) 4059 + #error TX_DESC_RING_INDEX must be between 0 and 8 4060 + #endif 4061 + 4062 + #if (RX_DESC_RING_INDEX > 8) || (RX_DESC_RING_INDEX < 0) 4063 + #error RX_DESC_RING_INDEX must be between 0 and 8 4064 + #endif 4065 + 4066 + #if (RX_COMP_RING_INDEX > 8) || (RX_COMP_RING_INDEX < 0) 4067 + #error RX_COMP_RING_INDEX must be between 0 and 8 4068 + #endif 4069 + 4070 + #define N_TX_RINGS MAX_TX_RINGS /* for QoS */ 4071 + #define N_TX_RINGS_MASK MAX_TX_RINGS_MASK 4072 + #define N_RX_DESC_RINGS MAX_RX_DESC_RINGS /* 1 for ipsec */ 4073 + #define N_RX_COMP_RINGS 0x1 /* for mult. PCI interrupts */ 4074 + 4075 + /* number of flows that can go through re-assembly */ 4076 + #define N_RX_FLOWS 64 4077 + 4078 + #define TX_DESC_RING_SIZE DESC_RING_I_TO_S(TX_DESC_RING_INDEX) 4079 + #define RX_DESC_RING_SIZE DESC_RING_I_TO_S(RX_DESC_RING_INDEX) 4080 + #define RX_COMP_RING_SIZE COMP_RING_I_TO_S(RX_COMP_RING_INDEX) 4081 + #define TX_DESC_RINGN_INDEX(x) TX_DESC_RING_INDEX 4082 + #define RX_DESC_RINGN_INDEX(x) RX_DESC_RING_INDEX 4083 + #define RX_COMP_RINGN_INDEX(x) RX_COMP_RING_INDEX 4084 + #define TX_DESC_RINGN_SIZE(x) TX_DESC_RING_SIZE 4085 + #define RX_DESC_RINGN_SIZE(x) RX_DESC_RING_SIZE 4086 + #define RX_COMP_RINGN_SIZE(x) RX_COMP_RING_SIZE 4087 + 4088 + /* convert values */ 4089 + #define CAS_BASE(x, y) (((y) << (x ## _SHIFT)) & (x ## _MASK)) 4090 + #define CAS_VAL(x, y) (((y) & (x ## _MASK)) >> (x ## _SHIFT)) 4091 + #define CAS_TX_RINGN_BASE(y) ((TX_DESC_RINGN_INDEX(y) << \ 4092 + TX_CFG_DESC_RINGN_SHIFT(y)) & \ 4093 + TX_CFG_DESC_RINGN_MASK(y)) 4094 + 4095 + /* min is 2k, but we can't do jumbo frames unless it's at least 8k */ 4096 + #define CAS_MIN_PAGE_SHIFT 11 /* 2048 */ 4097 + #define CAS_JUMBO_PAGE_SHIFT 13 /* 8192 */ 4098 + #define CAS_MAX_PAGE_SHIFT 14 /* 16384 */ 4099 + 4100 + #define TX_DESC_BUFLEN_MASK 0x0000000000003FFFULL /* buffer length in 4101 + bytes. 0 - 9256 */ 4102 + #define TX_DESC_BUFLEN_SHIFT 0 4103 + #define TX_DESC_CSUM_START_MASK 0x00000000001F8000ULL /* checksum start. # 4104 + of bytes to be 4105 + skipped before 4106 + csum calc begins. 4107 + value must be 4108 + even */ 4109 + #define TX_DESC_CSUM_START_SHIFT 15 4110 + #define TX_DESC_CSUM_STUFF_MASK 0x000000001FE00000ULL /* checksum stuff. 4111 + byte offset w/in 4112 + the pkt for the 4113 + 1st csum byte. 4114 + must be > 8 */ 4115 + #define TX_DESC_CSUM_STUFF_SHIFT 21 4116 + #define TX_DESC_CSUM_EN 0x0000000020000000ULL /* enable checksum */ 4117 + #define TX_DESC_EOF 0x0000000040000000ULL /* end of frame */ 4118 + #define TX_DESC_SOF 0x0000000080000000ULL /* start of frame */ 4119 + #define TX_DESC_INTME 0x0000000100000000ULL /* interrupt me */ 4120 + #define TX_DESC_NO_CRC 0x0000000200000000ULL /* debugging only. 4121 + CRC will not be 4122 + inserted into 4123 + outgoing frame. */ 4124 + struct cas_tx_desc { 4125 + u64 control; 4126 + u64 buffer; 4127 + }; 4128 + 4129 + /* descriptor ring for free buffers contains page-sized buffers. the index 4130 + * value is not used by the hw in any way. it's just stored and returned in 4131 + * the completion ring. 4132 + */ 4133 + struct cas_rx_desc { 4134 + u64 index; 4135 + u64 buffer; 4136 + }; 4137 + 4138 + /* received packets are put on the completion ring. */ 4139 + /* word 1 */ 4140 + #define RX_COMP1_DATA_SIZE_MASK 0x0000000007FFE000ULL 4141 + #define RX_COMP1_DATA_SIZE_SHIFT 13 4142 + #define RX_COMP1_DATA_OFF_MASK 0x000001FFF8000000ULL 4143 + #define RX_COMP1_DATA_OFF_SHIFT 27 4144 + #define RX_COMP1_DATA_INDEX_MASK 0x007FFE0000000000ULL 4145 + #define RX_COMP1_DATA_INDEX_SHIFT 41 4146 + #define RX_COMP1_SKIP_MASK 0x0180000000000000ULL 4147 + #define RX_COMP1_SKIP_SHIFT 55 4148 + #define RX_COMP1_RELEASE_NEXT 0x0200000000000000ULL 4149 + #define RX_COMP1_SPLIT_PKT 0x0400000000000000ULL 4150 + #define RX_COMP1_RELEASE_FLOW 0x0800000000000000ULL 4151 + #define RX_COMP1_RELEASE_DATA 0x1000000000000000ULL 4152 + #define RX_COMP1_RELEASE_HDR 0x2000000000000000ULL 4153 + #define RX_COMP1_TYPE_MASK 0xC000000000000000ULL 4154 + #define RX_COMP1_TYPE_SHIFT 62 4155 + 4156 + /* word 2 */ 4157 + #define RX_COMP2_NEXT_INDEX_MASK 0x00000007FFE00000ULL 4158 + #define RX_COMP2_NEXT_INDEX_SHIFT 21 4159 + #define RX_COMP2_HDR_SIZE_MASK 0x00000FF800000000ULL 4160 + #define RX_COMP2_HDR_SIZE_SHIFT 35 4161 + #define RX_COMP2_HDR_OFF_MASK 0x0003F00000000000ULL 4162 + #define RX_COMP2_HDR_OFF_SHIFT 44 4163 + #define RX_COMP2_HDR_INDEX_MASK 0xFFFC000000000000ULL 4164 + #define RX_COMP2_HDR_INDEX_SHIFT 50 4165 + 4166 + /* word 3 */ 4167 + #define RX_COMP3_SMALL_PKT 0x0000000000000001ULL 4168 + #define RX_COMP3_JUMBO_PKT 0x0000000000000002ULL 4169 + #define RX_COMP3_JUMBO_HDR_SPLIT_EN 0x0000000000000004ULL 4170 + #define RX_COMP3_CSUM_START_MASK 0x000000000007F000ULL 4171 + #define RX_COMP3_CSUM_START_SHIFT 12 4172 + #define RX_COMP3_FLOWID_MASK 0x0000000001F80000ULL 4173 + #define RX_COMP3_FLOWID_SHIFT 19 4174 + #define RX_COMP3_OPCODE_MASK 0x000000000E000000ULL 4175 + #define RX_COMP3_OPCODE_SHIFT 25 4176 + #define RX_COMP3_FORCE_FLAG 0x0000000010000000ULL 4177 + #define RX_COMP3_NO_ASSIST 0x0000000020000000ULL 4178 + #define RX_COMP3_LOAD_BAL_MASK 0x000001F800000000ULL 4179 + #define RX_COMP3_LOAD_BAL_SHIFT 35 4180 + #define RX_PLUS_COMP3_ENC_PKT 0x0000020000000000ULL /* cas+ */ 4181 + #define RX_COMP3_L3_HEAD_OFF_MASK 0x0000FE0000000000ULL /* cas */ 4182 + #define RX_COMP3_L3_HEAD_OFF_SHIFT 41 4183 + #define RX_PLUS_COMP_L3_HEAD_OFF_MASK 0x0000FC0000000000ULL /* cas+ */ 4184 + #define RX_PLUS_COMP_L3_HEAD_OFF_SHIFT 42 4185 + #define RX_COMP3_SAP_MASK 0xFFFF000000000000ULL 4186 + #define RX_COMP3_SAP_SHIFT 48 4187 + 4188 + /* word 4 */ 4189 + #define RX_COMP4_TCP_CSUM_MASK 0x000000000000FFFFULL 4190 + #define RX_COMP4_TCP_CSUM_SHIFT 0 4191 + #define RX_COMP4_PKT_LEN_MASK 0x000000003FFF0000ULL 4192 + #define RX_COMP4_PKT_LEN_SHIFT 16 4193 + #define RX_COMP4_PERFECT_MATCH_MASK 0x00000003C0000000ULL 4194 + #define RX_COMP4_PERFECT_MATCH_SHIFT 30 4195 + #define RX_COMP4_ZERO 0x0000080000000000ULL 4196 + #define RX_COMP4_HASH_VAL_MASK 0x0FFFF00000000000ULL 4197 + #define RX_COMP4_HASH_VAL_SHIFT 44 4198 + #define RX_COMP4_HASH_PASS 0x1000000000000000ULL 4199 + #define RX_COMP4_BAD 0x4000000000000000ULL 4200 + #define RX_COMP4_LEN_MISMATCH 0x8000000000000000ULL 4201 + 4202 + /* we encode the following: ring/index/release. only 14 bits 4203 + * are usable. 4204 + * NOTE: the encoding is dependent upon RX_DESC_RING_SIZE and 4205 + * MAX_RX_DESC_RINGS. */ 4206 + #define RX_INDEX_NUM_MASK 0x0000000000000FFFULL 4207 + #define RX_INDEX_NUM_SHIFT 0 4208 + #define RX_INDEX_RING_MASK 0x0000000000001000ULL 4209 + #define RX_INDEX_RING_SHIFT 12 4210 + #define RX_INDEX_RELEASE 0x0000000000002000ULL 4211 + 4212 + struct cas_rx_comp { 4213 + u64 word1; 4214 + u64 word2; 4215 + u64 word3; 4216 + u64 word4; 4217 + }; 4218 + 4219 + enum link_state { 4220 + link_down = 0, /* No link, will retry */ 4221 + link_aneg, /* Autoneg in progress */ 4222 + link_force_try, /* Try Forced link speed */ 4223 + link_force_ret, /* Forced mode worked, retrying autoneg */ 4224 + link_force_ok, /* Stay in forced mode */ 4225 + link_up /* Link is up */ 4226 + }; 4227 + 4228 + typedef struct cas_page { 4229 + struct list_head list; 4230 + struct page *buffer; 4231 + dma_addr_t dma_addr; 4232 + int used; 4233 + } cas_page_t; 4234 + 4235 + 4236 + /* some alignment constraints: 4237 + * TX DESC, RX DESC, and RX COMP must each be 8K aligned. 4238 + * TX COMPWB must be 8-byte aligned. 4239 + * to accomplish this, here's what we do: 4240 + * 4241 + * INIT_BLOCK_RX_COMP = 64k (already aligned) 4242 + * INIT_BLOCK_RX_DESC = 8k 4243 + * INIT_BLOCK_TX = 8k 4244 + * INIT_BLOCK_RX1_DESC = 8k 4245 + * TX COMPWB 4246 + */ 4247 + #define INIT_BLOCK_TX (TX_DESC_RING_SIZE) 4248 + #define INIT_BLOCK_RX_DESC (RX_DESC_RING_SIZE) 4249 + #define INIT_BLOCK_RX_COMP (RX_COMP_RING_SIZE) 4250 + 4251 + struct cas_init_block { 4252 + struct cas_rx_comp rxcs[N_RX_COMP_RINGS][INIT_BLOCK_RX_COMP]; 4253 + struct cas_rx_desc rxds[N_RX_DESC_RINGS][INIT_BLOCK_RX_DESC]; 4254 + struct cas_tx_desc txds[N_TX_RINGS][INIT_BLOCK_TX]; 4255 + u64 tx_compwb; 4256 + }; 4257 + 4258 + /* tiny buffers to deal with target abort issue. we allocate a bit 4259 + * over so that we don't have target abort issues with these buffers 4260 + * as well. 4261 + */ 4262 + #define TX_TINY_BUF_LEN 0x100 4263 + #define TX_TINY_BUF_BLOCK ((INIT_BLOCK_TX + 1)*TX_TINY_BUF_LEN) 4264 + 4265 + struct cas_tiny_count { 4266 + int nbufs; 4267 + int used; 4268 + }; 4269 + 4270 + struct cas { 4271 + spinlock_t lock; /* for most bits */ 4272 + spinlock_t tx_lock[N_TX_RINGS]; /* tx bits */ 4273 + spinlock_t stat_lock[N_TX_RINGS + 1]; /* for stat gathering */ 4274 + spinlock_t rx_inuse_lock; /* rx inuse list */ 4275 + spinlock_t rx_spare_lock; /* rx spare list */ 4276 + 4277 + void __iomem *regs; 4278 + int tx_new[N_TX_RINGS], tx_old[N_TX_RINGS]; 4279 + int rx_old[N_RX_DESC_RINGS]; 4280 + int rx_cur[N_RX_COMP_RINGS], rx_new[N_RX_COMP_RINGS]; 4281 + int rx_last[N_RX_DESC_RINGS]; 4282 + 4283 + /* Set when chip is actually in operational state 4284 + * (ie. not power managed) */ 4285 + int hw_running; 4286 + int opened; 4287 + struct semaphore pm_sem; /* open/close/suspend/resume */ 4288 + 4289 + struct cas_init_block *init_block; 4290 + struct cas_tx_desc *init_txds[MAX_TX_RINGS]; 4291 + struct cas_rx_desc *init_rxds[MAX_RX_DESC_RINGS]; 4292 + struct cas_rx_comp *init_rxcs[MAX_RX_COMP_RINGS]; 4293 + 4294 + /* we use sk_buffs for tx and pages for rx. the rx skbuffs 4295 + * are there for flow re-assembly. */ 4296 + struct sk_buff *tx_skbs[N_TX_RINGS][TX_DESC_RING_SIZE]; 4297 + struct sk_buff_head rx_flows[N_RX_FLOWS]; 4298 + cas_page_t *rx_pages[N_RX_DESC_RINGS][RX_DESC_RING_SIZE]; 4299 + struct list_head rx_spare_list, rx_inuse_list; 4300 + int rx_spares_needed; 4301 + 4302 + /* for small packets when copying would be quicker than 4303 + mapping */ 4304 + struct cas_tiny_count tx_tiny_use[N_TX_RINGS][TX_DESC_RING_SIZE]; 4305 + u8 *tx_tiny_bufs[N_TX_RINGS]; 4306 + 4307 + u32 msg_enable; 4308 + 4309 + /* N_TX_RINGS must be >= N_RX_DESC_RINGS */ 4310 + struct net_device_stats net_stats[N_TX_RINGS + 1]; 4311 + 4312 + u32 pci_cfg[64 >> 2]; 4313 + u8 pci_revision; 4314 + 4315 + int phy_type; 4316 + int phy_addr; 4317 + u32 phy_id; 4318 + #define CAS_FLAG_1000MB_CAP 0x00000001 4319 + #define CAS_FLAG_REG_PLUS 0x00000002 4320 + #define CAS_FLAG_TARGET_ABORT 0x00000004 4321 + #define CAS_FLAG_SATURN 0x00000008 4322 + #define CAS_FLAG_RXD_POST_MASK 0x000000F0 4323 + #define CAS_FLAG_RXD_POST_SHIFT 4 4324 + #define CAS_FLAG_RXD_POST(x) ((1 << (CAS_FLAG_RXD_POST_SHIFT + (x))) & \ 4325 + CAS_FLAG_RXD_POST_MASK) 4326 + #define CAS_FLAG_ENTROPY_DEV 0x00000100 4327 + #define CAS_FLAG_NO_HW_CSUM 0x00000200 4328 + u32 cas_flags; 4329 + int packet_min; /* minimum packet size */ 4330 + int tx_fifo_size; 4331 + int rx_fifo_size; 4332 + int rx_pause_off; 4333 + int rx_pause_on; 4334 + int crc_size; /* 4 if half-duplex */ 4335 + 4336 + int pci_irq_INTC; 4337 + int min_frame_size; /* for tx fifo workaround */ 4338 + 4339 + /* page size allocation */ 4340 + int page_size; 4341 + int page_order; 4342 + int mtu_stride; 4343 + 4344 + u32 mac_rx_cfg; 4345 + 4346 + /* Autoneg & PHY control */ 4347 + int link_cntl; 4348 + int link_fcntl; 4349 + enum link_state lstate; 4350 + struct timer_list link_timer; 4351 + int timer_ticks; 4352 + struct work_struct reset_task; 4353 + #if 0 4354 + atomic_t reset_task_pending; 4355 + #else 4356 + atomic_t reset_task_pending; 4357 + atomic_t reset_task_pending_mtu; 4358 + atomic_t reset_task_pending_spare; 4359 + atomic_t reset_task_pending_all; 4360 + #endif 4361 + 4362 + #ifdef CONFIG_CASSINI_QGE_DEBUG 4363 + atomic_t interrupt_seen; /* 1 if any interrupts are getting through */ 4364 + #endif 4365 + 4366 + /* Link-down problem workaround */ 4367 + #define LINK_TRANSITION_UNKNOWN 0 4368 + #define LINK_TRANSITION_ON_FAILURE 1 4369 + #define LINK_TRANSITION_STILL_FAILED 2 4370 + #define LINK_TRANSITION_LINK_UP 3 4371 + #define LINK_TRANSITION_LINK_CONFIG 4 4372 + #define LINK_TRANSITION_LINK_DOWN 5 4373 + #define LINK_TRANSITION_REQUESTED_RESET 6 4374 + int link_transition; 4375 + int link_transition_jiffies_valid; 4376 + unsigned long link_transition_jiffies; 4377 + 4378 + /* Tuning */ 4379 + u8 orig_cacheline_size; /* value when loaded */ 4380 + #define CAS_PREF_CACHELINE_SIZE 0x20 /* Minimum desired */ 4381 + 4382 + /* Diagnostic counters and state. */ 4383 + int casreg_len; /* reg-space size for dumping */ 4384 + u64 pause_entered; 4385 + u16 pause_last_time_recvd; 4386 + 4387 + dma_addr_t block_dvma, tx_tiny_dvma[N_TX_RINGS]; 4388 + struct pci_dev *pdev; 4389 + struct net_device *dev; 4390 + }; 4391 + 4392 + #define TX_DESC_NEXT(r, x) (((x) + 1) & (TX_DESC_RINGN_SIZE(r) - 1)) 4393 + #define RX_DESC_ENTRY(r, x) ((x) & (RX_DESC_RINGN_SIZE(r) - 1)) 4394 + #define RX_COMP_ENTRY(r, x) ((x) & (RX_COMP_RINGN_SIZE(r) - 1)) 4395 + 4396 + #define TX_BUFF_COUNT(r, x, y) ((x) <= (y) ? ((y) - (x)) : \ 4397 + (TX_DESC_RINGN_SIZE(r) - (x) + (y))) 4398 + 4399 + #define TX_BUFFS_AVAIL(cp, i) ((cp)->tx_old[(i)] <= (cp)->tx_new[(i)] ? \ 4400 + (cp)->tx_old[(i)] + (TX_DESC_RINGN_SIZE(i) - 1) - (cp)->tx_new[(i)] : \ 4401 + (cp)->tx_old[(i)] - (cp)->tx_new[(i)] - 1) 4402 + 4403 + #define CAS_ALIGN(addr, align) \ 4404 + (((unsigned long) (addr) + ((align) - 1UL)) & ~((align) - 1)) 4405 + 4406 + #define RX_FIFO_SIZE 16384 4407 + #define EXPANSION_ROM_SIZE 65536 4408 + 4409 + #define CAS_MC_EXACT_MATCH_SIZE 15 4410 + #define CAS_MC_HASH_SIZE 256 4411 + #define CAS_MC_HASH_MAX (CAS_MC_EXACT_MATCH_SIZE + \ 4412 + CAS_MC_HASH_SIZE) 4413 + 4414 + #define TX_TARGET_ABORT_LEN 0x20 4415 + #define RX_SWIVEL_OFF_VAL 0x2 4416 + #define RX_AE_FREEN_VAL(x) (RX_DESC_RINGN_SIZE(x) >> 1) 4417 + #define RX_AE_COMP_VAL (RX_COMP_RING_SIZE >> 1) 4418 + #define RX_BLANK_INTR_PKT_VAL 0x05 4419 + #define RX_BLANK_INTR_TIME_VAL 0x0F 4420 + #define HP_TCP_THRESH_VAL 1530 /* reduce to enable reassembly */ 4421 + 4422 + #define RX_SPARE_COUNT (RX_DESC_RING_SIZE >> 1) 4423 + #define RX_SPARE_RECOVER_VAL (RX_SPARE_COUNT >> 2) 4424 + 4425 + #endif /* _CASSINI_H */
+2
include/linux/if_ether.h
··· 111 111 return (struct ethhdr *)skb->mac.raw; 112 112 } 113 113 114 + #ifdef CONFIG_SYSCTL 114 115 extern struct ctl_table ether_table[]; 116 + #endif 115 117 #endif 116 118 117 119 #endif /* _LINUX_IF_ETHER_H */
+55 -34
include/linux/netdevice.h
··· 265 265 * the interface. 266 266 */ 267 267 char name[IFNAMSIZ]; 268 + /* device name hash chain */ 269 + struct hlist_node name_hlist; 268 270 269 271 /* 270 272 * I/O specific fields ··· 294 292 295 293 /* ------- Fields preinitialized in Space.c finish here ------- */ 296 294 295 + /* Net device features */ 296 + unsigned long features; 297 + #define NETIF_F_SG 1 /* Scatter/gather IO. */ 298 + #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ 299 + #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ 300 + #define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */ 301 + #define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */ 302 + #define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */ 303 + #define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */ 304 + #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ 305 + #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ 306 + #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ 307 + #define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */ 308 + #define NETIF_F_LLTX 4096 /* LockLess TX */ 309 + 297 310 struct net_device *next_sched; 298 311 299 312 /* Interface index. Unique device identifier */ ··· 333 316 * will (read: may be cleaned up at will). 334 317 */ 335 318 336 - /* These may be needed for future network-power-down code. */ 337 - unsigned long trans_start; /* Time (in jiffies) of last Tx */ 338 - unsigned long last_rx; /* Time of last Rx */ 339 319 340 320 unsigned short flags; /* interface flags (a la BSD) */ 341 321 unsigned short gflags; ··· 342 328 unsigned mtu; /* interface MTU value */ 343 329 unsigned short type; /* interface hardware type */ 344 330 unsigned short hard_header_len; /* hardware hdr length */ 345 - void *priv; /* pointer to private data */ 346 331 347 332 struct net_device *master; /* Pointer to master device of a group, 348 333 * which this device is member of. 349 334 */ 350 335 351 336 /* Interface address info. */ 352 - unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ 353 - unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */ 354 337 unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ 355 338 unsigned char addr_len; /* hardware address length */ 356 339 unsigned short dev_id; /* for shared network cards */ ··· 357 346 int promiscuity; 358 347 int allmulti; 359 348 360 - int watchdog_timeo; 361 - struct timer_list watchdog_timer; 362 349 363 350 /* Protocol specific pointers */ 364 351 ··· 367 358 void *ec_ptr; /* Econet specific data */ 368 359 void *ax25_ptr; /* AX.25 specific data */ 369 360 370 - struct list_head poll_list; /* Link to poll list */ 361 + /* 362 + * Cache line mostly used on receive path (including eth_type_trans()) 363 + */ 364 + struct list_head poll_list ____cacheline_aligned_in_smp; 365 + /* Link to poll list */ 366 + 367 + int (*poll) (struct net_device *dev, int *quota); 371 368 int quota; 372 369 int weight; 370 + unsigned long last_rx; /* Time of last Rx */ 371 + /* Interface address info used in eth_type_trans() */ 372 + unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast 373 + because most packets are unicast) */ 373 374 375 + unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ 376 + 377 + /* 378 + * Cache line mostly used on queue transmit path (qdisc) 379 + */ 380 + /* device queue lock */ 381 + spinlock_t queue_lock ____cacheline_aligned_in_smp; 374 382 struct Qdisc *qdisc; 375 383 struct Qdisc *qdisc_sleeping; 376 - struct Qdisc *qdisc_ingress; 377 384 struct list_head qdisc_list; 378 385 unsigned long tx_queue_len; /* Max frames per queue allowed */ 379 386 380 387 /* ingress path synchronizer */ 381 388 spinlock_t ingress_lock; 389 + struct Qdisc *qdisc_ingress; 390 + 391 + /* 392 + * One part is mostly used on xmit path (device) 393 + */ 382 394 /* hard_start_xmit synchronizer */ 383 - spinlock_t xmit_lock; 395 + spinlock_t xmit_lock ____cacheline_aligned_in_smp; 384 396 /* cpu id of processor entered to hard_start_xmit or -1, 385 397 if nobody entered there. 386 398 */ 387 399 int xmit_lock_owner; 388 - /* device queue lock */ 389 - spinlock_t queue_lock; 400 + void *priv; /* pointer to private data */ 401 + int (*hard_start_xmit) (struct sk_buff *skb, 402 + struct net_device *dev); 403 + /* These may be needed for future network-power-down code. */ 404 + unsigned long trans_start; /* Time (in jiffies) of last Tx */ 405 + 406 + int watchdog_timeo; /* used by dev_watchdog() */ 407 + struct timer_list watchdog_timer; 408 + 409 + /* 410 + * refcnt is a very hot point, so align it on SMP 411 + */ 390 412 /* Number of references to this device */ 391 - atomic_t refcnt; 413 + atomic_t refcnt ____cacheline_aligned_in_smp; 414 + 392 415 /* delayed register/unregister */ 393 416 struct list_head todo_list; 394 - /* device name hash chain */ 395 - struct hlist_node name_hlist; 396 417 /* device index hash chain */ 397 418 struct hlist_node index_hlist; 398 419 ··· 435 396 NETREG_RELEASED, /* called free_netdev */ 436 397 } reg_state; 437 398 438 - /* Net device features */ 439 - unsigned long features; 440 - #define NETIF_F_SG 1 /* Scatter/gather IO. */ 441 - #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ 442 - #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ 443 - #define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */ 444 - #define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */ 445 - #define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */ 446 - #define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */ 447 - #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ 448 - #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ 449 - #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ 450 - #define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */ 451 - #define NETIF_F_LLTX 4096 /* LockLess TX */ 452 - 453 399 /* Called after device is detached from network. */ 454 400 void (*uninit)(struct net_device *dev); 455 401 /* Called after last user reference disappears. */ ··· 443 419 /* Pointers to interface service routines. */ 444 420 int (*open)(struct net_device *dev); 445 421 int (*stop)(struct net_device *dev); 446 - int (*hard_start_xmit) (struct sk_buff *skb, 447 - struct net_device *dev); 448 422 #define HAVE_NETDEV_POLL 449 - int (*poll) (struct net_device *dev, int *quota); 450 423 int (*hard_header) (struct sk_buff *skb, 451 424 struct net_device *dev, 452 425 unsigned short type,
+2
include/linux/pci_ids.h
··· 392 392 #define PCI_DEVICE_ID_NS_87560_USB 0x0012 393 393 #define PCI_DEVICE_ID_NS_83815 0x0020 394 394 #define PCI_DEVICE_ID_NS_83820 0x0022 395 + #define PCI_DEVICE_ID_NS_SATURN 0x0035 395 396 #define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500 396 397 #define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501 397 398 #define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502 ··· 984 983 #define PCI_DEVICE_ID_SUN_SABRE 0xa000 985 984 #define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001 986 985 #define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801 986 + #define PCI_DEVICE_ID_SUN_CASSINI 0xabba 987 987 988 988 #define PCI_VENDOR_ID_CMD 0x1095 989 989 #define PCI_DEVICE_ID_CMD_640 0x0640
+22 -9
net/appletalk/ddp.c
··· 100 100 continue; 101 101 102 102 if (to->sat_addr.s_net == ATADDR_ANYNET && 103 - to->sat_addr.s_node == ATADDR_BCAST && 104 - at->src_net == atif->address.s_net) 103 + to->sat_addr.s_node == ATADDR_BCAST) 105 104 goto found; 106 105 107 106 if (to->sat_addr.s_net == at->src_net && ··· 1442 1443 else 1443 1444 atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); 1444 1445 1445 - /* Not ours, so we route the packet via the correct AppleTalk iface */ 1446 1446 if (!atif) { 1447 + /* Not ours, so we route the packet via the correct 1448 + * AppleTalk iface 1449 + */ 1447 1450 atalk_route_packet(skb, dev, ddp, &ddphv, origlen); 1448 1451 goto out; 1449 1452 } ··· 1593 1592 1594 1593 if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { 1595 1594 rt = atrtr_find(&usat->sat_addr); 1596 - if (!rt) 1597 - return -ENETUNREACH; 1598 - 1599 1595 dev = rt->dev; 1600 1596 } else { 1601 1597 struct atalk_addr at_hint; ··· 1601 1603 at_hint.s_net = at->src_net; 1602 1604 1603 1605 rt = atrtr_find(&at_hint); 1604 - if (!rt) 1605 - return -ENETUNREACH; 1606 - 1607 1606 dev = rt->dev; 1608 1607 } 1608 + if (!rt) 1609 + return -ENETUNREACH; 1610 + 1611 + dev = rt->dev; 1609 1612 1610 1613 SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", 1611 1614 sk, size, dev->name); ··· 1676 1677 SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); 1677 1678 /* loop back */ 1678 1679 skb_orphan(skb); 1680 + if (ddp->deh_dnode == ATADDR_BCAST) { 1681 + struct atalk_addr at_lo; 1682 + 1683 + at_lo.s_node = 0; 1684 + at_lo.s_net = 0; 1685 + 1686 + rt = atrtr_find(&at_lo); 1687 + if (!rt) { 1688 + kfree_skb(skb); 1689 + return -ENETUNREACH; 1690 + } 1691 + dev = rt->dev; 1692 + skb->dev = dev; 1693 + } 1679 1694 ddp_dl->request(ddp_dl, skb, dev->dev_addr); 1680 1695 } else { 1681 1696 SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
+4 -2
net/atm/addr.c
··· 50 50 struct atm_dev_addr *this, *p; 51 51 52 52 spin_lock_irqsave(&dev->lock, flags); 53 - list_for_each_entry_safe(this, p, &dev->local, entry) 54 - kfree(this); 53 + list_for_each_entry_safe(this, p, &dev->local, entry) { 54 + list_del(&this->entry); 55 + kfree(this); 56 + } 55 57 spin_unlock_irqrestore(&dev->lock, flags); 56 58 notify_sigd(dev); 57 59 }
+2 -2
net/atm/common.c
··· 178 178 if (vcc->push) 179 179 vcc->push(vcc, NULL); /* atmarpd has no push */ 180 180 181 - vcc_remove_socket(sk); /* no more receive */ 182 - 183 181 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 184 182 atm_return(vcc,skb->truesize); 185 183 kfree_skb(skb); ··· 186 188 module_put(vcc->dev->ops->owner); 187 189 atm_dev_put(vcc->dev); 188 190 } 191 + 192 + vcc_remove_socket(sk); 189 193 } 190 194 191 195
+26 -8
net/atm/ioctl.c
··· 105 105 if (!error) 106 106 sock->state = SS_CONNECTED; 107 107 goto done; 108 - default: 108 + case ATM_SETBACKEND: 109 + case ATM_NEWBACKENDIF: 110 + { 111 + atm_backend_t backend; 112 + error = get_user(backend, (atm_backend_t __user *) argp); 113 + if (error) 114 + goto done; 115 + switch (backend) { 116 + case ATM_BACKEND_PPP: 117 + request_module("pppoatm"); 118 + break; 119 + case ATM_BACKEND_BR2684: 120 + request_module("br2684"); 121 + break; 122 + } 123 + } 124 + break; 125 + case ATMMPC_CTRL: 126 + case ATMMPC_DATA: 127 + request_module("mpoa"); 128 + break; 129 + case ATMARPD_CTRL: 130 + request_module("clip"); 131 + break; 132 + case ATMLEC_CTRL: 133 + request_module("lec"); 109 134 break; 110 135 } 111 - 112 - if (cmd == ATMMPC_CTRL || cmd == ATMMPC_DATA) 113 - request_module("mpoa"); 114 - if (cmd == ATMARPD_CTRL) 115 - request_module("clip"); 116 - if (cmd == ATMLEC_CTRL) 117 - request_module("lec"); 118 136 119 137 error = -ENOIOCTLCMD; 120 138
+4 -4
net/atm/signaling.c
··· 217 217 static void purge_vcc(struct atm_vcc *vcc) 218 218 { 219 219 if (sk_atm(vcc)->sk_family == PF_ATMSVC && 220 - !test_bit(ATM_VF_META,&vcc->flags)) { 221 - set_bit(ATM_VF_RELEASED,&vcc->flags); 220 + !test_bit(ATM_VF_META, &vcc->flags)) { 221 + set_bit(ATM_VF_RELEASED, &vcc->flags); 222 + clear_bit(ATM_VF_REGIS, &vcc->flags); 222 223 vcc_release_async(vcc, -EUNATCH); 223 224 } 224 225 } ··· 244 243 sk_for_each(s, node, head) { 245 244 struct atm_vcc *vcc = atm_sk(s); 246 245 247 - if (vcc->dev) 248 - purge_vcc(vcc); 246 + purge_vcc(vcc); 249 247 } 250 248 } 251 249 read_unlock(&vcc_sklist_lock);
+1
net/atm/svc.c
··· 302 302 error = -EINVAL; 303 303 goto out; 304 304 } 305 + vcc_insert_socket(sk); 305 306 set_bit(ATM_VF_WAITING, &vcc->flags); 306 307 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 307 308 sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
+26 -55
net/core/datagram.c
··· 211 211 int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, 212 212 struct iovec *to, int len) 213 213 { 214 - int start = skb_headlen(skb); 215 - int i, copy = start - offset; 214 + int i, err, fraglen, end = 0; 215 + struct sk_buff *next = skb_shinfo(skb)->frag_list; 216 + next_skb: 217 + fraglen = skb_headlen(skb); 218 + i = -1; 216 219 217 - /* Copy header. */ 218 - if (copy > 0) { 219 - if (copy > len) 220 - copy = len; 221 - if (memcpy_toiovec(to, skb->data + offset, copy)) 222 - goto fault; 223 - if ((len -= copy) == 0) 224 - return 0; 225 - offset += copy; 226 - } 220 + while (1) { 221 + int start = end; 227 222 228 - /* Copy paged appendix. Hmm... why does this look so complicated? */ 229 - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 230 - int end; 231 - 232 - BUG_TRAP(start <= offset + len); 233 - 234 - end = start + skb_shinfo(skb)->frags[i].size; 235 - if ((copy = end - offset) > 0) { 236 - int err; 237 - u8 *vaddr; 238 - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 239 - struct page *page = frag->page; 223 + if ((end += fraglen) > offset) { 224 + int copy = end - offset, o = offset - start; 240 225 241 226 if (copy > len) 242 227 copy = len; 243 - vaddr = kmap(page); 244 - err = memcpy_toiovec(to, vaddr + frag->page_offset + 245 - offset - start, copy); 246 - kunmap(page); 228 + if (i == -1) 229 + err = memcpy_toiovec(to, skb->data + o, copy); 230 + else { 231 + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 232 + struct page *page = frag->page; 233 + void *p = kmap(page) + frag->page_offset + o; 234 + err = memcpy_toiovec(to, p, copy); 235 + kunmap(page); 236 + } 247 237 if (err) 248 238 goto fault; 249 239 if (!(len -= copy)) 250 240 return 0; 251 241 offset += copy; 252 242 } 253 - start = end; 243 + if (++i >= skb_shinfo(skb)->nr_frags) 244 + break; 245 + fraglen = skb_shinfo(skb)->frags[i].size; 254 246 } 255 - 256 - if (skb_shinfo(skb)->frag_list) { 257 - struct sk_buff *list = skb_shinfo(skb)->frag_list; 258 - 259 - for (; list; list = list->next) { 260 - int end; 261 - 262 - BUG_TRAP(start <= offset + len); 263 - 264 - end = start + list->len; 265 - if ((copy = end - offset) > 0) { 266 - if (copy > len) 267 - copy = len; 268 - if (skb_copy_datagram_iovec(list, 269 - offset - start, 270 - to, copy)) 271 - goto fault; 272 - if ((len -= copy) == 0) 273 - return 0; 274 - offset += copy; 275 - } 276 - start = end; 277 - } 247 + if (next) { 248 + skb = next; 249 + BUG_ON(skb_shinfo(skb)->frag_list); 250 + next = skb->next; 251 + goto next_skb; 278 252 } 279 - if (!len) 280 - return 0; 281 - 282 253 fault: 283 254 return -EFAULT; 284 255 }
+2
net/core/dev.c
··· 1259 1259 if (skb_checksum_help(skb, 0)) 1260 1260 goto out_kfree_skb; 1261 1261 1262 + spin_lock_prefetch(&dev->queue_lock); 1263 + 1262 1264 /* Disable soft irqs for various locks below. Also 1263 1265 * stops preemption for RCU. 1264 1266 */
+12 -8
net/core/sock.c
··· 660 660 sock_lock_init(sk); 661 661 } 662 662 663 - if (security_sk_alloc(sk, family, priority)) { 664 - if (slab != NULL) 665 - kmem_cache_free(slab, sk); 666 - else 667 - kfree(sk); 668 - sk = NULL; 669 - } else 670 - __module_get(prot->owner); 663 + if (security_sk_alloc(sk, family, priority)) 664 + goto out_free; 665 + 666 + if (!try_module_get(prot->owner)) 667 + goto out_free; 671 668 } 672 669 return sk; 670 + 671 + out_free: 672 + if (slab != NULL) 673 + kmem_cache_free(slab, sk); 674 + else 675 + kfree(sk); 676 + return NULL; 673 677 } 674 678 675 679 void sk_free(struct sock *sk)
+21 -10
net/ethernet/eth.c
··· 146 146 return 0; 147 147 } 148 148 149 + static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b) 150 + { 151 + const unsigned short *dest = (unsigned short *) __a; 152 + const unsigned short *devaddr = (unsigned short *) __b; 153 + unsigned int res; 154 + 155 + BUILD_BUG_ON(ETH_ALEN != 6); 156 + res = ((dest[0] ^ devaddr[0]) | 157 + (dest[1] ^ devaddr[1]) | 158 + (dest[2] ^ devaddr[2])) != 0; 159 + 160 + return res; 161 + } 149 162 150 163 /* 151 164 * Determine the packet's protocol ID. The rule here is that we ··· 171 158 struct ethhdr *eth; 172 159 unsigned char *rawp; 173 160 174 - skb->mac.raw=skb->data; 161 + skb->mac.raw = skb->data; 175 162 skb_pull(skb,ETH_HLEN); 176 163 eth = eth_hdr(skb); 177 164 178 - if(*eth->h_dest&1) 179 - { 180 - if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0) 181 - skb->pkt_type=PACKET_BROADCAST; 165 + if (*eth->h_dest&1) { 166 + if (!compare_eth_addr(eth->h_dest, dev->broadcast)) 167 + skb->pkt_type = PACKET_BROADCAST; 182 168 else 183 - skb->pkt_type=PACKET_MULTICAST; 169 + skb->pkt_type = PACKET_MULTICAST; 184 170 } 185 171 186 172 /* ··· 190 178 * seems to set IFF_PROMISC. 191 179 */ 192 180 193 - else if(1 /*dev->flags&IFF_PROMISC*/) 194 - { 195 - if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN)) 196 - skb->pkt_type=PACKET_OTHERHOST; 181 + else if(1 /*dev->flags&IFF_PROMISC*/) { 182 + if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr))) 183 + skb->pkt_type = PACKET_OTHERHOST; 197 184 } 198 185 199 186 if (ntohs(eth->h_proto) >= 1536)
+6 -5
net/ipv4/tcp_output.c
··· 190 190 } 191 191 192 192 /* Set initial window to value enough for senders, 193 - * following RFC1414. Senders, not following this RFC, 193 + * following RFC2414. Senders, not following this RFC, 194 194 * will be satisfied with 2. 195 195 */ 196 196 if (mss > (1<<*rcv_wscale)) { 197 - int init_cwnd = 4; 198 - if (mss > 1460*3) 197 + int init_cwnd; 198 + 199 + if (mss > 1460) 199 200 init_cwnd = 2; 200 - else if (mss > 1460) 201 - init_cwnd = 3; 201 + else 202 + init_cwnd = (mss > 1095) ? 3 : 4; 202 203 if (*rcv_wnd > init_cwnd*mss) 203 204 *rcv_wnd = init_cwnd*mss; 204 205 }
+16 -10
net/rose/af_rose.c
··· 1472 1472 static int __init rose_proto_init(void) 1473 1473 { 1474 1474 int i; 1475 - int rc = proto_register(&rose_proto, 0); 1475 + int rc; 1476 1476 1477 + if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) { 1478 + printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n"); 1479 + rc = -EINVAL; 1480 + goto out; 1481 + } 1482 + 1483 + rc = proto_register(&rose_proto, 0); 1477 1484 if (rc != 0) 1478 1485 goto out; 1479 1486 1480 1487 rose_callsign = null_ax25_address; 1481 1488 1482 - if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) { 1483 - printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n"); 1484 - return -1; 1485 - } 1486 - 1487 1489 dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL); 1488 1490 if (dev_rose == NULL) { 1489 1491 printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); 1490 - return -1; 1492 + rc = -ENOMEM; 1493 + goto out_proto_unregister; 1491 1494 } 1492 1495 1493 1496 memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device*)); ··· 1503 1500 name, rose_setup); 1504 1501 if (!dev) { 1505 1502 printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n"); 1503 + rc = -ENOMEM; 1506 1504 goto fail; 1507 1505 } 1508 - if (register_netdev(dev)) { 1509 - printk(KERN_ERR "ROSE: netdevice regeistration failed\n"); 1506 + rc = register_netdev(dev); 1507 + if (rc) { 1508 + printk(KERN_ERR "ROSE: netdevice registration failed\n"); 1510 1509 free_netdev(dev); 1511 1510 goto fail; 1512 1511 } ··· 1541 1536 free_netdev(dev_rose[i]); 1542 1537 } 1543 1538 kfree(dev_rose); 1539 + out_proto_unregister: 1544 1540 proto_unregister(&rose_proto); 1545 - return -ENOMEM; 1541 + goto out; 1546 1542 } 1547 1543 module_init(rose_proto_init); 1548 1544
+8 -5
net/socket.c
··· 1145 1145 if (!try_module_get(net_families[family]->owner)) 1146 1146 goto out_release; 1147 1147 1148 - if ((err = net_families[family]->create(sock, protocol)) < 0) 1148 + if ((err = net_families[family]->create(sock, protocol)) < 0) { 1149 + sock->ops = NULL; 1149 1150 goto out_module_put; 1151 + } 1152 + 1150 1153 /* 1151 1154 * Now to bump the refcnt of the [loadable] module that owns this 1152 1155 * socket at sock_release time we decrement its refcnt. ··· 1363 1360 newsock->type = sock->type; 1364 1361 newsock->ops = sock->ops; 1365 1362 1366 - err = security_socket_accept(sock, newsock); 1367 - if (err) 1368 - goto out_release; 1369 - 1370 1363 /* 1371 1364 * We don't need try_module_get here, as the listening socket (sock) 1372 1365 * has the protocol module (sock->ops->owner) held. 1373 1366 */ 1374 1367 __module_get(newsock->ops->owner); 1368 + 1369 + err = security_socket_accept(sock, newsock); 1370 + if (err) 1371 + goto out_release; 1375 1372 1376 1373 err = sock->ops->accept(sock, newsock, sock->file->f_flags); 1377 1374 if (err < 0)