📄 xircom_cb.c
字号:
} xircom_up(xp); leave(); return 0;}static int xircom_close(struct net_device *dev){ struct xircom_private *card; unsigned long flags; enter(); card = dev->priv; netif_stop_queue(dev); /* we don't want to send new packets */ spin_lock_irqsave(&card->lock,flags); disable_all_interrupts(card);#if 0 /* We can enable this again once we send dummy packets on ifconfig ethX up */ deactivate_receiver(card); deactivate_transmitter(card);#endif remove_descriptors(card); spin_unlock_irqrestore(&card->lock,flags); free_irq(dev->irq,dev); leave(); return 0; }static struct net_device_stats *xircom_get_stats(struct net_device *dev){ struct xircom_private *card = (struct xircom_private *)dev->priv; return &card->stats;} static void initialize_card(struct xircom_private *card){ unsigned int val; unsigned long flags; enter(); spin_lock_irqsave(&card->lock, flags); /* First: reset the card */ val = inl(card->io_port + CSR0); val |= 0x01; /* Software reset */ outl(val, card->io_port + CSR0); udelay(100); /* give the card some time to reset */ val = inl(card->io_port + CSR0); val &= ~0x01; /* disable Software reset */ outl(val, card->io_port + CSR0); val = 0; /* Value 0x00 is a safe and conservative value for the PCI configuration settings */ outl(val, card->io_port + CSR0); disable_all_interrupts(card); deactivate_receiver(card); deactivate_transmitter(card); spin_unlock_irqrestore(&card->lock, flags); leave();}/*trigger_transmit causes the card to check for frames to be transmitted.This is accomplished by writing to the CSR1 port. The documentationclaims that the act of writing is sufficient and that the value isignored; I chose zero.*/static inline void trigger_transmit(struct xircom_private *card){ enter(); outl(0, card->io_port + CSR1); leave();}/*trigger_receive causes the card to check for empty frames in thedescriptor list in which packets can be received.This is accomplished by writing to the CSR2 port. The documentationclaims that the act of writing is sufficient and that the value isignored; I chose zero.*/static inline void trigger_receive(struct xircom_private *card){ enter(); outl(0, card->io_port + CSR2); leave();}/*setup_descriptors initializes the send and receive buffers to be validdescriptors and programs the addresses into the card.*/static void setup_descriptors(struct xircom_private *card){ unsigned int val; u32 address; unsigned int i; enter(); if (card->rx_buffer == NULL) BUG(); if (card->tx_buffer == NULL) BUG(); /* Receive descriptors */ memset(card->rx_desc, 0, 128); /* clear the descriptors */ for (i=0;i<NUMDESCRIPTORS;i++ ) { /* Rx Descr0: It's empty, let the card own it, no errors -> 0x80000000 */ card->rx_desc[i].status = DescOwnedCard; /* Rx Descr1: buffer 1 is 1536 bytes, buffer 2 is 0 bytes */ card->rx_desc[i].control = MAX_PACKETSIZE; if (i==NUMDESCRIPTORS-1) card->rx_desc[i].control |= LastDescBit; /* bit 25 is "last descriptor" */ /* Rx Descr2: address of the buffer we store the buffer at the 2nd half of the page */ address = card->rx_dma_handle; card->rx_desc[i].address1 = cpu_to_le32(address + bufferoffsets[i]); /* Rx Desc3: address of 2nd buffer -> 0 */ card->rx_desc[i].address2 = 0; } wmb(); /* Write the receive descriptor ring address to the card */ address = card->rx_dma_handle; val = cpu_to_le32(address); outl(val, card->io_port + CSR3); /* Receive descr list address */ /* transmit descriptors */ memset(card->tx_desc, 0, 128); /* clear the descriptors */ for (i=0;i<NUMDESCRIPTORS;i++ ) { /* Tx Descr0: Empty, we own it, no errors -> 0x00000000 */ card->tx_desc[i].status = DescOwnedDriver; /* Tx Descr1: buffer 1 is 1536 bytes, buffer 2 is 0 bytes */ card->tx_desc[i].control = MAX_PACKETSIZE; if (i==NUMDESCRIPTORS-1) card->tx_desc[i].control |= LastDescBit; /* bit 25 is "last descriptor" */ /* Tx Descr2: address of the buffer we store the buffer at the 2nd half of the page */ address = card->tx_dma_handle; card->tx_desc[i].address1 = cpu_to_le32(address + bufferoffsets[i]); /* Tx Desc3: address of 2nd buffer -> 0 */ card->tx_desc[i].address2 = 0; } wmb(); /* wite the transmit descriptor ring to the card */ address = card->tx_dma_handle; val =cpu_to_le32(address); outl(val, card->io_port + CSR4); /* xmit descr list address */ leave();}/*remove_descriptors informs the card the descriptors are no longervalid by setting the address in the card to 0x00.*/static inline void remove_descriptors(struct xircom_private *card){ unsigned int val; enter(); val = 0; outl(val, card->io_port + CSR3); /* Receive descriptor address */ outl(val, card->io_port + CSR4); /* Send descriptor address */ leave();}/*link_status_changed returns 1 if the card has indicated thatthe link status has changed. The new link status has to be read from CSR12.This function also clears the status-bit.*/static inline unsigned int link_status_changed(struct xircom_private *card){ unsigned int val; enter(); val = inl(card->io_port + CSR5); /* Status register */ if ((val & LinkStatusBit) == 0) { /* no change */ leave(); return 0; } /* clear the event by writing a 1 to the bit in the status register. */ val = LinkStatusBit; outl(val, card->io_port + CSR5); leave(); return 1;}/*transmit_active returns 1 if the transmitter on the card isin a non-stopped state.*/static inline int transmit_active(struct xircom_private *card){ unsigned int val; enter(); val = inl(card->io_port + CSR5); /* Status register */ if ((val & (7 << 20)) == 0) { /* transmitter disabled */ leave(); return 0; } leave(); return 1;}/*receive_active returns 1 if the receiver on the card isin a non-stopped state.*/static inline unsigned int receive_active(struct xircom_private *card){ unsigned int val; enter(); val = inl(card->io_port + CSR5); /* Status register */ if ((val & (7 << 17)) == 0) { /* receiver disabled */ leave(); return 0; } leave(); return 1;}/*activate_receiver enables the receiver on the card.Before being allowed to active the receiver, the receivermust be completely de-activated. To achieve this,this code actually disables the receiver first; then it waits for the receiver to become inactive, then it activates the receiver and thenit waits for the receiver to be active.must be called with the lock held and interrupts disabled.*/static void activate_receiver(struct xircom_private *card){ unsigned int val; int counter; enter(); val = inl(card->io_port + CSR6); /* Operation mode */ /* If the "active" bit (1) is set and the receiver is already active, no need to do the expensive thing */ if ((val& RxActiveBit) && (receive_active(card))) return; val = val & ~RxActiveBit; /* disable the receiver */ outl(val, card->io_port + CSR6); counter = 10; while (counter > 0) { if (!receive_active(card)) break; /* wait a while */ udelay(50); counter--; if (counter <= 0) printk(KERN_ERR "xircom_cb: Receiver failed to deactivate\n"); } /* enable the receiver */ val = inl(card->io_port + CSR6); /* Operation mode */ val = val | RxActiveBit; /* enable the receiver */ outl(val, card->io_port + CSR6); /* now wait for the card to activate again */ counter = 10; while (counter > 0) { if (receive_active(card)) break; /* wait a while */ udelay(50); counter--; if (counter <= 0) printk(KERN_ERR "xircom_cb: Receiver failed to re-activate\n"); } leave();}/*deactivate_receiver disables the receiver on the card.To achieve this this code disables the receiver first; then it waits for the receiver to become inactive.must be called with the lock held and interrupts disabled.*/static void deactivate_receiver(struct xircom_private *card){ unsigned int val; int counter; enter(); val = inl(card->io_port + CSR6); /* Operation mode */ val = val & ~RxActiveBit; /* disable the receiver */ outl(val, card->io_port + CSR6); counter = 10; while (counter > 0) { if (!receive_active(card)) break; /* wait a while */ udelay(50); counter--; if (counter <= 0) printk(KERN_ERR "xircom_cb: Receiver failed to deactivate\n"); } leave();}/*activate_transmitter enables the transmitter on the card.Before being allowed to active the transmitter, the transmittermust be completely de-activated. To achieve this,this code actually disables the transmitter first; then it waits for the transmitter to become inactive, then it activates the transmitter and thenit waits for the transmitter to be active again.must be called with the lock held and interrupts disabled.*/static void activate_transmitter(struct xircom_private *card){ unsigned int val; int counter; enter(); val = inl(card->io_port + CSR6); /* Operation mode */ /* If the "active" bit (13) is set and the receiver is already active, no need to do the expensive thing */ if ((val & TxActiveBit) && (transmit_active(card))) return; val = val & ~TxActiveBit; /* disable the transmitter */ outl(val, card->io_port + CSR6); counter = 10; while (counter > 0) { if (!transmit_active(card)) break; /* wait a while */ udelay(50); counter--; if (counter <= 0) printk(KERN_ERR "xircom_cb: Transmitter failed to deactivate\n"); } /* enable the transmitter */ val = inl(card->io_port + CSR6); /* Operation mode */ val = val | TxActiveBit; /* enable the transmitter */ outl(val, card->io_port + CSR6); /* now wait for the card to activate again */ counter = 10; while (counter > 0) { if (transmit_active(card)) break; /* wait a while */ udelay(50); counter--; if (counter <= 0) printk(KERN_ERR "xircom_cb: Transmitter failed to re-activate\n"); } leave();}/*deactivate_transmitter disables the transmitter on the card.To achieve this this code disables the transmitter first; then it waits for the transmitter to become inactive.must be called with the lock held and interrupts disabled.*/static void deactivate_transmitter(struct xircom_private *card){ unsigned int val; int counter; enter(); val = inl(card->io_port + CSR6); /* Operation mode */ val = val & ~TxActiveBit; /* disable the transmitter */ outl(val, card->io_port + CSR6); counter = 20; while (counter > 0) { if (!transmit_active(card)) break; /* wait a while */ udelay(50); counter--; if (counter <= 0) printk(KERN_ERR "xircom_cb: Transmitter failed to deactivate\n"); } leave();}/*enable_transmit_interrupt enables the transmit interruptmust be called with the lock held and interrupts disabled.*/static void enable_transmit_interrupt(struct xircom_private *card){ unsigned int val; enter(); val = inl(card->io_port + CSR7); /* Interrupt enable register */ val |= 1; /* enable the transmit interrupt */ outl(val, card->io_port + CSR7); leave();}/*enable_receive_interrupt enables the receive interrupt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -