From: mwitosz-linux <mwitosz-linux@o2.pl>
To: linux-kernel@vger.kernel.org
Subject: problem with OWN bit when writting driver for rtl8139?
Date: Sun, 10 Sep 2006 16:32:13 +0200 [thread overview]
Message-ID: <231c973f.7ffabfd8.450421ed.620bc@o2.pl> (raw)
hi, everybody
my name is Mariusz, I am newbie to linux kernel,
For several weeks I have been writing kernel driver for network card based on
rtl8139c chip.
I have some problems with DMA, i suppose.
there is a bit in Transmit Status Descriptor of RTL8139c which after clearing(It must be cleared to
start transmit operation) shouldb be placed in 1 state - which according to RTL8139 specification means that
DMA copy from memory to internal RTL fifo has finished.
The problem is: rtl doesn't clear this bit
I use pci_map_single to map address of packet buffer to dma capable memory, then cpu_to_le32 to get physicall
address of this buffer.
Do you have any idea what may work wrong?
here is transmit part of my driver:
/**function called by kernel when kernel wat to transmit packet which is
located in socket buffer structure skb
@param skb: socket buffer structure with packet to transmit
@param netdev: device used to send this packet
*/
int rtl_tx(struct sk_buff *skb, struct net_device *netdev){
int len;
char *data, shortpkt[ETH_ZLEN];
struct rtl_private_data *priv;
//get private data pointer
priv = netdev_priv(netdev);
//if the length of this packet is below 64 bytes, expand it to 64 bytes
//by padding
data = skb->data;
len = skb->len;
if(len < ETH_ZLEN){
memset(shortpkt, 0, ETH_ZLEN);
memcpy(shortpkt, skb->data, skb->len);
len = ETH_ZLEN;
data = shortpkt;
}
//save skb for freeing when this packet will be transmited
priv->skb = skb;
//finaly transmit this packet
udelay(500);
rtl_hw_tx(data, len, netdev, skb);
return 0;
};
/**transmit data from packet
@param data: buffer with packet
@param len: lenth of this packet
@param netdev: network device used to transmit this packet
*/
int rtl_hw_tx(char *data, int len, struct net_device *netdev, struct sk_buff *skb){
unsigned char td;
u32 physical_addr;
unsigned int physical_addr_len;
//void *base_ptr;
u32 io_base;
struct rtl_private_data *priv;
unsigned int dword;
//u32 ertx;
int i;
u16 word;
bool assigned;
dma_addr_t mapping;
int result;
int j;
//KDEBUG("@PACKET IS --------------------------------------------------------------\n");
//show_packet(data, len);
//KDEBUG("@PACKET IS --------------------------------------------------------------\n");
KDEBUG("@rtl_hw_tx: new packet to transmit \n");
priv = netdev_priv(netdev);
//base_ptr = priv->base_ptr;
io_base = priv->io_base;
//wait for available free transmit descriptor
assigned = false;
//while(true){
for(i=0; i<1000; i++){
if( !is_empty( &descriptors ) ){
//there is no available transmit descriptor
assigned = true;
break;
}
}
if( !assigned) {
KERROR("@rtl_hw_txt: no available desriptor \n");
return 1;
}
//free transmit descriptor found, get it!
dequeue(&descriptors, &td);
spin_lock_irq(&priv->lock);
//skb_copy_and_csum_dev(skb, priv->tx_buff[td]);
//dev_kfree_skb(skb);
//get physical address of data buffer
//physical_addr = __pa(data);
mapping = pci_map_single(priv->pcidev, data, len, PCI_DMA_TODEVICE);
if(mapping == NULL){
KERROR("MAPPING null \n");
}
KDEBUG("@rtl_hw_tx: mapping is %d \n", mapping);
physical_addr = cpu_to_le32(mapping);
//KDEBUG("@rtl_hw_tx: compare: %ld ... %ld \n", physical_addr, __pa(data));
//set physical_address of this packet in tsad register
outl(physical_addr, io_base + tsad[td]);
//outl(priv->dma_buff[td], io_base + tsad[td]);
//iowrite32(physical_addr, base_ptr + tsad[td]);
//outl(physical_addr, io_ba
//early transmit threshlog
//ertx = 2;
//ertx = ertx << TSD_ERTHX_OFS;
//set size of transmited data
physical_addr_len = len;
KINFO("@rtl_hw_tx: physical_addr_len is %x \n", physical_addr_len);
dword = inl(io_base + tsd[td]);
KINFO("@rtl_hw_tx: current tsd is %x \n", dword);
dword = dword & ~(TSD_SIZE | TSD_ERTHX);
physical_addr_len = physical_addr_len & TSD_SIZE;
dword = dword | (physical_addr_len);
KINFO("@rtl_hw_tx: new tsd is %x \n", dword);
outl(dword, io_base + tsd[td]);
dword = inl(io_base + tsd[td]);
KINFO("@rtl_hw_tx: written tsd is %x \n", dword);
//save skb buffer pointer for future use
//skbs[td]= priv->skb;
priv->x = 0;
//clear own bit to start transmision
KINFO("@rtl_hw_tx: before clearing OWN: %x \n", dword);
word = inw(io_base+ IMR);
dword = inl(io_base + tsd[td]);
KDEBUG("@-----------IMR-------------: %x \n", word);
KDEBUG("@-----------TSD: %d %x-------------: \n", td, dword);
netdev->trans_start = jiffies;
dword = dword & ~TSD_OWN;
outl(dword, io_base + tsd[td]);
//dword = inl(io_base + tsd[td]);
//KINFO("@rtl_hw_tx: after clearing OWN: %x \n", dword);
for(j=0; j<500; j++){
word = inw(io_base + ISR);
dword = inl(io_base + tsd[td]);
KINFO("@rtl_hw_tx: ISR is %x TSD is %x \n", word, dword);
udelay(10000);
}
spin_unlock_irq(&priv->lock);
return 0;
}
and here is output from kernel
klogd 1.4.1#17.2, log source = /proc/kmsg started.
Cannot find map file.
No module symbols loaded - kernel modules not enabled.
<7>kobject rtl: registering. parent: <NULL>, set: module
<7>DEBUG __________________________module rtlmodule loaded___________________________
<7>DEBUG @register_as_network_device: New pci_dev to register as net_device
<6>ACPI: PCI Interrupt 0000:00:09.0[A] -> Link [LNKB] -> GSI 11 (level, low) -> IRQ 11
<7>DEBUG @register_as_network_device: Device Enabled
<7>DEBUG @register_as_network_device: pci_set_dma_mask ok
<7>DEBUG @register_as_network_device: request region ok
<7>DEBUG @register_as_network_device: IOAR is e001
<7>PCI: Enabling bus mastering for device 0000:00:09.0
<7>DEBUG @ether_dev_init: New net_device registered
<7>DEBUG @init_hardware: initializing hardware
<7>DEBUG @init_hardware: reseting rtl8139
<3>ERROR @init_hardware: NOT RESET
<7>DEBUG @init_hardware: enabling transmiter and receiver
<7>DEBUG @init_hardware: TCR is 74400600
<7>DEBUG @create_transmit_descriptors: creating 4 transmit descriptors
<7>DEBUG @create_transmit_descriptors: queue initialized
<7>DEBUG @create_transmit_descriptors: 4 transmit descriptors enqueued
<7>DEBUG @create TSD is 2000
<7>DEBUG @create TSD is 2000
<7>DEBUG @create TSD is 2000
<7>DEBUG @create TSD is 2000
<7>DEBUG @create ISR is 0
<7>DEBUG @init_software: found irq for this device: 11
<7>kobject eth1: registering. parent: net, set: class_obj
<7>DEBUG @register_as_network_device: netdev registered
<7>DEBUG @rtlinit: New device found
<7>DEBUG @ether_dev_open: interface is going up
<7>DEBUG @ether_dev_open: setting mac address to 0:e:2e:80:2d:de
<7>DEBUG @ether_dev_open: mac addres set properly
<7>DEBUG @ether_dev_open: irq successfuly requested
<7>DEBUG @ether_dev_open: setting interrupt mask register: 49260
<7>DEBUG @ether_dev_open: queue stared
tx: ISR is 0 TSD is 3c
<6>INFO @rtl_hw_tx: ISR is 0 TSD is 3c
<6>INFO @rtl_hw_tx: ISR is 0 TSD is 3c
...
...
<6>INFO @rtl_hw_tx: ISR is 0 TSD is 3c
best regards,
Mariusz Witosz
next reply other threads:[~2006-09-10 14:32 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-10 14:32 mwitosz-linux [this message]
2006-09-10 15:46 ` problem with OWN bit when writting driver for rtl8139? Jindrich Makovicka
2006-09-10 15:57 ` Dave Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=231c973f.7ffabfd8.450421ed.620bc@o2.pl \
--to=mwitosz-linux@o2.pl \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.