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