via-velocity.h 48.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This software may be redistributed and/or modified under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 *
 * File: via-velocity.h
 *
 * Purpose: Header file to define driver's private structures.
 *
 * Author: Chuang Liang-Shing, AJ Jiang
 *
 * Date: Jan 24, 2003
 */


#ifndef VELOCITY_H
#define VELOCITY_H

#define VELOCITY_TX_CSUM_SUPPORT

#define VELOCITY_NAME          "via-velocity"
#define VELOCITY_FULL_DRV_NAM  "VIA Networking Velocity Family Gigabit Ethernet Adapter Driver"
#define VELOCITY_VERSION       "1.13"

#define PKT_BUF_SZ          1540

#define MAX_UNITS           8
#define OPTION_DEFAULT      { [0 ... MAX_UNITS-1] = -1}

#define REV_ID_VT6110       (0)

#define BYTE_REG_BITS_ON(x,p)       do { writeb(readb((p))|(x),(p));} while (0)
#define WORD_REG_BITS_ON(x,p)       do { writew(readw((p))|(x),(p));} while (0)
#define DWORD_REG_BITS_ON(x,p)      do { writel(readl((p))|(x),(p));} while (0)

#define BYTE_REG_BITS_IS_ON(x,p)    (readb((p)) & (x))
#define WORD_REG_BITS_IS_ON(x,p)    (readw((p)) & (x))
#define DWORD_REG_BITS_IS_ON(x,p)   (readl((p)) & (x))

#define BYTE_REG_BITS_OFF(x,p)      do { writeb(readb((p)) & (~(x)),(p));} while (0)
#define WORD_REG_BITS_OFF(x,p)      do { writew(readw((p)) & (~(x)),(p));} while (0)
#define DWORD_REG_BITS_OFF(x,p)     do { writel(readl((p)) & (~(x)),(p));} while (0)

#define BYTE_REG_BITS_SET(x,m,p)    do { writeb( (readb((p)) & (~(m))) |(x),(p));} while (0)
#define WORD_REG_BITS_SET(x,m,p)    do { writew( (readw((p)) & (~(m))) |(x),(p));} while (0)
#define DWORD_REG_BITS_SET(x,m,p)   do { writel( (readl((p)) & (~(m)))|(x),(p));}  while (0)

#define VAR_USED(p)     do {(p)=(p);} while (0)

/*
 * Purpose: Structures for MAX RX/TX descriptors.
 */


#define B_OWNED_BY_CHIP     1
#define B_OWNED_BY_HOST     0

/*
 * Bits in the RSR0 register
 */

#define RSR_DETAG          0x0080
#define RSR_SNTAG          0x0040
#define RSR_RXER           0x0020
#define RSR_RL             0x0010
#define RSR_CE             0x0008
#define RSR_FAE            0x0004
#define RSR_CRC            0x0002
#define RSR_VIDM           0x0001

/*
 * Bits in the RSR1 register
 */

#define RSR_RXOK           0x8000	// rx OK
#define RSR_PFT            0x4000	// Perfect filtering address match
#define RSR_MAR            0x2000	// MAC accept multicast address packet
#define RSR_BAR            0x1000	// MAC accept broadcast address packet
#define RSR_PHY            0x0800	// MAC accept physical address packet
#define RSR_VTAG           0x0400	// 802.1p/1q tagging packet indicator
#define RSR_STP            0x0200	// start of packet
#define RSR_EDP            0x0100	// end of packet

/*
 * Bits in the RSR1 register
 */

#define RSR1_RXOK           0x80	// rx OK
#define RSR1_PFT            0x40	// Perfect filtering address match
#define RSR1_MAR            0x20	// MAC accept multicast address packet
#define RSR1_BAR            0x10	// MAC accept broadcast address packet
#define RSR1_PHY            0x08	// MAC accept physical address packet
#define RSR1_VTAG           0x04	// 802.1p/1q tagging packet indicator
#define RSR1_STP            0x02	// start of packet
#define RSR1_EDP            0x01	// end of packet

/*
 * Bits in the CSM register
 */

#define CSM_IPOK            0x40	//IP Checkusm validatiaon ok
#define CSM_TUPOK           0x20	//TCP/UDP Checkusm validatiaon ok
#define CSM_FRAG            0x10	//Fragment IP datagram
#define CSM_IPKT            0x04	//Received an IP packet
#define CSM_TCPKT           0x02	//Received a TCP packet
#define CSM_UDPKT           0x01	//Received a UDP packet

/*
 * Bits in the TSR0 register
 */

#define TSR0_ABT            0x0080	// Tx abort because of excessive collision
#define TSR0_OWT            0x0040	// Jumbo frame Tx abort
#define TSR0_OWC            0x0020	// Out of window collision
#define TSR0_COLS           0x0010	// experience collision in this transmit event
#define TSR0_NCR3           0x0008	// collision retry counter[3]
#define TSR0_NCR2           0x0004	// collision retry counter[2]
#define TSR0_NCR1           0x0002	// collision retry counter[1]
#define TSR0_NCR0           0x0001	// collision retry counter[0]
#define TSR0_TERR           0x8000	//
#define TSR0_FDX            0x4000	// current transaction is serviced by full duplex mode
#define TSR0_GMII           0x2000	// current transaction is serviced by GMII mode
#define TSR0_LNKFL          0x1000	// packet serviced during link down
#define TSR0_SHDN           0x0400	// shutdown case
#define TSR0_CRS            0x0200	// carrier sense lost
#define TSR0_CDH            0x0100	// AQE test fail (CD heartbeat)

/*
 * Bits in the TSR1 register
 */

#define TSR1_TERR           0x80	//
#define TSR1_FDX            0x40	// current transaction is serviced by full duplex mode
#define TSR1_GMII           0x20	// current transaction is serviced by GMII mode
#define TSR1_LNKFL          0x10	// packet serviced during link down
#define TSR1_SHDN           0x04	// shutdown case
#define TSR1_CRS            0x02	// carrier sense lost
#define TSR1_CDH            0x01	// AQE test fail (CD heartbeat)

//
// Bits in the TCR0 register
//
#define TCR0_TIC            0x80	// assert interrupt immediately while descriptor has been send complete
#define TCR0_PIC            0x40	// priority interrupt request, INA# is issued over adaptive interrupt scheme
#define TCR0_VETAG          0x20	// enable VLAN tag
#define TCR0_IPCK           0x10	// request IP  checksum calculation.
#define TCR0_UDPCK          0x08	// request UDP checksum calculation.
#define TCR0_TCPCK          0x04	// request TCP checksum calculation.
#define TCR0_JMBO           0x02	// indicate a jumbo packet in GMAC side
#define TCR0_CRC            0x01	// disable CRC generation

#define TCPLS_NORMAL        3
#define TCPLS_START         2
#define TCPLS_END           1
#define TCPLS_MED           0


// max transmit or receive buffer size
#define CB_RX_BUF_SIZE     2048UL	// max buffer size
					// NOTE: must be multiple of 4

#define CB_MAX_RD_NUM       512	// MAX # of RD
#define CB_MAX_TD_NUM       256	// MAX # of TD

#define CB_INIT_RD_NUM_3119 128	// init # of RD, for setup VT3119
#define CB_INIT_TD_NUM_3119 64	// init # of TD, for setup VT3119

#define CB_INIT_RD_NUM      128	// init # of RD, for setup default
#define CB_INIT_TD_NUM      64	// init # of TD, for setup default

// for 3119
#define CB_TD_RING_NUM      4	// # of TD rings.
#define CB_MAX_SEG_PER_PKT  7	// max data seg per packet (Tx)


/*
 *	If collisions excess 15 times , tx will abort, and
 *	if tx fifo underflow, tx will fail
 *	we should try to resend it
 */

#define CB_MAX_TX_ABORT_RETRY   3

/*
 *	Receive descriptor
 */

struct rdesc0 {
	u16 RSR;		/* Receive status */
	u16 len:14;		/* Received packet length */
	u16 reserved:1;
	u16 owner:1;		/* Who owns this buffer ? */
};

struct rdesc1 {
	u16 PQTAG;
	u8 CSM;
	u8 IPKT;
};

struct rx_desc {
	struct rdesc0 rdesc0;
	struct rdesc1 rdesc1;
	u32 pa_low;		/* Low 32 bit PCI address */
	u16 pa_high;		/* Next 16 bit PCI address (48 total) */
	u16 len:15;		/* Frame size */
	u16 inten:1;		/* Enable interrupt */
} __attribute__ ((__packed__));

/*
 *	Transmit descriptor
 */

struct tdesc0 {
	u16 TSR;		/* Transmit status register */
	u16 pktsize:14;		/* Size of frame */
	u16 reserved:1;
	u16 owner:1;		/* Who owns the buffer */
};

struct pqinf {			/* Priority queue info */
	u16 VID:12;
	u16 CFI:1;
	u16 priority:3;
} __attribute__ ((__packed__));

struct tdesc1 {
	struct pqinf pqinf;
	u8 TCR;
	u8 TCPLS:2;
	u8 reserved:2;
	u8 CMDZ:4;
} __attribute__ ((__packed__));

struct td_buf {
	u32 pa_low;
	u16 pa_high;
	u16 bufsize:14;	
	u16 reserved:1;
	u16 queue:1;
} __attribute__ ((__packed__));

struct tx_desc {
	struct tdesc0 tdesc0;
	struct tdesc1 tdesc1;
	struct td_buf td_buf[7];
};

struct velocity_rd_info {
	struct sk_buff *skb;
	dma_addr_t skb_dma;
};

/**
 *	alloc_rd_info		-	allocate an rd info block
 *
 *	Alocate and initialize a receive info structure used for keeping
 *	track of kernel side information related to each receive
 *	descriptor we are using
 */

static inline struct velocity_rd_info *alloc_rd_info(void)
{
	struct velocity_rd_info *ptr;
	if ((ptr = kmalloc(sizeof(struct velocity_rd_info), GFP_ATOMIC)) == NULL)
		return NULL;
	else {
		memset(ptr, 0, sizeof(struct velocity_rd_info));
		return ptr;
	}
}

/*
 *	Used to track transmit side buffers.
 */

struct velocity_td_info {
	struct sk_buff *skb;
	u8 *buf;
	int nskb_dma;
	dma_addr_t skb_dma[7];
	dma_addr_t buf_dma;
};

enum  velocity_owner {
	OWNED_BY_HOST = 0,
	OWNED_BY_NIC = 1
};


/*
 *	MAC registers and macros.
 */


#define MCAM_SIZE           64
#define VCAM_SIZE           64
#define TX_QUEUE_NO         4

#define MAX_HW_MIB_COUNTER  32
310
#define VELOCITY_MIN_MTU    (64)
L
Linus Torvalds 已提交
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416
#define VELOCITY_MAX_MTU    (9000)

/*
 *	Registers in the MAC
 */

#define MAC_REG_PAR         0x00	// physical address
#define MAC_REG_RCR         0x06
#define MAC_REG_TCR         0x07
#define MAC_REG_CR0_SET     0x08
#define MAC_REG_CR1_SET     0x09
#define MAC_REG_CR2_SET     0x0A
#define MAC_REG_CR3_SET     0x0B
#define MAC_REG_CR0_CLR     0x0C
#define MAC_REG_CR1_CLR     0x0D
#define MAC_REG_CR2_CLR     0x0E
#define MAC_REG_CR3_CLR     0x0F
#define MAC_REG_MAR         0x10
#define MAC_REG_CAM         0x10
#define MAC_REG_DEC_BASE_HI 0x18
#define MAC_REG_DBF_BASE_HI 0x1C
#define MAC_REG_ISR_CTL     0x20
#define MAC_REG_ISR_HOTMR   0x20
#define MAC_REG_ISR_TSUPTHR 0x20
#define MAC_REG_ISR_RSUPTHR 0x20
#define MAC_REG_ISR_CTL1    0x21
#define MAC_REG_TXE_SR      0x22
#define MAC_REG_RXE_SR      0x23
#define MAC_REG_ISR         0x24
#define MAC_REG_ISR0        0x24
#define MAC_REG_ISR1        0x25
#define MAC_REG_ISR2        0x26
#define MAC_REG_ISR3        0x27
#define MAC_REG_IMR         0x28
#define MAC_REG_IMR0        0x28
#define MAC_REG_IMR1        0x29
#define MAC_REG_IMR2        0x2A
#define MAC_REG_IMR3        0x2B
#define MAC_REG_TDCSR_SET   0x30
#define MAC_REG_RDCSR_SET   0x32
#define MAC_REG_TDCSR_CLR   0x34
#define MAC_REG_RDCSR_CLR   0x36
#define MAC_REG_RDBASE_LO   0x38
#define MAC_REG_RDINDX      0x3C
#define MAC_REG_TDBASE_LO   0x40
#define MAC_REG_RDCSIZE     0x50
#define MAC_REG_TDCSIZE     0x52
#define MAC_REG_TDINDX      0x54
#define MAC_REG_TDIDX0      0x54
#define MAC_REG_TDIDX1      0x56
#define MAC_REG_TDIDX2      0x58
#define MAC_REG_TDIDX3      0x5A
#define MAC_REG_PAUSE_TIMER 0x5C
#define MAC_REG_RBRDU       0x5E
#define MAC_REG_FIFO_TEST0  0x60
#define MAC_REG_FIFO_TEST1  0x64
#define MAC_REG_CAMADDR     0x68
#define MAC_REG_CAMCR       0x69
#define MAC_REG_GFTEST      0x6A
#define MAC_REG_FTSTCMD     0x6B
#define MAC_REG_MIICFG      0x6C
#define MAC_REG_MIISR       0x6D
#define MAC_REG_PHYSR0      0x6E
#define MAC_REG_PHYSR1      0x6F
#define MAC_REG_MIICR       0x70
#define MAC_REG_MIIADR      0x71
#define MAC_REG_MIIDATA     0x72
#define MAC_REG_SOFT_TIMER0 0x74
#define MAC_REG_SOFT_TIMER1 0x76
#define MAC_REG_CFGA        0x78
#define MAC_REG_CFGB        0x79
#define MAC_REG_CFGC        0x7A
#define MAC_REG_CFGD        0x7B
#define MAC_REG_DCFG0       0x7C
#define MAC_REG_DCFG1       0x7D
#define MAC_REG_MCFG0       0x7E
#define MAC_REG_MCFG1       0x7F

#define MAC_REG_TBIST       0x80
#define MAC_REG_RBIST       0x81
#define MAC_REG_PMCC        0x82
#define MAC_REG_STICKHW     0x83
#define MAC_REG_MIBCR       0x84
#define MAC_REG_EERSV       0x85
#define MAC_REG_REVID       0x86
#define MAC_REG_MIBREAD     0x88
#define MAC_REG_BPMA        0x8C
#define MAC_REG_EEWR_DATA   0x8C
#define MAC_REG_BPMD_WR     0x8F
#define MAC_REG_BPCMD       0x90
#define MAC_REG_BPMD_RD     0x91
#define MAC_REG_EECHKSUM    0x92
#define MAC_REG_EECSR       0x93
#define MAC_REG_EERD_DATA   0x94
#define MAC_REG_EADDR       0x96
#define MAC_REG_EMBCMD      0x97
#define MAC_REG_JMPSR0      0x98
#define MAC_REG_JMPSR1      0x99
#define MAC_REG_JMPSR2      0x9A
#define MAC_REG_JMPSR3      0x9B
#define MAC_REG_CHIPGSR     0x9C
#define MAC_REG_TESTCFG     0x9D
#define MAC_REG_DEBUG       0x9E
#define MAC_REG_CHIPGCR     0x9F
#define MAC_REG_WOLCR0_SET  0xA0
#define MAC_REG_WOLCR1_SET  0xA1
#define MAC_REG_PWCFG_SET   0xA2
#define MAC_REG_WOLCFG_SET  0xA3
#define MAC_REG_WOLCR0_CLR  0xA4
#define MAC_REG_WOLCR1_CLR  0xA5
#define MAC_REG_PWCFG_CLR   0xA6
#define MAC_REG_WOLCFG_CLR  0xA7
#define MAC_REG_WOLSR0_SET  0xA8
#define MAC_REG_WOLSR1_SET  0xA9
#define MAC_REG_WOLSR0_CLR  0xAC
#define MAC_REG_WOLSR1_CLR  0xAD
#define MAC_REG_PATRN_CRC0  0xB0
#define MAC_REG_PATRN_CRC1  0xB2
#define MAC_REG_PATRN_CRC2  0xB4
#define MAC_REG_PATRN_CRC3  0xB6
#define MAC_REG_PATRN_CRC4  0xB8
#define MAC_REG_PATRN_CRC5  0xBA
#define MAC_REG_PATRN_CRC6  0xBC
#define MAC_REG_PATRN_CRC7  0xBE
#define MAC_REG_BYTEMSK0_0  0xC0
#define MAC_REG_BYTEMSK0_1  0xC4
#define MAC_REG_BYTEMSK0_2  0xC8
#define MAC_REG_BYTEMSK0_3  0xCC
#define MAC_REG_BYTEMSK1_0  0xD0
#define MAC_REG_BYTEMSK1_1  0xD4
#define MAC_REG_BYTEMSK1_2  0xD8
#define MAC_REG_BYTEMSK1_3  0xDC
#define MAC_REG_BYTEMSK2_0  0xE0
#define MAC_REG_BYTEMSK2_1  0xE4
#define MAC_REG_BYTEMSK2_2  0xE8
#define MAC_REG_BYTEMSK2_3  0xEC
#define MAC_REG_BYTEMSK3_0  0xF0
#define MAC_REG_BYTEMSK3_1  0xF4
#define MAC_REG_BYTEMSK3_2  0xF8
#define MAC_REG_BYTEMSK3_3  0xFC

/*
 *	Bits in the RCR register
 */

#define RCR_AS              0x80
#define RCR_AP              0x40
#define RCR_AL              0x20
#define RCR_PROM            0x10
#define RCR_AB              0x08
#define RCR_AM              0x04
#define RCR_AR              0x02
#define RCR_SEP             0x01

/*
 *	Bits in the TCR register
 */

#define TCR_TB2BDIS         0x80
#define TCR_COLTMC1         0x08
#define TCR_COLTMC0         0x04
#define TCR_LB1             0x02	/* loopback[1] */
#define TCR_LB0             0x01	/* loopback[0] */

/*
 *	Bits in the CR0 register
 */

#define CR0_TXON            0x00000008UL
#define CR0_RXON            0x00000004UL
#define CR0_STOP            0x00000002UL	/* stop MAC, default = 1 */
#define CR0_STRT            0x00000001UL	/* start MAC */
#define CR0_SFRST           0x00008000UL	/* software reset */
#define CR0_TM1EN           0x00004000UL
#define CR0_TM0EN           0x00002000UL
#define CR0_DPOLL           0x00000800UL	/* disable rx/tx auto polling */
#define CR0_DISAU           0x00000100UL
#define CR0_XONEN           0x00800000UL
#define CR0_FDXTFCEN        0x00400000UL	/* full-duplex TX flow control enable */
#define CR0_FDXRFCEN        0x00200000UL	/* full-duplex RX flow control enable */
#define CR0_HDXFCEN         0x00100000UL	/* half-duplex flow control enable */
#define CR0_XHITH1          0x00080000UL	/* TX XON high threshold 1 */
#define CR0_XHITH0          0x00040000UL	/* TX XON high threshold 0 */
#define CR0_XLTH1           0x00020000UL	/* TX pause frame low threshold 1 */
#define CR0_XLTH0           0x00010000UL	/* TX pause frame low threshold 0 */
#define CR0_GSPRST          0x80000000UL
#define CR0_FORSRST         0x40000000UL
#define CR0_FPHYRST         0x20000000UL
#define CR0_DIAG            0x10000000UL
#define CR0_INTPCTL         0x04000000UL
#define CR0_GINTMSK1        0x02000000UL
#define CR0_GINTMSK0        0x01000000UL

/*
 *	Bits in the CR1 register
 */

#define CR1_SFRST           0x80	/* software reset */
#define CR1_TM1EN           0x40
#define CR1_TM0EN           0x20
#define CR1_DPOLL           0x08	/* disable rx/tx auto polling */
#define CR1_DISAU           0x01

/*
 *	Bits in the CR2 register
 */

#define CR2_XONEN           0x80
#define CR2_FDXTFCEN        0x40	/* full-duplex TX flow control enable */
#define CR2_FDXRFCEN        0x20	/* full-duplex RX flow control enable */
#define CR2_HDXFCEN         0x10	/* half-duplex flow control enable */
#define CR2_XHITH1          0x08	/* TX XON high threshold 1 */
#define CR2_XHITH0          0x04	/* TX XON high threshold 0 */
#define CR2_XLTH1           0x02	/* TX pause frame low threshold 1 */
#define CR2_XLTH0           0x01	/* TX pause frame low threshold 0 */

/*
 *	Bits in the CR3 register
 */

#define CR3_GSPRST          0x80
#define CR3_FORSRST         0x40
#define CR3_FPHYRST         0x20
#define CR3_DIAG            0x10
#define CR3_INTPCTL         0x04
#define CR3_GINTMSK1        0x02
#define CR3_GINTMSK0        0x01

#define ISRCTL_UDPINT       0x8000
#define ISRCTL_TSUPDIS      0x4000
#define ISRCTL_RSUPDIS      0x2000
#define ISRCTL_PMSK1        0x1000
#define ISRCTL_PMSK0        0x0800
#define ISRCTL_INTPD        0x0400
#define ISRCTL_HCRLD        0x0200
#define ISRCTL_SCRLD        0x0100

/*
 *	Bits in the ISR_CTL1 register
 */

#define ISRCTL1_UDPINT      0x80
#define ISRCTL1_TSUPDIS     0x40
#define ISRCTL1_RSUPDIS     0x20
#define ISRCTL1_PMSK1       0x10
#define ISRCTL1_PMSK0       0x08
#define ISRCTL1_INTPD       0x04
#define ISRCTL1_HCRLD       0x02
#define ISRCTL1_SCRLD       0x01

/*
 *	Bits in the TXE_SR register
 */

#define TXESR_TFDBS         0x08
#define TXESR_TDWBS         0x04
#define TXESR_TDRBS         0x02
#define TXESR_TDSTR         0x01

/*
 *	Bits in the RXE_SR register
 */

#define RXESR_RFDBS         0x08
#define RXESR_RDWBS         0x04
#define RXESR_RDRBS         0x02
#define RXESR_RDSTR         0x01

/*
 *	Bits in the ISR register
 */

#define ISR_ISR3            0x80000000UL
#define ISR_ISR2            0x40000000UL
#define ISR_ISR1            0x20000000UL
#define ISR_ISR0            0x10000000UL
#define ISR_TXSTLI          0x02000000UL
#define ISR_RXSTLI          0x01000000UL
#define ISR_HFLD            0x00800000UL
#define ISR_UDPI            0x00400000UL
#define ISR_MIBFI           0x00200000UL
#define ISR_SHDNI           0x00100000UL
#define ISR_PHYI            0x00080000UL
#define ISR_PWEI            0x00040000UL
#define ISR_TMR1I           0x00020000UL
#define ISR_TMR0I           0x00010000UL
#define ISR_SRCI            0x00008000UL
#define ISR_LSTPEI          0x00004000UL
#define ISR_LSTEI           0x00002000UL
#define ISR_OVFI            0x00001000UL
#define ISR_FLONI           0x00000800UL
#define ISR_RACEI           0x00000400UL
#define ISR_TXWB1I          0x00000200UL
#define ISR_TXWB0I          0x00000100UL
#define ISR_PTX3I           0x00000080UL
#define ISR_PTX2I           0x00000040UL
#define ISR_PTX1I           0x00000020UL
#define ISR_PTX0I           0x00000010UL
#define ISR_PTXI            0x00000008UL
#define ISR_PRXI            0x00000004UL
#define ISR_PPTXI           0x00000002UL
#define ISR_PPRXI           0x00000001UL

/*
 *	Bits in the IMR register
 */

#define IMR_TXSTLM          0x02000000UL
#define IMR_UDPIM           0x00400000UL
#define IMR_MIBFIM          0x00200000UL
#define IMR_SHDNIM          0x00100000UL
#define IMR_PHYIM           0x00080000UL
#define IMR_PWEIM           0x00040000UL
#define IMR_TMR1IM          0x00020000UL
#define IMR_TMR0IM          0x00010000UL

#define IMR_SRCIM           0x00008000UL
#define IMR_LSTPEIM         0x00004000UL
#define IMR_LSTEIM          0x00002000UL
#define IMR_OVFIM           0x00001000UL
#define IMR_FLONIM          0x00000800UL
#define IMR_RACEIM          0x00000400UL
#define IMR_TXWB1IM         0x00000200UL
#define IMR_TXWB0IM         0x00000100UL

#define IMR_PTX3IM          0x00000080UL
#define IMR_PTX2IM          0x00000040UL
#define IMR_PTX1IM          0x00000020UL
#define IMR_PTX0IM          0x00000010UL
#define IMR_PTXIM           0x00000008UL
#define IMR_PRXIM           0x00000004UL
#define IMR_PPTXIM          0x00000002UL
#define IMR_PPRXIM          0x00000001UL

/* 0x0013FB0FUL  =  initial value of IMR */

#define INT_MASK_DEF        (IMR_PPTXIM|IMR_PPRXIM|IMR_PTXIM|IMR_PRXIM|\
                            IMR_PWEIM|IMR_TXWB0IM|IMR_TXWB1IM|IMR_FLONIM|\
                            IMR_OVFIM|IMR_LSTEIM|IMR_LSTPEIM|IMR_SRCIM|IMR_MIBFIM|\
                            IMR_SHDNIM|IMR_TMR1IM|IMR_TMR0IM|IMR_TXSTLM)

/*
 *	Bits in the TDCSR0/1, RDCSR0 register
 */

#define TRDCSR_DEAD         0x0008
#define TRDCSR_WAK          0x0004
#define TRDCSR_ACT          0x0002
#define TRDCSR_RUN	    0x0001

/*
 *	Bits in the CAMADDR register
 */

#define CAMADDR_CAMEN       0x80
#define CAMADDR_VCAMSL      0x40

/*
 *	Bits in the CAMCR register
 */

#define CAMCR_PS1           0x80
#define CAMCR_PS0           0x40
#define CAMCR_AITRPKT       0x20
#define CAMCR_AITR16        0x10
#define CAMCR_CAMRD         0x08
#define CAMCR_CAMWR         0x04
#define CAMCR_PS_CAM_MASK   0x40
#define CAMCR_PS_CAM_DATA   0x80
#define CAMCR_PS_MAR        0x00

/*
 *	Bits in the MIICFG register
 */

#define MIICFG_MPO1         0x80
#define MIICFG_MPO0         0x40
#define MIICFG_MFDC         0x20

/*
 *	Bits in the MIISR register
 */

#define MIISR_MIDLE         0x80

/*
 *	 Bits in the PHYSR0 register
 */

#define PHYSR0_PHYRST       0x80
#define PHYSR0_LINKGD       0x40
#define PHYSR0_FDPX         0x10
#define PHYSR0_SPDG         0x08
#define PHYSR0_SPD10        0x04
#define PHYSR0_RXFLC        0x02
#define PHYSR0_TXFLC        0x01

/*
 *	Bits in the PHYSR1 register
 */

#define PHYSR1_PHYTBI       0x01

/*
 *	Bits in the MIICR register
 */

#define MIICR_MAUTO         0x80
#define MIICR_RCMD          0x40
#define MIICR_WCMD          0x20
#define MIICR_MDPM          0x10
#define MIICR_MOUT          0x08
#define MIICR_MDO           0x04
#define MIICR_MDI           0x02
#define MIICR_MDC           0x01

/*
 *	Bits in the MIIADR register
 */

#define MIIADR_SWMPL        0x80

/*
 *	Bits in the CFGA register
 */

#define CFGA_PMHCTG         0x08
#define CFGA_GPIO1PD        0x04
#define CFGA_ABSHDN         0x02
#define CFGA_PACPI          0x01

/*
 *	Bits in the CFGB register
 */

#define CFGB_GTCKOPT        0x80
#define CFGB_MIIOPT         0x40
#define CFGB_CRSEOPT        0x20
#define CFGB_OFSET          0x10
#define CFGB_CRANDOM        0x08
#define CFGB_CAP            0x04
#define CFGB_MBA            0x02
#define CFGB_BAKOPT         0x01

/*
 *	Bits in the CFGC register
 */

#define CFGC_EELOAD         0x80
#define CFGC_BROPT          0x40
#define CFGC_DLYEN          0x20
#define CFGC_DTSEL          0x10
#define CFGC_BTSEL          0x08
#define CFGC_BPS2           0x04	/* bootrom select[2] */
#define CFGC_BPS1           0x02	/* bootrom select[1] */
#define CFGC_BPS0           0x01	/* bootrom select[0] */

/*
 * Bits in the CFGD register
 */

#define CFGD_IODIS          0x80
#define CFGD_MSLVDACEN      0x40
#define CFGD_CFGDACEN       0x20
#define CFGD_PCI64EN        0x10
#define CFGD_HTMRL4         0x08

/*
 *	Bits in the DCFG1 register
 */

#define DCFG_XMWI           0x8000
#define DCFG_XMRM           0x4000
#define DCFG_XMRL           0x2000
#define DCFG_PERDIS         0x1000
#define DCFG_MRWAIT         0x0400
#define DCFG_MWWAIT         0x0200
#define DCFG_LATMEN         0x0100

/*
 *	Bits in the MCFG0 register
 */

#define MCFG_RXARB          0x0080
#define MCFG_RFT1           0x0020
#define MCFG_RFT0           0x0010
#define MCFG_LOWTHOPT       0x0008
#define MCFG_PQEN           0x0004
#define MCFG_RTGOPT         0x0002
#define MCFG_VIDFR          0x0001

/*
 *	Bits in the MCFG1 register
 */

#define MCFG_TXARB          0x8000
#define MCFG_TXQBK1         0x0800
#define MCFG_TXQBK0         0x0400
#define MCFG_TXQNOBK        0x0200
#define MCFG_SNAPOPT        0x0100

/*
 *	Bits in the PMCC  register
 */

#define PMCC_DSI            0x80
#define PMCC_D2_DIS         0x40
#define PMCC_D1_DIS         0x20
#define PMCC_D3C_EN         0x10
#define PMCC_D3H_EN         0x08
#define PMCC_D2_EN          0x04
#define PMCC_D1_EN          0x02
#define PMCC_D0_EN          0x01

/*
 *	Bits in STICKHW
 */

#define STICKHW_SWPTAG      0x10
#define STICKHW_WOLSR       0x08
#define STICKHW_WOLEN       0x04
#define STICKHW_DS1         0x02	/* R/W by software/cfg cycle */
#define STICKHW_DS0         0x01	/* suspend well DS write port */

/*
 *	Bits in the MIBCR register
 */

#define MIBCR_MIBISTOK      0x80
#define MIBCR_MIBISTGO      0x40
#define MIBCR_MIBINC        0x20
#define MIBCR_MIBHI         0x10
#define MIBCR_MIBFRZ        0x08
#define MIBCR_MIBFLSH       0x04
#define MIBCR_MPTRINI       0x02
#define MIBCR_MIBCLR        0x01

/*
 *	Bits in the EERSV register
 */

#define EERSV_BOOT_RPL      ((u8) 0x01)	 /* Boot method selection for VT6110 */

#define EERSV_BOOT_MASK     ((u8) 0x06)
#define EERSV_BOOT_INT19    ((u8) 0x00)
#define EERSV_BOOT_INT18    ((u8) 0x02)
#define EERSV_BOOT_LOCAL    ((u8) 0x04)
#define EERSV_BOOT_BEV      ((u8) 0x06)


/*
 *	Bits in BPCMD
 */

#define BPCMD_BPDNE         0x80
#define BPCMD_EBPWR         0x02
#define BPCMD_EBPRD         0x01

/*
 *	Bits in the EECSR register
 */

#define EECSR_EMBP          0x40	/* eeprom embeded programming */
#define EECSR_RELOAD        0x20	/* eeprom content reload */
#define EECSR_DPM           0x10	/* eeprom direct programming */
#define EECSR_ECS           0x08	/* eeprom CS pin */
#define EECSR_ECK           0x04	/* eeprom CK pin */
#define EECSR_EDI           0x02	/* eeprom DI pin */
#define EECSR_EDO           0x01	/* eeprom DO pin */

/*
 *	Bits in the EMBCMD register
 */

#define EMBCMD_EDONE        0x80
#define EMBCMD_EWDIS        0x08
#define EMBCMD_EWEN         0x04
#define EMBCMD_EWR          0x02
#define EMBCMD_ERD          0x01

/*
 *	Bits in TESTCFG register
 */

#define TESTCFG_HBDIS       0x80

/*
 *	Bits in CHIPGCR register
 */

#define CHIPGCR_FCGMII      0x80
#define CHIPGCR_FCFDX       0x40
#define CHIPGCR_FCRESV      0x20
#define CHIPGCR_FCMODE      0x10
#define CHIPGCR_LPSOPT      0x08
#define CHIPGCR_TM1US       0x04
#define CHIPGCR_TM0US       0x02
#define CHIPGCR_PHYINTEN    0x01

/*
 *	Bits in WOLCR0
 */

#define WOLCR_MSWOLEN7      0x0080	/* enable pattern match filtering */
#define WOLCR_MSWOLEN6      0x0040
#define WOLCR_MSWOLEN5      0x0020
#define WOLCR_MSWOLEN4      0x0010
#define WOLCR_MSWOLEN3      0x0008
#define WOLCR_MSWOLEN2      0x0004
#define WOLCR_MSWOLEN1      0x0002
#define WOLCR_MSWOLEN0      0x0001
#define WOLCR_ARP_EN        0x0001

/*
 *	Bits in WOLCR1
 */

#define WOLCR_LINKOFF_EN      0x0800	/* link off detected enable */
#define WOLCR_LINKON_EN       0x0400	/* link on detected enable */
#define WOLCR_MAGIC_EN        0x0200	/* magic packet filter enable */
#define WOLCR_UNICAST_EN      0x0100	/* unicast filter enable */


/*
 *	Bits in PWCFG
 */

#define PWCFG_PHYPWOPT          0x80	/* internal MII I/F timing */
#define PWCFG_PCISTICK          0x40	/* PCI sticky R/W enable */
#define PWCFG_WOLTYPE           0x20	/* pulse(1) or button (0) */
#define PWCFG_LEGCY_WOL         0x10
#define PWCFG_PMCSR_PME_SR      0x08
#define PWCFG_PMCSR_PME_EN      0x04	/* control by PCISTICK */
#define PWCFG_LEGACY_WOLSR      0x02	/* Legacy WOL_SR shadow */
#define PWCFG_LEGACY_WOLEN      0x01	/* Legacy WOL_EN shadow */

/*
 *	Bits in WOLCFG
 */

#define WOLCFG_PMEOVR           0x80	/* for legacy use, force PMEEN always */
#define WOLCFG_SAM              0x20	/* accept multicast case reset, default=0 */
#define WOLCFG_SAB              0x10	/* accept broadcast case reset, default=0 */
#define WOLCFG_SMIIACC          0x08	/* ?? */
#define WOLCFG_SGENWH           0x02
#define WOLCFG_PHYINTEN         0x01	/* 0:PHYINT trigger enable, 1:use internal MII
					  to report status change */
/*
 *	Bits in WOLSR1
 */

#define WOLSR_LINKOFF_INT      0x0800
#define WOLSR_LINKON_INT       0x0400
#define WOLSR_MAGIC_INT        0x0200
#define WOLSR_UNICAST_INT      0x0100

/*
 *	Ethernet address filter type
 */

#define PKT_TYPE_NONE               0x0000	/* Turn off receiver */
#define PKT_TYPE_DIRECTED           0x0001	/* obselete, directed address is always accepted */
#define PKT_TYPE_MULTICAST          0x0002
#define PKT_TYPE_ALL_MULTICAST      0x0004
#define PKT_TYPE_BROADCAST          0x0008
#define PKT_TYPE_PROMISCUOUS        0x0020
#define PKT_TYPE_LONG               0x2000	/* NOTE.... the definition of LONG is >2048 bytes in our chip */
#define PKT_TYPE_RUNT               0x4000
#define PKT_TYPE_ERROR              0x8000	/* Accept error packets, e.g. CRC error */

/*
 *	Loopback mode
 */

#define MAC_LB_NONE         0x00
#define MAC_LB_INTERNAL     0x01
#define MAC_LB_EXTERNAL     0x02

/*
 *	Enabled mask value of irq
 */

#if defined(_SIM)
#define IMR_MASK_VALUE      0x0033FF0FUL	/* initial value of IMR
						   set IMR0 to 0x0F according to spec */

#else
#define IMR_MASK_VALUE      0x0013FB0FUL	/* initial value of IMR
						   ignore MIBFI,RACEI to
						   reduce intr. frequency
						   NOTE.... do not enable NoBuf int mask at driver driver
						      when (1) NoBuf -> RxThreshold = SF
							   (2) OK    -> RxThreshold = original value
						 */
#endif

/*
 *	Revision id
 */

#define REV_ID_VT3119_A0	0x00
#define REV_ID_VT3119_A1	0x01
#define REV_ID_VT3216_A0	0x10

/*
 *	Max time out delay time
 */

#define W_MAX_TIMEOUT       0x0FFFU


/*
 *	MAC registers as a structure. Cannot be directly accessed this
 *	way but generates offsets for readl/writel() calls
 */

struct mac_regs {
	volatile u8 PAR[6];		/* 0x00 */
	volatile u8 RCR;
	volatile u8 TCR;

	volatile u32 CR0Set;		/* 0x08 */
	volatile u32 CR0Clr;		/* 0x0C */

	volatile u8 MARCAM[8];		/* 0x10 */

	volatile u32 DecBaseHi;		/* 0x18 */
	volatile u16 DbfBaseHi;		/* 0x1C */
	volatile u16 reserved_1E;

	volatile u16 ISRCTL;		/* 0x20 */
	volatile u8 TXESR;
	volatile u8 RXESR;

	volatile u32 ISR;		/* 0x24 */
	volatile u32 IMR;

	volatile u32 TDStatusPort;	/* 0x2C */

	volatile u16 TDCSRSet;		/* 0x30 */
	volatile u8 RDCSRSet;
	volatile u8 reserved_33;
	volatile u16 TDCSRClr;
	volatile u8 RDCSRClr;
	volatile u8 reserved_37;

	volatile u32 RDBaseLo;		/* 0x38 */
	volatile u16 RDIdx;		/* 0x3C */
	volatile u16 reserved_3E;

	volatile u32 TDBaseLo[4];	/* 0x40 */

	volatile u16 RDCSize;		/* 0x50 */
	volatile u16 TDCSize;		/* 0x52 */
	volatile u16 TDIdx[4];		/* 0x54 */
	volatile u16 tx_pause_timer;	/* 0x5C */
	volatile u16 RBRDU;		/* 0x5E */

	volatile u32 FIFOTest0;		/* 0x60 */
	volatile u32 FIFOTest1;		/* 0x64 */

	volatile u8 CAMADDR;		/* 0x68 */
	volatile u8 CAMCR;		/* 0x69 */
	volatile u8 GFTEST;		/* 0x6A */
	volatile u8 FTSTCMD;		/* 0x6B */

	volatile u8 MIICFG;		/* 0x6C */
	volatile u8 MIISR;
	volatile u8 PHYSR0;
	volatile u8 PHYSR1;
	volatile u8 MIICR;
	volatile u8 MIIADR;
	volatile u16 MIIDATA;

	volatile u16 SoftTimer0;	/* 0x74 */
	volatile u16 SoftTimer1;

	volatile u8 CFGA;		/* 0x78 */
	volatile u8 CFGB;
	volatile u8 CFGC;
	volatile u8 CFGD;

	volatile u16 DCFG;		/* 0x7C */
	volatile u16 MCFG;

	volatile u8 TBIST;		/* 0x80 */
	volatile u8 RBIST;
	volatile u8 PMCPORT;
	volatile u8 STICKHW;

	volatile u8 MIBCR;		/* 0x84 */
	volatile u8 reserved_85;
	volatile u8 rev_id;
	volatile u8 PORSTS;

	volatile u32 MIBData;		/* 0x88 */

	volatile u16 EEWrData;

	volatile u8 reserved_8E;
	volatile u8 BPMDWr;
	volatile u8 BPCMD;
	volatile u8 BPMDRd;

	volatile u8 EECHKSUM;		/* 0x92 */
	volatile u8 EECSR;

	volatile u16 EERdData;		/* 0x94 */
	volatile u8 EADDR;
	volatile u8 EMBCMD;


	volatile u8 JMPSR0;		/* 0x98 */
	volatile u8 JMPSR1;
	volatile u8 JMPSR2;
	volatile u8 JMPSR3;
	volatile u8 CHIPGSR;		/* 0x9C */
	volatile u8 TESTCFG;
	volatile u8 DEBUG;
	volatile u8 CHIPGCR;

	volatile u16 WOLCRSet;		/* 0xA0 */
	volatile u8 PWCFGSet;
	volatile u8 WOLCFGSet;

	volatile u16 WOLCRClr;		/* 0xA4 */
	volatile u8 PWCFGCLR;
	volatile u8 WOLCFGClr;

	volatile u16 WOLSRSet;		/* 0xA8 */
	volatile u16 reserved_AA;

	volatile u16 WOLSRClr;		/* 0xAC */
	volatile u16 reserved_AE;

	volatile u16 PatternCRC[8];	/* 0xB0 */
	volatile u32 ByteMask[4][4];	/* 0xC0 */
} __attribute__ ((__packed__));


enum hw_mib {
	HW_MIB_ifRxAllPkts = 0,
	HW_MIB_ifRxOkPkts,
	HW_MIB_ifTxOkPkts,
	HW_MIB_ifRxErrorPkts,
	HW_MIB_ifRxRuntOkPkt,
	HW_MIB_ifRxRuntErrPkt,
	HW_MIB_ifRx64Pkts,
	HW_MIB_ifTx64Pkts,
	HW_MIB_ifRx65To127Pkts,
	HW_MIB_ifTx65To127Pkts,
	HW_MIB_ifRx128To255Pkts,
	HW_MIB_ifTx128To255Pkts,
	HW_MIB_ifRx256To511Pkts,
	HW_MIB_ifTx256To511Pkts,
	HW_MIB_ifRx512To1023Pkts,
	HW_MIB_ifTx512To1023Pkts,
	HW_MIB_ifRx1024To1518Pkts,
	HW_MIB_ifTx1024To1518Pkts,
	HW_MIB_ifTxEtherCollisions,
	HW_MIB_ifRxPktCRCE,
	HW_MIB_ifRxJumboPkts,
	HW_MIB_ifTxJumboPkts,
	HW_MIB_ifRxMacControlFrames,
	HW_MIB_ifTxMacControlFrames,
	HW_MIB_ifRxPktFAE,
	HW_MIB_ifRxLongOkPkt,
	HW_MIB_ifRxLongPktErrPkt,
	HW_MIB_ifTXSQEErrors,
	HW_MIB_ifRxNobuf,
	HW_MIB_ifRxSymbolErrors,
	HW_MIB_ifInRangeLengthErrors,
	HW_MIB_ifLateCollisions,
	HW_MIB_SIZE
};

enum chip_type {
	CHIP_TYPE_VT6110 = 1,
};

struct velocity_info_tbl {
	enum chip_type chip_id;
	char *name;
	int io_size;
	int txqueue;
	u32 flags;
};

#define mac_hw_mibs_init(regs) {\
	BYTE_REG_BITS_ON(MIBCR_MIBFRZ,&((regs)->MIBCR));\
	BYTE_REG_BITS_ON(MIBCR_MIBCLR,&((regs)->MIBCR));\
	do {}\
		while (BYTE_REG_BITS_IS_ON(MIBCR_MIBCLR,&((regs)->MIBCR)));\
	BYTE_REG_BITS_OFF(MIBCR_MIBFRZ,&((regs)->MIBCR));\
}

#define mac_read_isr(regs)  		readl(&((regs)->ISR))
#define mac_write_isr(regs, x)  	writel((x),&((regs)->ISR))
#define mac_clear_isr(regs) 		writel(0xffffffffL,&((regs)->ISR))

#define mac_write_int_mask(mask, regs) 	writel((mask),&((regs)->IMR));
#define mac_disable_int(regs)       	writel(CR0_GINTMSK1,&((regs)->CR0Clr))
#define mac_enable_int(regs)    	writel(CR0_GINTMSK1,&((regs)->CR0Set))

#define mac_hw_mibs_read(regs, MIBs) {\
	int i;\
	BYTE_REG_BITS_ON(MIBCR_MPTRINI,&((regs)->MIBCR));\
	for (i=0;i<HW_MIB_SIZE;i++) {\
		(MIBs)[i]=readl(&((regs)->MIBData));\
	}\
}

#define mac_set_dma_length(regs, n) {\
	BYTE_REG_BITS_SET((n),0x07,&((regs)->DCFG));\
}

#define mac_set_rx_thresh(regs, n) {\
	BYTE_REG_BITS_SET((n),(MCFG_RFT0|MCFG_RFT1),&((regs)->MCFG));\
}

#define mac_rx_queue_run(regs) {\
	writeb(TRDCSR_RUN, &((regs)->RDCSRSet));\
}

#define mac_rx_queue_wake(regs) {\
	writeb(TRDCSR_WAK, &((regs)->RDCSRSet));\
}

#define mac_tx_queue_run(regs, n) {\
	writew(TRDCSR_RUN<<((n)*4),&((regs)->TDCSRSet));\
}

#define mac_tx_queue_wake(regs, n) {\
	writew(TRDCSR_WAK<<(n*4),&((regs)->TDCSRSet));\
}

#define mac_eeprom_reload(regs) {\
	int i=0;\
	BYTE_REG_BITS_ON(EECSR_RELOAD,&((regs)->EECSR));\
	do {\
		udelay(10);\
		if (i++>0x1000) {\
			break;\
		}\
	}while (BYTE_REG_BITS_IS_ON(EECSR_RELOAD,&((regs)->EECSR)));\
}

enum velocity_cam_type {
	VELOCITY_VLAN_ID_CAM = 0,
	VELOCITY_MULTICAST_CAM
};

/**
 *	mac_get_cam_mask	-	Read a CAM mask
 *	@regs: register block for this velocity
 *	@mask: buffer to store mask
 *	@cam_type: CAM to fetch
 *
 *	Fetch the mask bits of the selected CAM and store them into the
 *	provided mask buffer.
 */

static inline void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
{
	int i;
	/* Select CAM mask */
	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);

	if (cam_type == VELOCITY_VLAN_ID_CAM)
		writeb(CAMADDR_VCAMSL, &regs->CAMADDR);
	else
		writeb(0, &regs->CAMADDR);

	/* read mask */
	for (i = 0; i < 8; i++)
		*mask++ = readb(&(regs->MARCAM[i]));

	/* disable CAMEN */
	writeb(0, &regs->CAMADDR);

	/* Select mar */
	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);

}

/**
 *	mac_set_cam_mask	-	Set a CAM mask
 *	@regs: register block for this velocity
 *	@mask: CAM mask to load
 *	@cam_type: CAM to store
 *
 *	Store a new mask into a CAM
 */

static inline void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
{
	int i;
	/* Select CAM mask */
	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);

	if (cam_type == VELOCITY_VLAN_ID_CAM)
		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
	else
		writeb(CAMADDR_CAMEN, &regs->CAMADDR);

	for (i = 0; i < 8; i++) {
		writeb(*mask++, &(regs->MARCAM[i]));
	}
	/* disable CAMEN */
	writeb(0, &regs->CAMADDR);

	/* Select mar */
	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
}

/**
 *	mac_set_cam	-	set CAM data
 *	@regs: register block of this velocity
 *	@idx: Cam index
 *	@addr: 2 or 6 bytes of CAM data
 *	@cam_type: CAM to load
 *
 *	Load an address or vlan tag into a CAM
 */

static inline void mac_set_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
{
	int i;

	/* Select CAM mask */
	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);

	idx &= (64 - 1);

	if (cam_type == VELOCITY_VLAN_ID_CAM)
		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
	else
		writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);

	if (cam_type == VELOCITY_VLAN_ID_CAM)
		writew(*((u16 *) addr), &regs->MARCAM[0]);
	else {
		for (i = 0; i < 6; i++) {
			writeb(*addr++, &(regs->MARCAM[i]));
		}
	}
	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);

	udelay(10);

	writeb(0, &regs->CAMADDR);

	/* Select mar */
	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
}

/**
 *	mac_get_cam	-	fetch CAM data
 *	@regs: register block of this velocity
 *	@idx: Cam index
 *	@addr: buffer to hold up to 6 bytes of CAM data
 *	@cam_type: CAM to load
 *
 *	Load an address or vlan tag from a CAM into the buffer provided by
 *	the caller. VLAN tags are 2 bytes the address cam entries are 6.
 */

static inline void mac_get_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
{
	int i;

	/* Select CAM mask */
	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);

	idx &= (64 - 1);

	if (cam_type == VELOCITY_VLAN_ID_CAM)
		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
	else
		writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);

	BYTE_REG_BITS_ON(CAMCR_CAMRD, &regs->CAMCR);

	udelay(10);

	if (cam_type == VELOCITY_VLAN_ID_CAM)
		*((u16 *) addr) = readw(&(regs->MARCAM[0]));
	else
		for (i = 0; i < 6; i++, addr++)
			*((u8 *) addr) = readb(&(regs->MARCAM[i]));

	writeb(0, &regs->CAMADDR);

	/* Select mar */
	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
}

/**
 *	mac_wol_reset	-	reset WOL after exiting low power
 *	@regs: register block of this velocity
 *
 *	Called after we drop out of wake on lan mode in order to
 *	reset the Wake on lan features. This function doesn't restore
 *	the rest of the logic from the result of sleep/wakeup
 */

1417
static inline void mac_wol_reset(struct mac_regs __iomem * regs)
L
Linus Torvalds 已提交
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
{

	/* Turn off SWPTAG right after leaving power mode */
	BYTE_REG_BITS_OFF(STICKHW_SWPTAG, &regs->STICKHW);
	/* clear sticky bits */
	BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);

	BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, &regs->CHIPGCR);
	BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
	/* disable force PME-enable */
	writeb(WOLCFG_PMEOVR, &regs->WOLCFGClr);
	/* disable power-event config bit */
	writew(0xFFFF, &regs->WOLCRClr);
	/* clear power status */
	writew(0xFFFF, &regs->WOLSRClr);
}


/*
 * Header for WOL definitions. Used to compute hashes
 */

typedef u8 MCAM_ADDR[ETH_ALEN];

struct arp_packet {
	u8 dest_mac[ETH_ALEN];
	u8 src_mac[ETH_ALEN];
	u16 type;
	u16 ar_hrd;
	u16 ar_pro;
	u8 ar_hln;
	u8 ar_pln;
	u16 ar_op;
	u8 ar_sha[ETH_ALEN];
	u8 ar_sip[4];
	u8 ar_tha[ETH_ALEN];
	u8 ar_tip[4];
} __attribute__ ((__packed__));

struct _magic_packet {
	u8 dest_mac[6];
	u8 src_mac[6];
	u16 type;
	u8 MAC[16][6];
	u8 password[6];
} __attribute__ ((__packed__));

/*
 *	Store for chip context when saving and restoring status. Not
 *	all fields are saved/restored currently.
 */

struct velocity_context {
	u8 mac_reg[256];
	MCAM_ADDR cam_addr[MCAM_SIZE];
	u16 vcam[VCAM_SIZE];
	u32 cammask[2];
	u32 patcrc[2];
	u32 pattern[8];
};


/*
 *	MII registers.
 */


/*
 *	Registers in the MII (offset unit is WORD)
 */

#define MII_REG_BMCR        0x00	// physical address
#define MII_REG_BMSR        0x01	//
#define MII_REG_PHYID1      0x02	// OUI
#define MII_REG_PHYID2      0x03	// OUI + Module ID + REV ID
#define MII_REG_ANAR        0x04	//
#define MII_REG_ANLPAR      0x05	//
#define MII_REG_G1000CR     0x09	//
#define MII_REG_G1000SR     0x0A	//
#define MII_REG_MODCFG      0x10	//
#define MII_REG_TCSR        0x16	//
#define MII_REG_PLED        0x1B	//
// NS, MYSON only
#define MII_REG_PCR         0x17	//
// ESI only
#define MII_REG_PCSR        0x17	//
#define MII_REG_AUXCR       0x1C	//

// Marvell 88E1000/88E1000S
#define MII_REG_PSCR        0x10	// PHY specific control register

//
// Bits in the BMCR register
//
#define BMCR_RESET          0x8000	//
#define BMCR_LBK            0x4000	//
#define BMCR_SPEED100       0x2000	//
#define BMCR_AUTO           0x1000	//
#define BMCR_PD             0x0800	//
#define BMCR_ISO            0x0400	//
#define BMCR_REAUTO         0x0200	//
#define BMCR_FDX            0x0100	//
#define BMCR_SPEED1G        0x0040	//
//
// Bits in the BMSR register
//
#define BMSR_AUTOCM         0x0020	//
#define BMSR_LNK            0x0004	//

//
// Bits in the ANAR register
//
#define ANAR_ASMDIR         0x0800	// Asymmetric PAUSE support
#define ANAR_PAUSE          0x0400	// Symmetric PAUSE Support
#define ANAR_T4             0x0200	//
#define ANAR_TXFD           0x0100	//
#define ANAR_TX             0x0080	//
#define ANAR_10FD           0x0040	//
#define ANAR_10             0x0020	//
//
// Bits in the ANLPAR register
//
#define ANLPAR_ASMDIR       0x0800	// Asymmetric PAUSE support
#define ANLPAR_PAUSE        0x0400	// Symmetric PAUSE Support
#define ANLPAR_T4           0x0200	//
#define ANLPAR_TXFD         0x0100	//
#define ANLPAR_TX           0x0080	//
#define ANLPAR_10FD         0x0040	//
#define ANLPAR_10           0x0020	//

//
// Bits in the G1000CR register
//
#define G1000CR_1000FD      0x0200	// PHY is 1000-T Full-duplex capable
#define G1000CR_1000        0x0100	// PHY is 1000-T Half-duplex capable

//
// Bits in the G1000SR register
//
#define G1000SR_1000FD      0x0800	// LP PHY is 1000-T Full-duplex capable
#define G1000SR_1000        0x0400	// LP PHY is 1000-T Half-duplex capable

#define TCSR_ECHODIS        0x2000	//
#define AUXCR_MDPPS         0x0004	//

// Bits in the PLED register
#define PLED_LALBE			0x0004	//

// Marvell 88E1000/88E1000S Bits in the PHY specific control register (10h)
#define PSCR_ACRSTX         0x0800	// Assert CRS on Transmit

#define PHYID_CICADA_CS8201 0x000FC410UL
#define PHYID_VT3216_32BIT  0x000FC610UL
#define PHYID_VT3216_64BIT  0x000FC600UL
#define PHYID_MARVELL_1000  0x01410C50UL
#define PHYID_MARVELL_1000S 0x01410C40UL

#define PHYID_REV_ID_MASK   0x0000000FUL

#define PHYID_GET_PHY_REV_ID(i)     ((i) & PHYID_REV_ID_MASK)
#define PHYID_GET_PHY_ID(i)         ((i) & ~PHYID_REV_ID_MASK)

#define MII_REG_BITS_ON(x,i,p) do {\
    u16 w;\
    velocity_mii_read((p),(i),&(w));\
    (w)|=(x);\
    velocity_mii_write((p),(i),(w));\
} while (0)

#define MII_REG_BITS_OFF(x,i,p) do {\
    u16 w;\
    velocity_mii_read((p),(i),&(w));\
    (w)&=(~(x));\
    velocity_mii_write((p),(i),(w));\
} while (0)

#define MII_REG_BITS_IS_ON(x,i,p) ({\
    u16 w;\
    velocity_mii_read((p),(i),&(w));\
    ((int) ((w) & (x)));})

#define MII_GET_PHY_ID(p) ({\
    u32 id;\
    velocity_mii_read((p),MII_REG_PHYID2,(u16 *) &id);\
    velocity_mii_read((p),MII_REG_PHYID1,((u16 *) &id)+1);\
    (id);})

/*
 * Inline debug routine
 */


enum velocity_msg_level {
	MSG_LEVEL_ERR = 0,	//Errors that will cause abnormal operation.
	MSG_LEVEL_NOTICE = 1,	//Some errors need users to be notified.
	MSG_LEVEL_INFO = 2,	//Normal message.
	MSG_LEVEL_VERBOSE = 3,	//Will report all trival errors.
	MSG_LEVEL_DEBUG = 4	//Only for debug purpose.
};

#ifdef VELOCITY_DEBUG
#define ASSERT(x) { \
	if (!(x)) { \
		printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\
			__FUNCTION__, __LINE__);\
		BUG(); \
	}\
}
#define VELOCITY_DBG(p,args...) printk(p, ##args)
#else
#define ASSERT(x)
#define VELOCITY_DBG(x)
#endif

#define VELOCITY_PRT(l, p, args...) do {if (l<=msglevel) printk( p ,##args);} while (0)

#define VELOCITY_PRT_CAMMASK(p,t) {\
	int i;\
	if ((t)==VELOCITY_MULTICAST_CAM) {\
        	for (i=0;i<(MCAM_SIZE/8);i++)\
			printk("%02X",(p)->mCAMmask[i]);\
	}\
	else {\
		for (i=0;i<(VCAM_SIZE/8);i++)\
			printk("%02X",(p)->vCAMmask[i]);\
	}\
	printk("\n");\
}



#define     VELOCITY_WOL_MAGIC             0x00000000UL
#define     VELOCITY_WOL_PHY               0x00000001UL
#define     VELOCITY_WOL_ARP               0x00000002UL
#define     VELOCITY_WOL_UCAST             0x00000004UL
#define     VELOCITY_WOL_BCAST             0x00000010UL
#define     VELOCITY_WOL_MCAST             0x00000020UL
#define     VELOCITY_WOL_MAGIC_SEC         0x00000040UL

/*
 *	Flags for options
 */

#define     VELOCITY_FLAGS_TAGGING         0x00000001UL
#define     VELOCITY_FLAGS_TX_CSUM         0x00000002UL
#define     VELOCITY_FLAGS_RX_CSUM         0x00000004UL
#define     VELOCITY_FLAGS_IP_ALIGN        0x00000008UL
#define     VELOCITY_FLAGS_VAL_PKT_LEN     0x00000010UL

#define     VELOCITY_FLAGS_FLOW_CTRL       0x01000000UL

/*
 *	Flags for driver status
 */

#define     VELOCITY_FLAGS_OPENED          0x00010000UL
#define     VELOCITY_FLAGS_VMNS_CONNECTED  0x00020000UL
#define     VELOCITY_FLAGS_VMNS_COMMITTED  0x00040000UL
#define     VELOCITY_FLAGS_WOL_ENABLED     0x00080000UL

/*
 *	Flags for MII status
 */

#define     VELOCITY_LINK_FAIL             0x00000001UL
#define     VELOCITY_SPEED_10              0x00000002UL
#define     VELOCITY_SPEED_100             0x00000004UL
#define     VELOCITY_SPEED_1000            0x00000008UL
#define     VELOCITY_DUPLEX_FULL           0x00000010UL
#define     VELOCITY_AUTONEG_ENABLE        0x00000020UL
#define     VELOCITY_FORCED_BY_EEPROM      0x00000040UL

/*
 *	For velocity_set_media_duplex
 */

#define     VELOCITY_LINK_CHANGE           0x00000001UL

enum speed_opt {
	SPD_DPX_AUTO = 0,
	SPD_DPX_100_HALF = 1,
	SPD_DPX_100_FULL = 2,
	SPD_DPX_10_HALF = 3,
	SPD_DPX_10_FULL = 4
};

enum velocity_init_type {
	VELOCITY_INIT_COLD = 0,
	VELOCITY_INIT_RESET,
	VELOCITY_INIT_WOL
};

enum velocity_flow_cntl_type {
	FLOW_CNTL_DEFAULT = 1,
	FLOW_CNTL_TX,
	FLOW_CNTL_RX,
	FLOW_CNTL_TX_RX,
	FLOW_CNTL_DISABLE,
};

struct velocity_opt {
	int numrx;			/* Number of RX descriptors */
	int numtx;			/* Number of TX descriptors */
	enum speed_opt spd_dpx;		/* Media link mode */
	int vid;			/* vlan id */
	int DMA_length;			/* DMA length */
	int rx_thresh;			/* RX_THRESH */
	int flow_cntl;
	int wol_opts;			/* Wake on lan options */
	int td_int_count;
	int int_works;
	int rx_bandwidth_hi;
	int rx_bandwidth_lo;
	int rx_bandwidth_en;
	u32 flags;
};

struct velocity_info {
	struct list_head list;

	struct pci_dev *pdev;
	struct net_device *dev;
	struct net_device_stats stats;

	dma_addr_t rd_pool_dma;
	dma_addr_t td_pool_dma[TX_QUEUE_NO];

	dma_addr_t tx_bufs_dma;
	u8 *tx_bufs;

	u8 ip_addr[4];
	enum chip_type chip_id;

	struct mac_regs __iomem * mac_regs;
	unsigned long memaddr;
	unsigned long ioaddr;
	u32 io_size;

	u8 rev_id;

#define AVAIL_TD(p,q)   ((p)->options.numtx-((p)->td_used[(q)]))

	int num_txq;

	volatile int td_used[TX_QUEUE_NO];
	int td_curr[TX_QUEUE_NO];
	int td_tail[TX_QUEUE_NO];
	struct tx_desc *td_rings[TX_QUEUE_NO];
	struct velocity_td_info *td_infos[TX_QUEUE_NO];

	int rd_curr;
	int rd_dirty;
	u32 rd_filled;
	struct rx_desc *rd_ring;
	struct velocity_rd_info *rd_info;	/* It's an array */

#define GET_RD_BY_IDX(vptr, idx)   (vptr->rd_ring[idx])
	u32 mib_counter[MAX_HW_MIB_COUNTER];
	struct velocity_opt options;

	u32 int_mask;

	u32 flags;

	int rx_buf_sz;
	u32 mii_status;
	u32 phy_id;
	int multicast_limit;

	u8 vCAMmask[(VCAM_SIZE / 8)];
	u8 mCAMmask[(MCAM_SIZE / 8)];

	spinlock_t lock;

	int wol_opts;
	u8 wol_passwd[6];

	struct velocity_context context;

	u32 ticks;
	u32 rx_bytes;

};

/**
 *	velocity_get_ip		-	find an IP address for the device
 *	@vptr: Velocity to query
 *
 *	Dig out an IP address for this interface so that we can
 *	configure wakeup with WOL for ARP. If there are multiple IP
 *	addresses on this chain then we use the first - multi-IP WOL is not
 *	supported.
 *
 *	CHECK ME: locking
 */

1814
static inline int velocity_get_ip(struct velocity_info *vptr)
L
Linus Torvalds 已提交
1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879
{
	struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr;
	struct in_ifaddr *ifa;

	if (in_dev != NULL) {
		ifa = (struct in_ifaddr *) in_dev->ifa_list;
		if (ifa != NULL) {
			memcpy(vptr->ip_addr, &ifa->ifa_address, 4);
			return 0;
		}
	}
	return -ENOENT;
}

/**
 *	velocity_update_hw_mibs	-	fetch MIB counters from chip
 *	@vptr: velocity to update
 *
 *	The velocity hardware keeps certain counters in the hardware
 * 	side. We need to read these when the user asks for statistics
 *	or when they overflow (causing an interrupt). The read of the
 *	statistic clears it, so we keep running master counters in user
 *	space.
 */

static inline void velocity_update_hw_mibs(struct velocity_info *vptr)
{
	u32 tmp;
	int i;
	BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR));

	while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)));

	BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR));
	for (i = 0; i < HW_MIB_SIZE; i++) {
		tmp = readl(&(vptr->mac_regs->MIBData)) & 0x00FFFFFFUL;
		vptr->mib_counter[i] += tmp;
	}
}

/**
 *	init_flow_control_register 	-	set up flow control
 *	@vptr: velocity to configure
 *
 *	Configure the flow control registers for this velocity device.
 */

static inline void init_flow_control_register(struct velocity_info *vptr)
{
	struct mac_regs __iomem * regs = vptr->mac_regs;

	/* Set {XHITH1, XHITH0, XLTH1, XLTH0} in FlowCR1 to {1, 0, 1, 1}
	   depend on RD=64, and Turn on XNOEN in FlowCR1 */
	writel((CR0_XONEN | CR0_XHITH1 | CR0_XLTH1 | CR0_XLTH0), &regs->CR0Set);
	writel((CR0_FDXTFCEN | CR0_FDXRFCEN | CR0_HDXFCEN | CR0_XHITH0), &regs->CR0Clr);

	/* Set TxPauseTimer to 0xFFFF */
	writew(0xFFFF, &regs->tx_pause_timer);

	/* Initialize RBRDU to Rx buffer count. */
	writew(vptr->options.numrx, &regs->RBRDU);
}


#endif