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