Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

rtl_rtl8139_drv.c

Go to the documentation of this file.
00001 
00002 /*
00003  
00004         8139too.c: A RealTek RTL-8139 Fast Ethernet driver for Linux.
00005  
00006         Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
00007         Copyright 2000,2001 Jeff Garzik
00008  
00009         Much code comes from Donald Becker's rtl8139.c driver,
00010         versions 1.13 and older.  This driver was originally based
00011         on rtl8139.c version 1.07.  Header of rtl8139.c version 1.13:
00012  
00013         -----<snip>-----
00014  
00015                 Written 1997-2001 by Donald Becker.
00016                 This software may be used and distributed according to the
00017                 terms of the GNU General Public License (GPL), incorporated
00018                 herein by reference.  Drivers based on or derived from this
00019                 code fall under the GPL and must retain the authorship,
00020                 copyright and license notice.  This file is not a complete
00021                 program and may only be used when the entire operating
00022                 system is licensed under the GPL.
00023  
00024                 This driver is for boards based on the RTL8129 and RTL8139
00025                 PCI ethernet chips.
00026  
00027                 The author may be reached as becker@scyld.com, or C/O Scyld
00028                 Computing Corporation 410 Severn Ave., Suite 210 Annapolis
00029                 MD 21403
00030                 Support and updates available at
00031                 http://www.scyld.com/network/rtl8139.html
00032                 Twister-tuning table provided by Kinston
00033                 <shangh@realtek.com.tw>.
00034  
00035         -----<snip>-----
00036         This software may be used and distributed according to the terms
00037         of the GNU General Public License, incorporated herein by reference.
00038  
00039         Contributors:
00040  
00041                 Donald Becker - he wrote the original driver, kudos to him!
00042                 (but please don't e-mail him for support, this isn't his driver)
00043  
00044                 Tigran Aivazian - bug fixes, skbuff free cleanup
00045  
00046                 Martin Mares - suggestions for PCI cleanup
00047  
00048                 David S. Miller - PCI DMA and softnet updates
00049  
00050                 Ernst Gill - fixes ported from BSD driver
00051  
00052                 Daniel Kobras - identified specific locations of
00053                         posted MMIO write bugginess
00054  
00055                 Gerard Sharp - bug fix, testing and feedback
00056 
00057                 David Ford - Rx ring wrap fix
00058 
00059                 Dan DeMaggio - swapped RTL8139 cards with me, and allowed me
00060                 to find and fix a crucial bug on older chipsets.
00061  
00062                 Donald Becker/Chris Butterworth/Marcus Westergren -
00063                 Noticed various Rx packet size-related buglets.
00064  
00065                 Santiago Garcia Mantinan - testing and feedback
00066  
00067                 Jens David - 2.2.x kernel backports
00068  
00069                 Martin Dennett - incredibly helpful insight on undocumented
00070                 features of the 8139 chips
00071  
00072                 Jean-Jacques Michel - bug fix
00073  
00074                 Tobias Ringström - Rx interrupt status checking suggestion
00075  
00076                 Andrew Morton - Clear blocked signals, avoid
00077                 buffer overrun setting current->comm.
00078 
00079         Submitting bug reports:
00080  
00081                 "rtl8139-diag -mmmaaavvveefN" output
00082                 enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log
00083  
00084                 See 8139too.txt for more details.
00085  
00086 -----------------------------------------------------------------------------
00087 2001/09/21
00088 Comments by ShuChen Shao
00089  
00090 1.This driver is originally based on 8139too.c version "0.9.15".
00091  
00092 2.It has been enhanced to support RTL8139C+ PCI ethernet chips and tested in 2.4.2 kernel.
00093  
00094 3.RTL8139C+ PCI ethernet chips is set to support C+ mode by default.
00095   If FORCE_C_Mode below is enable, the RTL8139C+ chip will be forced to support C mode
00096   after reboot.
00097  
00098 4.This program can be compiled at /usr/src/linux-2.4.2/drivers/net/ using the attached Makefile.
00099   And the object file named 8139too.o should be moved to the directory
00100   /lib/modules/2.4.2-2/kernel/drivers/net/
00101  
00102 -----------------------------------------------------------------------------
00103 
00104 =====================================================================================
00105                           PORTING TO RT-LINUX
00106 =====================================================================================
00107  
00108 15 May 2003 
00109             
00110             ByungGi Baek <gi@realtimewave.com||weapon100@empal.com>
00111  
00112             1. This driver is originally based on 8139too.c
00113             2. This   file  is also based  in   one file  part  of the
00114             RTL-lwIP TCP/IP   stack.   The  file  is: rt_3c905x_phys.c
00115             which   author      is:       Sergio    Perez      Alcañiz
00116             <serpeal@disca.upv.es>
00117             3. This file is compiled and tested on RTL-lwIP-0.2.1
00118             4.  Unload the original 8139  linux  driver then load this
00119             driver.
00120  
00121 
00122 12     January    2004
00123 
00124             Sergio Perez Alcañiz <serpeal@disca.upv.es> Departamento
00125             de Informática de Sistemas y Computadores Universidad
00126             Politécnica de Valencia
00127 
00128             The RTL-lwIP project  has  been supported by   the Spanish
00129             Government     Research   Office   (CICYT)    under  grant
00130             TIC2002-04123-C03-03  SISTEMAS DE  TIEMPO REAL EMPOTRADOS,
00131             FIABLES Y  DISTRIBUIDOS  BASADOS EN  COMPONENTES  Valencia
00132             (Spain)
00133 
00134             -Removed threads  registration (to  better comply with the
00135             POSIX standard).
00136             -Added  a semaphore   to block   threads  when they    are
00137             performing a read and there are not packets available.
00138             -Modified to use the  new release of DIDMA (Dynamic Memory
00139             Allocator) now called TLSF.
00140 
00141  
00142 =====================================================================================
00143  
00144 */
00145 
00146 #include "rtl_rtl8139_drv.h"
00147 #include "netif/net_policy/FIFO_policy.h"
00148 #include "rt_pci.h"
00149 
00150 MODULE_LICENSE("GPL");
00151 
00152 static sem_t rtl8139_sem;
00153 
00154 static struct net_policy_operations rt_rtl8139_policy = {
00155   FIFO_add_frame_to_buffer,
00156   FIFO_extract_frame_of_buffer,
00157   FIFO_initialize_rx_buffer,
00158   FIFO_dealloc_rx_buffer,
00159 };
00160 
00161 static struct fifo_rx_buffer_t rt_rtl8139_rx_buffer;
00162 
00163 #define RTL8139_MAJOR   205
00164 #define RTL8139_NAME    "rtl"
00165 #define RTL8139_SIGNAL  RTL_SIGUSR1
00166 
00167 static int rt_rtl8139_read_eeprom (void *ioaddr, int location, int addr_len);
00168 static int rt_rtl8139_mdio_read (struct pci_dev *dev, int phy_id, int location);
00169 static void rt_rtl8139_mdio_write (struct pci_dev *dev, int phy_id, int location, int val);
00170 struct pci_dev *init_rtl8139_device(void);
00171 int start_up_rtl8139_device(struct pci_dev *dev);
00172 
00173 
00174 static int dev_rtl8139_open(struct pci_dev *dev);
00175 
00176 static int rt_rtl8139_open (struct rtl_file *filp);
00177 static int rt_rtl8139_release (struct rtl_file *filp);
00178 static ssize_t rt_rtl8139_write(struct rtl_file *filp, const char *buf, size_t count, loff_t* ppos);
00179 static int rt_rtl8139_ioctl(struct rtl_file * filp, unsigned int request, unsigned long other);
00180 static ssize_t rt_rtl8139_read(struct rtl_file *filp, char *buf, size_t count, loff_t* ppos);
00181 void rt_rtl8139_send_signal(void);
00182 
00183 
00184 
00185 static struct rtl_file_operations rt_rtl8139_fops = {
00186         NULL,
00187         rt_rtl8139_read,
00188         rt_rtl8139_write,
00189         rt_rtl8139_ioctl,
00190         NULL,
00191         rt_rtl8139_open,
00192         rt_rtl8139_release
00193 };
00194 
00195 static int rt_rtl8139_inside_the_interrupt_handler = 0, rt_rtl8139_trying_to_close = 0;
00196 static int rt_rtl8139_interrupted = 0, rt_rtl8139_writting = 0;
00197 
00198 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
00199 static int rt_rtl8139_max_interrupt_work = 20;
00200 unsigned char rt_rtl8139_ip_addr[2][4]={{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}};                     
00201 static int rt_rtl8139_n_filters = 0;
00202 unsigned char rt_rtl8139_registered = 0x00, rt_rtl8139_opened = 0x00, rt_rtl8139_sended = 0x01;
00203 struct pci_dev *rtl8139dev;
00204 struct rtl8139_private rtl_8139_tp;  
00205 
00206 /***************************************************************************************/
00207 int rt_rtl8139_obtain_mac_address(unsigned char *mac){
00208         int i;
00209         for(i=0; i<6; i++)
00210                 mac[i]=rtl_8139_tp.dev_addr[i];
00211         return 0;
00212 }
00213 
00214 
00215 
00216 /*************************************************************************************/
00217 int rt_rtl8139_set_ip_filter(long ipaddr){
00218         if(rt_rtl8139_n_filters<=1){
00219                 rt_rtl8139_ip_addr[rt_rtl8139_n_filters][0]=ipaddr & 0x000000ff; rt_rtl8139_ip_addr[rt_rtl8139_n_filters][1]= (ipaddr >> 8) & 0x000000ff;
00220                 rt_rtl8139_ip_addr[rt_rtl8139_n_filters][2]= (ipaddr >> 16) & 0x000000ff; rt_rtl8139_ip_addr[rt_rtl8139_n_filters][3]= (ipaddr >> 24) & 0x000000ff;
00221                 rt_rtl8139_n_filters++;
00222                 return 0;
00223         }
00224  
00225         rtl_printf("You cannot set more than 2 IP filters !!");
00226         return -1;
00227 }
00228 
00229 
00230 /* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
00231    field alignments and semantics. */
00232 static void rt_rtl8139_rx_interrupt (struct pci_dev *dev)
00233 {
00234         unsigned char *rx_ring;
00235         u16 cur_rx;
00236         unsigned char mine = 0x01;
00237         unsigned char multicast_packet= 0x01;
00238         unsigned char arp_request_for_me = 0x01 ;
00239         void *ioaddr = rtl_8139_tp.mmio_addr;
00240         int i, j;
00241 
00242 
00243         rx_ring = rtl_8139_tp.rx_ring;
00244         cur_rx = rtl_8139_tp.cur_rx;
00245 
00246         while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
00247                 int ring_offset = cur_rx % RX_BUF_LEN;
00248                 u32 rx_status;
00249                 unsigned int rx_size;
00250                 unsigned int pkt_size;
00251                 unsigned char *skb;
00252  
00253                 /* read size+status of next frame from DMA ring buffer */
00254                 rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
00255                 rx_size = rx_status >> 16;
00256                 pkt_size = rx_size - 4;
00257 
00258                 if (rx_size == 0xfff0)
00259                         break;
00260 
00261                 if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) || (!(rx_status & RxStatusOK))) {
00262                         return;
00263                 }
00264                 
00265                 skb = &rx_ring[ring_offset+4]; 
00266                 rtl_8139_tp.stats.rx_bytes += pkt_size;
00267 
00268                 rtl_8139_tp.stats.rx_packets++;
00269                 
00270                 for(i=0; i<6; i++){
00271                         if(skb[i] == rtl_8139_tp.dev_addr[i]) {
00272                                 continue;
00273                         } else{
00274                                 mine = 0x00;
00275                                 break;
00276                         }
00277                 }
00278 
00279                 if(mine == 0x01) {
00280                    goto accept_frame;
00281                 }
00282 
00283                 if((skb[12]==0x08) && (skb[13]==0x06)){
00284                     for(j=0; j<rt_rtl8139_n_filters; j++){
00285                         for(i=0; i<4;i++){
00286                                 if(skb[38+i]==rt_rtl8139_ip_addr[j][i]) {
00287                                         continue;
00288                                 } else{
00289                                         arp_request_for_me = 0x00;
00290                                         break;
00291                                 }
00292                         }
00293                     }
00294                 }else
00295                 arp_request_for_me = 0x00;
00296 
00297                 
00298                 for(i=0; i<6; i++){
00299                         if(skb[i] == 0xff)
00300                                 continue;
00301                         else{
00302                                 multicast_packet = 0x00;
00303                                 break;
00304                         }
00305                 }
00306 
00307 accept_frame:
00308                 if((mine == 0x01) || ((multicast_packet==0x01) && (arp_request_for_me==0x01))){ 
00309                    rtl_8139_tp.rx_frames_for_us++;
00310                    if(rt_rtl8139_policy.add_frame_to_buffer(&rt_rtl8139_rx_buffer,skb,pkt_size)== 0){
00311                      sem_post(&rtl8139_sem);
00312 
00313                      rtl_schedule();
00314                    }
00315                 }
00316  
00317                 cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
00318                 RTL_W16_F (RxBufPtr, cur_rx - 16);
00319 
00320                 mine = 0x01;
00321                 multicast_packet= 0x01;
00322                 arp_request_for_me = 0x01 ;
00323         }
00324         rtl_8139_tp.cur_rx = cur_rx;
00325 }               
00326 
00327 
00328 /***************************************************************************************/
00329 static int rt_rtl8139_send_packet(const char *buffer, size_t size)
00330 {
00331         unsigned char *buff;
00332         void *ioaddr = rtl_8139_tp.mmio_addr;
00333         int entry, len = 0;
00334  
00335         rt_rtl8139_writting = 1;
00336 
00337         /* Calculate the next Tx descriptor entry. */
00338         entry = rtl_8139_tp.cur_tx % NUM_TX_DESC;
00339 
00340         buff = rtl_8139_tp.tx_buf[entry];
00341         if(buff) {
00342                 memcpy(buff, buffer, size);
00343                 len = sizeof(buff);
00344         }
00345 
00346         rtl_8139_tp.tx_info[entry].mapping = pci_map_single (rtl_8139_tp.pci_dev, rtl_8139_tp.tx_buf[entry], size, PCI_DMA_TODEVICE);
00347 
00348         RTL_W32 (TxAddr0 + (entry * 4), rtl_8139_tp.tx_info[entry].mapping);
00349 
00350         rtl_8139_tp.cur_tx++;                                                                                
00351 
00352         /* Note: the chip doesn't have auto-pad! */
00353 
00354         RTL_W32 (TxStatus0 + (entry * sizeof (u32)),
00355                  rtl_8139_tp.tx_flag | (size >= ETH_ZLEN ? size : ETH_ZLEN));
00356 
00357         rt_rtl8139_writting = 0; 
00358         return size;                                                                                        
00359 }
00360 
00361 
00362 static void rt_rtl8139_tx_interrupt (struct pci_dev *dev)
00363 {
00364         void *ioaddr = rtl_8139_tp.mmio_addr;
00365         unsigned long dirty_tx, tx_left;
00366  
00367  
00368         dirty_tx = rtl_8139_tp.dirty_tx;
00369         tx_left = rtl_8139_tp.cur_tx - dirty_tx;
00370         while (tx_left > 0) {
00371                 int entry = dirty_tx % NUM_TX_DESC;
00372                 int txstatus;
00373  
00374                 txstatus = RTL_R32 (TxStatus0 + (entry * sizeof (u32)));
00375  
00376                 if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
00377                         break;  /* It still hasn't been Txed */
00378                 /* Note: TxCarrierLost is always asserted at 100mbps. */
00379                 if (txstatus & (TxOutOfWindow | TxAborted)) {
00380                         /* There was an major error, log it. */
00381                         rtl_printf ("Transmit error, Tx status %8.8x.\n",
00382                                  txstatus);
00383                         rtl_8139_tp.stats.tx_errors++;
00384                         if (txstatus & TxAborted) {
00385                                 rtl_8139_tp.stats.tx_aborted_errors++;
00386                                 RTL_W32 (TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift));
00387                         }
00388                         if (txstatus & TxCarrierLost)
00389                                 rtl_8139_tp.stats.tx_carrier_errors++;
00390                         if (txstatus & TxOutOfWindow)
00391                                 rtl_8139_tp.stats.tx_window_errors++;
00392 #ifdef ETHER_STATS
00393                         if ((txstatus & 0x0f000000) == 0x0f000000)
00394                                 rtl_8139_tp.stats.collisions16++;
00395 #endif
00396                 } else {
00397                         if (txstatus & TxUnderrun) {
00398                                 /* Add 64 to the Tx FIFO threshold. */
00399                                 if (rtl_8139_tp.tx_flag < 0x00300000)
00400                                         rtl_8139_tp.tx_flag += 0x00020000;
00401                                 rtl_8139_tp.stats.tx_fifo_errors++;
00402                         }
00403                         rtl_8139_tp.stats.collisions += (txstatus >> 24) & 15;
00404                         rtl_8139_tp.stats.tx_bytes += txstatus & 0x7ff;
00405                         rtl_8139_tp.stats.tx_packets++;
00406                 }
00407                 /* Free the original skb. */
00408                 if (rtl_8139_tp.tx_info[entry].mapping != 0) {
00409                         pci_unmap_single(rtl_8139_tp.pci_dev,
00410                                          rtl_8139_tp.tx_info[entry].mapping,
00411                                          rtl_8139_tp.tx_info[entry].skb->len,
00412                                          PCI_DMA_TODEVICE);
00413                         rtl_8139_tp.tx_info[entry].mapping = 0;
00414                 }
00415                 rtl_8139_tp.tx_info[entry].skb = NULL;
00416  
00417                 dirty_tx++;
00418                 tx_left--;
00419         }
00420  
00421 #ifdef RTL8139_DEBUG
00422         if (rtl_8139_tp.cur_tx - dirty_tx > NUM_TX_DESC) {
00423                 printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
00424                         dev->name, dirty_tx, rtl_8139_tp.cur_tx);
00425                 dirty_tx += NUM_TX_DESC;
00426         }
00427 #endif /* RTL8139_NDEBUG */
00428         /* only wake the queue if we did work, and the queue is stopped */
00429         if (rtl_8139_tp.dirty_tx != dirty_tx) {
00430                 rtl_8139_tp.dirty_tx = dirty_tx;
00431         }
00432 
00433 }
00434 
00435                                                                          
00436 
00437 /* The interrupt handler does all of the Rx thread work and cleans up
00438    after the Tx thread. */
00439 
00440 unsigned int  rt_rtl8139_interrupt (unsigned int irq, struct pt_regs *regs)
00441 {
00442 
00443         struct pci_dev *dev = rtl8139dev;
00444         int boguscnt = rt_rtl8139_max_interrupt_work; 
00445         void *ioaddr = rtl_8139_tp.mmio_addr;
00446         int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
00447   
00448         rt_rtl8139_inside_the_interrupt_handler = 1; 
00449         rt_rtl8139_interrupted++;
00450  
00451         do {
00452                 status = RTL_R16 (IntrStatus);
00453  
00454                 /* h/w no longer present (hotplug?) or major error, bail */
00455                 if (status == 0xFFFF)
00456                         break;
00457                 /* Acknowledge all of the current interrupt sources ASAP, but
00458                    an first get an additional status bit from CSCR. */
00459                 if (status & RxUnderrun)
00460                         link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
00461 
00462                 RTL_W16_F (IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status);
00463  
00464                 if ((status &
00465                      (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
00466                       RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0) {
00467                         break;
00468                         }
00469  
00470                 if (status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))  {   /* Rx interrupt */
00471                         rt_rtl8139_rx_interrupt (dev);  
00472                 }
00473  
00474                 if (status & (TxOK | TxErr)) {
00475                         rt_rtl8139_tx_interrupt (dev);   
00476                 }
00477  
00478                 boguscnt--;
00479         } while (boguscnt > 0);  
00480 
00481         if (boguscnt <= 0) {
00482                 rtl_printf ( "%s: Too much work at interrupt, "
00483                         "IntrStatus=0x%4.4x.\n", dev->name,
00484                         status);
00485  
00486                 /* Clear all interrupt sources. */
00487                 RTL_W16 (IntrStatus, 0xffff);
00488         }
00489         if(!rt_rtl8139_trying_to_close){
00490                 rtl_hard_enable_irq(rtl_8139_tp.pci_dev->irq);
00491         }    
00492 
00493         rt_rtl8139_interrupted--;  
00494  
00495         return (rt_rtl8139_inside_the_interrupt_handler = 0);
00496 }
00497 
00498 
00499 
00500 /* Syncronize the MII management interface by shifting 32 one bits out. */                                    
00501 static void rt_rtl8139_mdio_sync (void *mdio_addr)
00502 {
00503         int i;
00504  
00505  
00506         for (i = 32; i >= 0; i--) {
00507                 writeb (MDIO_WRITE1, mdio_addr);
00508                 rt_rtl8139_mdio_delay (mdio_addr);
00509                 writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
00510                 rt_rtl8139_mdio_delay (mdio_addr);
00511         }
00512  
00513 }
00514 
00515 
00516 static int rt_rtl8139_mdio_read (struct pci_dev *dev, int phy_id, int location)
00517 {
00518         void *mdio_addr = rtl_8139_tp.mmio_addr + Config4;
00519         int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
00520         int retval = 0;
00521         int i;
00522  
00523  
00524         if (phy_id > 31) {      /* Really a 8139.  Use internal registers. */
00525                 return location < 8 && mii_2_8139_map[location] ?
00526                     readw (rtl_8139_tp.mmio_addr + mii_2_8139_map[location]) : 0;
00527         }
00528         rt_rtl8139_mdio_sync (mdio_addr);
00529         /* Shift the read command bits out. */
00530         for (i = 15; i >= 0; i--) {
00531                 int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
00532  
00533                 writeb (MDIO_DIR | dataval, mdio_addr);
00534                 rt_rtl8139_mdio_delay (mdio_addr);
00535                 writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
00536                 rt_rtl8139_mdio_delay (mdio_addr);
00537         }
00538  
00539         /* Read the two transition, 16 data, and wire-idle bits. */
00540         for (i = 19; i > 0; i--) {
00541                 writeb (0, mdio_addr);
00542                 rt_rtl8139_mdio_delay (mdio_addr);
00543                 retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
00544                 writeb (MDIO_CLK, mdio_addr);
00545                 rt_rtl8139_mdio_delay (mdio_addr);
00546         }
00547  
00548         return (retval >> 1) & 0xffff;
00549 }
00550 
00551 
00552 static void rt_rtl8139_mdio_write (struct pci_dev *dev, int phy_id, int location,
00553                         int value)
00554 {
00555         void *mdio_addr = rtl_8139_tp.mmio_addr + Config4;
00556         int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
00557         int i;
00558  
00559  
00560         if (phy_id > 31) {      /* Really a 8139.  Use internal registers. */
00561                 void *ioaddr = rtl_8139_tp.mmio_addr;
00562                 if (location == 0) {
00563                         RTL_W8_F (Cfg9346, Cfg9346_Unlock);
00565                         switch(rtl_8139_tp.AutoNegoAbility){
00566                         case 1: RTL_W16 (NWayAdvert, AutoNegoAbility10half); break;
00567                         case 2: RTL_W16 (NWayAdvert, AutoNegoAbility10full); break;
00568                         case 4: RTL_W16 (NWayAdvert, AutoNegoAbility100half); break;
00569                         case 8: RTL_W16 (NWayAdvert, AutoNegoAbility100full); break;
00570                         default: break;
00571                         }
00572                         RTL_W16_F (BasicModeCtrl, AutoNegotiationEnable|AutoNegotiationRestart);
00574                         RTL_W8_F (Cfg9346, Cfg9346_Lock);
00575                 } else if (location < 8 && mii_2_8139_map[location])
00576                         RTL_W16_F (mii_2_8139_map[location], value);
00577  
00578                 return;
00579         }
00580         rt_rtl8139_mdio_sync (mdio_addr);
00581         /* Shift the command bits out. */
00582         for (i = 31; i >= 0; i--) {
00583                 int dataval =
00584                     (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
00585                 writeb (dataval, mdio_addr);
00586                 rt_rtl8139_mdio_delay (mdio_addr);
00587                 writeb (dataval | MDIO_CLK, mdio_addr);
00588                 rt_rtl8139_mdio_delay (mdio_addr);
00589         }
00590         /* Clear out extra bits. */
00591         for (i = 2; i > 0; i--) {
00592                 writeb (0, mdio_addr);
00593                 rt_rtl8139_mdio_delay (mdio_addr);
00594                 writeb (MDIO_CLK, mdio_addr);
00595                 rt_rtl8139_mdio_delay (mdio_addr);
00596         }
00597         return;
00598 }
00599 
00600 
00601 /* Serial EEPROM section. */
00602  
00603 /*  EEPROM_Ctrl bits. */
00604 #define EE_SHIFT_CLK    0x04    /* EEPROM shift clock. */
00605 #define EE_CS                   0x08    /* EEPROM chip select. */
00606 #define EE_DATA_WRITE   0x02    /* EEPROM chip data in. */
00607 #define EE_WRITE_0              0x00
00608 #define EE_WRITE_1              0x02
00609 #define EE_DATA_READ    0x01    /* EEPROM chip data out. */
00610 #define EE_ENB                  (0x80 | EE_CS)
00611  
00612 /* Delay between EEPROM clock transitions.
00613    No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
00614  */
00615  
00616 #define rt_rtl8139_eeprom_delay()  readl(ee_addr)
00617  
00618 /* The EEPROM commands include the alway-set leading bit. */
00619 #define EE_WRITE_CMD    (5)
00620 #define EE_READ_CMD             (6)
00621 #define EE_ERASE_CMD    (7)
00622 
00623 static int __devinit rt_rtl8139_read_eeprom (void *ioaddr, int location, int addr_len)
00624 {
00625         int i;
00626         unsigned retval = 0;
00627         void *ee_addr = ioaddr + Cfg9346;
00628         int read_cmd = location | (EE_READ_CMD << addr_len);
00629  
00630  
00631         writeb (EE_ENB & ~EE_CS, ee_addr);
00632         writeb (EE_ENB, ee_addr);
00633         rt_rtl8139_eeprom_delay ();
00634  
00635         /* Shift the read command bits out. */
00636         for (i = 4 + addr_len; i >= 0; i--) {
00637                 int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
00638                 writeb (EE_ENB | dataval, ee_addr);
00639                 rt_rtl8139_eeprom_delay ();
00640                 writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
00641                 rt_rtl8139_eeprom_delay ();
00642         }
00643         writeb (EE_ENB, ee_addr);
00644         rt_rtl8139_eeprom_delay ();
00645  
00646         for (i = 16; i > 0; i--) {
00647                 writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
00648                 rt_rtl8139_eeprom_delay ();
00649                 retval =
00650                     (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
00651                                      0);
00652                 writeb (EE_ENB, ee_addr);
00653                 rt_rtl8139_eeprom_delay ();
00654         }
00655  
00656         /* Terminate the EEPROM access. */
00657         writeb (~EE_CS, ee_addr);
00658         rt_rtl8139_eeprom_delay ();
00659  
00660         return retval;
00661 }
00662 
00663 
00664 /* Set or clear the multicast filter for this adaptor.
00665    This routine is not state sensitive and need not be SMP locked. */
00666  
00667 static unsigned const ethernet_polynomial = 0x04c11db7U;
00668 static inline u32 rt_rtl8139_ether_crc (int length, unsigned char *data)
00669 {
00670         int crc = -1;
00671  
00672  
00673         while (--length >= 0) {
00674                 unsigned char current_octet = *data++;
00675                 int bit;
00676                 for (bit = 0; bit < 8; bit++, current_octet >>= 1)
00677                         crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ?
00678                              ethernet_polynomial : 0);
00679         }
00680  
00681         return crc;
00682 }
00683 
00684 
00685  
00686 static void rt_rtl8139_set_rx_mode (struct pci_dev *dev)
00687 {
00688         void *ioaddr = rtl_8139_tp.mmio_addr;
00689         int rx_mode;
00690         u32 tmp;
00691  
00692         /* Note: do not reorder, GCC is clever about common statements. */
00693         rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptAllPhys;
00694  
00695         /* We can safely update without stopping the chip. */
00696         tmp = rtl8139_rx_config | rx_mode |
00697                 (RTL_R32 (RxConfig) & rtl_chip_info[rtl_8139_tp.chipset].RxConfigMask);
00698         RTL_W32_F (RxConfig, tmp);
00699  
00700         rtl_printf ("%s:   rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
00701                         dev->name, rtl_8139_tp.drv_flags, RTL_R32 (RxConfig));
00702  
00703 }
00704 
00705 
00706 
00707 /* Start the hardware at open or resume. */
00708 static void rt_rtl8139_hw_start (struct pci_dev *dev)
00709 {
00710         void *ioaddr = rtl_8139_tp.mmio_addr;
00711         u32 i;
00712         u8 tmp;
00713  
00714  
00715         /* Soft reset the chip. */
00716         RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
00717         rtl_delay (100);
00718  
00719         /* Check that the chip has finished the reset. */
00720         for (i = 1000; i > 0; i--)
00721                 if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
00722                         break;
00723 
00724         /* unlock Config[01234] and BMCR register writes */
00725         RTL_W8_F (Cfg9346, Cfg9346_Unlock);
00726         /* Restore our idea of the MAC address. */
00727         RTL_W32_F (MAC0 + 0, cpu_to_le32 (*(u32 *) (rtl_8139_tp.dev_addr + 0)));
00728         RTL_W32_F (MAC0 + 4, cpu_to_le32 (*(u32 *) (rtl_8139_tp.dev_addr + 4)));
00729  
00730         /* Must enable Tx/Rx before setting transfer thresholds! */
00731         RTL_W8_F (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) |
00732                            CmdRxEnb | CmdTxEnb);
00733  
00734         i = rtl8139_rx_config |
00735             (RTL_R32 (RxConfig) & rtl_chip_info[rtl_8139_tp.chipset].RxConfigMask);
00736         RTL_W32_F (RxConfig, i);
00737  
00738         /* Check this value: the documentation for IFG contradicts ifself. */
00739         RTL_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift));
00740  
00741         rtl_8139_tp.cur_rx = 0;
00742  
00743         /* This is check_duplex() */
00744         if (rtl_8139_tp.phys[0] >= 0  ||  (rtl_8139_tp.drv_flags & HAS_MII_XCVR)) {
00745                 u16 mii_reg5 = rt_rtl8139_mdio_read(dev, rtl_8139_tp.phys[0], 5);
00746                 if (mii_reg5 == 0xffff)
00747                         ;                                       /* Not there */
00748                 else if ((mii_reg5 & 0x0100) == 0x0100
00749                                  || (mii_reg5 & 0x00C0) == 0x0040)
00750                         rtl_8139_tp.full_duplex = 1;
00751                 rtl_printf("%s: Setting %s%s-duplex based on"
00752                            " auto-negotiated partner ability %4.4x.\n", dev->name,
00753                            mii_reg5 == 0 ? "" :
00754                            (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
00755                            rtl_8139_tp.full_duplex ? "full" : "half", mii_reg5);
00756         }
00757         if (rtl_8139_tp.chipset >= CH_8139A) {
00758                 tmp = RTL_R8 (Config1) & Config1Clear;
00759                 tmp |= Cfg1_Driver_Load;
00760                 tmp |= (rtl_8139_tp.chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */
00761                 RTL_W8_F (Config1, tmp);
00762         } else {
00763                 u8 foo = RTL_R8 (Config1) & Config1Clear;
00764                 RTL_W8 (Config1, rtl_8139_tp.full_duplex ? (foo|0x60) : (foo|0x20));
00765         }
00766  
00767         if (rtl_8139_tp.chipset >= CH_8139B) {
00768                 tmp = RTL_R8 (Config4) & ~(1<<2);
00769                 /* chip will clear Rx FIFO overflow automatically */
00770                 tmp |= (1<<7);
00771                 RTL_W8 (Config4, tmp);
00772  
00773                 /* disable magic packet scanning, which is enabled
00774                  * when PM is enabled above (Config1) */
00775                 RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
00776         }
00777 
00778         /* Lock Config[01234] and BMCR register writes */
00779         RTL_W8_F (Cfg9346, Cfg9346_Lock);
00780         rtl_delay (10);
00781  
00782         /* init Rx ring buffer DMA address */
00783         RTL_W32_F (RxBuf, rtl_8139_tp.rx_ring_dma);
00784  
00785         /* init Tx buffer DMA addresses */
00786         for (i = 0; i < NUM_TX_DESC; i++)
00787                 RTL_W32_F (TxAddr0 + (i * 4), rtl_8139_tp.tx_bufs_dma + (rtl_8139_tp.tx_buf[i] - rtl_8139_tp.tx_bufs)); 
00788         RTL_W32_F (RxMissed, 0);
00789  
00790         rt_rtl8139_set_rx_mode (dev);   
00791  
00792         /* no early-rx interrupts */
00793         RTL_W16 (MultiIntr, RTL_R16 (MultiIntr) & MultiIntrClear);
00794  
00795         /* make sure RxTx has started */
00796         RTL_W8_F (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) |
00797                            CmdRxEnb | CmdTxEnb);
00798  
00799         /* Enable all known interrupts by setting the interrupt mask. */
00800         RTL_W16_F (IntrMask, rtl8139_intr_mask);
00801  
00802  
00803 }
00804 
00805 
00806 
00807 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
00808 static void rt_rtl8139_init_ring (struct pci_dev *dev)
00809 {
00810         int i;
00811  
00812  
00813         rtl_8139_tp.cur_rx = 0;
00814         rtl_8139_tp.cur_tx = 0;
00815         rtl_8139_tp.dirty_tx = 0;
00816  
00817         for (i = 0; i < NUM_TX_DESC; i++) {
00818                 rtl_8139_tp.tx_info[i].skb = NULL;
00819                 rtl_8139_tp.tx_info[i].mapping = 0;
00820                 rtl_8139_tp.tx_buf[i] = &rtl_8139_tp.tx_bufs[i * TX_BUF_SIZE];
00821         }
00822  
00823 }
00824 
00825 
00826 
00827 static int dev_rtl8139_open (struct pci_dev *dev)
00828 {
00829         int retval;
00830         long ioaddr;
00831         ioaddr = (long)rtl_8139_tp.mmio_addr;
00832  
00833  
00834         retval = rtl_request_irq (dev->irq, &rt_rtl8139_interrupt);
00835         if (retval) {
00836                 rtl_printf ("rtl_request_irq : EXIT, returning %d\n", retval);
00837                 return retval;
00838         } else rtl_8139_tp.must_free_irq = 1;
00839 
00840         rtl_8139_tp.tx_bufs = pci_alloc_consistent(rtl_8139_tp.pci_dev, TX_BUF_TOT_LEN,
00841                                            &rtl_8139_tp.tx_bufs_dma);
00842         rtl_8139_tp.rx_ring = pci_alloc_consistent(rtl_8139_tp.pci_dev, RX_BUF_TOT_LEN,
00843                                            &rtl_8139_tp.rx_ring_dma);
00844         if (rtl_8139_tp.tx_bufs == NULL || rtl_8139_tp.rx_ring == NULL) {
00845                 rtl_free_irq(dev->irq);
00846  
00847                 if (rtl_8139_tp.tx_bufs)
00848                         pci_free_consistent(rtl_8139_tp.pci_dev, TX_BUF_TOT_LEN,
00849                                             rtl_8139_tp.tx_bufs, rtl_8139_tp.tx_bufs_dma);
00850                 if (rtl_8139_tp.rx_ring)
00851                         pci_free_consistent(rtl_8139_tp.pci_dev, RX_BUF_TOT_LEN,
00852                                             rtl_8139_tp.rx_ring, rtl_8139_tp.rx_ring_dma);
00853  
00854                 rtl_printf ("EXIT, returning -ENOMEM\n");
00855                 return -ENOMEM;
00856  
00857         }
00858         rtl_8139_tp.full_duplex = rtl_8139_tp.duplex_lock;
00859         rtl_8139_tp.tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
00860         rtl_8139_tp.twistie = 1;
00861  
00862         rt_rtl8139_init_ring (dev);
00863         rt_rtl8139_hw_start (dev);     
00864  
00865         rtl_printf ("%s: dev_8139_open() ioaddr %#lx IRQ %d"
00866                         " GP Pins %2.2x %s-duplex.\n",
00867                         dev->name, pci_resource_start (rtl_8139_tp.pci_dev, 1),
00868                         dev->irq, RTL_R8 (MediaStatus),
00869                         rtl_8139_tp.full_duplex ? "full" : "half");
00870  
00871         if (rtl_8139_tp.thr_pid < 0)
00872                 rtl_printf ( "%s: unable to start kernel thread\n",
00873                         dev->name);
00874  
00875         return 0;
00876 }
00877 
00878 
00879 
00880 
00881 /***************************************************************************************/
00882 int start_up_rtl8139_device(struct pci_dev *dev){
00883 
00884         u32 pio_start, pio_end, pio_flags, pio_len;
00885         unsigned long mmio_start, mmio_end, mmio_flags;
00886         unsigned int mmio_len;
00887         u8 tmp8;
00888         int rc=0, i, option, addr_len;
00889         static int board_idx=0;
00890         u32 tmp;
00891         void *ioaddr = NULL;
00892         char *print_name;
00893  
00894         print_name = dev ? dev->slot_name : "rtl8139";
00895 
00896         pio_start = rt_pci_resource_start (dev, 0);
00897         pio_end = rt_pci_resource_end (dev, 0);
00898         pio_flags = rt_pci_resource_flags (dev, 0);
00899         pio_len = rt_pci_resource_len (dev, 0);
00900  
00901         mmio_start = rt_pci_resource_start (dev, 1);
00902         mmio_end = rt_pci_resource_end (dev, 1);
00903         mmio_flags = rt_pci_resource_flags (dev, 1);
00904         mmio_len = rt_pci_resource_len (dev, 1);
00905         rtl_8139_tp.mmio_len = mmio_len;
00906 
00907         /* set this immediately, we need to know before
00908         * we talk to the chip directly */
00909         if (pio_len == RTL8139B_IO_SIZE) {
00910                 rtl_8139_tp.chipset = CH_8139B;
00911         }
00912  
00913         /* make sure PCI base addr 0 is PIO */
00914         if (!(pio_flags & IORESOURCE_IO)) {
00915                 rtl_printf ("region #0 not a PIO resource, aborting\n");
00916         }
00917  
00918         /* make sure PCI base addr 1 is MMIO */
00919         if (!(mmio_flags & IORESOURCE_MEM)) {
00920                 rtl_printf ( "region #1 not an MMIO resource, aborting\n");
00921         }
00922  
00923         /* check for weird/broken PCI region reporting */
00924         if ((pio_len < RTL_MIN_IO_SIZE) || (mmio_len < RTL_MIN_IO_SIZE)) {
00925                 rtl_printf ( "Invalid PCI region size(s), aborting\n");
00926         }
00927 
00928  
00929 
00930  
00931         print_name = dev ? dev->slot_name : "rtl8139";
00932 
00933         rc = pci_request_regions (dev, dev->name);   
00934 
00935 
00936         if (rc)
00937                 goto err_out;
00938 
00939 
00940         pci_set_master (dev); 
00941 
00942         /* ioremap MMIO region */
00943         ioaddr = ioremap (mmio_start, mmio_len);
00944         if (ioaddr == NULL) {
00945                 rtl_printf ("cannot remap MMIO, aborting\n");
00946                 rc = -EIO;
00947                 goto err_out;
00948         }
00949 
00950 
00951 
00952         /* Soft reset the chip. */
00953         RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
00954  
00955         /* Check that the chip has finished the reset. */
00956         for (i = 1000; i > 0; i--)
00957                 if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
00958                         break;
00959                 else
00960                         udelay (10);
00961  
00962         /* Bring the chip out of low-power mode. */
00963         if (rtl_8139_tp.chipset == CH_8139B) {
00964                 RTL_W8 (Config1, RTL_R8 (Config1) & ~(1<<4));
00965 
00966                 RTL_W8 (Config4, RTL_R8 (Config4) & ~(1<<2));
00967         } else {
00968                 /* handle RTL8139A and RTL8139 cases */
00969                 /* XXX from becker driver. is this right?? */
00970                 RTL_W8 (Config1, 0);
00971         }
00972 
00973         /* make sure chip thinks PIO and MMIO are enabled */
00974         tmp8 = RTL_R8 (Config1);
00975         if ((tmp8 & Cfg1_PIO) == 0) {
00976                 rtl_printf ("PIO not enabled, Cfg1=%02X, aborting\n", tmp8);
00977                 rc = -EIO;
00978                 goto err_out;
00979         }
00980         if ((tmp8 & Cfg1_MMIO) == 0) {
00981                 rtl_printf ("MMIO not enabled, Cfg1=%02X, aborting\n", tmp8);
00982                 rc = -EIO;
00983                 goto err_out;
00984         }
00985 
00986         /* identify chip attached to board */
00987         /*      tmp = RTL_R8 (ChipVersion);   */
00988         tmp = RTL_R32 (TxConfig);
00989         tmp = ( (tmp&0x7c000000) + ( (tmp&0x00800000)<<2 ) )>>24;
00990 
00991 
00992 
00993         rtl_8139_tp.drv_flags = board_info[0].hw_flags;
00994         rtl_8139_tp.pci_dev = dev;
00995         rtl_8139_tp.mmio_addr = ioaddr;
00996  
00997         for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--)
00998                 if (tmp == rtl_chip_info[i].version) {
00999                         rtl_8139_tp.chipset = i;
01000                 }
01001         if(rtl_8139_tp.chipset > (ARRAY_SIZE (rtl_chip_info) - 2))
01002                 rtl_8139_tp.chipset = ARRAY_SIZE (rtl_chip_info) - 2;
01003  
01004 
01005         /* Find the connected MII xcvrs.
01006         Doing this in open() would allow detecting external xcvrs later, but takes too much time. */
01007 
01008         if (rtl_8139_tp.drv_flags & HAS_MII_XCVR) {
01009                 int phy, phy_idx = 0;
01010                 for (phy = 0; phy < 32 && phy_idx < sizeof(rtl_8139_tp.phys); phy++) {
01011                         int mii_status = rt_rtl8139_mdio_read(dev, phy, 1);
01012                         if (mii_status != 0xffff  &&  mii_status != 0x0000) {
01013                                 rtl_8139_tp.phys[phy_idx++] = phy;
01014                                 rtl_8139_tp.advertising = rt_rtl8139_mdio_read(dev, phy, 4);
01015                                 rtl_printf( "%s: MII transceiver %d status 0x%4.4x "
01016                                         "advertising %4.4x.\n",
01017                                         dev->name, phy, mii_status, rtl_8139_tp.advertising);
01018                         }
01019                 }
01020                 if (phy_idx == 0) {
01021                         rtl_printf( "%s: No MII transceivers found!  Assuming SYM "
01022                                 "transceiver.\n",
01023                                 dev->name);
01024                         rtl_8139_tp.phys[0] = 32;
01025                 }
01026         } else
01027                 rtl_8139_tp.phys[0] = 32;
01028  
01029         /* Put the chip into low-power mode. */
01030         RTL_W8_F (Cfg9346, Cfg9346_Unlock);
01031  
01032         tmp = RTL_R8 (Config1) & Config1Clear;
01033         tmp |= (rtl_8139_tp.chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */
01034         RTL_W8_F (Config1, tmp);
01035  
01036         RTL_W8_F (HltClk, 'H'); /* 'R' would leave the clock running. */
01037  
01038         /* The lower four bits are the media type. */
01039         option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
01040         rtl_8139_tp.AutoNegoAbility = option&0xF;
01041  
01042         if (option > 0) {
01043                 rtl_8139_tp.full_duplex = (option & 0x210) ? 1 : 0;
01044                 rtl_8139_tp.default_port = option & 0xFF;
01045                 if (rtl_8139_tp.default_port)
01046                         rtl_8139_tp.medialock = 1;
01047         }
01048         if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)
01049                 rtl_8139_tp.full_duplex = full_duplex[board_idx];
01050         if (rtl_8139_tp.full_duplex) {
01051                 rtl_printf( "%s: Media type forced to Full Duplex.\n", dev->name);
01052                 /* Changing the MII-advertised media because might prevent  re-connection. */
01053                 rtl_8139_tp.duplex_lock = 1;
01054         }
01055  
01056         if (rtl_8139_tp.default_port) {
01057                 rtl_printf( "%s: Forcing %dMbs %s-duplex operation.\n", dev->name,
01058                         (option & 0x0C ? 100 : 10),
01059                         (option & 0x0A ? "full" : "half"));
01060                         rt_rtl8139_mdio_write(dev, rtl_8139_tp.phys[0], 0,
01061                         ((option & 0x20) ? 0x2000 : 0) |     /* 100mbps? */
01062                         ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
01063         }
01064 
01065         addr_len = rt_rtl8139_read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
01066         for (i = 0; i < 3; i++)
01067                 ((u16 *) (rtl_8139_tp.dev_addr))[i] =  le16_to_cpu (rt_rtl8139_read_eeprom (ioaddr, i + 7, addr_len));
01068 
01069         rtl_printf( "%s: %s at 0x%lx, "
01070                 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
01071                 "IRQ %d\n",
01072                 dev->name,
01073                 board_info[0].name,
01074                 rtl_8139_tp.mmio_addr,
01075                 rtl_8139_tp.dev_addr[0], rtl_8139_tp.dev_addr[1],
01076                 rtl_8139_tp.dev_addr[2], rtl_8139_tp.dev_addr[3],
01077                 rtl_8139_tp.dev_addr[4], rtl_8139_tp.dev_addr[5],
01078                 dev->irq);
01079 
01080         dev_rtl8139_open(dev);
01081 
01082         return 0;
01083 err_out:
01084                 rtl_printf ("EXIT, returning %d\n", rc);
01085                 return rc;
01086 }
01087 
01088 
01089 
01090 static void rt_rtl8139_tx_clear (struct rtl8139_private rtl_8139_tp)
01091 {
01092         int i;
01093  
01094         rtl_8139_tp.cur_tx = 0;
01095         rtl_8139_tp.dirty_tx = 0;
01096  
01097         /* Dump the unsent Tx packets. */
01098         for (i = 0; i < NUM_TX_DESC; i++) {
01099                 struct ring_info *rp = &rtl_8139_tp.tx_info[i];
01100                 if (rp->mapping != 0) {
01101                         pci_unmap_single (rtl_8139_tp.pci_dev, rp->mapping,
01102                                           rp->skb->len, PCI_DMA_TODEVICE);
01103                         rp->mapping = 0;
01104                 }
01105                 if (rp->skb) {
01106                         dev_kfree_skb (rp->skb);
01107                         rp->skb = NULL;
01108                         rtl_8139_tp.stats.tx_dropped++;
01109                 }
01110         }
01111 }
01112 
01113 
01114 
01115 static int rt_rtl8139_close (struct pci_dev *dev)
01116 {
01117         void *ioaddr = rtl_8139_tp.mmio_addr;
01118  
01119         rtl_printf ("%s: Shutting down ethercard, status was 0x%4.4x.\n", dev->name, RTL_R16 (IntrStatus));
01120  
01121         /* Stop the chip's Tx and Rx DMA processes. */
01122         RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear));
01123  
01124         /* Disable interrupts by clearing the interrupt mask. */
01125         RTL_W16 (IntrMask, 0x0000);
01126  
01127         /* Update the error counts. */
01128         rtl_8139_tp.stats.rx_missed_errors += RTL_R32 (RxMissed);
01129         RTL_W32 (RxMissed, 0);
01130  
01131         if(rtl_8139_tp.must_free_irq) { 
01132             rtl_free_irq (dev->irq);
01133             rtl_8139_tp.must_free_irq = 0;
01134         }
01135  
01136         rt_rtl8139_tx_clear(rtl_8139_tp);
01137         pci_free_consistent(rtl_8139_tp.pci_dev, RX_BUF_TOT_LEN,rtl_8139_tp.rx_ring, rtl_8139_tp.rx_ring_dma);
01138         pci_free_consistent(rtl_8139_tp.pci_dev, TX_BUF_TOT_LEN,rtl_8139_tp.tx_bufs, rtl_8139_tp.tx_bufs_dma);
01139         rtl_8139_tp.rx_ring = NULL;
01140         rtl_8139_tp.tx_bufs = NULL;
01141  
01142         /* Green! Put the chip in low-power mode. */
01143         RTL_W8 (Cfg9346, Cfg9346_Unlock);
01144         RTL_W8 (Config1, 0x03);
01145         RTL_W8 (HltClk, 'H');   /* 'R' would leave the clock running. */
01146  
01147         return 0;
01148 }
01149 
01150 
01151 static void  rt_rtl8139_remove_one (struct pci_dev *pdev)
01152 {
01153         long io_addr;
01154         io_addr = (long)rtl_8139_tp.mmio_addr;
01155  
01156         iounmap (rtl_8139_tp.mmio_addr);
01157 
01158         pci_release_regions (pdev);  
01159 }
01160 
01161 
01162 
01163 
01164 /***************************************************************************************/
01165 static ssize_t rt_rtl8139_read(struct rtl_file *filp, char *buf, size_t count, loff_t* ppos){
01166   sem_wait(&rtl8139_sem);
01167   return  rt_rtl8139_policy.extract_frame_of_buffer(&rt_rtl8139_rx_buffer,buf); 
01168 }
01169 
01170 
01171 /***************************************************************************************/
01172 static int rt_rtl8139_ioctl(struct rtl_file * filp, unsigned int request, unsigned long other){
01173 
01174 
01175         switch(request) {
01176         case 1:           /* set_ip_filter */
01177                 rt_rtl8139_set_ip_filter(other);
01178                 break;
01179         case 2:           /* obtain_mac_address */
01180                 rt_rtl8139_obtain_mac_address((unsigned char *)other);
01181                 break;
01182         }
01183         return 0;
01184 }
01185 
01186 /***************************************************************************************/
01187 static int rt_rtl8139_release (struct rtl_file *filp){
01188         rtl_irqstate_t state;
01189         rtl_no_interrupts(state);
01190         
01191         rtl_printf("rtl8139_close\n");
01192 
01193         rt_rtl8139_close(rtl8139dev);
01194 
01195         rtl_printf("rtl8139_remove_one\n");
01196 
01197         rt_rtl8139_remove_one (rtl8139dev);
01198 
01199         if(rt_rtl8139_opened == 0x01){
01200           sem_destroy(&rtl8139_sem);
01201           rtl_printf("Deallocating rx_buffer\n");
01202           rt_rtl8139_policy.dealloc_rx_buffer(&rt_rtl8139_rx_buffer);
01203         }
01204 
01205         rtl_printf("After deallocating rx_buffer\n");
01206 
01207         rt_rtl8139_opened = 0x00;
01208         rtl_restore_interrupts(state);
01209 
01210         return 0;
01211 }
01212 
01213 /***************************************************************************************/
01214 static ssize_t rt_rtl8139_write(struct rtl_file *filp, const char *buf, size_t count, loff_t* ppos)
01215 {
01216 
01217         ssize_t tmp;
01218         rtl_irqstate_t state;
01219  
01220         rtl_no_interrupts(state);
01221         tmp=rt_rtl8139_send_packet(buf,count);
01222         rtl_restore_interrupts(state);
01223  
01224         return tmp;
01225  
01226 }
01227 
01228 /***************************************************************************************/
01229 static int rt_rtl8139_open (struct rtl_file *filp){
01230 
01231 
01232         if(rt_rtl8139_opened == 0x00){
01233                 if((rtl8139dev = init_rtl8139_device())!=NULL){
01234                   sem_init(&rtl8139_sem, 0, 0);
01235 
01236                   start_up_rtl8139_device(rtl8139dev);
01237                   rt_rtl8139_opened = 0x01;
01238                   rtl_printf("Successfully Opened\n");
01239                   return RTL8139_MAJOR;
01240                 }else{
01241                         rtl_printf("ERROR: Couldn't initialize device\n");
01242                         return -1;
01243                 }
01244         }else{
01245                 rtl_printf("Device is already opened\n");
01246                 return -1;
01247         }
01248 }
01249 
01250 /***************************************************************************************/
01251 struct pci_dev *init_rtl8139_device(void){
01252         struct pci_dev *dev;
01253  
01254         /* First of all, we must get a pointer to the pci_dev structure */
01255         if((dev = rt_pci_find_device(RTL8139_VENDOR_ID, RTL8139_DEVICE_ID, NULL))== NULL)
01256         return NULL;
01257  
01258         rt_rtl8139_policy.initialize_rx_buffer(&rt_rtl8139_rx_buffer);
01259  
01260         /* Let's enable the device */
01261         if (rt_pci_enable_device(dev)){
01262                 rtl_printf("PCI ERROR: Can't enable device\n");
01263                 return NULL;
01264         }
01265  
01266         return dev;
01267 }
01268 
01269 
01270 
01271 /***************************************************************************************/
01272 int init_module(void){
01273         printk("\n\n\nRT-Linux driver for the Ethernet Card rtl8139 being loaded\n\n\n");
01274  
01275         if (rtl_register_rtldev (RTL8139_MAJOR, RTL8139_NAME, &rt_rtl8139_fops)) {
01276                 printk ("RTLinux /dev/%s: unable to get RTLinux major %d\n", RTL8139_NAME, RTL8139_MAJOR);
01277                 return -EIO;
01278         }else{
01279                 printk("Registered device /dev/%s major number %d\n",RTL8139_NAME, RTL8139_MAJOR);
01280                 rt_rtl8139_registered = 0x01;
01281                 return 0;
01282         }
01283 }
01284 
01285 
01286 /***************************************************************************************/
01287 void cleanup_module(void){
01288 
01289         int inside = 1;
01290         rtl_irqstate_t state;
01291  
01292         if((rt_rtl8139_opened == 0x01) || rt_rtl8139_inside_the_interrupt_handler){
01293 
01294           rt_rtl8139_trying_to_close = 1;
01295  
01296           /* Since inside the interrupt handler there's a call to the scheduler, there may  */
01297           /* be an execution of the interrupt handler that hasn't been completely executed. */
01298           /* The card cannot be released in that case, so we must be sure that there is no  */
01299           /* interrupt handler execution pending. Otherwise, that may crash the system.     */
01300           while(inside){
01301             rtl_no_interrupts(state);
01302  
01303             if(rt_rtl8139_inside_the_interrupt_handler){
01304               rtl_restore_interrupts(state);
01305               usleep(10);
01306             }else{
01307               rtl_hard_disable_irq(rtl_8139_tp.pci_dev->irq);
01308               rtl_restore_interrupts(state);
01309               inside = 0;
01310             }
01311           }
01312         }
01313 
01314         if(rt_rtl8139_registered == 0x01){
01315                 printk("Unregistering device /dev/%s\n",RTL8139_NAME);
01316                 rtl_unregister_rtldev(RTL8139_MAJOR,RTL8139_NAME);
01317         }
01318         printk("\n\n\nRT-Linux driver for the Ethernet Card rtl8139 being removed\n\n\n");
01319 }
01320 
01321 

Generated on Wed Jan 14 12:58:57 2004 for RTL-lwIP-0.4 by doxygen 1.3.4