master/ethernet.c
changeset 217 dcfd406e7786
parent 216 e7f3e485c5b8
child 218 80fb87518f3d
equal deleted inserted replaced
216:e7f3e485c5b8 217:dcfd406e7786
    39 
    39 
    40 #define EOE_DEBUG_LEVEL 0
    40 #define EOE_DEBUG_LEVEL 0
    41 
    41 
    42 /*****************************************************************************/
    42 /*****************************************************************************/
    43 
    43 
    44 /**
       
    45    Queued frame structure.
       
    46 */
       
    47 
       
    48 typedef struct
       
    49 {
       
    50     struct list_head queue; /**< list item */
       
    51     struct sk_buff *skb; /**< socket buffer */
       
    52 }
       
    53 ec_eoe_frame_t;
       
    54 
       
    55 /*****************************************************************************/
       
    56 
       
    57 void ec_eoe_flush(ec_eoe_t *);
    44 void ec_eoe_flush(ec_eoe_t *);
    58 void ec_eoedev_init(struct net_device *);
    45 void ec_eoedev_init(struct net_device *);
    59 int ec_eoedev_open(struct net_device *);
    46 int ec_eoedev_open(struct net_device *);
    60 int ec_eoedev_stop(struct net_device *);
    47 int ec_eoedev_stop(struct net_device *);
    61 int ec_eoedev_tx(struct sk_buff *, struct net_device *);
    48 int ec_eoedev_tx(struct sk_buff *, struct net_device *);
   147         kfree(frame);
   134         kfree(frame);
   148     }
   135     }
   149     eoe->queued_frames = 0;
   136     eoe->queued_frames = 0;
   150 
   137 
   151     spin_unlock_bh(&eoe->tx_queue_lock);
   138     spin_unlock_bh(&eoe->tx_queue_lock);
       
   139 }
       
   140 
       
   141 /*****************************************************************************/
       
   142 
       
   143 /**
       
   144    Sends a frame or the next fragment.
       
   145 */
       
   146 
       
   147 int ec_eoe_send(ec_eoe_t *eoe)
       
   148 {
       
   149     ec_eoe_frame_t *frame = eoe->tx_frame;
       
   150     size_t remaining_size, current_size, complete_offset;
       
   151     unsigned int last_fragment;
       
   152     uint8_t *data;
       
   153 #if EOE_DEBUG_LEVEL > 1
       
   154     unsigned int i;
       
   155 #endif
       
   156 
       
   157     remaining_size = frame->skb->len - eoe->tx_offset;
       
   158 
       
   159     if (remaining_size <= eoe->slave->sii_tx_mailbox_size - 10) {
       
   160         current_size = remaining_size;
       
   161         last_fragment = 1;
       
   162     }
       
   163     else {
       
   164         current_size = ((eoe->slave->sii_tx_mailbox_size - 10) / 32) * 32;
       
   165         last_fragment = 0;
       
   166     }
       
   167 
       
   168     if (eoe->tx_fragment_number) {
       
   169         complete_offset = eoe->tx_offset / 32;
       
   170     }
       
   171     else {
       
   172         complete_offset = remaining_size / 32 + 1;
       
   173     }
       
   174 
       
   175 #if EOE_DEBUG_LEVEL > 0
       
   176     EC_DBG("EoE TX sending %sfragment %i with %i octets (%i)."
       
   177            " %i frames queued.\n", last_fragment ? "last " : "",
       
   178            eoe->tx_fragment_number, current_size, complete_offset,
       
   179            eoe->queued_frames);
       
   180 #endif
       
   181 
       
   182 #if EOE_DEBUG_LEVEL > 1
       
   183     EC_DBG("");
       
   184     for (i = 0; i < current_size; i++) {
       
   185         printk("%02X ", frame->skb->data[eoe->tx_offset + i]);
       
   186         if ((i + 1) % 16 == 0) {
       
   187             printk("\n");
       
   188             EC_DBG("");
       
   189         }
       
   190     }
       
   191     printk("\n");
       
   192 #endif
       
   193 
       
   194     if (!(data = ec_slave_mbox_prepare_send(eoe->slave, 0x02,
       
   195                                             current_size + 4)))
       
   196         return -1;
       
   197 
       
   198     EC_WRITE_U8 (data,     0x00); // eoe fragment req.
       
   199     EC_WRITE_U8 (data + 1, last_fragment);
       
   200     EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
       
   201                             (complete_offset & 0x3F) << 6 |
       
   202                             (eoe->tx_frame_number & 0x0F) << 12));
       
   203 
       
   204     memcpy(data + 4, frame->skb->data + eoe->tx_offset, current_size);
       
   205     ec_master_queue_command(eoe->slave->master, &eoe->slave->mbox_command);
       
   206 
       
   207     eoe->tx_offset += current_size;
       
   208     eoe->tx_fragment_number++;
       
   209 
       
   210     return 0;
   152 }
   211 }
   153 
   212 
   154 /*****************************************************************************/
   213 /*****************************************************************************/
   155 
   214 
   156 /**
   215 /**
   341                 wakeup = 1;
   400                 wakeup = 1;
   342             }
   401             }
   343             eoe->queued_frames--;
   402             eoe->queued_frames--;
   344             spin_unlock_bh(&eoe->tx_queue_lock);
   403             spin_unlock_bh(&eoe->tx_queue_lock);
   345 
   404 
   346 #if EOE_DEBUG_LEVEL > 0
   405             eoe->tx_frame_number++;
   347             EC_DBG("EoE TX Sending frame with %i octets."
   406             eoe->tx_frame_number %= 16;
   348                    " (%i frames queued).\n",
   407             eoe->tx_frame = frame;
   349                    frame->skb->len, eoe->queued_frames);
   408             eoe->tx_fragment_number = 0;
   350 
   409             eoe->tx_offset = 0;
   351 #if EOE_DEBUG_LEVEL > 1
   410 
   352             EC_DBG("");
   411             if (ec_eoe_send(eoe)) {
   353             for (i = 0; i < frame->skb->len; i++) {
       
   354                 printk("%02X ", frame->skb->data[i]);
       
   355                 if ((i + 1) % 16 == 0) {
       
   356                     printk("\n");
       
   357                     EC_DBG("");
       
   358                 }
       
   359             }
       
   360             printk("\n");
       
   361 #endif
       
   362 
       
   363             if (wakeup) EC_DBG("waking up TX queue...\n");
       
   364 #endif
       
   365 
       
   366             if (!(data = ec_slave_mbox_prepare_send(eoe->slave, 0x02,
       
   367                                                     frame->skb->len + 4))) {
       
   368                 dev_kfree_skb(frame->skb);
   412                 dev_kfree_skb(frame->skb);
   369                 kfree(frame);
   413                 kfree(frame);
   370                 eoe->stats.tx_errors++;
   414                 eoe->stats.tx_errors++;
   371                 eoe->state = EC_EOE_RX_START;
   415                 eoe->state = EC_EOE_RX_START;
   372                 break;
   416                 break;
   373             }
   417             }
   374 
   418 
   375             eoe->tx_frame_number++;
   419 #if EOE_DEBUG_LEVEL > 0
   376             eoe->tx_frame_number %= 16;
   420             if (wakeup) EC_DBG("waking up TX queue...\n");
   377 
   421 #endif
   378             EC_WRITE_U16(data, 0x0100); // eoe fragment req.
       
   379             EC_WRITE_U16(data + 2, (eoe->tx_frame_number & 0x0F) << 12);
       
   380 
       
   381             memcpy(data + 4, frame->skb->data, frame->skb->len);
       
   382             ec_master_queue_command(master, &eoe->slave->mbox_command);
       
   383 
       
   384             eoe->last_tx_bytes = frame->skb->len;
       
   385             dev_kfree_skb(frame->skb);
       
   386             kfree(frame);
       
   387 
   422 
   388             eoe->state = EC_EOE_TX_SENT;
   423             eoe->state = EC_EOE_TX_SENT;
   389             break;
   424             break;
   390 
   425 
   391         case EC_EOE_TX_SENT:
   426         case EC_EOE_TX_SENT:
   398                 eoe->stats.tx_errors++;
   433                 eoe->stats.tx_errors++;
   399                 eoe->state = EC_EOE_RX_START;
   434                 eoe->state = EC_EOE_RX_START;
   400                 break;
   435                 break;
   401             }
   436             }
   402 
   437 
   403             eoe->stats.tx_packets++;
   438             // frame completely sent
   404             eoe->stats.tx_bytes += eoe->last_tx_bytes;
   439             if (eoe->tx_offset >= eoe->tx_frame->skb->len) {
   405             eoe->state = EC_EOE_RX_START;
   440                 eoe->stats.tx_packets++;
       
   441                 eoe->stats.tx_bytes += eoe->tx_frame->skb->len;
       
   442                 dev_kfree_skb(eoe->tx_frame->skb);
       
   443                 kfree(eoe->tx_frame);
       
   444                 eoe->state = EC_EOE_RX_START;
       
   445             }
       
   446             else { // send next fragment
       
   447                 if (ec_eoe_send(eoe)) {
       
   448                     dev_kfree_skb(eoe->tx_frame->skb);
       
   449                     kfree(eoe->tx_frame);
       
   450                     eoe->stats.tx_errors++;
       
   451                     eoe->state = EC_EOE_RX_START;
       
   452                     break;
       
   453                 }
       
   454             }
       
   455 
   406             break;
   456             break;
   407 
   457 
   408         default:
   458         default:
   409             break;
   459             break;
   410     }
   460     }
   495                 )
   545                 )
   496 {
   546 {
   497     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
   547     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
   498     ec_eoe_frame_t *frame;
   548     ec_eoe_frame_t *frame;
   499 
   549 
   500     if (skb->len + 10 > eoe->slave->sii_tx_mailbox_size) {
   550 #if 0
       
   551     if (skb->len > eoe->slave->sii_tx_mailbox_size - 10) {
   501         EC_WARN("EoE TX frame (%i octets) exceeds MTU. dropping.\n", skb->len);
   552         EC_WARN("EoE TX frame (%i octets) exceeds MTU. dropping.\n", skb->len);
   502         dev_kfree_skb(skb);
   553         dev_kfree_skb(skb);
   503         eoe->stats.tx_dropped++;
   554         eoe->stats.tx_dropped++;
   504         return 0;
   555         return 0;
   505     }
   556     }
       
   557 #endif
   506 
   558 
   507     if (!(frame =
   559     if (!(frame =
   508           (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) {
   560           (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) {
   509         if (printk_ratelimit())
   561         if (printk_ratelimit())
   510             EC_WARN("EoE TX: low on mem. frame dropped.\n");
   562             EC_WARN("EoE TX: low on mem. frame dropped.\n");