00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <linux/kernel.h>
00020 #include <linux/sched.h>
00021 #include <linux/string.h>
00022 #include <linux/ptrace.h>
00023 #include <linux/errno.h>
00024 #include <linux/ioport.h>
00025 #include <linux/malloc.h>
00026 #include <linux/interrupt.h>
00027 #include <linux/pci.h>
00028 #include <linux/init.h>
00029 #include <linux/delay.h>
00030 #include <linux/netdevice.h>
00031 #include <linux/etherdevice.h>
00032 #include <linux/skbuff.h>
00033
00034 #include <asm/8xx_immap.h>
00035 #include <asm/pgtable.h>
00036 #include <asm/fads.h>
00037 #include <asm/irq.h>
00038 #include <asm/bitops.h>
00039 #include <asm/uaccess.h>
00040 #include "commproc.h"
00041
00042
00043
00044
00045
00046
00047
00048 #if 1
00049 #define FEC_ENET_RX_PAGES 4
00050 #define FEC_ENET_RX_FRSIZE 2048
00051 #define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE)
00052 #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
00053 #define TX_RING_SIZE 8
00054 #define TX_RING_MOD_MASK 7
00055 #else
00056 #define FEC_ENET_RX_PAGES 16
00057 #define FEC_ENET_RX_FRSIZE 2048
00058 #define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE)
00059 #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
00060 #define TX_RING_SIZE 16
00061 #define TX_RING_MOD_MASK 15
00062 #endif
00063
00064
00065
00066 #define FEC_ENET_HBERR ((uint)0x80000000)
00067 #define FEC_ENET_BABR ((uint)0x40000000)
00068 #define FEC_ENET_BABT ((uint)0x20000000)
00069 #define FEC_ENET_GRA ((uint)0x10000000)
00070 #define FEC_ENET_TXF ((uint)0x08000000)
00071 #define FEC_ENET_TXB ((uint)0x04000000)
00072 #define FEC_ENET_RXF ((uint)0x02000000)
00073 #define FEC_ENET_RXB ((uint)0x01000000)
00074 #define FEC_ENET_MII ((uint)0x00800000)
00075 #define FEC_ENET_EBERR ((uint)0x00400000)
00076
00077
00078
00079 #define PKT_MAXBUF_SIZE 1518
00080 #define PKT_MINBUF_SIZE 64
00081 #define PKT_MAXBLR_SIZE 1520
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 struct fec_enet_private {
00092
00093 struct sk_buff* tx_skbuff[TX_RING_SIZE];
00094 ushort skb_cur;
00095 ushort skb_dirty;
00096
00097
00098
00099 cbd_t *rx_bd_base;
00100 cbd_t *tx_bd_base;
00101 cbd_t *cur_rx, *cur_tx;
00102 cbd_t *dirty_tx;
00103 scc_t *sccp;
00104 struct net_device_stats stats;
00105 char tx_full;
00106 unsigned long lock;
00107 };
00108
00109 static int fec_enet_open(struct device *dev);
00110 static int fec_enet_start_xmit(struct sk_buff *skb, struct device *dev);
00111 static int fec_enet_rx(struct device *dev);
00112 static void fec_enet_mii(struct device *dev);
00113 static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
00114 static int fec_enet_close(struct device *dev);
00115 static struct net_device_stats *fec_enet_get_stats(struct device *dev);
00116 static void set_multicast_list(struct device *dev);
00117
00118 static ushort my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
00119
00120
00121
00122
00123
00124 typedef struct mii_list {
00125 uint mii_regval;
00126 void (*mii_func)(uint val);
00127 struct mii_list *mii_next;
00128 } mii_list_t;
00129
00130 #define NMII 10
00131 mii_list_t mii_cmds[NMII];
00132 mii_list_t *mii_free;
00133 mii_list_t *mii_head;
00134 mii_list_t *mii_tail;
00135
00136 static int mii_queue(int request, void (*func)(int));
00137
00138
00139
00140 #define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18))
00141 #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
00142 (VAL & 0xffff))
00143
00144 static int
00145 fec_enet_open(struct device *dev)
00146 {
00147
00148
00149
00150
00151
00152 dev->tbusy = 0;
00153 dev->interrupt = 0;
00154 dev->start = 1;
00155
00156 return 0;
00157 }
00158
00159 static int
00160 fec_enet_start_xmit(struct sk_buff *skb, struct device *dev)
00161 {
00162 struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv;
00163 volatile cbd_t *bdp;
00164 unsigned long flags;
00165
00166
00167 if (dev->tbusy) {
00168 int tickssofar = jiffies - dev->trans_start;
00169 if (tickssofar < 20)
00170 return 1;
00171 printk("%s: transmit timed out.\n", dev->name);
00172 fep->stats.tx_errors++;
00173 #ifndef final_version
00174 {
00175 int i;
00176 cbd_t *bdp;
00177 printk(" Ring data dump: cur_tx %x%s cur_rx %x.\n",
00178 fep->cur_tx, fep->tx_full ? " (full)" : "",
00179 fep->cur_rx);
00180 bdp = fep->tx_bd_base;
00181 for (i = 0 ; i < TX_RING_SIZE; i++)
00182 printk("%04x %04x %08x\n",
00183 bdp->cbd_sc,
00184 bdp->cbd_datlen,
00185 bdp->cbd_bufaddr);
00186 bdp = fep->rx_bd_base;
00187 for (i = 0 ; i < RX_RING_SIZE; i++)
00188 printk("%04x %04x %08x\n",
00189 bdp->cbd_sc,
00190 bdp->cbd_datlen,
00191 bdp->cbd_bufaddr);
00192 }
00193 #endif
00194
00195 dev->tbusy=0;
00196 dev->trans_start = jiffies;
00197
00198 return 0;
00199 }
00200
00201
00202
00203 if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
00204 printk("%s: Transmitter access conflict.\n", dev->name);
00205 return 1;
00206 }
00207
00208 if (test_and_set_bit(0, (void*)&fep->lock) != 0) {
00209 printk("%s: tx queue lock!.\n", dev->name);
00210
00211 return 1;
00212 }
00213
00214
00215 bdp = fep->cur_tx;
00216
00217 #ifndef final_version
00218 if (bdp->cbd_sc & BD_ENET_TX_READY) {
00219
00220
00221
00222 printk("%s: tx queue full!.\n", dev->name);
00223 fep->lock = 0;
00224 return 1;
00225 }
00226 #endif
00227
00228
00229
00230 bdp->cbd_sc &= ~BD_ENET_TX_STATS;
00231
00232
00233
00234 bdp->cbd_bufaddr = __pa(skb->data);
00235 bdp->cbd_datlen = skb->len;
00236
00237
00238
00239 fep->tx_skbuff[fep->skb_cur] = skb;
00240
00241 fep->stats.tx_bytes += skb->len;
00242 fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 save_flags(flags);
00253 cli();
00254
00255 bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
00256
00257 dev->trans_start = jiffies;
00258 (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_x_des_active = 0x01000000;
00259
00260
00261
00262 if (bdp->cbd_sc & BD_ENET_TX_WRAP)
00263 bdp = fep->tx_bd_base;
00264 else
00265 bdp++;
00266
00267 fep->lock = 0;
00268 if (bdp->cbd_sc & BD_ENET_TX_READY)
00269 fep->tx_full = 1;
00270 else
00271 dev->tbusy=0;
00272 restore_flags(flags);
00273
00274 fep->cur_tx = (cbd_t *)bdp;
00275
00276 return 0;
00277 }
00278
00279
00280
00281
00282 static void
00283 fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
00284 {
00285 struct device *dev = dev_id;
00286 struct fec_enet_private *fep;
00287 volatile cbd_t *bdp;
00288 volatile fec_t *ep;
00289 uint int_events;
00290 int c=0;
00291
00292 fep = (struct fec_enet_private *)dev->priv;
00293 ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
00294 if (dev->interrupt)
00295 printk("%s: Re-entering the interrupt handler.\n", dev->name);
00296 dev->interrupt = 1;
00297
00298
00299
00300 while ((int_events = ep->fec_ievent) != 0) {
00301 ep->fec_ievent = int_events;
00302 if ((int_events &
00303 (FEC_ENET_HBERR | FEC_ENET_BABR |
00304 FEC_ENET_BABT | FEC_ENET_EBERR)) != 0)
00305 printk("FEC ERROR %x\n", int_events);
00306
00307
00308
00309 if (int_events & (FEC_ENET_RXF | FEC_ENET_RXB))
00310 fec_enet_rx(dev_id);
00311
00312
00313
00314
00315
00316 if (int_events & (FEC_ENET_TXF | FEC_ENET_TXB)) {
00317 bdp = fep->dirty_tx;
00318 while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
00319 #if 1
00320 if (bdp==fep->cur_tx)
00321 break;
00322 #endif
00323 if (++c>1) {};
00324
00325
00326 if (bdp->cbd_sc & BD_ENET_TX_HB)
00327 fep->stats.tx_heartbeat_errors++;
00328 if (bdp->cbd_sc & BD_ENET_TX_LC)
00329 fep->stats.tx_window_errors++;
00330 if (bdp->cbd_sc & BD_ENET_TX_RL)
00331 fep->stats.tx_aborted_errors++;
00332 if (bdp->cbd_sc & BD_ENET_TX_UN)
00333 fep->stats.tx_fifo_errors++;
00334 if (bdp->cbd_sc & BD_ENET_TX_CSL)
00335 fep->stats.tx_carrier_errors++;
00336
00337 fep->stats.tx_errors++;
00338
00339 fep->stats.tx_packets++;
00340
00341 #ifndef final_version
00342 if (bdp->cbd_sc & BD_ENET_TX_READY)
00343 printk("HEY! Enet xmit interrupt and TX_READY.\n");
00344 #endif
00345
00346
00347
00348 if (bdp->cbd_sc & BD_ENET_TX_DEF)
00349 fep->stats.collisions++;
00350
00351
00352
00353 dev_kfree_skb(fep->tx_skbuff[fep->skb_dirty]);
00354 fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
00355
00356
00357
00358 if (bdp->cbd_sc & BD_ENET_TX_WRAP)
00359 bdp = fep->tx_bd_base;
00360 else
00361 bdp++;
00362
00363
00364
00365
00366 if (fep->tx_full && dev->tbusy) {
00367 fep->tx_full = 0;
00368 dev->tbusy = 0;
00369 mark_bh(NET_BH);
00370 }
00371
00372 fep->dirty_tx = (cbd_t *)bdp;
00373 #if 0
00374 if (bdp==fep->cur_tx)
00375 break;
00376 #endif
00377 }
00378 }
00379
00380 if (int_events & FEC_ENET_MII)
00381 fec_enet_mii(dev_id);
00382
00383 }
00384
00385 dev->interrupt = 0;
00386
00387 return;
00388 }
00389
00390
00391
00392
00393
00394
00395 static int
00396 fec_enet_rx(struct device *dev)
00397 {
00398 struct fec_enet_private *fep;
00399 volatile cbd_t *bdp;
00400 struct sk_buff *skb;
00401 ushort pkt_len;
00402 volatile fec_t *ep;
00403
00404 fep = (struct fec_enet_private *)dev->priv;
00405 ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
00406
00407
00408
00409
00410 bdp = fep->cur_rx;
00411
00412 for (;;) {
00413 if (bdp->cbd_sc & BD_ENET_RX_EMPTY)
00414 break;
00415
00416 #ifndef final_version
00417
00418
00419
00420 if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0)
00421 printk("FEC ENET: rcv is not +last\n");
00422 #endif
00423
00424
00425
00426 if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
00427 fep->stats.rx_length_errors++;
00428 if (bdp->cbd_sc & BD_ENET_RX_NO)
00429 fep->stats.rx_frame_errors++;
00430 if (bdp->cbd_sc & BD_ENET_RX_CR)
00431 fep->stats.rx_crc_errors++;
00432 if (bdp->cbd_sc & BD_ENET_RX_OV)
00433 fep->stats.rx_crc_errors++;
00434
00435
00436
00437
00438
00439 if (bdp->cbd_sc & BD_ENET_RX_CL) {
00440 fep->stats.rx_frame_errors++;
00441 }
00442 else {
00443
00444
00445
00446 fep->stats.rx_packets++;
00447 pkt_len = bdp->cbd_datlen;
00448 fep->stats.rx_bytes += pkt_len;
00449
00450
00451
00452 skb = dev_alloc_skb(pkt_len);
00453
00454 if (skb == NULL) {
00455 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
00456 fep->stats.rx_dropped++;
00457 }
00458 else {
00459 skb->dev = dev;
00460 skb_put(skb,pkt_len);
00461 eth_copy_and_sum(skb,
00462 (unsigned char *)__va(bdp->cbd_bufaddr),
00463 pkt_len, 0);
00464 skb->protocol=eth_type_trans(skb,dev);
00465 netif_rx(skb);
00466 }
00467 }
00468
00469
00470
00471 bdp->cbd_sc &= ~BD_ENET_RX_STATS;
00472
00473
00474
00475 bdp->cbd_sc |= BD_ENET_RX_EMPTY;
00476
00477
00478
00479 if (bdp->cbd_sc & BD_ENET_RX_WRAP)
00480 bdp = fep->rx_bd_base;
00481 else
00482 bdp++;
00483
00484 #if 1
00485
00486
00487
00488
00489 ep->fec_r_des_active = 0x01000000;
00490 #endif
00491 }
00492 fep->cur_rx = (cbd_t *)bdp;
00493
00494 #if 0
00495
00496
00497
00498
00499
00500
00501
00502 ep->fec_r_des_active = 0x01000000;
00503 #endif
00504
00505 return 0;
00506 }
00507
00508 static void
00509 fec_enet_mii(struct device *dev)
00510 {
00511 struct fec_enet_private *fep;
00512 volatile fec_t *ep;
00513 mii_list_t *mip;
00514 uint mii_reg;
00515
00516 fep = (struct fec_enet_private *)dev->priv;
00517 ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
00518 mii_reg = ep->fec_mii_data;
00519
00520 if ((mip = mii_head) == NULL) {
00521 printk("MII and no head!\n");
00522 return;
00523 }
00524
00525 if (mip->mii_func != NULL)
00526 (*(mip->mii_func))(mii_reg);
00527
00528 mii_head = mip->mii_next;
00529 mip->mii_next = mii_free;
00530 mii_free = mip;
00531
00532 if ((mip = mii_head) != NULL)
00533 ep->fec_mii_data = mip->mii_regval;
00534 }
00535
00536 static int
00537 mii_queue(int regval, void (*func)(int))
00538 {
00539 unsigned long flags;
00540 mii_list_t *mip;
00541 int retval;
00542
00543 retval = 0;
00544
00545 save_flags(flags);
00546 cli();
00547
00548 if ((mip = mii_free) != NULL) {
00549 mii_free = mip->mii_next;
00550 mip->mii_regval = regval;
00551 mip->mii_func = func;
00552 mip->mii_next = NULL;
00553 if (mii_head) {
00554 mii_tail->mii_next = mip;
00555 mii_tail = mip;
00556 }
00557 else {
00558 mii_head = mii_tail = mip;
00559 (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval;
00560 }
00561 }
00562 else {
00563 retval = 1;
00564 }
00565
00566 restore_flags(flags);
00567
00568 return(retval);
00569 }
00570
00571 static void
00572 mii_status(uint mii_reg)
00573 {
00574 if (((mii_reg >> 18) & 0x1f) == 1) {
00575
00576
00577 printk("fec: ");
00578 if (mii_reg & 0x0004)
00579 printk("link up");
00580 else
00581 printk("link down");
00582
00583 if (mii_reg & 0x0010)
00584 printk(",remote fault");
00585 if (mii_reg & 0x0020)
00586 printk(",auto complete");
00587 printk("\n");
00588 }
00589 if (((mii_reg >> 18) & 0x1f) == 0x14) {
00590
00591
00592 printk("fec: ");
00593 if (mii_reg & 0x0800)
00594 printk("100 Mbps");
00595 else
00596 printk("10 Mbps");
00597
00598 if (mii_reg & 0x1000)
00599 printk(", Full-Duplex\n");
00600 else
00601 printk(", Half-Duplex\n");
00602 }
00603 }
00604
00605 static void
00606 mii_startup_cmds(void)
00607 {
00608
00609
00610
00611 mii_queue(mk_mii_read(1), mii_status);
00612 mii_queue(mk_mii_read(18), mii_status);
00613
00614
00615
00616 mii_queue(mk_mii_read(0x14), mii_status);
00617
00618
00619
00620
00621 }
00622
00623
00624
00625
00626
00627 static uint mii_saved_reg1;
00628
00629 static void
00630 mii_relink(uint mii_reg)
00631 {
00632 if (((mii_reg >> 18) & 0x1f) == 1) {
00633
00634
00635 mii_saved_reg1 = mii_reg;
00636 return;
00637 }
00638 if (((mii_reg >> 18) & 0x1f) == 18) {
00639
00640
00641
00642 if ((mii_reg & 0x8000) == 0)
00643 printk("fec: re-link and no IRQ?\n");
00644 if ((mii_reg & 0x4000) == 0)
00645 printk("fec: no PHY power?\n");
00646 }
00647 if (((mii_reg >> 18) & 0x1f) == 20) {
00648
00649
00650
00651 printk("fec: ");
00652 if (mii_saved_reg1 & 0x0004)
00653 printk("link up");
00654 else
00655 printk("link down");
00656
00657 if (mii_saved_reg1 & 0x0010)
00658 printk(", remote fault");
00659 if (mii_saved_reg1 & 0x0020)
00660 printk(", auto complete");
00661
00662 if (mii_reg & 0x0800)
00663 printk(", 100 Mbps");
00664 else
00665 printk(", 10 Mbps");
00666
00667 if (mii_reg & 0x1000)
00668 printk(", Full-Duplex\n");
00669 else
00670 printk(", Half-Duplex\n");
00671 }
00672 }
00673
00674
00675
00676 static void
00677 mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
00678 {
00679 struct device *dev = dev_id;
00680 struct fec_enet_private *fep;
00681 volatile fec_t *ep;
00682
00683 fep = (struct fec_enet_private *)dev->priv;
00684 ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
00685
00686
00687
00688
00689
00690
00691
00692
00693 mii_queue(mk_mii_read(1), mii_relink);
00694 mii_queue(mk_mii_read(18), mii_relink);
00695 mii_queue(mk_mii_read(20), mii_relink);
00696 }
00697
00698 static int
00699 fec_enet_close(struct device *dev)
00700 {
00701
00702
00703
00704 return 0;
00705 }
00706
00707 static struct net_device_stats *fec_enet_get_stats(struct device *dev)
00708 {
00709 struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv;
00710
00711 return &fep->stats;
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 static void set_multicast_list(struct device *dev)
00725 {
00726 struct fec_enet_private *fep;
00727 struct dev_mc_list *dmi;
00728 u_char *mcptr, *tdptr;
00729 volatile fec_t *ep;
00730 int i, j;
00731
00732 fep = (struct fec_enet_private *)dev->priv;
00733 ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
00734
00735 if (dev->flags&IFF_PROMISC) {
00736
00737
00738 printk("%s: Promiscuous mode enabled.\n", dev->name);
00739 ep->fec_r_cntrl |= 0x0008;
00740 } else {
00741
00742 ep->fec_r_cntrl &= ~0x0008;
00743
00744 if (dev->flags & IFF_ALLMULTI) {
00745
00746
00747
00748 ep->fec_hash_table_high = 0xffffffff;
00749 ep->fec_hash_table_low = 0xffffffff;
00750 }
00751 #if 0
00752 else {
00753
00754
00755 ep->sen_gaddr1 = 0;
00756 ep->sen_gaddr2 = 0;
00757 ep->sen_gaddr3 = 0;
00758 ep->sen_gaddr4 = 0;
00759
00760 dmi = dev->mc_list;
00761
00762 for (i=0; i<dev->mc_count; i++) {
00763
00764
00765
00766 if (!(dmi->dmi_addr[0] & 1))
00767 continue;
00768
00769
00770
00771
00772
00773 mcptr = (u_char *)dmi->dmi_addr + 5;
00774 tdptr = (u_char *)&ep->sen_taddrh;
00775 for (j=0; j<6; j++)
00776 *tdptr++ = *mcptr--;
00777
00778
00779
00780
00781 cpmp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SCC1, CPM_CR_SET_GADDR) | CPM_CR_FLG;
00782
00783 udelay(10);
00784 while (cpmp->cp_cpcr & CPM_CR_FLG);
00785 }
00786 }
00787 #endif
00788 }
00789 }
00790
00791
00792
00793 __initfunc(int m8xx_enet_init(void))
00794 {
00795 struct device *dev;
00796 struct fec_enet_private *fep;
00797 int i, j;
00798 unsigned char *eap;
00799 unsigned long mem_addr;
00800 pte_t *pte;
00801 volatile cbd_t *bdp;
00802 cbd_t *cbd_base;
00803 volatile immap_t *immap;
00804 volatile fec_t *fecp;
00805 unsigned char rtc_save_cfg, rtc_val;
00806
00807 immap = (immap_t *)IMAP_ADDR;
00808
00809
00810
00811 fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL);
00812 __clear_user(fep,sizeof(*fep));
00813
00814
00815
00816 dev = init_etherdev(0, 0);
00817
00818 fecp = &(immap->im_cpm.cp_fec);
00819
00820
00821
00822 fecp->fec_ecntrl = 1;
00823 udelay(10);
00824
00825
00826
00827 fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
00828 FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
00829
00830
00831
00832 fecp->fec_ievent = 0xffc0;
00833
00834 fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
00835
00836
00837
00838 fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1];
00839 fecp->fec_addr_high = my_enet_addr[2];
00840
00841 eap = (unsigned char *)&my_enet_addr[0];
00842 for (i=0; i<6; i++)
00843 dev->dev_addr[i] = *eap++;
00844
00845
00846
00847 fecp->fec_hash_table_high = 0;
00848 fecp->fec_hash_table_low = 0;
00849
00850
00851
00852 fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
00853 fecp->fec_r_hash = PKT_MAXBUF_SIZE;
00854
00855
00856
00857 if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
00858 printk("FECC init error. Need more space.\n");
00859 printk("FECC initialization failed.\n");
00860 return 1;
00861 }
00862 mem_addr = __get_free_page(GFP_KERNEL);
00863 cbd_base = (cbd_t *)mem_addr;
00864
00865
00866
00867 pte = va_to_pte(&init_task, (int)mem_addr);
00868 pte_val(*pte) |= _PAGE_NO_CACHE;
00869 flush_tlb_page(current->mm->mmap, mem_addr);
00870
00871
00872
00873 fecp->fec_r_des_start = __pa(mem_addr);
00874 fep->rx_bd_base = cbd_base;
00875 fecp->fec_x_des_start = __pa((unsigned long)(cbd_base + RX_RING_SIZE));
00876 fep->tx_bd_base = cbd_base + RX_RING_SIZE;
00877
00878 fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
00879 fep->cur_rx = fep->rx_bd_base;
00880
00881 fep->skb_cur = fep->skb_dirty = 0;
00882
00883
00884
00885 bdp = fep->rx_bd_base;
00886 for (i=0; i<FEC_ENET_RX_PAGES; i++) {
00887
00888
00889
00890 mem_addr = __get_free_page(GFP_KERNEL);
00891
00892
00893
00894 pte = va_to_pte(&init_task, mem_addr);
00895 pte_val(*pte) |= _PAGE_NO_CACHE;
00896 flush_tlb_page(current->mm->mmap, mem_addr);
00897
00898
00899
00900 for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
00901 bdp->cbd_sc = BD_ENET_RX_EMPTY;
00902 bdp->cbd_bufaddr = __pa(mem_addr);
00903 mem_addr += FEC_ENET_RX_FRSIZE;
00904 bdp++;
00905 }
00906 }
00907
00908
00909
00910 bdp--;
00911 bdp->cbd_sc |= BD_SC_WRAP;
00912
00913
00914
00915 bdp = fep->tx_bd_base;
00916 for (i=0; i<TX_RING_SIZE; i++) {
00917
00918
00919
00920 bdp->cbd_sc = 0;
00921 bdp->cbd_bufaddr = 0;
00922 bdp++;
00923 }
00924
00925
00926
00927 bdp--;
00928 bdp->cbd_sc |= BD_SC_WRAP;
00929
00930
00931
00932 fecp->fec_r_cntrl = 0x0c;
00933 fecp->fec_x_cntrl = 0x00;
00934
00935
00936
00937 fecp->fec_fun_code = 0x78000000;
00938
00939
00940
00941 fecp->fec_mii_speed = 0x14;
00942
00943
00944
00945 immap->im_ioport.iop_pdpar = 0x1fff;
00946 immap->im_ioport.iop_pddir = 0x1c58;
00947
00948
00949
00950
00951 if (request_irq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
00952 panic("Could not allocate FEC IRQ!");
00953 if (request_irq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0)
00954 panic("Could not allocate MII IRQ!");
00955
00956 dev->base_addr = (unsigned long)fecp;
00957 dev->priv = fep;
00958 dev->name = "fec";
00959
00960
00961 dev->open = fec_enet_open;
00962 dev->hard_start_xmit = fec_enet_start_xmit;
00963 dev->stop = fec_enet_close;
00964 dev->get_stats = fec_enet_get_stats;
00965 dev->set_multicast_list = set_multicast_list;
00966
00967
00968
00969 fecp->fec_ecntrl = 2;
00970 fecp->fec_r_des_active = 0x01000000;
00971
00972 printk("FEC ENET Version 0.1, ");
00973 for (i=0; i<5; i++)
00974 printk("%02x:", dev->dev_addr[i]);
00975 printk("%02x\n", dev->dev_addr[5]);
00976
00977 for (i=0; i<NMII-1; i++)
00978 mii_cmds[i].mii_next = &mii_cmds[i+1];
00979 mii_free = mii_cmds;
00980
00981 mii_startup_cmds();
00982
00983 return 0;
00984 }
00985