July 4: Meeting with Marty: There are obviously some shortcommings in my driver design; As my driver progress has been good up to this point, I'm going to take a step back for a while and do some personal education on other drivers and driver structure;
Marty asked me to profile some drivers (r8169 and 3c90x specificly) and create outlines for each driver. I'm still not directly sure on the intention behind this; I feel a little bit like the karatee kid painting a fence.
July 5: I outlined r8169 -> see notes
July 6: I outlined 3c90x -> see notes.
While looking at 3c90x (in comparison to the outline I had done while looking through r8169), I noticed a missing memset. In theory, this shouldn't make a difference as I assume that the usage of the variables that are used are independant of the "initialization" that is done to the memory before it is used, however, all variables *should* be propperly initialized. I will speek with Marty about his opinion on this. I'm not sure if this is some sort of optimization or if it was unintentionally left out.
July 7: I'm currently working on the SKGE driver outline, in the same format as r8169 and 3c90x. -> see notes.
July 8: Worked on a new outline for skge, worked on a new version of probe. Power failure. Nothing to show for it :(
July 9-10: Missing my pills; with out them I can't stay awake at a keyboard.
July 11: Meeting with mentors. Informed that I need to make some "major progress" by monday, or be failed.
Re-wrote probe section of skge.outline
Moved the software reset section of skge_initialize into a new function and called it in probe instead. (skge_hardware_reset)
Moved chip identification section of skge_initialize into a new function and called int in probe instead. (skge_load_chip_identifiers)
in skge_initialize:
- moved hardware reset and chip identification code out of this function
- moved clock code into new function: (skge_stop_and_configure_clocks)
- moved non-genesis specific information into new function: (generic init)
outline now looks like this:
skge_probe
alloc_etherdev
netdev_init
pci_set_drvdata
adjust_pci_device
skge_get_register_address
skge_hardware_reset
skge_load_chip_identifiers
skge_initialize
skge_genesis_init
skge_generic_init
skge_stop_and_configure_clocks
skge_devinit
skge_supported_modes
netdev_link_down
netdev_link_up
skge_open
Setup RX Resources
skge_ring_alloc
skge_rx_fill
populate_rx_descriptor
Setup TX Resources
skge_ring_alloc
skge_tx_fill
skge_start_clocks
software_reset_device
skge_irq
netdev_priv
skge_transmit
skge_avail
skge_write8
skge_poll
skge_extirq
skge_process_tx
skge_tx_done
skge_process_rx
skge_rx_desc
skge_rx_get
netdev_rx
skge_refill_rx_ring
populate_rx_descriptor
skge_close
skge_hardware_reset
skge_configure_irq
skge_free_tx_resources
skge_free_rx_resources
skge_remove
pci_get_Drvdata
unregister_netdev
netdev_nullify
netdev_put
-- removed every line not directly used by probe:
- Commented out all operations in all root (core 7) functions except probe. Recompiled and commented out any "declaired but unused" functions until compiled cleanly.
cp skge.c skge.c.2
cat skge.c.2 | grep -v \n// > skge.c
- recompiled to check everything's running.
-- Resorted all functions in skge.c based on call order.
-- Changed how netdev_priv() is being used. It was previously being used to store information about the skge_port structure. It is holding the skge_private structure which was previously the skge_adapter structure.
struct skge_private {
unsigned long regs; //hardware register base
uint8_t *hw_addr; //
unsigned long io_base; // physical chip base add
struct net_device *netdev; // net device instance
struct skge_port *port; // port specific private variables
struct pci_device *pdev; // physical device instance
u32 intr_mask;
uint32_t ioaddr; // io address
uint32_t irqno; // irq number of device
uint32_t tx_ring_size; //
uint32_t rx_ring_size; //
u16 phy_addr; // physical device addres
u8 chip_id; // chip id of device
u8 chip_rev; // chip revision
u8 copper; // medium
u8 port_count; // number of ports
u8 phy_type; // ???
u32 ram_size; // ram size
u32 ram_offset; // ram offset
};
struct skge_port {
struct skge_private *adapter; // Link to parent adapter
struct net_device *netdev; // Link to sibling net_device
int port_number;
u32 msg_enable;
struct skge_ring tx_ring;
struct skge_ring rx_ring;
unsigned int rx_buf_size;
enum pause_control flow_control;
enum pause_status flow_status;
u8 rx_csum;
u8 blink_on;
u8 wol;
u8 autoneg; /* AUTONEG_ENABLE, AUTONE
u8 duplex; /* DUPLEX_HALF, DUPLEX_FU
u16 speed; /* SPEED_1000, SPEED_100,
u32 advertising;
void *mem; /* PCI memory for rings *
u32 dma;
unsigned long mem_size;
int use_xm_link_timer;
};
struct net_device {
struct refcnt refcnt;
struct list_head list;
struct list_head open_list;
char name[8];
struct device *dev;
struct net_device_operations *op;
struct ll_protocol *ll_protocol;
uint8_t ll_addr[MAX_LL_ADDR_LEN];
unsigned int state;
size_t max_pkt_len;
struct list_head tx_queue;
struct list_head rx_queue;
struct net_device_stats tx_stats;
struct net_device_stats rx_stats;
struct generic_settings settings;
void *priv;
};
As an example of how data will be passed around:
netdev
|->name
|->dev
|->op
|->ll_adr[]
|->priv
|->regs
|->netdev
|
|->port_count
|->port
| |->port_number
| |->tx_ring
| | |->*to_use -> skge_element
| | |->*to_clean -> skge_element
| | |->*start -> skge_element
| |->rx_ring
| | |->*to_use -> skge_element
| | |->*to_clean -> skge_element
| | |->*start -> skge_element
| |->rx_buf_size
| |->autoneg
| |->duplex
| |->speed
| |->advertising
| |->dma
| |->mem_size
| |->use_xm_link_timer
|->pdev
|->tx_ring_size
|->rx_ring_size
|->phy_addr
|->phy_type
|->chip_id
|->chip_rev
|->copper
|->ram_size
|->ram_offset
I took another look at open, and I'm not happy with the structure as it was;
It's again been redefined to this (but it's very likely to change by tomorrow).
skge_open
setup_rx_resources
skge_ring_alloc
refill_rx_ring
populate_rx_descriptor
setup_tx_resources
skge_ring_alloc
start_clocks
software_reset_device
Plan for tomorrow:
/Re-outline existing skge_open in much more detail
|Compare above outline with the intended structure for skge_open
|Separate tx and rx memory sections; perform two malloc_dma's instead of one;
\Each tx and rx section of open should be completely separate
Re-write skge_open (and all it's child functions)in it's new form and outline
Specificly:
- Change all instances of netdev_priv (as now netdev_priv is an instance of skge_private, not skge_port)
- Enumerate all access to the tx and rx rings and make sure they are using separated access methods.
-- Chris