Changeset 9334


Ignore:
Timestamp:
2007-10-16T15:12:51+02:00 (10 years ago)
Author:
juhosg
Message:

[adm5120] switch driver cleanup, 3rd phase

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/adm5120/files/drivers/net/adm5120sw.c

    r9330 r9334  
    164164 
    165165static struct net_device sw_dev; 
    166 static struct net_device *poll_dev; 
    167166 
    168167/* ------------------------------------------------------------------------ */ 
     
    459458 
    460459 
    461 static int adm5120_switch_poll(struct net_device *dev, int *budget) 
    462 { 
    463         int limit = min(dev->quota, *budget); 
    464         int done; 
    465         u32 status; 
    466  
    467         done = adm5120_switch_rx(limit); 
    468  
    469         *budget -= done; 
    470         dev->quota -= done; 
    471  
    472         status = sw_int_status() & SWITCH_INTS_POLL; 
    473         if ((done < limit) && (!status)) { 
    474                 spin_lock_irq(&poll_lock); 
    475                 SW_DBG("disable polling mode for %s\n", poll_dev->name); 
    476                 netif_rx_complete(poll_dev); 
    477                 sw_int_unmask(SWITCH_INTS_POLL); 
    478                 poll_dev = NULL; 
    479                 spin_unlock_irq(&poll_lock); 
    480                 return 0; 
    481         } 
    482  
    483         return 1; 
    484 } 
    485  
    486460static void adm5120_switch_tx(void) 
    487461{ 
     
    518492} 
    519493 
     494static int adm5120_if_poll(struct net_device *dev, int *budget) 
     495{ 
     496        int limit = min(dev->quota, *budget); 
     497        int done; 
     498        u32 status; 
     499 
     500        done = adm5120_switch_rx(limit); 
     501 
     502        *budget -= done; 
     503        dev->quota -= done; 
     504 
     505        status = sw_int_status() & SWITCH_INTS_POLL; 
     506        if ((done < limit) && (!status)) { 
     507                SW_DBG("disable polling mode for %s\n", poll_dev->name); 
     508                netif_rx_complete(dev); 
     509                sw_int_unmask(SWITCH_INTS_POLL); 
     510                return 0; 
     511        } 
     512 
     513        return 1; 
     514} 
     515 
    520516static irqreturn_t adm5120_poll_irq(int irq, void *dev_id) 
    521517{ 
     
    530526        sw_dump_intr_mask("poll ints", status); 
    531527 
    532         if (!netif_running(dev)) { 
    533                 SW_DBG("device %s is not running\n", dev->name); 
    534                 return IRQ_NONE; 
    535         } 
    536  
    537         spin_lock(&poll_lock); 
    538         if (!poll_dev) { 
    539                 SW_DBG("enable polling mode for %s\n", dev->name); 
    540                 poll_dev = dev; 
    541                 sw_int_mask(SWITCH_INTS_POLL); 
    542                 netif_rx_schedule(poll_dev); 
    543         } 
    544         spin_unlock(&poll_lock); 
     528        SW_DBG("enable polling mode for %s\n", dev->name); 
     529        sw_int_mask(SWITCH_INTS_POLL); 
     530        netif_rx_schedule(dev); 
    545531 
    546532        return IRQ_HANDLED; 
     
    606592} 
    607593 
    608 static int adm5120_switch_open(struct net_device *dev) 
     594static void adm5120_switch_tx_ring_reset(struct dma_desc *desc, 
     595                struct sk_buff **skbl, int num) 
     596{ 
     597        memset(desc, 0, num * sizeof(*desc)); 
     598        desc[num-1].buf1 |= DESC_EOR; 
     599        memset(skbl, 0, sizeof(struct skb*)*num); 
     600 
     601        cur_txl = 0; 
     602        dirty_txl = 0; 
     603} 
     604 
     605static void adm5120_switch_rx_ring_reset(struct dma_desc *desc, 
     606                struct sk_buff **skbl, int num) 
     607{ 
     608        int i; 
     609 
     610        memset(desc, 0, num * sizeof(*desc)); 
     611        for (i = 0; i < num; i++) { 
     612                skbl[i] = dev_alloc_skb(SKB_ALLOC_LEN); 
     613                if (!skbl[i]) { 
     614                        i = num; 
     615                        break; 
     616                } 
     617                skb_reserve(skbl[i], SKB_RESERVE_LEN); 
     618                adm5120_rx_dma_update(&desc[i], skbl[i], (num-1==i)); 
     619        } 
     620 
     621        cur_rxl = 0; 
     622        dirty_rxl = 0; 
     623} 
     624 
     625static int adm5120_switch_tx_ring_alloc(void) 
     626{ 
     627        int err; 
     628 
     629        txl_descs = dma_alloc_coherent(NULL, TX_DESCS_SIZE, &txl_descs_dma, 
     630                                        GFP_ATOMIC); 
     631        if (!txl_descs) { 
     632                err = -ENOMEM; 
     633                goto err; 
     634        } 
     635 
     636        txl_skbuff = kzalloc(TX_SKBS_SIZE, GFP_KERNEL); 
     637        if (!txl_skbuff) { 
     638                err = -ENOMEM; 
     639                goto err; 
     640        } 
     641 
     642        return 0; 
     643 
     644err: 
     645        return err; 
     646} 
     647 
     648static void adm5120_switch_tx_ring_free(void) 
     649{ 
     650        int i; 
     651 
     652        if (txl_skbuff) { 
     653                for (i = 0; i < TX_RING_SIZE; i++) 
     654                        if (txl_skbuff[i]) 
     655                                kfree_skb(txl_skbuff[i]); 
     656                kfree(txl_skbuff); 
     657        } 
     658 
     659        if (txl_descs) 
     660                dma_free_coherent(NULL, TX_DESCS_SIZE, txl_descs, 
     661                        txl_descs_dma); 
     662} 
     663 
     664static int adm5120_switch_rx_ring_alloc(void) 
     665{ 
     666        int err; 
     667        int i; 
     668 
     669        /* init RX ring */ 
     670        rxl_descs = dma_alloc_coherent(NULL, RX_DESCS_SIZE, &rxl_descs_dma, 
     671                                        GFP_ATOMIC); 
     672        if (!rxl_descs) { 
     673                err = -ENOMEM; 
     674                goto err; 
     675        } 
     676 
     677        rxl_skbuff = kzalloc(RX_SKBS_SIZE, GFP_KERNEL); 
     678        if (!rxl_skbuff) { 
     679                err = -ENOMEM; 
     680                goto err; 
     681        } 
     682 
     683        for (i = 0; i < RX_RING_SIZE; i++) { 
     684                struct sk_buff *skb; 
     685                skb = alloc_skb(SKB_ALLOC_LEN, GFP_ATOMIC); 
     686                if (!skb) { 
     687                        err = -ENOMEM; 
     688                        goto err; 
     689                } 
     690                rxl_skbuff[i] = skb; 
     691                skb_reserve(skb, SKB_RESERVE_LEN); 
     692        } 
     693 
     694        return 0; 
     695 
     696err: 
     697        return err; 
     698} 
     699 
     700static void adm5120_switch_rx_ring_free(void) 
     701{ 
     702        int i; 
     703 
     704        if (rxl_skbuff) { 
     705                for (i = 0; i < RX_RING_SIZE; i++) 
     706                        if (rxl_skbuff[i]) 
     707                                kfree_skb(rxl_skbuff[i]); 
     708                kfree(rxl_skbuff); 
     709        } 
     710 
     711        if (rxl_descs) 
     712                dma_free_coherent(NULL, RX_DESCS_SIZE, rxl_descs, 
     713                        rxl_descs_dma); 
     714} 
     715 
     716/* ------------------------------------------------------------------------ */ 
     717 
     718static int adm5120_if_open(struct net_device *dev) 
    609719{ 
    610720        u32 t; 
     721        int err; 
    611722        int i; 
    612723 
    613         netif_start_queue(dev); 
     724        err = request_irq(dev->irq, adm5120_poll_irq, 
     725                (IRQF_SHARED | IRQF_DISABLED), dev->name, dev); 
     726        if (err) { 
     727                SW_ERR("unable to get irq for %s\n", dev->name); 
     728                goto err; 
     729        } 
     730 
    614731        if (!sw_used++) 
    615732                /* enable interrupts on first open */ 
     
    624741        sw_write_reg(SWITCH_REG_PORT_CONF0, t); 
    625742 
     743        netif_start_queue(dev); 
     744 
    626745        return 0; 
    627 } 
    628  
    629 static int adm5120_switch_stop(struct net_device *dev) 
     746 
     747err: 
     748        return err; 
     749} 
     750 
     751static int adm5120_if_stop(struct net_device *dev) 
    630752{ 
    631753        u32 t; 
    632754        int i; 
    633755 
    634         if (!--sw_used) 
    635                 sw_int_mask(SWITCH_INTS_USED); 
     756        netif_stop_queue(dev); 
    636757 
    637758        /* disable port if not assigned to other devices */ 
     
    644765        sw_write_reg(SWITCH_REG_PORT_CONF0, t); 
    645766 
    646         netif_stop_queue(dev); 
     767        if (!--sw_used) 
     768                sw_int_mask(SWITCH_INTS_USED); 
     769 
     770        free_irq(dev->irq, dev); 
     771 
    647772        return 0; 
    648773} 
    649774 
    650 static int adm5120_sw_start_xmit(struct sk_buff *skb, struct net_device *dev) 
     775static int adm5120_if_hard_start_xmit(struct sk_buff *skb, 
     776                struct net_device *dev) 
    651777{ 
    652778        struct dma_desc *desc; 
     
    696822} 
    697823 
    698 static void adm5120_tx_timeout(struct net_device *dev) 
     824static void adm5120_if_tx_timeout(struct net_device *dev) 
    699825{ 
    700826        SW_INFO("TX timeout on %s\n",dev->name); 
     
    770896} 
    771897 
    772 static int adm5120_sw_set_mac_address(struct net_device *dev, void *p) 
     898static int adm5120_if_set_mac_address(struct net_device *dev, void *p) 
    773899{ 
    774900        struct sockaddr *addr = p; 
     
    779905} 
    780906 
    781 static int adm5120_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 
     907static int adm5120_if_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 
    782908{ 
    783909        int err; 
     
    828954} 
    829955 
    830 static void adm5120_dma_tx_init(struct dma_desc *desc, struct sk_buff **skbl, 
    831                 int num) 
    832 { 
    833         memset(desc, 0, num * sizeof(*desc)); 
    834         desc[num-1].buf1 |= DESC_EOR; 
    835         memset(skbl, 0, sizeof(struct skb*)*num); 
    836 } 
    837  
    838 static void adm5120_dma_rx_init(struct dma_desc *desc, struct sk_buff **skbl, 
    839                 int num) 
    840 { 
    841         int i; 
    842  
    843         memset(desc, 0, num * sizeof(*desc)); 
    844         for (i=0; i<num; i++) { 
    845                 skbl[i] = dev_alloc_skb(SKB_ALLOC_LEN); 
    846                 if (!skbl[i]) { 
    847                         i=num; 
    848                         break; 
    849                 } 
    850                 skb_reserve(skbl[i], SKB_RESERVE_LEN); 
    851                 adm5120_rx_dma_update(&desc[i], skbl[i], (num-1==i)); 
    852         } 
     956static struct net_device *adm5120_if_alloc(void) 
     957{ 
     958        struct net_device *dev; 
     959        struct adm5120_sw *priv; 
     960 
     961        dev = alloc_etherdev(sizeof(*priv)); 
     962        if (!dev) 
     963                return NULL; 
     964 
     965        dev->irq                = ADM5120_IRQ_SWITCH; 
     966        dev->open               = adm5120_if_open; 
     967        dev->hard_start_xmit    = adm5120_if_hard_start_xmit; 
     968        dev->stop               = adm5120_if_stop; 
     969        dev->set_multicast_list = adm5120_set_multicast_list; 
     970        dev->do_ioctl           = adm5120_if_do_ioctl; 
     971        dev->tx_timeout         = adm5120_if_tx_timeout; 
     972        dev->watchdog_timeo     = TX_TIMEOUT; 
     973        dev->set_mac_address    = adm5120_if_set_mac_address; 
     974        dev->poll               = adm5120_if_poll; 
     975        dev->weight             = 64; 
     976 
     977        SET_MODULE_OWNER(dev); 
     978 
     979        return dev; 
    853980} 
    854981 
     
    864991                if (dev) { 
    865992                        unregister_netdev(dev); 
    866                         free_irq(ADM5120_IRQ_SWITCH, dev); 
    867993                        free_netdev(dev); 
    868994                } 
    869995        } 
    870996 
    871         /* cleanup TX ring */ 
    872         if (txl_skbuff) { 
    873                 for (i = 0; i < TX_RING_SIZE; i++) 
    874                         if (txl_skbuff[i]) 
    875                                 kfree_skb(txl_skbuff[i]); 
    876                 kfree(txl_skbuff); 
    877         } 
    878  
    879         if (txl_descs) 
    880                 dma_free_coherent(NULL, TX_DESCS_SIZE, txl_descs, 
    881                         txl_descs_dma); 
    882  
    883         /* cleanup RX ring */ 
    884         if (rxl_skbuff) { 
    885                 for (i = 0; i < RX_RING_SIZE; i++) 
    886                         if (rxl_skbuff[i]) 
    887                                 kfree_skb(rxl_skbuff[i]); 
    888                 kfree(rxl_skbuff); 
    889         } 
    890  
    891         if (rxl_descs) 
    892                 dma_free_coherent(NULL, RX_DESCS_SIZE, rxl_descs, 
    893                         rxl_descs_dma); 
     997        adm5120_switch_tx_ring_free(); 
     998        adm5120_switch_rx_ring_free(); 
    894999 
    8951000        free_irq(ADM5120_IRQ_SWITCH, &sw_dev); 
     
    8981003static int __init adm5120_switch_init(void) 
    8991004{ 
    900         struct net_device *dev; 
    9011005        u32 t; 
    9021006        int i, err; 
     
    9401044        sw_int_ack(SWITCH_INTS_ALL); 
    9411045 
    942         /* init RX ring */ 
    943         cur_rxl = dirty_rxl = 0; 
    944         rxl_descs = dma_alloc_coherent(NULL, RX_DESCS_SIZE, &rxl_descs_dma, 
    945                                         GFP_ATOMIC); 
    946         if (!rxl_descs) { 
    947                 err = -ENOMEM; 
     1046        err = adm5120_switch_rx_ring_alloc(); 
     1047        if (err) 
    9481048                goto err; 
    949         } 
    950  
    951         rxl_skbuff = kzalloc(RX_SKBS_SIZE, GFP_KERNEL); 
    952         if (!rxl_skbuff) { 
    953                 err = -ENOMEM; 
     1049 
     1050        err = adm5120_switch_tx_ring_alloc(); 
     1051        if (err) 
    9541052                goto err; 
    955         } 
    956  
    957         for (i = 0; i < RX_RING_SIZE; i++) { 
    958                 struct sk_buff *skb; 
    959                 skb = alloc_skb(SKB_ALLOC_LEN, GFP_ATOMIC); 
    960                 if (!skb) { 
    961                         err = -ENOMEM; 
    962                         goto err; 
    963                 } 
    964                 rxl_skbuff[i] = skb; 
    965                 skb_reserve(skb, SKB_RESERVE_LEN); 
    966         } 
    967  
    968         /* init TX ring */ 
    969         cur_txl = dirty_txl = 0; 
    970         txl_descs = dma_alloc_coherent(NULL, TX_DESCS_SIZE, &txl_descs_dma, 
    971                                         GFP_ATOMIC); 
    972         if (!txl_descs) { 
    973                 err = -ENOMEM; 
    974                 goto err; 
    975         } 
    976  
    977         txl_skbuff = kzalloc(TX_SKBS_SIZE, GFP_KERNEL); 
    978         if (!txl_skbuff) { 
    979                 err = -ENOMEM; 
    980                 goto err; 
    981         } 
    982  
    983         adm5120_dma_tx_init(txl_descs, txl_skbuff, TX_RING_SIZE); 
    984         adm5120_dma_rx_init(rxl_descs, rxl_skbuff, RX_RING_SIZE); 
     1053 
     1054        adm5120_switch_tx_ring_reset(txl_descs, txl_skbuff, TX_RING_SIZE); 
     1055        adm5120_switch_rx_ring_reset(rxl_descs, rxl_skbuff, RX_RING_SIZE); 
    9851056 
    9861057        sw_write_reg(SWITCH_REG_SHDA, 0); 
     
    9901061 
    9911062        for (i = 0; i < SWITCH_NUM_PORTS; i++) { 
    992                 adm5120_devs[i] = alloc_etherdev(sizeof(struct adm5120_sw)); 
    993                 if (!adm5120_devs[i]) { 
     1063                struct net_device *dev; 
     1064                struct adm5120_sw *priv; 
     1065 
     1066                dev = adm5120_if_alloc(); 
     1067                if (!dev) { 
    9941068                        err = -ENOMEM; 
    9951069                        goto err; 
    9961070                } 
    9971071 
    998                 dev = adm5120_devs[i]; 
    999                 err = request_irq(ADM5120_IRQ_SWITCH, adm5120_poll_irq, 
    1000                         (IRQF_SHARED | IRQF_DISABLED), dev->name, dev); 
    1001                 if (err) { 
    1002                         SW_ERR("unable to get irq for %s\n", dev->name); 
    1003                         goto err; 
    1004                 } 
    1005  
    1006                 SET_MODULE_OWNER(dev); 
    1007                 memset(netdev_priv(dev), 0, sizeof(struct adm5120_sw)); 
    1008                 ((struct adm5120_sw*)netdev_priv(dev))->port = i; 
    1009                 dev->base_addr = ADM5120_SWITCH_BASE; 
    1010                 dev->irq = ADM5120_IRQ_SWITCH; 
    1011                 dev->open = adm5120_switch_open; 
    1012                 dev->hard_start_xmit = adm5120_sw_start_xmit; 
    1013                 dev->stop = adm5120_switch_stop; 
    1014                 dev->set_multicast_list = adm5120_set_multicast_list; 
    1015                 dev->do_ioctl = adm5120_do_ioctl; 
    1016                 dev->tx_timeout = adm5120_tx_timeout; 
    1017                 dev->watchdog_timeo = TX_TIMEOUT; 
    1018                 dev->set_mac_address = adm5120_sw_set_mac_address; 
    1019                 dev->poll = adm5120_switch_poll; 
    1020                 dev->weight = 64; 
     1072                adm5120_devs[i] = dev; 
     1073                priv = netdev_priv(dev); 
     1074 
     1075                priv->port = i; 
    10211076 
    10221077                memcpy(dev->dev_addr, adm5120_eth_macs[i], 6); 
     
    10291084                        goto err; 
    10301085                } 
    1031                 SW_INFO("%s created for switch port%d\n", dev->name, i); 
    10321086        } 
    10331087 
Note: See TracChangeset for help on using the changeset viewer.