diff options
Diffstat (limited to 'drivers/net/spider_net.c')
-rw-r--r-- | drivers/net/spider_net.c | 313 |
1 files changed, 150 insertions, 163 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 8ea2fc1b96cb..bf6ff39e02bb 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -280,72 +280,67 @@ spider_net_free_chain(struct spider_net_card *card, | |||
280 | { | 280 | { |
281 | struct spider_net_descr *descr; | 281 | struct spider_net_descr *descr; |
282 | 282 | ||
283 | for (descr = chain->tail; !descr->bus_addr; descr = descr->next) { | 283 | descr = chain->ring; |
284 | pci_unmap_single(card->pdev, descr->bus_addr, | 284 | do { |
285 | SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
286 | descr->bus_addr = 0; | 285 | descr->bus_addr = 0; |
287 | } | 286 | descr->next_descr_addr = 0; |
287 | descr = descr->next; | ||
288 | } while (descr != chain->ring); | ||
289 | |||
290 | dma_free_coherent(&card->pdev->dev, chain->num_desc, | ||
291 | chain->ring, chain->dma_addr); | ||
288 | } | 292 | } |
289 | 293 | ||
290 | /** | 294 | /** |
291 | * spider_net_init_chain - links descriptor chain | 295 | * spider_net_init_chain - alloc and link descriptor chain |
292 | * @card: card structure | 296 | * @card: card structure |
293 | * @chain: address of chain | 297 | * @chain: address of chain |
294 | * @start_descr: address of descriptor array | ||
295 | * @no: number of descriptors | ||
296 | * | 298 | * |
297 | * we manage a circular list that mirrors the hardware structure, | 299 | * We manage a circular list that mirrors the hardware structure, |
298 | * except that the hardware uses bus addresses. | 300 | * except that the hardware uses bus addresses. |
299 | * | 301 | * |
300 | * returns 0 on success, <0 on failure | 302 | * Returns 0 on success, <0 on failure |
301 | */ | 303 | */ |
302 | static int | 304 | static int |
303 | spider_net_init_chain(struct spider_net_card *card, | 305 | spider_net_init_chain(struct spider_net_card *card, |
304 | struct spider_net_descr_chain *chain, | 306 | struct spider_net_descr_chain *chain) |
305 | struct spider_net_descr *start_descr, | ||
306 | int no) | ||
307 | { | 307 | { |
308 | int i; | 308 | int i; |
309 | struct spider_net_descr *descr; | 309 | struct spider_net_descr *descr; |
310 | dma_addr_t buf; | 310 | dma_addr_t buf; |
311 | size_t alloc_size; | ||
311 | 312 | ||
312 | descr = start_descr; | 313 | alloc_size = chain->num_desc * sizeof (struct spider_net_descr); |
313 | memset(descr, 0, sizeof(*descr) * no); | ||
314 | 314 | ||
315 | /* set up the hardware pointers in each descriptor */ | 315 | chain->ring = dma_alloc_coherent(&card->pdev->dev, alloc_size, |
316 | for (i=0; i<no; i++, descr++) { | 316 | &chain->dma_addr, GFP_KERNEL); |
317 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 317 | |
318 | if (!chain->ring) | ||
319 | return -ENOMEM; | ||
318 | 320 | ||
319 | buf = pci_map_single(card->pdev, descr, | 321 | descr = chain->ring; |
320 | SPIDER_NET_DESCR_SIZE, | 322 | memset(descr, 0, alloc_size); |
321 | PCI_DMA_BIDIRECTIONAL); | ||
322 | 323 | ||
323 | if (pci_dma_mapping_error(buf)) | 324 | /* Set up the hardware pointers in each descriptor */ |
324 | goto iommu_error; | 325 | buf = chain->dma_addr; |
326 | for (i=0; i < chain->num_desc; i++, descr++) { | ||
327 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | ||
325 | 328 | ||
326 | descr->bus_addr = buf; | 329 | descr->bus_addr = buf; |
330 | descr->next_descr_addr = 0; | ||
327 | descr->next = descr + 1; | 331 | descr->next = descr + 1; |
328 | descr->prev = descr - 1; | 332 | descr->prev = descr - 1; |
329 | 333 | ||
334 | buf += sizeof(struct spider_net_descr); | ||
330 | } | 335 | } |
331 | /* do actual circular list */ | 336 | /* do actual circular list */ |
332 | (descr-1)->next = start_descr; | 337 | (descr-1)->next = chain->ring; |
333 | start_descr->prev = descr-1; | 338 | chain->ring->prev = descr-1; |
334 | 339 | ||
335 | spin_lock_init(&chain->lock); | 340 | spin_lock_init(&chain->lock); |
336 | chain->head = start_descr; | 341 | chain->head = chain->ring; |
337 | chain->tail = start_descr; | 342 | chain->tail = chain->ring; |
338 | |||
339 | return 0; | 343 | return 0; |
340 | |||
341 | iommu_error: | ||
342 | descr = start_descr; | ||
343 | for (i=0; i < no; i++, descr++) | ||
344 | if (descr->bus_addr) | ||
345 | pci_unmap_single(card->pdev, descr->bus_addr, | ||
346 | SPIDER_NET_DESCR_SIZE, | ||
347 | PCI_DMA_BIDIRECTIONAL); | ||
348 | return -ENOMEM; | ||
349 | } | 344 | } |
350 | 345 | ||
351 | /** | 346 | /** |
@@ -372,21 +367,20 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) | |||
372 | } | 367 | } |
373 | 368 | ||
374 | /** | 369 | /** |
375 | * spider_net_prepare_rx_descr - reinitializes a rx descriptor | 370 | * spider_net_prepare_rx_descr - Reinitialize RX descriptor |
376 | * @card: card structure | 371 | * @card: card structure |
377 | * @descr: descriptor to re-init | 372 | * @descr: descriptor to re-init |
378 | * | 373 | * |
379 | * return 0 on succes, <0 on failure | 374 | * Return 0 on succes, <0 on failure. |
380 | * | 375 | * |
381 | * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. | 376 | * Allocates a new rx skb, iommu-maps it and attaches it to the |
382 | * Activate the descriptor state-wise | 377 | * descriptor. Mark the descriptor as activated, ready-to-use. |
383 | */ | 378 | */ |
384 | static int | 379 | static int |
385 | spider_net_prepare_rx_descr(struct spider_net_card *card, | 380 | spider_net_prepare_rx_descr(struct spider_net_card *card, |
386 | struct spider_net_descr *descr) | 381 | struct spider_net_descr *descr) |
387 | { | 382 | { |
388 | dma_addr_t buf; | 383 | dma_addr_t buf; |
389 | int error = 0; | ||
390 | int offset; | 384 | int offset; |
391 | int bufsize; | 385 | int bufsize; |
392 | 386 | ||
@@ -414,7 +408,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
414 | (SPIDER_NET_RXBUF_ALIGN - 1); | 408 | (SPIDER_NET_RXBUF_ALIGN - 1); |
415 | if (offset) | 409 | if (offset) |
416 | skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); | 410 | skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); |
417 | /* io-mmu-map the skb */ | 411 | /* iommu-map the skb */ |
418 | buf = pci_map_single(card->pdev, descr->skb->data, | 412 | buf = pci_map_single(card->pdev, descr->skb->data, |
419 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | 413 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
420 | descr->buf_addr = buf; | 414 | descr->buf_addr = buf; |
@@ -425,11 +419,16 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
425 | card->spider_stats.rx_iommu_map_error++; | 419 | card->spider_stats.rx_iommu_map_error++; |
426 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 420 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
427 | } else { | 421 | } else { |
422 | descr->next_descr_addr = 0; | ||
423 | wmb(); | ||
428 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | | 424 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | |
429 | SPIDER_NET_DMAC_NOINTR_COMPLETE; | 425 | SPIDER_NET_DMAC_NOINTR_COMPLETE; |
426 | |||
427 | wmb(); | ||
428 | descr->prev->next_descr_addr = descr->bus_addr; | ||
430 | } | 429 | } |
431 | 430 | ||
432 | return error; | 431 | return 0; |
433 | } | 432 | } |
434 | 433 | ||
435 | /** | 434 | /** |
@@ -493,10 +492,10 @@ spider_net_refill_rx_chain(struct spider_net_card *card) | |||
493 | } | 492 | } |
494 | 493 | ||
495 | /** | 494 | /** |
496 | * spider_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains | 495 | * spider_net_alloc_rx_skbs - Allocates rx skbs in rx descriptor chains |
497 | * @card: card structure | 496 | * @card: card structure |
498 | * | 497 | * |
499 | * returns 0 on success, <0 on failure | 498 | * Returns 0 on success, <0 on failure. |
500 | */ | 499 | */ |
501 | static int | 500 | static int |
502 | spider_net_alloc_rx_skbs(struct spider_net_card *card) | 501 | spider_net_alloc_rx_skbs(struct spider_net_card *card) |
@@ -507,16 +506,16 @@ spider_net_alloc_rx_skbs(struct spider_net_card *card) | |||
507 | result = -ENOMEM; | 506 | result = -ENOMEM; |
508 | 507 | ||
509 | chain = &card->rx_chain; | 508 | chain = &card->rx_chain; |
510 | /* put at least one buffer into the chain. if this fails, | 509 | /* Put at least one buffer into the chain. if this fails, |
511 | * we've got a problem. if not, spider_net_refill_rx_chain | 510 | * we've got a problem. If not, spider_net_refill_rx_chain |
512 | * will do the rest at the end of this function */ | 511 | * will do the rest at the end of this function. */ |
513 | if (spider_net_prepare_rx_descr(card, chain->head)) | 512 | if (spider_net_prepare_rx_descr(card, chain->head)) |
514 | goto error; | 513 | goto error; |
515 | else | 514 | else |
516 | chain->head = chain->head->next; | 515 | chain->head = chain->head->next; |
517 | 516 | ||
518 | /* this will allocate the rest of the rx buffers; if not, it's | 517 | /* This will allocate the rest of the rx buffers; |
519 | * business as usual later on */ | 518 | * if not, it's business as usual later on. */ |
520 | spider_net_refill_rx_chain(card); | 519 | spider_net_refill_rx_chain(card); |
521 | spider_net_enable_rxdmac(card); | 520 | spider_net_enable_rxdmac(card); |
522 | return 0; | 521 | return 0; |
@@ -707,7 +706,7 @@ spider_net_set_low_watermark(struct spider_net_card *card) | |||
707 | } | 706 | } |
708 | 707 | ||
709 | /* If TX queue is short, don't even bother with interrupts */ | 708 | /* If TX queue is short, don't even bother with interrupts */ |
710 | if (cnt < card->num_tx_desc/4) | 709 | if (cnt < card->tx_chain.num_desc/4) |
711 | return cnt; | 710 | return cnt; |
712 | 711 | ||
713 | /* Set low-watermark 3/4th's of the way into the queue. */ | 712 | /* Set low-watermark 3/4th's of the way into the queue. */ |
@@ -915,16 +914,13 @@ spider_net_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
915 | * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on | 914 | * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on |
916 | * @descr: descriptor to process | 915 | * @descr: descriptor to process |
917 | * @card: card structure | 916 | * @card: card structure |
918 | * @napi: whether caller is in NAPI context | ||
919 | * | ||
920 | * returns 1 on success, 0 if no packet was passed to the stack | ||
921 | * | 917 | * |
922 | * iommu-unmaps the skb, fills out skb structure and passes the data to the | 918 | * Fills out skb structure and passes the data to the stack. |
923 | * stack. The descriptor state is not changed. | 919 | * The descriptor state is not changed. |
924 | */ | 920 | */ |
925 | static int | 921 | static void |
926 | spider_net_pass_skb_up(struct spider_net_descr *descr, | 922 | spider_net_pass_skb_up(struct spider_net_descr *descr, |
927 | struct spider_net_card *card, int napi) | 923 | struct spider_net_card *card) |
928 | { | 924 | { |
929 | struct sk_buff *skb; | 925 | struct sk_buff *skb; |
930 | struct net_device *netdev; | 926 | struct net_device *netdev; |
@@ -932,23 +928,8 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, | |||
932 | 928 | ||
933 | data_status = descr->data_status; | 929 | data_status = descr->data_status; |
934 | data_error = descr->data_error; | 930 | data_error = descr->data_error; |
935 | |||
936 | netdev = card->netdev; | 931 | netdev = card->netdev; |
937 | 932 | ||
938 | /* unmap descriptor */ | ||
939 | pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, | ||
940 | PCI_DMA_FROMDEVICE); | ||
941 | |||
942 | /* the cases we'll throw away the packet immediately */ | ||
943 | if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { | ||
944 | if (netif_msg_rx_err(card)) | ||
945 | pr_err("error in received descriptor found, " | ||
946 | "data_status=x%08x, data_error=x%08x\n", | ||
947 | data_status, data_error); | ||
948 | card->spider_stats.rx_desc_error++; | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | skb = descr->skb; | 933 | skb = descr->skb; |
953 | skb->dev = netdev; | 934 | skb->dev = netdev; |
954 | skb_put(skb, descr->valid_size); | 935 | skb_put(skb, descr->valid_size); |
@@ -977,57 +958,72 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, | |||
977 | } | 958 | } |
978 | 959 | ||
979 | /* pass skb up to stack */ | 960 | /* pass skb up to stack */ |
980 | if (napi) | 961 | netif_receive_skb(skb); |
981 | netif_receive_skb(skb); | ||
982 | else | ||
983 | netif_rx_ni(skb); | ||
984 | 962 | ||
985 | /* update netdevice statistics */ | 963 | /* update netdevice statistics */ |
986 | card->netdev_stats.rx_packets++; | 964 | card->netdev_stats.rx_packets++; |
987 | card->netdev_stats.rx_bytes += skb->len; | 965 | card->netdev_stats.rx_bytes += skb->len; |
966 | } | ||
988 | 967 | ||
989 | return 1; | 968 | #ifdef DEBUG |
969 | static void show_rx_chain(struct spider_net_card *card) | ||
970 | { | ||
971 | struct spider_net_descr_chain *chain = &card->rx_chain; | ||
972 | struct spider_net_descr *start= chain->tail; | ||
973 | struct spider_net_descr *descr= start; | ||
974 | int status; | ||
975 | |||
976 | int cnt = 0; | ||
977 | int cstat = spider_net_get_descr_status(descr); | ||
978 | printk(KERN_INFO "RX chain tail at descr=%ld\n", | ||
979 | (start - card->descr) - card->tx_chain.num_desc); | ||
980 | status = cstat; | ||
981 | do | ||
982 | { | ||
983 | status = spider_net_get_descr_status(descr); | ||
984 | if (cstat != status) { | ||
985 | printk(KERN_INFO "Have %d descrs with stat=x%08x\n", cnt, cstat); | ||
986 | cstat = status; | ||
987 | cnt = 0; | ||
988 | } | ||
989 | cnt ++; | ||
990 | descr = descr->next; | ||
991 | } while (descr != start); | ||
992 | printk(KERN_INFO "Last %d descrs with stat=x%08x\n", cnt, cstat); | ||
990 | } | 993 | } |
994 | #endif | ||
991 | 995 | ||
992 | /** | 996 | /** |
993 | * spider_net_decode_one_descr - processes an rx descriptor | 997 | * spider_net_decode_one_descr - processes an rx descriptor |
994 | * @card: card structure | 998 | * @card: card structure |
995 | * @napi: whether caller is in NAPI context | ||
996 | * | 999 | * |
997 | * returns 1 if a packet has been sent to the stack, otherwise 0 | 1000 | * Returns 1 if a packet has been sent to the stack, otherwise 0 |
998 | * | 1001 | * |
999 | * processes an rx descriptor by iommu-unmapping the data buffer and passing | 1002 | * Processes an rx descriptor by iommu-unmapping the data buffer and passing |
1000 | * the packet up to the stack. This function is called in softirq | 1003 | * the packet up to the stack. This function is called in softirq |
1001 | * context, e.g. either bottom half from interrupt or NAPI polling context | 1004 | * context, e.g. either bottom half from interrupt or NAPI polling context |
1002 | */ | 1005 | */ |
1003 | static int | 1006 | static int |
1004 | spider_net_decode_one_descr(struct spider_net_card *card, int napi) | 1007 | spider_net_decode_one_descr(struct spider_net_card *card) |
1005 | { | 1008 | { |
1006 | struct spider_net_descr_chain *chain = &card->rx_chain; | 1009 | struct spider_net_descr_chain *chain = &card->rx_chain; |
1007 | struct spider_net_descr *descr = chain->tail; | 1010 | struct spider_net_descr *descr = chain->tail; |
1008 | int status; | 1011 | int status; |
1009 | int result; | ||
1010 | 1012 | ||
1011 | status = spider_net_get_descr_status(descr); | 1013 | status = spider_net_get_descr_status(descr); |
1012 | 1014 | ||
1013 | if (status == SPIDER_NET_DESCR_CARDOWNED) { | 1015 | /* Nothing in the descriptor, or ring must be empty */ |
1014 | /* nothing in the descriptor yet */ | 1016 | if ((status == SPIDER_NET_DESCR_CARDOWNED) || |
1015 | result=0; | 1017 | (status == SPIDER_NET_DESCR_NOT_IN_USE)) |
1016 | goto out; | 1018 | return 0; |
1017 | } | ||
1018 | |||
1019 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) { | ||
1020 | /* not initialized yet, the ring must be empty */ | ||
1021 | spider_net_refill_rx_chain(card); | ||
1022 | spider_net_enable_rxdmac(card); | ||
1023 | result=0; | ||
1024 | goto out; | ||
1025 | } | ||
1026 | 1019 | ||
1027 | /* descriptor definitively used -- move on tail */ | 1020 | /* descriptor definitively used -- move on tail */ |
1028 | chain->tail = descr->next; | 1021 | chain->tail = descr->next; |
1029 | 1022 | ||
1030 | result = 0; | 1023 | /* unmap descriptor */ |
1024 | pci_unmap_single(card->pdev, descr->buf_addr, | ||
1025 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | ||
1026 | |||
1031 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || | 1027 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || |
1032 | (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || | 1028 | (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || |
1033 | (status == SPIDER_NET_DESCR_FORCE_END) ) { | 1029 | (status == SPIDER_NET_DESCR_FORCE_END) ) { |
@@ -1035,31 +1031,55 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) | |||
1035 | pr_err("%s: dropping RX descriptor with state %d\n", | 1031 | pr_err("%s: dropping RX descriptor with state %d\n", |
1036 | card->netdev->name, status); | 1032 | card->netdev->name, status); |
1037 | card->netdev_stats.rx_dropped++; | 1033 | card->netdev_stats.rx_dropped++; |
1038 | pci_unmap_single(card->pdev, descr->buf_addr, | 1034 | goto bad_desc; |
1039 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | ||
1040 | dev_kfree_skb_irq(descr->skb); | ||
1041 | goto refill; | ||
1042 | } | 1035 | } |
1043 | 1036 | ||
1044 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && | 1037 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && |
1045 | (status != SPIDER_NET_DESCR_FRAME_END) ) { | 1038 | (status != SPIDER_NET_DESCR_FRAME_END) ) { |
1046 | if (netif_msg_rx_err(card)) { | 1039 | if (netif_msg_rx_err(card)) |
1047 | pr_err("%s: RX descriptor with state %d\n", | 1040 | pr_err("%s: RX descriptor with unkown state %d\n", |
1048 | card->netdev->name, status); | 1041 | card->netdev->name, status); |
1049 | card->spider_stats.rx_desc_unk_state++; | 1042 | card->spider_stats.rx_desc_unk_state++; |
1050 | } | 1043 | goto bad_desc; |
1051 | goto refill; | ||
1052 | } | 1044 | } |
1053 | 1045 | ||
1054 | /* ok, we've got a packet in descr */ | 1046 | /* The cases we'll throw away the packet immediately */ |
1055 | result = spider_net_pass_skb_up(descr, card, napi); | 1047 | if (descr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { |
1056 | refill: | 1048 | if (netif_msg_rx_err(card)) |
1049 | pr_err("%s: error in received descriptor found, " | ||
1050 | "data_status=x%08x, data_error=x%08x\n", | ||
1051 | card->netdev->name, | ||
1052 | descr->data_status, descr->data_error); | ||
1053 | goto bad_desc; | ||
1054 | } | ||
1055 | |||
1056 | if (descr->dmac_cmd_status & 0xfefe) { | ||
1057 | pr_err("%s: bad status, cmd_status=x%08x\n", | ||
1058 | card->netdev->name, | ||
1059 | descr->dmac_cmd_status); | ||
1060 | pr_err("buf_addr=x%08x\n", descr->buf_addr); | ||
1061 | pr_err("buf_size=x%08x\n", descr->buf_size); | ||
1062 | pr_err("next_descr_addr=x%08x\n", descr->next_descr_addr); | ||
1063 | pr_err("result_size=x%08x\n", descr->result_size); | ||
1064 | pr_err("valid_size=x%08x\n", descr->valid_size); | ||
1065 | pr_err("data_status=x%08x\n", descr->data_status); | ||
1066 | pr_err("data_error=x%08x\n", descr->data_error); | ||
1067 | pr_err("bus_addr=x%08x\n", descr->bus_addr); | ||
1068 | pr_err("which=%ld\n", descr - card->rx_chain.ring); | ||
1069 | |||
1070 | card->spider_stats.rx_desc_error++; | ||
1071 | goto bad_desc; | ||
1072 | } | ||
1073 | |||
1074 | /* Ok, we've got a packet in descr */ | ||
1075 | spider_net_pass_skb_up(descr, card); | ||
1057 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 1076 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
1058 | /* change the descriptor state: */ | 1077 | return 1; |
1059 | if (!napi) | 1078 | |
1060 | spider_net_refill_rx_chain(card); | 1079 | bad_desc: |
1061 | out: | 1080 | dev_kfree_skb_irq(descr->skb); |
1062 | return result; | 1081 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
1082 | return 0; | ||
1063 | } | 1083 | } |
1064 | 1084 | ||
1065 | /** | 1085 | /** |
@@ -1085,7 +1105,7 @@ spider_net_poll(struct net_device *netdev, int *budget) | |||
1085 | packets_to_do = min(*budget, netdev->quota); | 1105 | packets_to_do = min(*budget, netdev->quota); |
1086 | 1106 | ||
1087 | while (packets_to_do) { | 1107 | while (packets_to_do) { |
1088 | if (spider_net_decode_one_descr(card, 1)) { | 1108 | if (spider_net_decode_one_descr(card)) { |
1089 | packets_done++; | 1109 | packets_done++; |
1090 | packets_to_do--; | 1110 | packets_to_do--; |
1091 | } else { | 1111 | } else { |
@@ -1098,6 +1118,7 @@ spider_net_poll(struct net_device *netdev, int *budget) | |||
1098 | netdev->quota -= packets_done; | 1118 | netdev->quota -= packets_done; |
1099 | *budget -= packets_done; | 1119 | *budget -= packets_done; |
1100 | spider_net_refill_rx_chain(card); | 1120 | spider_net_refill_rx_chain(card); |
1121 | spider_net_enable_rxdmac(card); | ||
1101 | 1122 | ||
1102 | /* if all packets are in the stack, enable interrupts and return 0 */ | 1123 | /* if all packets are in the stack, enable interrupts and return 0 */ |
1103 | /* if not, return 1 */ | 1124 | /* if not, return 1 */ |
@@ -1227,24 +1248,6 @@ spider_net_set_mac(struct net_device *netdev, void *p) | |||
1227 | } | 1248 | } |
1228 | 1249 | ||
1229 | /** | 1250 | /** |
1230 | * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt | ||
1231 | * @card: card structure | ||
1232 | * | ||
1233 | * spider_net_handle_rxram_full empties the RX ring so that spider can put | ||
1234 | * more packets in it and empty its RX RAM. This is called in bottom half | ||
1235 | * context | ||
1236 | */ | ||
1237 | static void | ||
1238 | spider_net_handle_rxram_full(struct spider_net_card *card) | ||
1239 | { | ||
1240 | while (spider_net_decode_one_descr(card, 0)) | ||
1241 | ; | ||
1242 | spider_net_enable_rxchtails(card); | ||
1243 | spider_net_enable_rxdmac(card); | ||
1244 | netif_rx_schedule(card->netdev); | ||
1245 | } | ||
1246 | |||
1247 | /** | ||
1248 | * spider_net_handle_error_irq - handles errors raised by an interrupt | 1251 | * spider_net_handle_error_irq - handles errors raised by an interrupt |
1249 | * @card: card structure | 1252 | * @card: card structure |
1250 | * @status_reg: interrupt status register 0 (GHIINT0STS) | 1253 | * @status_reg: interrupt status register 0 (GHIINT0STS) |
@@ -1366,10 +1369,10 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1366 | case SPIDER_NET_GRFAFLLINT: /* fallthrough */ | 1369 | case SPIDER_NET_GRFAFLLINT: /* fallthrough */ |
1367 | case SPIDER_NET_GRMFLLINT: | 1370 | case SPIDER_NET_GRMFLLINT: |
1368 | if (netif_msg_intr(card) && net_ratelimit()) | 1371 | if (netif_msg_intr(card) && net_ratelimit()) |
1369 | pr_debug("Spider RX RAM full, incoming packets " | 1372 | pr_err("Spider RX RAM full, incoming packets " |
1370 | "might be discarded!\n"); | 1373 | "might be discarded!\n"); |
1371 | spider_net_rx_irq_off(card); | 1374 | spider_net_rx_irq_off(card); |
1372 | tasklet_schedule(&card->rxram_full_tl); | 1375 | netif_rx_schedule(card->netdev); |
1373 | show_error = 0; | 1376 | show_error = 0; |
1374 | break; | 1377 | break; |
1375 | 1378 | ||
@@ -1384,7 +1387,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1384 | case SPIDER_NET_GDCDCEINT: /* fallthrough */ | 1387 | case SPIDER_NET_GDCDCEINT: /* fallthrough */ |
1385 | case SPIDER_NET_GDBDCEINT: /* fallthrough */ | 1388 | case SPIDER_NET_GDBDCEINT: /* fallthrough */ |
1386 | case SPIDER_NET_GDADCEINT: | 1389 | case SPIDER_NET_GDADCEINT: |
1387 | if (netif_msg_intr(card)) | 1390 | if (netif_msg_intr(card) && net_ratelimit()) |
1388 | pr_err("got descriptor chain end interrupt, " | 1391 | pr_err("got descriptor chain end interrupt, " |
1389 | "restarting DMAC %c.\n", | 1392 | "restarting DMAC %c.\n", |
1390 | 'D'-(i-SPIDER_NET_GDDDCEINT)/3); | 1393 | 'D'-(i-SPIDER_NET_GDDDCEINT)/3); |
@@ -1455,7 +1458,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1455 | break; | 1458 | break; |
1456 | } | 1459 | } |
1457 | 1460 | ||
1458 | if ((show_error) && (netif_msg_intr(card))) | 1461 | if ((show_error) && (netif_msg_intr(card)) && net_ratelimit()) |
1459 | pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " | 1462 | pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " |
1460 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", | 1463 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", |
1461 | card->netdev->name, | 1464 | card->netdev->name, |
@@ -1651,27 +1654,18 @@ int | |||
1651 | spider_net_open(struct net_device *netdev) | 1654 | spider_net_open(struct net_device *netdev) |
1652 | { | 1655 | { |
1653 | struct spider_net_card *card = netdev_priv(netdev); | 1656 | struct spider_net_card *card = netdev_priv(netdev); |
1654 | struct spider_net_descr *descr; | 1657 | int result; |
1655 | int i, result; | ||
1656 | 1658 | ||
1657 | result = -ENOMEM; | 1659 | result = spider_net_init_chain(card, &card->tx_chain); |
1658 | if (spider_net_init_chain(card, &card->tx_chain, card->descr, | 1660 | if (result) |
1659 | card->num_tx_desc)) | ||
1660 | goto alloc_tx_failed; | 1661 | goto alloc_tx_failed; |
1661 | |||
1662 | card->low_watermark = NULL; | 1662 | card->low_watermark = NULL; |
1663 | 1663 | ||
1664 | /* rx_chain is after tx_chain, so offset is descr + tx_count */ | 1664 | result = spider_net_init_chain(card, &card->rx_chain); |
1665 | if (spider_net_init_chain(card, &card->rx_chain, | 1665 | if (result) |
1666 | card->descr + card->num_tx_desc, | ||
1667 | card->num_rx_desc)) | ||
1668 | goto alloc_rx_failed; | 1666 | goto alloc_rx_failed; |
1669 | 1667 | ||
1670 | descr = card->rx_chain.head; | 1668 | /* Allocate rx skbs */ |
1671 | for (i=0; i < card->num_rx_desc; i++, descr++) | ||
1672 | descr->next_descr_addr = descr->next->bus_addr; | ||
1673 | |||
1674 | /* allocate rx skbs */ | ||
1675 | if (spider_net_alloc_rx_skbs(card)) | 1669 | if (spider_net_alloc_rx_skbs(card)) |
1676 | goto alloc_skbs_failed; | 1670 | goto alloc_skbs_failed; |
1677 | 1671 | ||
@@ -1902,7 +1896,6 @@ spider_net_stop(struct net_device *netdev) | |||
1902 | { | 1896 | { |
1903 | struct spider_net_card *card = netdev_priv(netdev); | 1897 | struct spider_net_card *card = netdev_priv(netdev); |
1904 | 1898 | ||
1905 | tasklet_kill(&card->rxram_full_tl); | ||
1906 | netif_poll_disable(netdev); | 1899 | netif_poll_disable(netdev); |
1907 | netif_carrier_off(netdev); | 1900 | netif_carrier_off(netdev); |
1908 | netif_stop_queue(netdev); | 1901 | netif_stop_queue(netdev); |
@@ -1924,6 +1917,7 @@ spider_net_stop(struct net_device *netdev) | |||
1924 | 1917 | ||
1925 | /* release chains */ | 1918 | /* release chains */ |
1926 | spider_net_release_tx_chain(card, 1); | 1919 | spider_net_release_tx_chain(card, 1); |
1920 | spider_net_free_rx_chain_contents(card); | ||
1927 | 1921 | ||
1928 | spider_net_free_rx_chain_contents(card); | 1922 | spider_net_free_rx_chain_contents(card); |
1929 | 1923 | ||
@@ -2046,9 +2040,6 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
2046 | 2040 | ||
2047 | pci_set_drvdata(card->pdev, netdev); | 2041 | pci_set_drvdata(card->pdev, netdev); |
2048 | 2042 | ||
2049 | card->rxram_full_tl.data = (unsigned long) card; | ||
2050 | card->rxram_full_tl.func = | ||
2051 | (void (*)(unsigned long)) spider_net_handle_rxram_full; | ||
2052 | init_timer(&card->tx_timer); | 2043 | init_timer(&card->tx_timer); |
2053 | card->tx_timer.function = | 2044 | card->tx_timer.function = |
2054 | (void (*)(unsigned long)) spider_net_cleanup_tx_ring; | 2045 | (void (*)(unsigned long)) spider_net_cleanup_tx_ring; |
@@ -2057,8 +2048,8 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
2057 | 2048 | ||
2058 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; | 2049 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; |
2059 | 2050 | ||
2060 | card->num_tx_desc = tx_descriptors; | 2051 | card->tx_chain.num_desc = tx_descriptors; |
2061 | card->num_rx_desc = rx_descriptors; | 2052 | card->rx_chain.num_desc = rx_descriptors; |
2062 | 2053 | ||
2063 | spider_net_setup_netdev_ops(netdev); | 2054 | spider_net_setup_netdev_ops(netdev); |
2064 | 2055 | ||
@@ -2107,12 +2098,8 @@ spider_net_alloc_card(void) | |||
2107 | { | 2098 | { |
2108 | struct net_device *netdev; | 2099 | struct net_device *netdev; |
2109 | struct spider_net_card *card; | 2100 | struct spider_net_card *card; |
2110 | size_t alloc_size; | ||
2111 | 2101 | ||
2112 | alloc_size = sizeof (*card) + | 2102 | netdev = alloc_etherdev(sizeof(struct spider_net_card)); |
2113 | sizeof (struct spider_net_descr) * rx_descriptors + | ||
2114 | sizeof (struct spider_net_descr) * tx_descriptors; | ||
2115 | netdev = alloc_etherdev(alloc_size); | ||
2116 | if (!netdev) | 2103 | if (!netdev) |
2117 | return NULL; | 2104 | return NULL; |
2118 | 2105 | ||