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 | <link to parent> |->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