00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <linux/config.h>
00025 #include <linux/kernel.h>
00026 #include <linux/sched.h>
00027 #include <linux/string.h>
00028 #include <linux/ptrace.h>
00029 #include <linux/errno.h>
00030 #include <linux/ioport.h>
00031 #include <linux/malloc.h>
00032 #include <linux/interrupt.h>
00033 #include <linux/pci.h>
00034 #include <linux/init.h>
00035 #include <linux/delay.h>
00036 #include <linux/netdevice.h>
00037 #include <linux/etherdevice.h>
00038 #include <linux/skbuff.h>
00039
00040 #include <asm/8xx_immap.h>
00041 #include <asm/pgtable.h>
00042 #include <asm/fads.h>
00043 #include <asm/bitops.h>
00044 #include <asm/uaccess.h>
00045 #include "commproc.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 #define CPM_ENET_RX_PAGES 4
00117 #define CPM_ENET_RX_FRSIZE 2048
00118 #define CPM_ENET_RX_FRPPG (PAGE_SIZE / CPM_ENET_RX_FRSIZE)
00119 #define RX_RING_SIZE (CPM_ENET_RX_FRPPG * CPM_ENET_RX_PAGES)
00120 #define TX_RING_SIZE 8
00121 #define TX_RING_MOD_MASK 7
00122
00123
00124
00125 #define PKT_MAXBUF_SIZE 1518
00126 #define PKT_MINBUF_SIZE 64
00127 #define PKT_MAXBLR_SIZE 1520
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 struct cpm_enet_private {
00138
00139 struct sk_buff* tx_skbuff[TX_RING_SIZE];
00140 ushort skb_cur;
00141 ushort skb_dirty;
00142
00143
00144
00145 cbd_t *rx_bd_base;
00146 cbd_t *tx_bd_base;
00147 cbd_t *cur_rx, *cur_tx;
00148 cbd_t *dirty_tx;
00149 scc_t *sccp;
00150 struct net_device_stats stats;
00151 char tx_full;
00152 unsigned long lock;
00153 };
00154
00155 static int cpm_enet_open(struct device *dev);
00156 static int cpm_enet_start_xmit(struct sk_buff *skb, struct device *dev);
00157 static int cpm_enet_rx(struct device *dev);
00158 static void cpm_enet_interrupt(void *dev_id);
00159 static int cpm_enet_close(struct device *dev);
00160 static struct net_device_stats *cpm_enet_get_stats(struct device *dev);
00161 static void set_multicast_list(struct device *dev);
00162
00163
00164
00165
00166
00167
00168
00169
00170 #ifndef CONFIG_MPC860
00171
00172 #define CPM_CR_ENET CPM_CR_CH_SCC2
00173 #define PROFF_ENET PROFF_SCC2
00174 #define SCC_ENET 1
00175 #define CPMVEC_ENET CPMVEC_SCC2
00176 #else
00177 #define CPM_CR_ENET CPM_CR_CH_SCC1
00178 #define PROFF_ENET PROFF_SCC1
00179 #define SCC_ENET 0
00180 #define CPMVEC_ENET CPMVEC_SCC1
00181 #endif
00182
00183 static int
00184 cpm_enet_open(struct device *dev)
00185 {
00186
00187
00188
00189
00190
00191 dev->tbusy = 0;
00192 dev->interrupt = 0;
00193 dev->start = 1;
00194
00195 return 0;
00196 }
00197
00198 static int
00199 cpm_enet_start_xmit(struct sk_buff *skb, struct device *dev)
00200 {
00201 struct cpm_enet_private *cep = (struct cpm_enet_private *)dev->priv;
00202 volatile cbd_t *bdp;
00203 unsigned long flags;
00204
00205
00206 if (dev->tbusy) {
00207 int tickssofar = jiffies - dev->trans_start;
00208 if (tickssofar < 200)
00209 return 1;
00210 printk("%s: transmit timed out.\n", dev->name);
00211 cep->stats.tx_errors++;
00212 #ifndef final_version
00213 {
00214 int i;
00215 cbd_t *bdp;
00216 printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
00217 cep->cur_tx, cep->tx_full ? " (full)" : "",
00218 cep->cur_rx);
00219 bdp = cep->tx_bd_base;
00220 for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
00221 printk("%04x %04x %08x\n",
00222 bdp->cbd_sc,
00223 bdp->cbd_datlen,
00224 bdp->cbd_bufaddr);
00225 bdp = cep->rx_bd_base;
00226 for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
00227 printk("%04x %04x %08x\n",
00228 bdp->cbd_sc,
00229 bdp->cbd_datlen,
00230 bdp->cbd_bufaddr);
00231 }
00232 #endif
00233
00234 dev->tbusy=0;
00235 dev->trans_start = jiffies;
00236
00237 return 0;
00238 }
00239
00240
00241
00242 if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
00243 printk("%s: Transmitter access conflict.\n", dev->name);
00244 return 1;
00245 }
00246
00247 if (test_and_set_bit(0, (void*)&cep->lock) != 0) {
00248 printk("%s: tx queue lock!.\n", dev->name);
00249
00250 return 1;
00251 }
00252
00253
00254 bdp = cep->cur_tx;
00255
00256 #ifndef final_version
00257 if (bdp->cbd_sc & BD_ENET_TX_READY) {
00258
00259
00260
00261 printk("%s: tx queue full!.\n", dev->name);
00262 cep->lock = 0;
00263 return 1;
00264 }
00265 #endif
00266
00267
00268
00269 bdp->cbd_sc &= ~BD_ENET_TX_STATS;
00270
00271
00272
00273 if (skb->len <= ETH_ZLEN)
00274 bdp->cbd_sc |= BD_ENET_TX_PAD;
00275 else
00276 bdp->cbd_sc &= ~BD_ENET_TX_PAD;
00277
00278
00279
00280 bdp->cbd_datlen = skb->len;
00281 bdp->cbd_bufaddr = __pa(skb->data);
00282
00283
00284
00285 cep->tx_skbuff[cep->skb_cur] = skb;
00286
00287 cep->stats.tx_bytes += skb->len;
00288 cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
00289
00290
00291
00292
00293 flush_dcache_range(skb->data, skb->data + skb->len);
00294
00295
00296
00297
00298 bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
00299
00300 dev->trans_start = jiffies;
00301
00302
00303
00304 if (bdp->cbd_sc & BD_ENET_TX_WRAP)
00305 bdp = cep->tx_bd_base;
00306 else
00307 bdp++;
00308
00309 save_flags(flags);
00310 cli();
00311 cep->lock = 0;
00312 if (bdp->cbd_sc & BD_ENET_TX_READY)
00313 cep->tx_full = 1;
00314 else
00315 dev->tbusy=0;
00316 restore_flags(flags);
00317
00318 cep->cur_tx = (cbd_t *)bdp;
00319
00320 return 0;
00321 }
00322
00323
00324
00325
00326 static void
00327 cpm_enet_interrupt(void *dev_id)
00328 {
00329 struct device *dev = dev_id;
00330 volatile struct cpm_enet_private *cep;
00331 volatile cbd_t *bdp;
00332 ushort int_events;
00333 int must_restart;
00334
00335 cep = (struct cpm_enet_private *)dev->priv;
00336 if (dev->interrupt)
00337 printk("%s: Re-entering the interrupt handler.\n", dev->name);
00338
00339 dev->interrupt = 1;
00340
00341
00342
00343 int_events = cep->sccp->scc_scce;
00344 cep->sccp->scc_scce = int_events;
00345 must_restart = 0;
00346
00347
00348
00349 if (int_events & SCCE_ENET_RXF)
00350 cpm_enet_rx(dev_id);
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 #if 0
00361 if (int_events & SCCE_ENET_TXE) {
00362
00363
00364
00365 bdp = cep->dirty_tx;
00366 #ifndef final_version
00367 printk("CPM ENET xmit error %x\n", bdp->cbd_sc);
00368 if (bdp->cbd_sc & BD_ENET_TX_READY)
00369 printk("HEY! Enet xmit interrupt and TX_READY.\n");
00370 #endif
00371 if (bdp->cbd_sc & BD_ENET_TX_HB)
00372 cep->stats.tx_heartbeat_errors++;
00373 if (bdp->cbd_sc & BD_ENET_TX_LC)
00374 cep->stats.tx_window_errors++;
00375 if (bdp->cbd_sc & BD_ENET_TX_RL)
00376 cep->stats.tx_aborted_errors++;
00377 if (bdp->cbd_sc & BD_ENET_TX_UN)
00378 cep->stats.tx_fifo_errors++;
00379 if (bdp->cbd_sc & BD_ENET_TX_CSL)
00380 cep->stats.tx_carrier_errors++;
00381
00382 cep->stats.tx_errors++;
00383
00384
00385
00386
00387 if (bdp->cbd_sc &
00388 (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN))
00389 must_restart = 1;
00390 }
00391 #endif
00392
00393
00394
00395 if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
00396 #if 1
00397 bdp = cep->dirty_tx;
00398 while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
00399 if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
00400 break;
00401
00402 if (bdp->cbd_sc & BD_ENET_TX_HB)
00403 cep->stats.tx_heartbeat_errors++;
00404 if (bdp->cbd_sc & BD_ENET_TX_LC)
00405 cep->stats.tx_window_errors++;
00406 if (bdp->cbd_sc & BD_ENET_TX_RL)
00407 cep->stats.tx_aborted_errors++;
00408 if (bdp->cbd_sc & BD_ENET_TX_UN)
00409 cep->stats.tx_fifo_errors++;
00410 if (bdp->cbd_sc & BD_ENET_TX_CSL)
00411 cep->stats.tx_carrier_errors++;
00412
00413
00414
00415
00416
00417 if (bdp->cbd_sc &
00418 (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
00419 must_restart = 1;
00420 cep->stats.tx_errors++;
00421 }
00422
00423 cep->stats.tx_packets++;
00424 #else
00425 bdp = cep->dirty_tx;
00426 #if 1
00427 if (bdp->cbd_sc & BD_ENET_TX_READY)
00428 printk("HEY! Enet xmit interrupt and TX_READY.\n");
00429 #endif
00430 #endif
00431
00432
00433
00434 if (bdp->cbd_sc & BD_ENET_TX_DEF)
00435 cep->stats.collisions++;
00436
00437
00438
00439 dev_kfree_skb(cep->tx_skbuff[cep->skb_dirty]);
00440 cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
00441
00442
00443
00444 if (bdp->cbd_sc & BD_ENET_TX_WRAP)
00445 bdp = cep->tx_bd_base;
00446 else
00447 bdp++;
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 if (cep->tx_full && dev->tbusy) {
00462 cep->tx_full = 0;
00463 dev->tbusy = 0;
00464 mark_bh(NET_BH);
00465 }
00466
00467 cep->dirty_tx = (cbd_t *)bdp;
00468 }
00469
00470 if (must_restart) {
00471 volatile cpm8xx_t *cp;
00472
00473
00474
00475
00476
00477
00478
00479 cp = cpmp;
00480 cp->cp_cpcr =
00481 mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
00482 while (cp->cp_cpcr & CPM_CR_FLG);
00483 }
00484 }
00485
00486
00487
00488
00489
00490 if (int_events & SCCE_ENET_BSY) {
00491 cep->stats.rx_dropped++;
00492 printk("CPM ENET: BSY can't happen.\n");
00493 }
00494
00495 dev->interrupt = 0;
00496
00497 return;
00498 }
00499
00500
00501
00502
00503
00504
00505 static int
00506 cpm_enet_rx(struct device *dev)
00507 {
00508 struct cpm_enet_private *cep;
00509 volatile cbd_t *bdp;
00510 struct sk_buff *skb;
00511 ushort pkt_len;
00512
00513 cep = (struct cpm_enet_private *)dev->priv;
00514
00515
00516
00517
00518 bdp = cep->cur_rx;
00519
00520 for (;;) {
00521 if (bdp->cbd_sc & BD_ENET_RX_EMPTY)
00522 break;
00523
00524 #ifndef final_version
00525
00526
00527
00528 if ((bdp->cbd_sc & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) !=
00529 (BD_ENET_RX_FIRST | BD_ENET_RX_LAST))
00530 printk("CPM ENET: rcv is not first+last\n");
00531 #endif
00532
00533
00534
00535 if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
00536 cep->stats.rx_length_errors++;
00537 if (bdp->cbd_sc & BD_ENET_RX_NO)
00538 cep->stats.rx_frame_errors++;
00539 if (bdp->cbd_sc & BD_ENET_RX_CR)
00540 cep->stats.rx_crc_errors++;
00541 if (bdp->cbd_sc & BD_ENET_RX_OV)
00542 cep->stats.rx_crc_errors++;
00543
00544
00545
00546
00547
00548 if (bdp->cbd_sc & BD_ENET_RX_CL) {
00549 cep->stats.rx_frame_errors++;
00550 }
00551 else {
00552
00553
00554
00555 cep->stats.rx_packets++;
00556 pkt_len = bdp->cbd_datlen;
00557 cep->stats.rx_bytes += pkt_len;
00558
00559
00560
00561 skb = dev_alloc_skb(pkt_len);
00562
00563 if (skb == NULL) {
00564 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
00565 cep->stats.rx_dropped++;
00566 }
00567 else {
00568 skb->dev = dev;
00569 skb_put(skb,pkt_len);
00570 eth_copy_and_sum(skb,
00571 (unsigned char *)__va(bdp->cbd_bufaddr),
00572 pkt_len, 0);
00573 skb->protocol=eth_type_trans(skb,dev);
00574 netif_rx(skb);
00575 }
00576 }
00577
00578
00579
00580 bdp->cbd_sc &= ~BD_ENET_RX_STATS;
00581
00582
00583
00584 bdp->cbd_sc |= BD_ENET_RX_EMPTY;
00585
00586
00587
00588 if (bdp->cbd_sc & BD_ENET_RX_WRAP)
00589 bdp = cep->rx_bd_base;
00590 else
00591 bdp++;
00592
00593 }
00594 cep->cur_rx = (cbd_t *)bdp;
00595
00596 return 0;
00597 }
00598
00599 static int
00600 cpm_enet_close(struct device *dev)
00601 {
00602
00603
00604
00605 return 0;
00606 }
00607
00608 static struct net_device_stats *cpm_enet_get_stats(struct device *dev)
00609 {
00610 struct cpm_enet_private *cep = (struct cpm_enet_private *)dev->priv;
00611
00612 return &cep->stats;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 static void set_multicast_list(struct device *dev)
00626 {
00627 struct cpm_enet_private *cep;
00628 struct dev_mc_list *dmi;
00629 u_char *mcptr, *tdptr;
00630 volatile scc_enet_t *ep;
00631 int i, j;
00632 cep = (struct cpm_enet_private *)dev->priv;
00633
00634
00635
00636 ep = (scc_enet_t *)dev->base_addr;
00637
00638 if (dev->flags&IFF_PROMISC) {
00639
00640
00641 printk("%s: Promiscuous mode enabled.\n", dev->name);
00642 cep->sccp->scc_pmsr |= SCC_PMSR_PRO;
00643 } else {
00644
00645 cep->sccp->scc_pmsr &= ~SCC_PMSR_PRO;
00646
00647 if (dev->flags & IFF_ALLMULTI) {
00648
00649
00650
00651 ep->sen_gaddr1 = 0xffff;
00652 ep->sen_gaddr2 = 0xffff;
00653 ep->sen_gaddr3 = 0xffff;
00654 ep->sen_gaddr4 = 0xffff;
00655 }
00656 else {
00657
00658
00659 ep->sen_gaddr1 = 0;
00660 ep->sen_gaddr2 = 0;
00661 ep->sen_gaddr3 = 0;
00662 ep->sen_gaddr4 = 0;
00663
00664 dmi = dev->mc_list;
00665
00666 for (i=0; i<dev->mc_count; i++) {
00667
00668
00669
00670 if (!(dmi->dmi_addr[0] & 1))
00671 continue;
00672
00673
00674
00675
00676
00677 mcptr = (u_char *)dmi->dmi_addr + 5;
00678 tdptr = (u_char *)&ep->sen_taddrh;
00679 for (j=0; j<6; j++)
00680 *tdptr++ = *mcptr--;
00681
00682
00683
00684
00685 cpmp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_SET_GADDR) | CPM_CR_FLG;
00686
00687 udelay(10);
00688 while (cpmp->cp_cpcr & CPM_CR_FLG);
00689 }
00690 }
00691 }
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701 int __init cpm_enet_init() { m8xx_enet_init(); }
00702 int __init m8xx_enet_init(void)
00703 {
00704 struct device *dev;
00705 struct cpm_enet_private *cep;
00706 int i, j;
00707 unsigned char *eap;
00708 unsigned long mem_addr;
00709 pte_t *pte;
00710 bd_t *bd;
00711 volatile cbd_t *bdp;
00712 volatile cpm8xx_t *cp;
00713 volatile scc_t *sccp;
00714 volatile scc_enet_t *ep;
00715 volatile immap_t *immap;
00716
00717 cp = cpmp;
00718
00719 immap = (immap_t *)IMAP_ADDR;
00720
00721 bd = (bd_t *)res;
00722
00723
00724
00725 cep = (struct cpm_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
00726
00727 __clear_user(cep,sizeof(*cep));
00728
00729
00730
00731 dev = init_etherdev(0, 0);
00732
00733
00734
00735 ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);
00736
00737
00738
00739 sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]);
00740 cep->sccp = (scc_t *)sccp;
00741
00742
00743
00744 sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
00757 immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
00758 immap->im_ioport.iop_paodr &= ~PA_ENET_TXD;
00759
00760
00761
00762 immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
00763 immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
00764 immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
00765
00766
00767
00768 immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
00769 immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
00770
00771
00772
00773
00774 cp->cp_sicr &= ~SICR_ENET_MASK;
00775 cp->cp_sicr |= SICR_ENET_CLKRT;
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786 i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE);
00787 ep->sen_genscc.scc_rbase = i;
00788 cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i];
00789
00790 i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE);
00791 ep->sen_genscc.scc_tbase = i;
00792 cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i];
00793
00794 cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
00795 cep->cur_rx = cep->rx_bd_base;
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 ep->sen_genscc.scc_rfcr = SCC_EB;
00810 ep->sen_genscc.scc_tfcr = SCC_EB;
00811
00812
00813
00814
00815
00816 ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;
00817
00818
00819
00820 ep->sen_cpres = 0xffffffff;
00821 ep->sen_cmask = 0xdebb20e3;
00822
00823 ep->sen_crcec = 0;
00824 ep->sen_alec = 0;
00825 ep->sen_disfc = 0;
00826
00827 ep->sen_pads = 0x8888;
00828 ep->sen_retlim = 15;
00829
00830 ep->sen_maxflr = PKT_MAXBUF_SIZE;
00831 ep->sen_minflr = PKT_MINBUF_SIZE;
00832
00833 ep->sen_maxd1 = PKT_MAXBUF_SIZE;
00834 ep->sen_maxd2 = PKT_MAXBUF_SIZE;
00835
00836
00837
00838 ep->sen_gaddr1 = 0;
00839 ep->sen_gaddr2 = 0;
00840 ep->sen_gaddr3 = 0;
00841 ep->sen_gaddr4 = 0;
00842 ep->sen_iaddr1 = 0;
00843 ep->sen_iaddr2 = 0;
00844 ep->sen_iaddr3 = 0;
00845 ep->sen_iaddr4 = 0;
00846
00847
00848
00849
00850
00851
00852
00853 eap = (unsigned char *)&(ep->sen_paddrh);
00854 #ifndef CONFIG_MBX
00855 for (i=5; i>=0; i--)
00856 *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
00857 #else
00858 for (i=5; i>=0; i--)
00859 dev->dev_addr[i] = *eap++;
00860 #endif
00861
00862 ep->sen_pper = 0;
00863 ep->sen_taddrl = 0;
00864 ep->sen_taddrm = 0;
00865 ep->sen_taddrh = 0;
00866
00867
00868
00869
00870 bdp = cep->tx_bd_base;
00871 for (i=0; i<TX_RING_SIZE; i++) {
00872
00873
00874
00875 bdp->cbd_sc = 0;
00876 bdp->cbd_bufaddr = 0;
00877 bdp++;
00878 }
00879
00880
00881
00882 bdp--;
00883 bdp->cbd_sc |= BD_SC_WRAP;
00884
00885 bdp = cep->rx_bd_base;
00886 for (i=0; i<CPM_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<CPM_ENET_RX_FRPPG; j++) {
00901 bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
00902 bdp->cbd_bufaddr = __pa(mem_addr);
00903 mem_addr += CPM_ENET_RX_FRSIZE;
00904 bdp++;
00905 }
00906 }
00907
00908
00909
00910 bdp--;
00911 bdp->cbd_sc |= BD_SC_WRAP;
00912
00913
00914
00915
00916
00917 cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
00918 while (cp->cp_cpcr & CPM_CR_FLG);
00919
00920 cep->skb_cur = cep->skb_dirty = 0;
00921
00922 sccp->scc_scce = 0xffff;
00923
00924
00925
00926
00927
00928 sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
00929
00930
00931
00932 cpm_install_handler(CPMVEC_ENET, cpm_enet_interrupt, dev);
00933
00934
00935
00936
00937 sccp->scc_gsmrh = 0;
00938 sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);
00939
00940
00941
00942 sccp->scc_dsr = 0xd555;
00943
00944
00945
00946
00947 sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);
00948
00949
00950
00951
00952 #ifdef CONFIG_MBX
00953 immap->im_ioport.iop_pcpar |= PC_ENET_TENA;
00954 immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
00955 #endif
00956
00957 #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
00958 cp->cp_pbpar |= PB_ENET_TENA;
00959 cp->cp_pbdir |= PB_ENET_TENA;
00960
00961
00962
00963 *((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK;
00964 *((volatile uint *)RPX_CSR_ADDR) |=
00965 (BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS);
00966 #endif
00967
00968 #ifdef CONFIG_BSEIP
00969 cp->cp_pbpar |= PB_ENET_TENA;
00970 cp->cp_pbdir |= PB_ENET_TENA;
00971
00972
00973
00974 cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS);
00975 cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);
00976 cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);
00977
00978 immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK;
00979 immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK;
00980 immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK;
00981 immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
00982 #endif
00983
00984 dev->base_addr = (unsigned long)ep;
00985 dev->priv = cep;
00986 dev->name = "CPM_ENET";
00987
00988
00989 dev->open = cpm_enet_open;
00990 dev->hard_start_xmit = cpm_enet_start_xmit;
00991 dev->stop = cpm_enet_close;
00992 dev->get_stats = cpm_enet_get_stats;
00993 dev->set_multicast_list = set_multicast_list;
00994
00995
00996
00997 sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
00998
00999 printk("CPM ENET Version 0.1, ");
01000 for (i=0; i<5; i++)
01001 printk("%02x:", dev->dev_addr[i]);
01002 printk("%02x\n", dev->dev_addr[5]);
01003
01004 return 0;
01005 }
01006