On Wed, 2006-05-31 at 11:59 -0700, Stephen Hemminger wrote:
> The following should be replaced with BUG_ON() or WARN_ON().
> and pr_debug()
> 
> +#ifdef C2_DEBUG
> +#define assert(expr)                                                  \
> +    if(!(expr)) {                                                     \
> +        printk(KERN_ERR PFX "Assertion failed! %s, %s, %s, line %d\n",\
> +               #expr, __FILE__, __FUNCTION__, __LINE__);              \
> +    }
> +#define dprintk(fmt, args...) do {printk(KERN_INFO PFX fmt, ##args);} while 
> (0)
> +#else
> +#define assert(expr)          do {} while (0)
> +#define dprintk(fmt, args...) do {} while (0)
> +#endif                               /* C2_DEBUG */
> 
> --------------------
> Also, you tend to use assert() as a bogus NULL pointer check.
> If you get passed a NULL, it is a bug, and the deref will fail
> and cause a pretty stack dump...
> 

done.

> 
> +static void c2_set_rxbufsize(struct c2_port *c2_port)
> +{
> +     struct net_device *netdev = c2_port->netdev;
> +
> +     assert(netdev != NULL);
> 
> Bogus, you will just fail on the deref below
> 

done.

> +
> +     if (netdev->mtu > RX_BUF_SIZE)
> +             c2_port->rx_buf_size =
> +                 netdev->mtu + ETH_HLEN + sizeof(struct c2_rxp_hdr) +
> +                 NET_IP_ALIGN;
> +     else
> +             c2_port->rx_buf_size = sizeof(struct c2_rxp_hdr) + RX_BUF_SIZE;
> +}
> 
> 
> +static void c2_rx_interrupt(struct net_device *netdev)
> +{
> +     struct c2_port *c2_port = netdev_priv(netdev);
> +     struct c2_dev *c2dev = c2_port->c2dev;
> +     struct c2_ring *rx_ring = &c2_port->rx_ring;
> +     struct c2_element *elem;
> +     struct c2_rx_desc *rx_desc;
> +     struct c2_rxp_hdr *rxp_hdr;
> +     struct sk_buff *skb;
> +     dma_addr_t mapaddr;
> +     u32 maplen, buflen;
> +     unsigned long flags;
> +
> +     spin_lock_irqsave(&c2dev->lock, flags);
> +
> +     /* Begin where we left off */
> +     rx_ring->to_clean = rx_ring->start + c2dev->cur_rx;
> +
> +     for (elem = rx_ring->to_clean; elem->next != rx_ring->to_clean;
> +          elem = elem->next) {
> +             rx_desc = elem->ht_desc;
> +             mapaddr = elem->mapaddr;
> +             maplen = elem->maplen;
> +             skb = elem->skb;
> +             rxp_hdr = (struct c2_rxp_hdr *) skb->data;
> +
> +             if (rxp_hdr->flags != RXP_HRXD_DONE)
> +                     break;
> +             buflen = rxp_hdr->len;
> +
> +             /* Sanity check the RXP header */
> +             if (rxp_hdr->status != RXP_HRXD_OK ||
> +                 buflen > (rx_desc->len - sizeof(*rxp_hdr))) {
> +                     c2_rx_error(c2_port, elem);
> +                     continue;
> +             }
> +
> +             /* 
> +              * Allocate and map a new skb for replenishing the host 
> +              * RX desc 
> +              */
> +             if (c2_rx_alloc(c2_port, elem)) {
> +                     c2_rx_error(c2_port, elem);
> +                     continue;
> +             }
> +
> +             /* Unmap the old skb */
> +             pci_unmap_single(c2dev->pcidev, mapaddr, maplen,
> +                              PCI_DMA_FROMDEVICE);
> +
> 
> prefetch(skb->data) here will help performance.
> 
> 

good. ok.

> +             /*
> +              * Skip past the leading 8 bytes comprising of the 
> +              * "struct c2_rxp_hdr", prepended by the adapter 
> +              * to the usual Ethernet header ("struct ethhdr"), 
> +              * to the start of the raw Ethernet packet.
> +              * 
> +              * Fix up the various fields in the sk_buff before 
> +              * passing it up to netif_rx(). The transfer size 
> +              * (in bytes) specified by the adapter len field of 
> +              * the "struct rxp_hdr_t" does NOT include the 
> +              * "sizeof(struct c2_rxp_hdr)".
> +              */
> +             skb->data += sizeof(*rxp_hdr);
> +             skb->tail = skb->data + buflen;
> +             skb->len = buflen;
> +             skb->dev = netdev;
> +             skb->protocol = eth_type_trans(skb, netdev);
> +
> +             /* Drop arp requests to the pseudo nic ip addr */
> +             if (unlikely(ntohs(skb->protocol) == ETH_P_ARP)) {
> +                     u8 *tpa;
> +
> +                     /* pull out the tgt ip addr */
> +                     tpa = skb->data /* beginning of the arp packet */
> +                             + 8     /* arp addr fmts, lens, and opcode */
> +                             + 6     /* arp src hw addr */
> +                             + 4     /* arp src proto addr */
> +                             + 6;    /* arp tgt hw addr */
> +                     if (is_rnic_addr(c2dev->pseudo_netdev, *((u32 *)tpa))) {
> +                             dprintk("Dropping arp req for"
> +                                     " %03d.%03d.%03d.%03d\n",
> +                                     tpa[0], tpa[1], tpa[2], tpa[3]); 
> +                             kfree_skb(skb);
> +                             continue;
> +                     }
> +             } 
> 
> This is looks like a mess, please do it at a higher level or
> code it with proper structure headers
> 

This code can be removed entirely.  It can be avoided having the c2
driver set in_dev->cnf.arp_ignore to 1 when loaded.


> +
> +             netif_rx(skb);
> +
> +             netdev->last_rx = jiffies;
> +             c2_port->netstats.rx_packets++;
> +             c2_port->netstats.rx_bytes += buflen;
> +     }
> +
> +     /* Save where we left off */
> +     rx_ring->to_clean = elem;
> +     c2dev->cur_rx = elem - rx_ring->start;
> +     C2_SET_CUR_RX(c2dev, c2dev->cur_rx);
> +
> +     spin_unlock_irqrestore(&c2dev->lock, flags);
> +}
> +
> +/*
> + * Handle netisr0 TX & RX interrupts.
> + */
> +static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
> +{
> +     unsigned int netisr0, dmaisr;
> +     int handled = 0;
> +     struct c2_dev *c2dev = (struct c2_dev *) dev_id;
> +
> +     assert(c2dev != NULL);
> +
> +     /* Process CCILNET interrupts */
> +     netisr0 = readl(c2dev->regs + C2_NISR0);
> +     if (netisr0) {
> +
> +             /*
> +              * There is an issue with the firmware that always
> +              * provides the status of RX for both TX & RX 
> +              * interrupts.  So process both queues here.
> +              */
> +             c2_rx_interrupt(c2dev->netdev);
> +             c2_tx_interrupt(c2dev->netdev);
> +
> +             /* Clear the interrupt */
> +             writel(netisr0, c2dev->regs + C2_NISR0);
> +             handled++;
> +     }
> +
> +     /* Process RNIC interrupts */
> +     dmaisr = readl(c2dev->regs + C2_DISR);
> +     if (dmaisr) {
> +             writel(dmaisr, c2dev->regs + C2_DISR);
> +             c2_rnic_interrupt(c2dev);
> +             handled++;
> +     }
> +
> +     if (handled) {
> +             return IRQ_HANDLED;
> +     } else {
> +             return IRQ_NONE;
> +     }
> 
>       return IRQ_RETVAL(handled);
> +}
> +
> +static int c2_up(struct net_device *netdev)
> +{
> +     struct c2_port *c2_port = netdev_priv(netdev);
> +     struct c2_dev *c2dev = c2_port->c2dev;
> +     struct c2_element *elem;
> +     struct c2_rxp_hdr *rxp_hdr;
> +     size_t rx_size, tx_size;
> +     int ret, i;
> +     unsigned int netimr0;
> +
> +     assert(c2dev != NULL);
> 
> More bogus asserts
> 

removed.

<snip>

> +static struct net_device_stats *c2_get_stats(struct net_device *netdev)
> +{
> +     struct c2_port *c2_port = netdev_priv(netdev);
> +
> +     return &c2_port->netstats;
> +}
> +
> +static int c2_set_mac_address(struct net_device *netdev, void *p)
> +{
> +     return -1;
> +}
> 
> If you don't handle changing mac_address, just leaveing
> dev->set_mac_address will do the right thing.
> Also, if you need to return an error, use -ESOMEERROR, not -1.
> 

I'll remove c2_set_mac_address() entirely.

<snip>


> This seems like log spam, or developer debug thing.
> You need to learn to watch netlink event's from user space.
> 

Yes, the entire block below will be removed.  It's not needed.

> 
> +
> +#ifdef NETEVENT_NOTIFIER
> +static int netevent_notifier(struct notifier_block *self, unsigned long 
> event,
> +                          void *data)
> +{
> +     int i;
> +     u8 *ha;
> +     struct neighbour *neigh = data;
> +     struct netevent_redirect *redir = data;
> +     struct netevent_route_change *rev = data;
> +
> +     switch (event) {
> +     case NETEVENT_ROUTE_UPDATE:
> +             printk(KERN_ERR "NETEVENT_ROUTE_UPDATE:\n");
> +             printk(KERN_ERR "fib_flags           : %d\n",
> +                    rev->fib_info->fib_flags);
> +             printk(KERN_ERR "fib_protocol        : %d\n",
> +                    rev->fib_info->fib_protocol);
> +             printk(KERN_ERR "fib_prefsrc         : %08x\n",
> +                    rev->fib_info->fib_prefsrc);
> +             printk(KERN_ERR "fib_priority        : %d\n",
> +                    rev->fib_info->fib_priority);
> +             break;
> +
> +     case NETEVENT_NEIGH_UPDATE:
> +             printk(KERN_ERR "NETEVENT_NEIGH_UPDATE:\n");
> +             printk(KERN_ERR "nud_state : %d\n", neigh->nud_state);
> +             printk(KERN_ERR "refcnt    : %d\n", neigh->refcnt);
> +             printk(KERN_ERR "used      : %d\n", neigh->used);
> +             printk(KERN_ERR "confirmed : %d\n", neigh->confirmed);
> +             printk(KERN_ERR "      ha: ");
> +             for (i = 0; i < neigh->dev->addr_len; i += 4) {
> +                     ha = &neigh->ha[i];
> +                     printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +                            ha[3]);
> +             }
> +             printk("\n");
> +
> +             printk(KERN_ERR "%8s: ", neigh->dev->name);
> +             for (i = 0; i < neigh->dev->addr_len; i += 4) {
> +                     ha = &neigh->ha[i];
> +                     printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +                            ha[3]);
> +             }
> +             printk("\n");
> +             break;
> +
> +     case NETEVENT_REDIRECT:
> +             printk(KERN_ERR "NETEVENT_REDIRECT:\n");
> +             printk(KERN_ERR "old: ");
> +             for (i = 0; i < redir->old->neighbour->dev->addr_len; i += 4) {
> +                     ha = &redir->old->neighbour->ha[i];
> +                     printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +                            ha[3]);
> +             }
> +             printk("\n");
> +
> +             printk(KERN_ERR "new: ");
> +             for (i = 0; i < redir->new->neighbour->dev->addr_len; i += 4) {
> +                     ha = &redir->new->neighbour->ha[i];
> +                     printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +                            ha[3]);
> +             }
> +             printk("\n");
> +             break;
> +
> +     default:
> +             printk(KERN_ERR "NETEVENT_WTFO:\n");
> +     }
> +
> +     return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block nb = {
> +     .notifier_call = netevent_notifier,
> +};
> +#endif
> +/*



Thanks,

Steve.



-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to