#include "rtl_3c905cx_drv.h"#include "rt_pci.h"#include "netif/net_policy/FIFO_policy.h"Include dependency graph for rtl_3c905cx_drv.c:
Go to the source code of this file.
Defines | |
| #define | COM3_905C_MAJOR 204 |
| #define | COM3_905C_NAME "eth" |
| #define | COM3_SIGNAL RTL_SIGUSR2 |
| #define | rtl_3COM905C_mdio_delay() inl(mdio_addr) |
| #define | MDIO_SHIFT_CLK 0x01 |
| #define | MDIO_DIR_WRITE 0x04 |
| #define | MDIO_DATA_WRITE0 (0x00 | MDIO_DIR_WRITE) |
| #define | MDIO_DATA_WRITE1 (0x02 | MDIO_DIR_WRITE) |
| #define | MDIO_DATA_READ 0x02 |
| #define | MDIO_ENB_IN 0x00 |
Functions | |
| MODULE_LICENSE ("GPL") | |
| int | rt_3c905c_set_ip_filter (unsigned long ipaddr) |
| int | rt_3c905c_obtain_mac_address (unsigned char *mac) |
| ssize_t | rtl_3COM905C_read (struct rtl_file *filp, char *buf, size_t count, loff_t *ppos) |
| int | rtl_3COM905C_ioctl (struct rtl_file *filp, unsigned int request, unsigned long other) |
| int | rtl_3COM905C_release (struct rtl_file *filp) |
| ssize_t | rtl_3COM905C_write (struct rtl_file *filp, const char *buf, size_t count, loff_t *ppos) |
| int | rtl_3COM905C_open (struct rtl_file *filp) |
| pci_dev * | rtl_3COM905C_init_device (void) |
| int | init_module (void) |
| void | cleanup_module (void) |
| unsigned int | boomerang_interrupt (unsigned int irq, struct pt_regs *regs) |
| int | boomerang_rx (struct pci_dev *dev) |
| int | rtl_3COM905C_start_up_device (struct pci_dev *dev) |
| void | rtl_3COM905C_acpi_set_WOL (void) |
| int | vortex_open (struct pci_dev *dev) |
| void | vortex_up (struct pci_dev *dev) |
| void | rtl_3COM905C_issue_and_wait (int cmd) |
| void | rtl_3COM905C_set_rx_mode (void) |
| void | vortex_down (struct pci_dev *dev) |
| int | vortex_close (struct pci_dev *dev) |
| void | vortex_error (struct pci_dev *dev, int status) |
| void | vortex_remove_one (struct pci_dev *pdev) |
| int | rt_3c905c_send_packet (const char *buffer, size_t size) |
| void | rtl_3COM905C_mdio_sync (long ioaddr, int bits) |
| int | rtl_3COM905C_mdio_read (int phy_id, int location) |
| void | rtl_3COM905C_mdio_write (int phy_id, int location, int value) |
Variables | |
| net_policy_operations | rt_3c905x_policy |
| fifo_rx_buffer_t | rt_3c905x_rx_buffer |
| sem_t | rt_3c905x_sem |
| int | rt_3c905c_inside_the_interrupt_handler = 0 rt_3c905c_trying_to_close = 0 |
| int | rt_3c905c_interrupted = 0 rt_3c905c_writting = 0 |
| rtl_file_operations | rtl_3COM905C_fops |
| pci_dev * | rt_3c905c_dev |
| vortex_private | rt_3c905c_vp |
| unsigned char | rt_3c905c_registered = 0x00 rt_3c905c_opened = 0x00 |
| unsigned char | rt_3c905c_ip_addr [2][4] = {{0x00,0x00,0x00,0x00},{0x00,0x00,0x00,0x00}} |
| int | rt_3c905c_n_filters = 0 |
|
|
Definition at line 248 of file rtl_3c905cx_drv.c. Referenced by cleanup_module(), init_module(), and rtl_3COM905C_open(). |
|
|
Definition at line 249 of file rtl_3c905cx_drv.c. |
|
|
Definition at line 250 of file rtl_3c905cx_drv.c. |
|
|
Definition at line 1386 of file rtl_3c905cx_drv.c. Referenced by rtl_3COM905C_mdio_read(). |
|
|
Definition at line 1384 of file rtl_3c905cx_drv.c. Referenced by rtl_3COM905C_mdio_read(), and rtl_3COM905C_mdio_write(). |
|
|
Definition at line 1385 of file rtl_3c905cx_drv.c. Referenced by rtl_3COM905C_mdio_read(), rtl_3COM905C_mdio_sync(), and rtl_3COM905C_mdio_write(). |
|
|
Definition at line 1383 of file rtl_3c905cx_drv.c. |
|
|
Definition at line 1387 of file rtl_3c905cx_drv.c. Referenced by rtl_3COM905C_mdio_read(), and rtl_3COM905C_mdio_write(). |
|
|
Definition at line 1382 of file rtl_3c905cx_drv.c. Referenced by rtl_3COM905C_mdio_read(), rtl_3COM905C_mdio_sync(), and rtl_3COM905C_mdio_write(). |
|
|
Definition at line 1380 of file rtl_3c905cx_drv.c. Referenced by rtl_3COM905C_mdio_read(), rtl_3COM905C_mdio_sync(), and rtl_3COM905C_mdio_write(). |
|
||||||||||||
|
Definition at line 477 of file rtl_3c905cx_drv.c. References AckIntr, boomerang_rx(), vortex_private::cb_fn_base, vortex_private::cur_rx, DownComplete, EL3_CMD, EL3_STATUS, HostError, IntLatch, IntReq, vortex_private::ioaddr, vortex_private::pdev, rt_3c905c_dev, rt_3c905c_inside_the_interrupt_handler, rt_3c905c_interrupted, rt_3c905c_vp, rtl_3COM905C_issue_and_wait(), vortex_private::rx_packets, vortex_private::rx_ring, RX_RING_SIZE, RxEarly, StatsFull, status, UpComplete, UpStall, UpUnstall, and vortex_error(). Referenced by vortex_open().
00477 {
00478 long ioaddr = rt_3c905c_vp.ioaddr;
00479 int status = inw(ioaddr + EL3_STATUS);
00480 int work_done = max_interrupt_work;
00481 struct pci_dev *dev = rt_3c905c_dev;
00482
00483 rt_3c905c_inside_the_interrupt_handler = 1;
00484 rt_3c905c_interrupted++;
00485 if(rt_3c905c_writting & rt_3c905c_interrupted)
00486 rtl_printf("I've been interrupted %d times\n",rt_3c905c_interrupted);
00487
00488 if (status & UpComplete) {
00489 rt_3c905c_vp.rx_packets++;
00490 rtl_3COM905C_issue_and_wait(UpStall);
00491 while(rt_3c905c_vp.rx_ring[rt_3c905c_vp.cur_rx % RX_RING_SIZE].status & 0x00008000){
00492 boomerang_rx(dev);
00493 outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
00494 if (--work_done < 0)
00495 break;
00496 }
00497 outw(UpUnstall, ioaddr + EL3_CMD);
00498 }
00499
00500 if (status & DownComplete){
00501 rtl_printf("Se acaba de enviar el paquete\n");
00502 outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
00503 }
00504
00505 /* Check for all uncommon interrupts at once. */
00506 if (status & (HostError | RxEarly | StatsFull | IntReq)){
00507 rtl_printf("VORTEX_ERROR\n");
00508 vortex_error(dev, status);
00509 }
00510
00511 /* Acknowledge the IRQ. */
00512 outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
00513 if (rt_3c905c_vp.cb_fn_base){
00514 writel(0x8000, rt_3c905c_vp.cb_fn_base + 4);
00515 }
00516
00517 /* We must be sure that we're out of the interrupt handler before cleanup_modules */
00518 /* is executed. If cleanup_modules is being executed, we don't have to enable the */
00519 /* irq. If enabled, then the system could crash. */
00520 if(!rt_3c905c_trying_to_close)
00521 rtl_hard_enable_irq(rt_3c905c_vp.pdev->irq);
00522
00523 rt_3c905c_interrupted--;
00524
00525 return (rt_3c905c_inside_the_interrupt_handler = 0);
00526 }
|
Here is the call graph for this function:
|
|
Definition at line 532 of file rtl_3c905cx_drv.c. References net_policy_operations::add_frame_to_buffer, buffer, vortex_private::cur_rx, vortex_private::dev_addr, vortex_private::dirty_rx, rt_3c905c_ip_addr, rt_3c905c_n_filters, rt_3c905c_vp, rt_3c905x_policy, rt_3c905x_rx_buffer, rt_3c905x_sem, vortex_private::rx_frames_for_us, vortex_private::rx_ring, RX_RING_SIZE, vortex_private::rx_skbuff, RxDComplete, RxDError, vortex_private::stats, and boom_rx_desc::status.
00533 {
00534 int entry = rt_3c905c_vp.cur_rx % RX_RING_SIZE;
00535 int rx_status;
00536 int rx_work_limit = rt_3c905c_vp.dirty_rx + RX_RING_SIZE - rt_3c905c_vp.cur_rx;
00537 int i,j;
00538 unsigned char *buffer;
00539 int temp = rt_3c905c_vp.rx_ring[entry].status & 0x1fff;
00540 unsigned char mine = 0x01, multicast_packet= 0x01, arp_request_for_me = 0x01 ;
00541
00542 buffer =rt_3c905c_vp.rx_skbuff[entry];
00543
00544 /* A NIC receives all the packets in the LAN so we will receive an interrupt for each one of those. */
00545 /* As we only want those packets sent to us we must filter them. So, we will only receive packets */
00546 /* directly sent us (i.e. destination address is ours) and those ARP frames which ask for our MAC. */
00547 /* An ARP improvement consist on receive all ARP request packets in the LAN, so, at least, we could */
00548 /* know the pair IP and MAC address of those computers performing the request. As most of the */
00549 /* frames in a LAN are ARP request frames the overhead produced by receiving all of them would be */
00550 /* considerable, so we won't bother with this improvement. */
00551
00552 //Is this frame for us??
00553 for(i=0; i<6; i++){
00554 if(buffer[i] == rt_3c905c_vp.dev_addr[i])
00555 continue;
00556 else{
00557 mine = 0x00;
00558 break;
00559 }
00560 }
00561
00562 if(mine == 0x01) goto accept_frame;
00563
00564 // Is an ARP frame???
00565 if((buffer[12]==0x08) && (buffer[13]==0x06)){
00566 // It asks for my IP??
00567 for(j=0; j<rt_3c905c_n_filters; j++){
00568 for(i=0; i<4;i++){
00569 if(buffer[38+i]==rt_3c905c_ip_addr[j][i])
00570 continue;
00571 else{
00572 arp_request_for_me = 0x00;
00573 break;
00574 }
00575 }
00576 }
00577 }else
00578 arp_request_for_me = 0x00;
00579
00580 // Is it a multicast frame??
00581 for(i=0; i<6; i++){
00582 if(buffer[i] == 0xff)
00583 continue;
00584 else{
00585 multicast_packet = 0x00;
00586 break;
00587 }
00588 }
00589
00590 accept_frame:
00591
00592 if((mine == 0x01) || ((multicast_packet==0x01) && (arp_request_for_me==0x01))){
00593 rt_3c905c_vp.rx_frames_for_us++;
00594
00595 if(rt_3c905x_policy.add_frame_to_buffer((void *) &rt_3c905x_rx_buffer,buffer,temp)== 0){
00596 sem_post(&rt_3c905x_sem);
00597
00598 rtl_schedule();
00599 }
00600 }
00601
00602 while ((rx_status = le32_to_cpu(rt_3c905c_vp.rx_ring[entry].status)) & RxDComplete){
00603
00604 if (--rx_work_limit < 0)
00605 break;
00606 if (!(rx_status & RxDError)) /* Error, update stats. */
00607 rt_3c905c_vp.stats.rx_packets++;
00608 }
00609
00610 entry = (++rt_3c905c_vp.cur_rx) % RX_RING_SIZE;
00611
00612 /* Refill the Rx ring buffers. */
00613 for (; rt_3c905c_vp.cur_rx - rt_3c905c_vp.dirty_rx > 0; rt_3c905c_vp.dirty_rx++) {
00614 entry = rt_3c905c_vp.dirty_rx % RX_RING_SIZE;
00615 rt_3c905c_vp.rx_ring[entry].status = 0; /* Clear complete bit. */
00616 }
00617 return 0;
00618 }
|
|
|
Definition at line 434 of file rtl_3c905cx_drv.c. References COM3_905C_MAJOR, COM3_905C_NAME, DownStall, vortex_private::pdev, rt_3c905c_inside_the_interrupt_handler, rt_3c905c_registered, rt_3c905c_vp, rtl_3COM905C_issue_and_wait(), and UpStall.
00434 {
00435 int inside = 1;
00436 rtl_irqstate_t state;
00437
00438 if((rt_3c905c_opened == 0x01) || rt_3c905c_inside_the_interrupt_handler){
00439
00440 rt_3c905c_trying_to_close = 1;
00441
00442 /* Since inside the interrupt handler there's a call to the scheduler, there may */
00443 /* be an execution of the interrupt handler that hasn't been completely executed. */
00444 /* The card cannot be released in that case, so we must be sure that there is no */
00445 /* interrupt handler execution pending. Otherwise, that may crash the system. */
00446 while(inside){
00447 rtl_no_interrupts(state);
00448
00449 if(rt_3c905c_inside_the_interrupt_handler){
00450 rtl_restore_interrupts(state);
00451 usleep(10);
00452 }else{
00453 rtl_hard_disable_irq(rt_3c905c_vp.pdev->irq);
00454 rtl_restore_interrupts(state);
00455 inside = 0;
00456 }
00457 }
00458
00459 rtl_3COM905C_issue_and_wait(UpStall);
00460 rtl_3COM905C_issue_and_wait(DownStall);
00461 }
00462
00463 if(rt_3c905c_registered == 0x01){
00464 printk("Unregistering device /dev/%s\n",COM3_905C_NAME);
00465 rtl_unregister_rtldev(COM3_905C_MAJOR,COM3_905C_NAME);
00466 }
00467
00468 printk("\n\n\nRT-Linux driver for the Ethernet Card 3Com905c-x being removed\n\n\n");
00469 }
|
Here is the call graph for this function:
|
|
Definition at line 416 of file rtl_3c905cx_drv.c. References COM3_905C_MAJOR, COM3_905C_NAME, rt_3c905c_registered, and rtl_3COM905C_fops.
00416 {
00417 printk("\n\n\nRT-Linux driver for the Ethernet Card 3Com905c-x being loaded\n\n\n");
00418
00419 if (rtl_register_rtldev (COM3_905C_MAJOR, COM3_905C_NAME, &rtl_3COM905C_fops)) {
00420 printk ("RTLinux /dev/%s: unable to get RTLinux major %d\n", COM3_905C_NAME, COM3_905C_MAJOR);
00421 return -EIO;
00422 }else{
00423 printk("Registered device 3Com905C-X: /dev/%s major number %d\n",COM3_905C_NAME, COM3_905C_MAJOR);
00424 rt_3c905c_registered = 0x01;
00425 return 0;
00426 }
00427 }
|
|
|
|
|
|
Definition at line 293 of file rtl_3c905cx_drv.c. References vortex_private::dev_addr, and rt_3c905c_vp. Referenced by rtl_3COM905C_ioctl().
00293 {
00294 int i;
00295 for(i=0; i<6; i++)
00296 mac[i]=rt_3c905c_vp.dev_addr[i];
00297 return 0;
00298 }
|
|
||||||||||||
|
Definition at line 1329 of file rtl_3c905cx_drv.c. References buffer, vortex_private::cur_tx, DownListPtr, DownStall, DownUnstall, EL3_CMD, vortex_private::ioaddr, LAST_FRAG, boom_tx_desc::next, vortex_private::queued_packet, rt_3c905c_vp, rtl_3COM905C_issue_and_wait(), vortex_private::tx_ring, vortex_private::tx_ring_dma, TX_RING_SIZE, and vortex_private::tx_skbuff.
01330 {
01331 long ioaddr = rt_3c905c_vp.ioaddr;
01332 unsigned char *buff;
01333 int entry = rt_3c905c_vp.cur_tx % TX_RING_SIZE;
01334 int previous = (rt_3c905c_vp.cur_tx + TX_RING_SIZE - 1) % TX_RING_SIZE;
01335 struct boom_tx_desc *actual = &rt_3c905c_vp.tx_ring[entry];
01336
01337 rt_3c905c_writting = 1;
01338
01339 /* Wait for the stall to complete. */
01340 rtl_3COM905C_issue_and_wait(DownStall);
01341
01342 buff = rt_3c905c_vp.tx_skbuff[entry];
01343
01344 if(buff)
01345 memcpy(buff, buffer, size);
01346
01347 actual->length = cpu_to_le32(size | LAST_FRAG);
01348
01349 if (inl(ioaddr + DownListPtr) == 0) {
01350 outl(rt_3c905c_vp.tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
01351 {
01352 int tmp = previous;
01353
01354 while((rt_3c905c_vp.tx_ring[tmp].next != 0) && (tmp != entry)){
01355 rt_3c905c_vp.tx_ring[tmp].next = 0;
01356 tmp = (tmp + TX_RING_SIZE - 1) % TX_RING_SIZE;
01357 }
01358 }
01359 rt_3c905c_vp.queued_packet++;
01360 }else
01361 rt_3c905c_vp.tx_ring[previous].next = cpu_to_le32(rt_3c905c_vp.tx_ring_dma + sizeof(struct boom_tx_desc) * entry);
01362
01363 outw(DownUnstall, ioaddr + EL3_CMD);
01364
01365 rt_3c905c_vp.cur_tx++;
01366
01367 rt_3c905c_writting = 0;
01368
01369 return size;
01370 }
|
Here is the call graph for this function:
|
|
Definition at line 275 of file rtl_3c905cx_drv.c. References ipaddr, rt_3c905c_ip_addr, and rt_3c905c_n_filters. Referenced by rtl_3COM905C_ioctl().
00275 {
00276 if(rt_3c905c_n_filters<=1){
00277 rt_3c905c_ip_addr[rt_3c905c_n_filters][0]=ipaddr & 0x000000ff;
00278 rt_3c905c_ip_addr[rt_3c905c_n_filters][1]= (ipaddr >> 8) & 0x000000ff;
00279 rt_3c905c_ip_addr[rt_3c905c_n_filters][2]= (ipaddr >> 16) & 0x000000ff;
00280 rt_3c905c_ip_addr[rt_3c905c_n_filters][3]= (ipaddr >> 24) & 0x000000ff;
00281 rt_3c905c_n_filters++;
00282 return 0;
00283 }
00284
00285 rtl_printf("You cannot set more than 2 IP filters !!");
00286 return -1;
00287 }
|
|
|
Definition at line 865 of file rtl_3c905cx_drv.c. References EL3_CMD, EL3WINDOW, vortex_private::ioaddr, vortex_private::pdev, rt_3c905c_vp, rt_pci_enable_wake(), rt_pci_set_power_state(), RxBroadcast, RxEnable, RxStation, and SetRxFilter. Referenced by rtl_3COM905C_start_up_device(), and vortex_down().
00866 {
00867 long ioaddr = rt_3c905c_vp.ioaddr;
00868
00869 /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
00870 EL3WINDOW(7);
00871 outw(2, ioaddr + 0x0c);
00872 /* The RxFilter must accept the WOL frames. */
00873 outw(SetRxFilter|RxStation|RxBroadcast, ioaddr + EL3_CMD); //RxMulticast
00874 outw(RxEnable, ioaddr + EL3_CMD);
00875
00876 /* Change the power state to D3; RxEnable doesn't take effect. */
00877 rt_pci_enable_wake(rt_3c905c_vp.pdev, 0, 1);
00878 rt_pci_set_power_state(rt_3c905c_vp.pdev, 3);
00879 }
|
Here is the call graph for this function:
|
|
Definition at line 393 of file rtl_3c905cx_drv.c. References COM3_DEVICE_ID, COM3_VENDOR_ID, net_policy_operations::initialize_rx_buffer, NULL, rt_3c905x_policy, rt_3c905x_rx_buffer, rt_pci_enable_device(), and rt_pci_find_device(). Referenced by rtl_3COM905C_open().
00393 {
00394 struct pci_dev *dev;
00395
00396 /* First of all, we must get a pointer to the pci_dev structure */
00397 if((dev = rt_pci_find_device(COM3_VENDOR_ID, COM3_DEVICE_ID, NULL))== NULL)
00398 return NULL;
00399
00400 rt_3c905x_policy.initialize_rx_buffer(&rt_3c905x_rx_buffer);
00401
00402 /* Let's enable the device */
00403 if (rt_pci_enable_device(dev)){
00404 rtl_printf("PCI ERROR: Can't enable device 3Com905C-X\n");
00405 return NULL;
00406 }
00407
00408 return dev;
00409 }
|
Here is the call graph for this function:
|
||||||||||||||||
|
Definition at line 313 of file rtl_3c905cx_drv.c. References rt_3c905c_obtain_mac_address(), and rt_3c905c_set_ip_filter().
00313 {
00314
00315 switch(request) {
00316 case 1: /* set_ip_filter */
00317 rt_3c905c_set_ip_filter(other);
00318 break;
00319 case 2: /* obtain_mac_address */
00320 rt_3c905c_obtain_mac_address((unsigned char *)other);
00321 break;
00322 }
00323 return 0;
00324 }
|
Here is the call graph for this function:
|
|
Definition at line 1126 of file rtl_3c905cx_drv.c. References CmdInProgress, EL3_CMD, EL3_STATUS, vortex_private::ioaddr, and rt_3c905c_vp.
01127 {
01128 int i;
01129
01130 outw(cmd, rt_3c905c_vp.ioaddr + EL3_CMD);
01131 for (i = 0; i < 2000; i++) {
01132 if (!(inw(rt_3c905c_vp.ioaddr + EL3_STATUS) & CmdInProgress))
01133 return;
01134 }
01135
01136 /* OK, that didn't work. Do it the slow way. One second */
01137 for (i = 0; i < 100000; i++) {
01138 if (!(inw(rt_3c905c_vp.ioaddr + EL3_STATUS) & CmdInProgress)) {
01139 return;
01140 }
01141 usleep(10);
01142 }
01143 printk(KERN_ERR ": command 0x%04x did not complete! Status=0x%x\n",
01144 cmd, inw(rt_3c905c_vp.ioaddr + EL3_STATUS));
01145 }
|
|
||||||||||||
|
Definition at line 1407 of file rtl_3c905cx_drv.c. References vortex_private::ioaddr, MDIO_DATA_READ, MDIO_DATA_WRITE0, MDIO_DATA_WRITE1, MDIO_ENB_IN, MDIO_SHIFT_CLK, rt_3c905c_vp, rtl_3COM905C_mdio_delay, rtl_3COM905C_mdio_sync(), and Wn4_PhysicalMgmt.
01408 {
01409 int i;
01410 long ioaddr = rt_3c905c_vp.ioaddr;
01411 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
01412 unsigned int retval = 0;
01413 long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
01414
01415 if (mii_preamble_required)
01416 rtl_3COM905C_mdio_sync(ioaddr, 32);
01417
01418 /* Shift the read command bits out. */
01419 for (i = 14; i >= 0; i--) {
01420 int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
01421 outw(dataval, mdio_addr);
01422 rtl_3COM905C_mdio_delay();
01423 outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
01424 rtl_3COM905C_mdio_delay();
01425 }
01426 /* Read the two transition, 16 data, and wire-idle bits. */
01427 for (i = 19; i > 0; i--) {
01428 outw(MDIO_ENB_IN, mdio_addr);
01429 rtl_3COM905C_mdio_delay();
01430 retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
01431 outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
01432 rtl_3COM905C_mdio_delay();
01433 }
01434
01435 return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
01436 }
|
Here is the call graph for this function:
|
||||||||||||
|
Definition at line 1393 of file rtl_3c905cx_drv.c. References MDIO_DATA_WRITE1, MDIO_SHIFT_CLK, rtl_3COM905C_mdio_delay, and Wn4_PhysicalMgmt.
01394 {
01395 long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
01396
01397 /* Establish sync by sending at least 32 logic ones. */
01398 while (-- bits >= 0) {
01399 outw(MDIO_DATA_WRITE1, mdio_addr);
01400 rtl_3COM905C_mdio_delay();
01401 outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
01402 rtl_3COM905C_mdio_delay();
01403 }
01404 }
|
|
||||||||||||||||
|
Definition at line 1439 of file rtl_3c905cx_drv.c. References vortex_private::ioaddr, MDIO_DATA_WRITE0, MDIO_DATA_WRITE1, MDIO_ENB_IN, MDIO_SHIFT_CLK, rt_3c905c_vp, rtl_3COM905C_mdio_delay, rtl_3COM905C_mdio_sync(), and Wn4_PhysicalMgmt.
01440 {
01441 long ioaddr = rt_3c905c_vp.ioaddr;
01442 int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
01443 long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
01444 int i;
01445
01446 if (mii_preamble_required)
01447 rtl_3COM905C_mdio_sync(ioaddr, 32);
01448
01449 /* Shift the command bits out. */
01450 for (i = 31; i >= 0; i--) {
01451 int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
01452 outw(dataval, mdio_addr);
01453 rtl_3COM905C_mdio_delay();
01454 outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
01455 rtl_3COM905C_mdio_delay();
01456 }
01457 /* Leave the interface idle. */
01458 for (i = 1; i >= 0; i--) {
01459 outw(MDIO_ENB_IN, mdio_addr);
01460 rtl_3COM905C_mdio_delay();
01461 outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
01462 rtl_3COM905C_mdio_delay();
01463 }
01464 return;
01465 }
|
Here is the call graph for this function:
|
|
Definition at line 368 of file rtl_3c905cx_drv.c. References COM3_905C_MAJOR, NULL, rt_3c905c_dev, rt_3c905x_sem, rtl_3COM905C_init_device(), rtl_3COM905C_release(), and rtl_3COM905C_start_up_device().
00368 {
00369
00370 rtl_3COM905C_release (filp);
00371
00372 if(rt_3c905c_opened == 0x00){
00373 if((rt_3c905c_dev = rtl_3COM905C_init_device())!=NULL){
00374
00375 sem_init(&rt_3c905x_sem, 0, 0);
00376
00377 rtl_3COM905C_start_up_device(rt_3c905c_dev);
00378 rt_3c905c_opened = 0x01;
00379 return COM3_905C_MAJOR;
00380 }else{
00381 rtl_printf("ERROR: Couldn't initialize device 3Com905C-X\n");
00382 return -1;
00383 }
00384 }else{
00385 rtl_printf("Device 3Com905C-X is already opened\n");
00386 return -1;
00387 }
00388 }
|
Here is the call graph for this function:
|
||||||||||||||||||||
|
Definition at line 305 of file rtl_3c905cx_drv.c. References net_policy_operations::extract_frame_of_buffer, rt_3c905x_policy, rt_3c905x_rx_buffer, and rt_3c905x_sem.
00305 {
00306 sem_wait(&rt_3c905x_sem);
00307 return rt_3c905x_policy.extract_frame_of_buffer(&rt_3c905x_rx_buffer, buf);
00308 }
|
|
|
Definition at line 329 of file rtl_3c905cx_drv.c. References net_policy_operations::dealloc_rx_buffer, rt_3c905c_dev, rt_3c905x_policy, rt_3c905x_rx_buffer, rt_3c905x_sem, vortex_close(), and vortex_remove_one().
00329 {
00330
00331 rtl_irqstate_t state;
00332 rtl_no_interrupts(state);
00333
00334 vortex_close(rt_3c905c_dev);
00335
00336 vortex_remove_one(rt_3c905c_dev);
00337
00338 if(rt_3c905c_opened == 0x01){
00339 sem_destroy(&rt_3c905x_sem);
00340 rt_3c905x_policy.dealloc_rx_buffer(&rt_3c905x_rx_buffer);
00341 }
00342
00343 rt_3c905c_opened = 0x00;
00344 rtl_restore_interrupts(state);
00345 return 0;
00346 }
|
Here is the call graph for this function:
|
|
Definition at line 1153 of file rtl_3c905cx_drv.c. References EL3_CMD, vortex_private::ioaddr, rt_3c905c_vp, RxBroadcast, RxStation, and SetRxFilter. Referenced by vortex_error(), and vortex_up().
01154 {
01155 long ioaddr = rt_3c905c_vp.ioaddr;
01156 int new_mode;
01157
01158 new_mode = SetRxFilter|RxStation|RxBroadcast;//RxMulticast|RxBroadcast;
01159
01160 outw(new_mode, ioaddr + EL3_CMD);
01161 }
|
|
|
Definition at line 624 of file rtl_3c905cx_drv.c. References vortex_private::advertising, vortex_private::autoselect, AUTOSELECT, vortex_private::available_media, vortex_private::bus_master, vortex_private::capabilities, CapBusMaster, vortex_private::card_idx, vortex_private::cb_fn_base, vortex_private::default_media, vortex_private::dev_addr, vortex_private::drv_flags, EEPROM_8BIT, EEPROM_OFFSET, EEPROM_Read, EL3WINDOW, vortex_private::enable_wol, vortex_private::full_bus_master_rx, vortex_private::full_bus_master_tx, vortex_private::full_duplex, HAS_CB_FNS, vortex_private::has_nway, HAS_NWAY, htons, vortex_private::if_port, vortex_private::info1, vortex_private::info2, INVERT_LED_PWR, INVERT_MII_PWR, vortex_private::io_size, vortex_private::ioaddr, IS_TORNADO, vortex_private::media_override, vortex_private::mtu, vortex_private::must_free_region, NULL, PCI_USES_MASTER, vortex_private::pdev, vortex_private::phys, vortex_private::pm_state_valid, vortex_private::power_state, rt_3c905c_vp, rt_pci_resource_start, rt_pci_save_state(), rtl_3COM905C_acpi_set_WOL(), rtl_3COM905C_mdio_read(), rtl_3COM905C_mdio_write(), vortex_private::rx_ring, vortex_private::rx_ring_dma, RX_RING_SIZE, vortex_private::tx_ring, vortex_private::tx_ring_dma, TX_RING_SIZE, vortex_open(), Wn0EepromCmd, Wn0EepromData, Wn2_ResetOptions, Wn3_Config, Wn3_Options, Wn4_NetDiag, XCVR, XCVR_MII, and XCVR_NWAY. Referenced by rtl_3COM905C_open().
00624 {
00625 struct vortex_chip_info * const vci = &vortex_info;
00626 unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */
00627 char *print_name;
00628 int retval;
00629 long ioaddr;
00630 int i,step;
00631
00632 print_name = dev ? dev->slot_name : "3c59x";
00633
00634 ioaddr = rt_pci_resource_start(dev, 0);
00635
00636 rt_3c905c_vp.drv_flags = vci->drv_flags;
00637 rt_3c905c_vp.has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
00638 rt_3c905c_vp.io_size = vci->io_size;
00639 rt_3c905c_vp.card_idx = 0;
00640 rt_3c905c_vp.ioaddr = ioaddr;
00641 rt_3c905c_vp.media_override = 7;
00642 rt_3c905c_vp.mtu = mtu;
00643
00644 print_name = dev ? dev->slot_name : "3c59x";
00645
00646 /* PCI-only startup logic */
00647 if (dev) {
00648 if (request_region(ioaddr, vci->io_size, print_name) != NULL){
00649 rt_3c905c_vp.must_free_region = 1;
00650 }
00651
00652 /* enable bus-mastering if necessary */
00653 if (vci->flags & PCI_USES_MASTER)
00654 pci_set_master (dev);
00655
00656 rt_3c905c_vp.pdev = dev;
00657
00658 /* Makes sure rings are at least 16 byte aligned. */
00659 rt_3c905c_vp.rx_ring = pci_alloc_consistent(dev, sizeof(struct boom_rx_desc) * RX_RING_SIZE, &rt_3c905c_vp.rx_ring_dma);
00660 rt_3c905c_vp.tx_ring = pci_alloc_consistent(dev, sizeof(struct boom_tx_desc) * TX_RING_SIZE, &rt_3c905c_vp.tx_ring_dma);
00661
00662 retval = -ENOMEM;
00663 if ((rt_3c905c_vp.rx_ring == 0) || (rt_3c905c_vp.tx_ring == 0))
00664 goto free_region;
00665
00666 EL3WINDOW(0);
00667 {
00668 int base;
00669
00670 if (vci->drv_flags & EEPROM_8BIT)
00671 base = 0x230;
00672 else if (vci->drv_flags & EEPROM_OFFSET)
00673 base = EEPROM_Read + 0x30;
00674 else
00675 base = EEPROM_Read;
00676
00677 for (i = 0; i < 0x40; i++) {
00678 int timer;
00679
00680 /* This means that we want to read EepromCommand Register and disable writting */
00681 /* Issuing ReadRegister & WriteDisable */
00682 outw(base + i, ioaddr + Wn0EepromCmd);
00683
00684 for (timer = 10; timer >= 0; timer--) {
00685
00686 /* The read data is available through the EepromData register 162us after */
00687 /* the ReadRegister command has been issued */
00688 rtl_delay(162000);
00689
00690 /* Bit 15th (eepromBusy) of EepromCommand register is a read-only bit asserted */
00691 /* during the execution of EEProm commands. Further commans should not be issued */
00692 /* to the EepromCommand register, nor should data be read from the EepromData */
00693 /* register while this bit is true */
00694 if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
00695 break;
00696 }
00697
00698 /* Save the contents of the 3C90xC NIC's EEPROM */
00699 eeprom[i] = inw(ioaddr + Wn0EepromData);
00700 }
00701
00702 }//EL3WINDOW(0) configuration finished
00703
00704 /* EEPROM can be checksummed in order to assure that reading was OK */
00705 for (i = 0; i < 0x18; i++)
00706 checksum ^= eeprom[i];
00707 checksum = (checksum ^ (checksum >> 8)) & 0xff;
00708 if (checksum != 0x00) { /* Grrr, needless incompatible change 3Com. */
00709 while (i < 0x21)
00710 checksum ^= eeprom[i++];
00711 checksum = (checksum ^ (checksum >> 8)) & 0xff;
00712 }
00713 if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
00714 printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
00715
00716 /* Save HW address into dev_addr (MAC address in format 00:04:75:bd:ea:e7) */
00717 for (i = 0; i < 3; i++)
00718 ((u16 *)rt_3c905c_vp.dev_addr)[i] = htons(eeprom[i + 10]);
00719
00720 /* This writes into the StationAddress register the NIC's HW address in order */
00721 /* to define the individual destination address that the NIC responds to when */
00722 /* receiving packets */
00723 EL3WINDOW(2);
00724 for (i = 0; i < 6; i++)
00725 outb(rt_3c905c_vp.dev_addr[i], ioaddr + i);
00726
00727 EL3WINDOW(4);
00728 step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
00729
00730 if (dev && vci->drv_flags & HAS_CB_FNS) {
00731 unsigned long fn_st_addr; /* Cardbus function status space */
00732 unsigned short n;
00733
00734 fn_st_addr = pci_resource_start (dev, 2);
00735 if (fn_st_addr) {
00736 rt_3c905c_vp.cb_fn_base = ioremap(fn_st_addr, 128);
00737 retval = -ENOMEM;
00738 if (!rt_3c905c_vp.cb_fn_base)
00739 goto free_ring;
00740 }
00741
00742 EL3WINDOW(2);
00743
00744 n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
00745 if (rt_3c905c_vp.drv_flags & INVERT_LED_PWR)
00746 n |= 0x10;
00747 if (rt_3c905c_vp.drv_flags & INVERT_MII_PWR)
00748 n |= 0x4000;
00749 outw(n, ioaddr + Wn2_ResetOptions);
00750 }
00751
00752 /* Extract our information from the EEPROM data. */
00753 rt_3c905c_vp.info1 = eeprom[13];
00754 rt_3c905c_vp.info2 = eeprom[15];
00755 rt_3c905c_vp.capabilities = eeprom[16];
00756
00757 if (rt_3c905c_vp.info1 & 0x8000){
00758 rt_3c905c_vp.full_duplex = 1;
00759 printk(KERN_INFO "Full duplex capable\n");
00760 }
00761
00762 {
00763 unsigned int config;
00764 EL3WINDOW(3);
00765
00766 /* This reads the MediaOptions register which shows what physical media */
00767 /* connections are available in the NIC */
00768 rt_3c905c_vp.available_media = inw(ioaddr + Wn3_Options); //Wn3_Options = 8 vp.available_media = 0xa
00769
00770 if ((rt_3c905c_vp.available_media & 0xff) == 0) /* Broken 3c916 */
00771 rt_3c905c_vp.available_media = 0x40;
00772
00773 /* This reads the InternalConfig register which provides a way to set */
00774 /* NIC-specific, non-host-related configuration settings */
00775 config = inl(ioaddr + Wn3_Config); //Wn3_Config = 0
00776
00777 rt_3c905c_vp.default_media = XCVR(config);
00778 if (rt_3c905c_vp.default_media == XCVR_NWAY)
00779 rt_3c905c_vp.has_nway = 1;
00780 rt_3c905c_vp.autoselect = AUTOSELECT(config);
00781 }
00782
00783 if (rt_3c905c_vp.media_override != 7) {
00784 rt_3c905c_vp.if_port = rt_3c905c_vp.media_override;
00785 } else
00786 rt_3c905c_vp.if_port = rt_3c905c_vp.default_media;
00787
00788 if (rt_3c905c_vp.if_port == XCVR_MII || rt_3c905c_vp.if_port == XCVR_NWAY) {
00789 int phy, phy_idx = 0;
00790 EL3WINDOW(4);
00791 mii_preamble_required++;
00792 mii_preamble_required++;
00793 rtl_3COM905C_mdio_read(24, 1);
00794 for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
00795 int mii_status, phyx;
00796
00797 /*
00798 * For the 3c905CX we look at index 24 first, because it bogusly
00799 * reports an external PHY at all indices
00800 */
00801 if (phy == 0)
00802 phyx = 24;
00803 else if (phy <= 24)
00804 phyx = phy - 1;
00805 else
00806 phyx = phy;
00807 mii_status = rtl_3COM905C_mdio_read(phyx, 1);
00808 if (mii_status && mii_status != 0xffff) {
00809 rt_3c905c_vp.phys[phy_idx++] = phyx;
00810
00811 if ((mii_status & 0x0040) == 0)
00812 mii_preamble_required++;
00813 }
00814 }
00815 mii_preamble_required--;
00816 if (phy_idx == 0) {
00817 rt_3c905c_vp.phys[0] = 24;
00818 } else {
00819 rt_3c905c_vp.advertising = rtl_3COM905C_mdio_read(rt_3c905c_vp.phys[0], 4);
00820 if (rt_3c905c_vp.full_duplex) {
00821 /* Only advertise the FD media types. */
00822 rt_3c905c_vp.advertising &= ~0x02A0;
00823 rtl_3COM905C_mdio_write(rt_3c905c_vp.phys[0], 4, rt_3c905c_vp.advertising);
00824 }
00825 }
00826 }
00827 if (rt_3c905c_vp.capabilities & CapBusMaster) {
00828 rt_3c905c_vp.full_bus_master_tx = 1;
00829
00830 rt_3c905c_vp.full_bus_master_rx = (rt_3c905c_vp.info2 & 1) ? 1 : 2;
00831 rt_3c905c_vp.bus_master = 0; /* AKPM: vortex only */
00832 }
00833 if (rt_3c905c_vp.pdev && rt_3c905c_vp.enable_wol) {
00834 rt_3c905c_vp.pm_state_valid = 1;
00835 rt_pci_save_state(dev, rt_3c905c_vp.power_state);
00836 rtl_3COM905C_acpi_set_WOL();
00837 }
00838 vortex_open(dev);
00839
00840 }// if(dev)
00841
00842 return 0;
00843
00844 free_ring:
00845
00846 pci_free_consistent(dev, sizeof(struct boom_rx_desc) * RX_RING_SIZE, rt_3c905c_vp.rx_ring, rt_3c905c_vp.rx_ring_dma);
00847 pci_free_consistent(dev, sizeof(struct boom_tx_desc) * TX_RING_SIZE, rt_3c905c_vp.tx_ring, rt_3c905c_vp.tx_ring_dma);
00848
00849 return -1;
00850
00851 free_region:
00852 if (rt_3c905c_vp.must_free_region){
00853 release_region(ioaddr, vci->io_size);
00854 rt_3c905c_vp.must_free_region = 0;
00855 }
00856 printk("vortex_probe1 fails. Returns %d\n", retval);
00857
00858 return -1;
00859 }
|
Here is the call graph for this function:
|
||||||||||||||||||||
|
Definition at line 353 of file rtl_3c905cx_drv.c. References rt_3c905c_send_packet().
00354 {
00355 ssize_t tmp;
00356 rtl_irqstate_t state;
00357
00358 rtl_no_interrupts(state);
00359 tmp=rt_3c905c_send_packet(buf,count);
00360 rtl_restore_interrupts(state);
00361 return tmp;
00362 }
|
Here is the call graph for this function:
|
|
Definition at line 1197 of file rtl_3c905cx_drv.c. References vortex_private::full_bus_master_rx, vortex_private::full_bus_master_tx, vortex_private::must_free_irq, rt_3c905c_vp, rtl_free, RX_RING_SIZE, vortex_private::rx_skbuff, TX_RING_SIZE, vortex_private::tx_skbuff, and vortex_down().
01198 {
01199 int i;
01200
01201 vortex_down(dev);
01202
01203 if(rt_3c905c_vp.must_free_irq){
01204 rtl_free_irq(dev->irq);
01205 rt_3c905c_vp.must_free_irq = 0;
01206 }
01207
01208 if (rt_3c905c_vp.full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */
01209 for (i = 0; i < RX_RING_SIZE; i++)
01210 if (rt_3c905c_vp.rx_skbuff[i]) {
01211 rtl_free(rt_3c905c_vp.rx_skbuff[i]);
01212 }
01213 }
01214 if (rt_3c905c_vp.full_bus_master_tx) { /* Free Boomerang bus master Tx buffers. */
01215 for (i = 0; i < TX_RING_SIZE; i++)
01216 if (rt_3c905c_vp.tx_skbuff[i]) {
01217 rtl_free(rt_3c905c_vp.tx_skbuff[i]);
01218 }
01219 }
01220
01221 return 0;
01222 }
|
Here is the call graph for this function:
|
|
Definition at line 1166 of file rtl_3c905cx_drv.c. References DownListPtr, EL3_CMD, vortex_private::enable_wol, vortex_private::full_bus_master_rx, vortex_private::full_bus_master_tx, vortex_private::if_port, vortex_private::ioaddr, vortex_private::pdev, vortex_private::power_state, rt_3c905c_vp, rt_pci_save_state(), rtl_3COM905C_acpi_set_WOL(), RxDisable, SetIntrEnb, StatsDisable, StopCoax, TxDisable, UpListPtr, and XCVR_10base2.
01167 {
01168 long ioaddr = rt_3c905c_vp.ioaddr;
01169
01170 /* Turn off statistics ASAP. We update rt_3c905c_vp->stats below. */
01171 outw(StatsDisable, ioaddr + EL3_CMD);
01172
01173 /* Disable the receiver and transmitter. */
01174 outw(RxDisable, ioaddr + EL3_CMD);
01175 outw(TxDisable, ioaddr + EL3_CMD);
01176
01177 if (rt_3c905c_vp.if_port == XCVR_10base2)
01178 /* Turn off thinnet power. Green! */
01179 outw(StopCoax, ioaddr + EL3_CMD);
01180
01181 outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
01182
01183 if (rt_3c905c_vp.full_bus_master_rx)
01184 outl(0, ioaddr + UpListPtr);
01185 if (rt_3c905c_vp.full_bus_master_tx)
01186 outl(0, ioaddr + DownListPtr);
01187
01188 if (rt_3c905c_vp.pdev && rt_3c905c_vp.enable_wol) {
01189 rt_pci_save_state(rt_3c905c_vp.pdev, rt_3c905c_vp.power_state);
01190 rtl_3COM905C_acpi_set_WOL();
01191 }
01192 }
|
Here is the call graph for this function:
|
||||||||||||
|
Definition at line 1229 of file rtl_3c905cx_drv.c. References AckIntr, EL3_CMD, EL3_STATUS, EL3WINDOW, vortex_private::full_bus_master_tx, HostError, vortex_private::intr_enable, IntReq, vortex_private::ioaddr, PktStatus, rt_3c905c_vp, rtl_3COM905C_issue_and_wait(), rtl_3COM905C_set_rx_mode(), RxEarly, RxEnable, RxReset, SetIntrEnb, StatsFull, status, vortex_private::status_enable, TotalReset, TxEnable, TxReset, vortex_down(), vortex_up(), and Wn4_FIFODiag.
01230 {
01231 long ioaddr = rt_3c905c_vp.ioaddr;
01232 int do_tx_reset = 0, reset_mask = 0;
01233
01234 if (status & RxEarly) { /* Rx early is unused. */
01235 outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
01236 }
01237 if (status & StatsFull) { /* Empty statistics. */
01238 static int DoneDidThat;
01239
01240 printk(KERN_DEBUG "%s: Updating stats.\n", dev->name);
01241 /* HACK: Disable statistics as an interrupt source. */
01242 /* This occurs when we have the wrong media type! */
01243 if (DoneDidThat == 0 &&
01244 inw(ioaddr + EL3_STATUS) & StatsFull) {
01245 printk(KERN_WARNING "%s: Updating statistics failed, disabling "
01246 "stats as an interrupt source.\n", dev->name);
01247 EL3WINDOW(5);
01248 outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
01249 rt_3c905c_vp.intr_enable &= ~StatsFull;
01250 EL3WINDOW(7);
01251 DoneDidThat++;
01252 }
01253 }
01254 if (status & IntReq) { /* Restore all interrupt sources. */
01255 outw(rt_3c905c_vp.status_enable, ioaddr + EL3_CMD);
01256 outw(rt_3c905c_vp.intr_enable, ioaddr + EL3_CMD);
01257 }
01258 if (status & HostError) {
01259 u16 fifo_diag;
01260 EL3WINDOW(4);
01261 fifo_diag = inw(ioaddr + Wn4_FIFODiag);
01262 printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
01263 dev->name, fifo_diag);
01264 /* Adapter failure requires Tx/Rx reset and reinit. */
01265 if (rt_3c905c_vp.full_bus_master_tx) {
01266 int bus_status = inl(ioaddr + PktStatus);
01267 /* 0x80000000 PCI master abort. */
01268 /* 0x40000000 PCI target abort. */
01269
01270 printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
01271
01272 /* In this case, blow the card away */
01273 vortex_down(dev);
01274 rtl_3COM905C_issue_and_wait(TotalReset | 0xff);
01275 vortex_up(dev); /* AKPM: bug. vortex_up() assumes that the rx ring is full. It may not be. */
01276 } else if (fifo_diag & 0x0400)
01277 do_tx_reset = 1;
01278 if (fifo_diag & 0x3000) {
01279 /* Reset Rx fifo and upload logic */
01280 rtl_3COM905C_issue_and_wait(RxReset|0x07);
01281 /* Set the Rx filter to the current state. */
01282 rtl_3COM905C_set_rx_mode();
01283 outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
01284 outw(AckIntr | HostError, ioaddr + EL3_CMD);
01285 }
01286 }
01287
01288 if (do_tx_reset) {
01289 rtl_3COM905C_issue_and_wait(TxReset|reset_mask);
01290 outw(TxEnable, ioaddr + EL3_CMD);
01291 }
01292 }
|
Here is the call graph for this function:
|
|
Definition at line 885 of file rtl_3c905cx_drv.c. References boom_tx_desc::addr, boom_rx_desc::addr, boomerang_interrupt(), vortex_private::full_bus_master_rx, LAST_FRAG, boom_tx_desc::length, boom_rx_desc::length, vortex_private::must_free_irq, boom_tx_desc::next, boom_rx_desc::next, NULL, vortex_private::pdev, PKT_BUF_SZ, rt_3c905c_vp, rtl_free, rtl_malloc, vortex_private::rx_ring, vortex_private::rx_ring_dma, RX_RING_SIZE, vortex_private::rx_skbuff, boom_tx_desc::status, boom_rx_desc::status, vortex_private::tx_ring, vortex_private::tx_ring_dma, TX_RING_SIZE, vortex_private::tx_skbuff, and vortex_up().
00886 {
00887 int i;
00888 int retval;
00889
00890 /* Use the now-standard shared IRQ implementation. */
00891 if ((retval = rtl_request_irq(dev->irq, &boomerang_interrupt))) {
00892 printk(KERN_ERR "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
00893 goto out;
00894 }else
00895 rt_3c905c_vp.must_free_irq = 1;
00896
00897 if (rt_3c905c_vp.full_bus_master_rx) { /* Boomerang bus master. */
00898
00899 /* RX RING INITIALIZATION */
00900 for (i = 0; i < RX_RING_SIZE; i++) {
00901 unsigned char *skb;
00902 rt_3c905c_vp.rx_ring[i].next = cpu_to_le32(rt_3c905c_vp.rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
00903 rt_3c905c_vp.rx_ring[i].status = 0; /* Clear complete bit. */
00904 rt_3c905c_vp.rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG);
00905 skb = rtl_malloc(PKT_BUF_SZ);
00906 rt_3c905c_vp.rx_skbuff[i] = skb;
00907 if (skb == NULL)
00908 break; /* Bad news! */
00909 rt_3c905c_vp.rx_ring[i].addr = cpu_to_le32(pci_map_single(rt_3c905c_vp.pdev, skb, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
00910 }
00911
00912 if (i != RX_RING_SIZE) {
00913 int j;
00914 printk(KERN_EMERG "%s: no memory for rx ring\n", dev->name);
00915 for (j = 0; j < i; j++) {
00916 if (rt_3c905c_vp.rx_skbuff[j]) {
00917 rtl_free(rt_3c905c_vp.rx_skbuff[j]);
00918 rt_3c905c_vp.rx_skbuff[j] = 0;
00919 }
00920 }
00921 retval = -ENOMEM;
00922 goto out_free_irq;
00923 }
00924
00925 /* Wrap the ring. */
00926 rt_3c905c_vp.rx_ring[i-1].next = cpu_to_le32(rt_3c905c_vp.rx_ring_dma);
00927
00928 /* TX RING INITIALIZATION */
00929 for (i = 0; i < TX_RING_SIZE; i++) {
00930 unsigned char *skb;
00931 rt_3c905c_vp.tx_ring[i].next = 0;
00932 rt_3c905c_vp.tx_ring[i].status = 0; /* Clear complete bit. */
00933 rt_3c905c_vp.tx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG);
00934 skb = rtl_malloc(PKT_BUF_SZ);
00935 rt_3c905c_vp.tx_skbuff[i] = skb;
00936 if (skb == NULL)
00937 break; /* Bad news! */
00938 rt_3c905c_vp.tx_ring[i].addr = cpu_to_le32(pci_map_single(rt_3c905c_vp.pdev, skb, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
00939 }
00940
00941
00942 if (i != TX_RING_SIZE) {
00943 int j;
00944 printk(KERN_EMERG "%s: no memory for tx ring\n", dev->name);
00945 for (j = 0; j < i; j++) {
00946 if (rt_3c905c_vp.tx_skbuff[j]) {
00947 rtl_free(rt_3c905c_vp.tx_skbuff[j]);
00948 rt_3c905c_vp.tx_skbuff[j] = 0;
00949 }
00950 }
00951 retval = -ENOMEM;
00952 goto out_free_irq;
00953 }
00954
00955 /* Wrap the ring. */
00956 rt_3c905c_vp.tx_ring[i-1].next = cpu_to_le32(rt_3c905c_vp.tx_ring_dma);
00957 }
00958
00959 vortex_up(dev);
00960 return 0;
00961
00962 out_free_irq:
00963 rtl_free_irq(dev->irq);
00964 out:
00965 return retval;
00966 }
|
Here is the call graph for this function:
|
Here is the call graph for this function:
|
|
Definition at line 972 of file rtl_3c905cx_drv.c. References AckIntr, vortex_private::autoselect, vortex_private::available_media, BFINS, vortex_private::cb_fn_base, vortex_private::cur_rx, vortex_private::cur_tx, vortex_private::default_media, vortex_private::dev_addr, vortex_private::dirty_rx, vortex_private::dirty_tx, DownComplete, DownListPtr, vortex_private::drv_flags, EL3_CMD, EL3WINDOW, vortex_private::enable_wol, vortex_private::flow_ctrl, vortex_private::force_fd, vortex_private::full_bus_master_rx, vortex_private::full_bus_master_tx, vortex_private::full_duplex, vortex_private::has_nway, vortex_private::if_port, vortex_private::info1, IntLatch, vortex_private::intr_enable, IntReq, INVERT_LED_PWR, INVERT_MII_PWR, vortex_private::ioaddr, IS_BOOMERANG, Media_10TP, vortex_private::media_override, Media_SQE, vortex_private::mtu, vortex_private::partner_flow_ctrl, vortex_private::pdev, vortex_private::phys, PKT_BUF_SZ, vortex_private::power_state, rt_3c905c_vp, rt_pci_restore_state(), rt_pci_set_power_state(), rtl_3COM905C_issue_and_wait(), rtl_3COM905C_mdio_read(), rtl_3COM905C_set_rx_mode(), vortex_private::rx_frames_for_us, vortex_private::rx_packets, vortex_private::rx_ring, vortex_private::rx_ring_dma, RX_RING_SIZE, RxComplete, RxEarly, RxEnable, RxReset, SetIntrEnb, SetStatusEnb, StartCoax, StatsDisable, boom_rx_desc::status, vortex_private::status_enable, TxAvailable, TxEnable, TxFreeThreshold, TxReset, UpComplete, UpListPtr, Wn2_ResetOptions, Wn3_Config, Wn3_MAC_Ctrl, Wn4_Media, XCVR_100baseTx, XCVR_10base2, XCVR_MII, and XCVR_NWAY.
00973 {
00974 long ioaddr = rt_3c905c_vp.ioaddr;
00975 unsigned int config;
00976 int i;
00977
00978 rt_3c905c_vp.rx_packets = 0;
00979 rt_3c905c_vp.rx_frames_for_us = 0;
00980
00981 if (rt_3c905c_vp.pdev && rt_3c905c_vp.enable_wol) {
00982 rt_pci_set_power_state(dev, 0); /* Go active */
00983 rt_pci_restore_state(dev, rt_3c905c_vp.power_state);
00984 }
00985
00986 /* Before initializing select the active media port. */
00987 EL3WINDOW(3);
00988 config = inl(ioaddr + Wn3_Config);
00989
00990 if (rt_3c905c_vp.media_override != 7) {
00991 rt_3c905c_vp.if_port = rt_3c905c_vp.media_override;
00992 } else if (rt_3c905c_vp.autoselect) {
00993 if (rt_3c905c_vp.has_nway) {
00994 } else {
00995 /* Find first available media type, starting with 100baseTx. */
00996 rt_3c905c_vp.if_port = XCVR_100baseTx;
00997 while (! (rt_3c905c_vp.available_media & media_tbl[rt_3c905c_vp.if_port].mask))
00998 rt_3c905c_vp.if_port = media_tbl[rt_3c905c_vp.if_port].next;
00999 }
01000 } else {
01001 rt_3c905c_vp.if_port = rt_3c905c_vp.default_media;
01002
01003 }
01004
01005 rt_3c905c_vp.full_duplex = rt_3c905c_vp.force_fd;
01006
01007 config = BFINS(config, rt_3c905c_vp.if_port, 20, 4);
01008
01009 outl(config, ioaddr + Wn3_Config);
01010
01011 if (rt_3c905c_vp.if_port == XCVR_MII || rt_3c905c_vp.if_port == XCVR_NWAY) {
01012 int mii_reg1, mii_reg5;
01013 EL3WINDOW(4);
01014 /* Read BMSR (reg1) only to clear old status. */
01015 mii_reg1 = rtl_3COM905C_mdio_read(rt_3c905c_vp.phys[0], 1);
01016 mii_reg5 = rtl_3COM905C_mdio_read(rt_3c905c_vp.phys[0], 5);
01017 if (mii_reg5 == 0xffff || mii_reg5 == 0x0000)
01018 ; /* No MII device or no link partner report */
01019 else if ((mii_reg5 & 0x0100) != 0 /* 100baseTx-FD */
01020 || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */
01021 rt_3c905c_vp.full_duplex = 1;
01022 rt_3c905c_vp.partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
01023
01024 EL3WINDOW(3);
01025 }
01026
01027 rt_3c905c_vp.full_duplex = 1;
01028
01029 /* Set the full-duplex bit. */
01030
01031 outw( ((rt_3c905c_vp.info1 & 0x8000) || rt_3c905c_vp.full_duplex ? 0x20 : 0) |
01032 (rt_3c905c_vp.mtu > 1500 ? 0x40 : 0) |
01033 ((rt_3c905c_vp.full_duplex && rt_3c905c_vp.flow_ctrl && rt_3c905c_vp.partner_flow_ctrl) ? 0x100 : 0),
01034 ioaddr + Wn3_MAC_Ctrl);
01035
01036 rtl_3COM905C_issue_and_wait(TxReset);
01037
01038 /*
01039 * Don't reset the PHY - that upsets autonegotiation during DHCP operations.
01040 */
01041 rtl_3COM905C_issue_and_wait(RxReset|0x04);
01042
01043 outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
01044
01045 EL3WINDOW(4);
01046
01047 /* Set the station address and mask in window 2 each time opened. */
01048 EL3WINDOW(2);
01049 for (i = 0; i < 6; i++)
01050 outb(rt_3c905c_vp.dev_addr[i], ioaddr + i);
01051 for (; i < 12; i+=2)
01052 outw(0, ioaddr + i);
01053
01054 if (rt_3c905c_vp.cb_fn_base) {
01055 unsigned short n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
01056 if (rt_3c905c_vp.drv_flags & INVERT_LED_PWR)
01057 n |= 0x10;
01058 if (rt_3c905c_vp.drv_flags & INVERT_MII_PWR)
01059 n |= 0x4000;
01060 outw(n, ioaddr + Wn2_ResetOptions);
01061 }
01062
01063 if (rt_3c905c_vp.if_port == XCVR_10base2)
01064 /* Start the thinnet transceiver. We should really wait 50ms...*/
01065 outw(StartCoax, ioaddr + EL3_CMD);
01066 if (rt_3c905c_vp.if_port != XCVR_NWAY) {
01067 EL3WINDOW(4);
01068 outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
01069 media_tbl[rt_3c905c_vp.if_port].media_bits, ioaddr + Wn4_Media);
01070 }
01071
01072 /* RTOS and statistic??? Let's disable stats. */
01073 outw(StatsDisable, ioaddr + EL3_CMD);
01074 EL3WINDOW(6);
01075 for (i = 0; i < 10; i++)
01076 inb(ioaddr + i);
01077 inw(ioaddr + 10);
01078 inw(ioaddr + 12);
01079 /* New: On the Vortex we must also clear the BadSSD counter. */
01080 EL3WINDOW(4);
01081 inb(ioaddr + 12);
01082
01083 /* Switch to register set 7 for normal use. */
01084 EL3WINDOW(7);
01085
01086 if (rt_3c905c_vp.full_bus_master_rx) { /* Boomerang bus master. */
01087 rt_3c905c_vp.cur_rx = rt_3c905c_vp.dirty_rx = rt_3c905c_vp.cur_tx = 0;
01088
01089 outl(rt_3c905c_vp.rx_ring_dma, ioaddr + UpListPtr);
01090 }
01091 if (rt_3c905c_vp.full_bus_master_tx) { /* Boomerang bus master Tx. */
01092 rt_3c905c_vp.cur_tx = rt_3c905c_vp.dirty_tx = 0;
01093 if (rt_3c905c_vp.drv_flags & IS_BOOMERANG)
01094
01095 outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
01096 /* Clear the Rx, Tx rings. */
01097 for (i = 0; i < RX_RING_SIZE; i++) /* AKPM: this is done in vortex_open, too */
01098 rt_3c905c_vp.rx_ring[i].status = 0;
01099 outl(0, ioaddr + DownListPtr);
01100 }
01101 /* Set receiver mode: presumably accept b-case and phys addr only. */
01102 rtl_3COM905C_set_rx_mode();
01103 outw(StatsDisable, ioaddr + EL3_CMD); /* Turn off statistics ASAP. */
01104
01105 outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
01106 outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
01107
01108 /* Allow status bits to be seen. */
01109 rt_3c905c_vp.status_enable = SetStatusEnb |
01110 (rt_3c905c_vp.full_bus_master_rx ? UpComplete : RxComplete) | DownComplete;
01111 rt_3c905c_vp.intr_enable = SetIntrEnb | UpComplete | DownComplete;
01112 outw(rt_3c905c_vp.status_enable, ioaddr + EL3_CMD);
01113 /* Ack all pending events, and set active indicator mask. */
01114 outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
01115 ioaddr + EL3_CMD);
01116 outw(rt_3c905c_vp.intr_enable, ioaddr + EL3_CMD);
01117 if (rt_3c905c_vp.cb_fn_base)
01118 writel(0x8000, rt_3c905c_vp.cb_fn_base + 4);
01119 }
|
Here is the call graph for this function:
|
|
Definition at line 265 of file rtl_3c905cx_drv.c. Referenced by boomerang_interrupt(), rtl_3COM905C_open(), and rtl_3COM905C_release(). |
|
|
Definition at line 252 of file rtl_3c905cx_drv.c. Referenced by boomerang_interrupt(), and cleanup_module(). |
|
|
Definition at line 253 of file rtl_3c905cx_drv.c. Referenced by boomerang_interrupt(). |
|
|
Definition at line 268 of file rtl_3c905cx_drv.c. Referenced by boomerang_rx(), and rt_3c905c_set_ip_filter(). |
|
|
Definition at line 269 of file rtl_3c905cx_drv.c. Referenced by boomerang_rx(), and rt_3c905c_set_ip_filter(). |
|
|
Definition at line 267 of file rtl_3c905cx_drv.c. Referenced by cleanup_module(), and init_module(). |
|
|
|
Initial value: {
FIFO_add_frame_to_buffer,
FIFO_extract_frame_of_buffer,
FIFO_initialize_rx_buffer,
FIFO_dealloc_rx_buffer,
}
Definition at line 237 of file rtl_3c905cx_drv.c. Referenced by boomerang_rx(), rtl_3COM905C_init_device(), rtl_3COM905C_read(), and rtl_3COM905C_release(). |
|
|
Definition at line 244 of file rtl_3c905cx_drv.c. Referenced by boomerang_rx(), rtl_3COM905C_init_device(), rtl_3COM905C_read(), and rtl_3COM905C_release(). |
|
|
Definition at line 246 of file rtl_3c905cx_drv.c. Referenced by boomerang_rx(), rtl_3COM905C_open(), rtl_3COM905C_read(), and rtl_3COM905C_release(). |
|
|
Initial value: {
NULL,
rtl_3COM905C_read,
rtl_3COM905C_write,
rtl_3COM905C_ioctl,
NULL,
rtl_3COM905C_open,
rtl_3COM905C_release
}
Definition at line 255 of file rtl_3c905cx_drv.c. Referenced by init_module(). |
1.3.4