master/ethernet.c
changeset 251 c1d0b63a9302
parent 246 0bf7c769de06
child 261 44a3a5833c49
equal deleted inserted replaced
250:440ae5f6d2c3 251:c1d0b63a9302
    68 
    68 
    69 /*****************************************************************************/
    69 /*****************************************************************************/
    70 
    70 
    71 /**
    71 /**
    72    EoE constructor.
    72    EoE constructor.
    73    Initializes the EoE object, creates a net_device and registeres it.
    73    Initializes the EoE handler, creates a net_device and registeres it.
    74 */
    74 */
    75 
    75 
    76 int ec_eoe_init(ec_eoe_t *eoe, /**< EoE object */
    76 int ec_eoe_init(ec_eoe_t *eoe /**< EoE handler */)
    77                 ec_slave_t *slave /**< assigned slave */
       
    78                 )
       
    79 {
    77 {
    80     ec_eoe_t **priv;
    78     ec_eoe_t **priv;
    81     int result, i;
    79     int result, i;
    82 
    80 
    83     eoe->slave = slave;
    81     eoe->slave = NULL;
    84     eoe->state = ec_eoe_state_rx_start;
    82     eoe->state = ec_eoe_state_rx_start;
    85     eoe->opened = 0;
    83     eoe->opened = 0;
    86     eoe->rx_skb = NULL;
    84     eoe->rx_skb = NULL;
    87     eoe->rx_expected_fragment = 0;
    85     eoe->rx_expected_fragment = 0;
    88     INIT_LIST_HEAD(&eoe->tx_queue);
    86     INIT_LIST_HEAD(&eoe->tx_queue);
    93     eoe->tx_frame_number = 0xFF;
    91     eoe->tx_frame_number = 0xFF;
    94     memset(&eoe->stats, 0, sizeof(struct net_device_stats));
    92     memset(&eoe->stats, 0, sizeof(struct net_device_stats));
    95 
    93 
    96     if (!(eoe->dev =
    94     if (!(eoe->dev =
    97           alloc_netdev(sizeof(ec_eoe_t *), "eoe%d", ether_setup))) {
    95           alloc_netdev(sizeof(ec_eoe_t *), "eoe%d", ether_setup))) {
    98         EC_ERR("Unable to allocate net_device for EoE object!\n");
    96         EC_ERR("Unable to allocate net_device for EoE handler!\n");
    99         goto out_return;
    97         goto out_return;
   100     }
    98     }
   101 
    99 
   102     // initialize net_device
   100     // initialize net_device
   103     eoe->dev->open = ec_eoedev_open;
   101     eoe->dev->open = ec_eoedev_open;
   143 /**
   141 /**
   144    EoE destructor.
   142    EoE destructor.
   145    Unregisteres the net_device and frees allocated memory.
   143    Unregisteres the net_device and frees allocated memory.
   146 */
   144 */
   147 
   145 
   148 void ec_eoe_clear(ec_eoe_t *eoe /**< EoE object */)
   146 void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
   149 {
   147 {
   150     if (eoe->dev) {
   148     if (eoe->dev) {
   151         unregister_netdev(eoe->dev);
   149         unregister_netdev(eoe->dev);
   152         free_netdev(eoe->dev);
   150         free_netdev(eoe->dev);
   153     }
   151     }
   167 
   165 
   168 /**
   166 /**
   169    Empties the transmit queue.
   167    Empties the transmit queue.
   170 */
   168 */
   171 
   169 
   172 void ec_eoe_flush(ec_eoe_t *eoe /**< EoE object */)
   170 void ec_eoe_flush(ec_eoe_t *eoe /**< EoE handler */)
   173 {
   171 {
   174     ec_eoe_frame_t *frame, *next;
   172     ec_eoe_frame_t *frame, *next;
   175 
   173 
   176     spin_lock_bh(&eoe->tx_queue_lock);
   174     spin_lock_bh(&eoe->tx_queue_lock);
   177 
   175 
   189 
   187 
   190 /**
   188 /**
   191    Sends a frame or the next fragment.
   189    Sends a frame or the next fragment.
   192 */
   190 */
   193 
   191 
   194 int ec_eoe_send(ec_eoe_t *eoe /**< EoE object */)
   192 int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
   195 {
   193 {
   196     size_t remaining_size, current_size, complete_offset;
   194     size_t remaining_size, current_size, complete_offset;
   197     unsigned int last_fragment;
   195     unsigned int last_fragment;
   198     uint8_t *data;
   196     uint8_t *data;
   199 #if EOE_DEBUG_LEVEL > 1
   197 #if EOE_DEBUG_LEVEL > 1
   260 
   258 
   261 /**
   259 /**
   262    Runs the EoE state machine.
   260    Runs the EoE state machine.
   263 */
   261 */
   264 
   262 
   265 void ec_eoe_run(ec_eoe_t *eoe /**< EoE object */)
   263 void ec_eoe_run(ec_eoe_t *eoe /**< EoE handler */)
   266 {
   264 {
   267     if (!eoe->opened) return;
   265     if (!eoe->opened) return;
   268 
   266 
   269     // call state function
   267     // call state function
   270     eoe->state(eoe);
   268     eoe->state(eoe);
   275 /**
   273 /**
   276    Returns the state of the device.
   274    Returns the state of the device.
   277    \return 1 if the device is "up", 0 if it is "down"
   275    \return 1 if the device is "up", 0 if it is "down"
   278 */
   276 */
   279 
   277 
   280 unsigned int ec_eoe_active(const ec_eoe_t *eoe /**< EoE object */)
   278 unsigned int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */)
   281 {
   279 {
   282     return eoe->opened;
   280     return eoe->slave && eoe->opened;
   283 }
   281 }
   284 
   282 
   285 /*****************************************************************************/
   283 /*****************************************************************************/
   286 
   284 
   287 /**
   285 /**
   288    Prints EoE object information.
   286    Prints EoE handler information.
   289 */
   287 */
   290 
   288 
   291 void ec_eoe_print(const ec_eoe_t *eoe /**< EoE object */)
   289 void ec_eoe_print(const ec_eoe_t *eoe /**< EoE handler */)
   292 {
   290 {
   293     EC_INFO("  EoE slave %i\n", eoe->slave->ring_position);
   291     EC_INFO("  EoE handler %s\n", eoe->dev->name);
   294     EC_INFO("    Assigned device: %s (%s)\n", eoe->dev->name,
   292     EC_INFO("    State: %s\n", eoe->opened ? "opened" : "closed");
   295             eoe->opened ? "opened" : "closed");
   293     if (eoe->slave)
       
   294         EC_INFO("    Coupled to slave %i.\n", eoe->slave->ring_position);
       
   295     else
       
   296         EC_INFO("    Not coupled.\n");
   296 }
   297 }
   297 
   298 
   298 /******************************************************************************
   299 /******************************************************************************
   299  *  STATE PROCESSING FUNCTIONS
   300  *  STATE PROCESSING FUNCTIONS
   300  *****************************************************************************/
   301  *****************************************************************************/
   303    State: RX_START.
   304    State: RX_START.
   304    Starts a new receiving sequence by queuing a command that checks the
   305    Starts a new receiving sequence by queuing a command that checks the
   305    slave's mailbox for a new command.
   306    slave's mailbox for a new command.
   306 */
   307 */
   307 
   308 
   308 void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE object */)
   309 void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
   309 {
   310 {
   310     ec_slave_mbox_prepare_check(eoe->slave);
   311     ec_slave_mbox_prepare_check(eoe->slave);
   311     ec_master_queue_command(eoe->slave->master, &eoe->slave->mbox_command);
   312     ec_master_queue_command(eoe->slave->master, &eoe->slave->mbox_command);
   312     eoe->state = ec_eoe_state_rx_check;
   313     eoe->state = ec_eoe_state_rx_check;
   313 }
   314 }
   318    State: RX_CHECK.
   319    State: RX_CHECK.
   319    Processes the checking command sent in RX_START and issues a receive
   320    Processes the checking command sent in RX_START and issues a receive
   320    command, if new data is available.
   321    command, if new data is available.
   321 */
   322 */
   322 
   323 
   323 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE object */)
   324 void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
   324 {
   325 {
   325     if (eoe->slave->mbox_command.state != EC_CMD_RECEIVED) {
   326     if (eoe->slave->mbox_command.state != EC_CMD_RECEIVED) {
   326         eoe->stats.rx_errors++;
   327         eoe->stats.rx_errors++;
   327         eoe->state = ec_eoe_state_tx_start;
   328         eoe->state = ec_eoe_state_tx_start;
   328         return;
   329         return;
   344    State: RX_FETCH.
   345    State: RX_FETCH.
   345    Checks if the requested data of RX_CHECK was received and processes the
   346    Checks if the requested data of RX_CHECK was received and processes the
   346    EoE command.
   347    EoE command.
   347 */
   348 */
   348 
   349 
   349 void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE object */)
   350 void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
   350 {
   351 {
   351     size_t rec_size, data_size;
   352     size_t rec_size, data_size;
   352     uint8_t *data, frame_type, last_fragment, time_appended;
   353     uint8_t *data, frame_type, last_fragment, time_appended;
   353     uint8_t frame_number, fragment_offset, fragment_number;
   354     uint8_t frame_number, fragment_offset, fragment_number;
   354     off_t offset;
   355     off_t offset;
   484    State: TX START.
   485    State: TX START.
   485    Starts a new transmit sequence. If no data is available, a new receive
   486    Starts a new transmit sequence. If no data is available, a new receive
   486    sequence is started instead.
   487    sequence is started instead.
   487 */
   488 */
   488 
   489 
   489 void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE object */)
   490 void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE handler */)
   490 {
   491 {
   491 #if EOE_DEBUG_LEVEL > 0
   492 #if EOE_DEBUG_LEVEL > 0
   492     unsigned int wakeup;
   493     unsigned int wakeup;
   493 #endif
   494 #endif
   494 
   495 
   544    State: TX SENT.
   545    State: TX SENT.
   545    Checks is the previous transmit command succeded and sends the next
   546    Checks is the previous transmit command succeded and sends the next
   546    fragment, if necessary.
   547    fragment, if necessary.
   547 */
   548 */
   548 
   549 
   549 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE object */)
   550 void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
   550 {
   551 {
   551     if (eoe->slave->mbox_command.state != EC_CMD_RECEIVED) {
   552     if (eoe->slave->mbox_command.state != EC_CMD_RECEIVED) {
   552         eoe->stats.tx_errors++;
   553         eoe->stats.tx_errors++;
   553         eoe->state = ec_eoe_state_rx_start;
   554         eoe->state = ec_eoe_state_rx_start;
   554         return;
   555         return;
   593     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
   594     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
   594     ec_eoe_flush(eoe);
   595     ec_eoe_flush(eoe);
   595     eoe->opened = 1;
   596     eoe->opened = 1;
   596     netif_start_queue(dev);
   597     netif_start_queue(dev);
   597     eoe->tx_queue_active = 1;
   598     eoe->tx_queue_active = 1;
   598     EC_INFO("%s (slave %i) opened.\n", dev->name, eoe->slave->ring_position);
   599     EC_INFO("%s opened.\n", dev->name);
       
   600     if (!eoe->slave)
       
   601         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
       
   602     else {
       
   603         eoe->slave->requested_state = EC_SLAVE_STATE_OP;
       
   604     }
   599     return 0;
   605     return 0;
   600 }
   606 }
   601 
   607 
   602 /*****************************************************************************/
   608 /*****************************************************************************/
   603 
   609 
   610     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
   616     ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
   611     netif_stop_queue(dev);
   617     netif_stop_queue(dev);
   612     eoe->tx_queue_active = 0;
   618     eoe->tx_queue_active = 0;
   613     eoe->opened = 0;
   619     eoe->opened = 0;
   614     ec_eoe_flush(eoe);
   620     ec_eoe_flush(eoe);
   615     EC_INFO("%s (slave %i) stopped.\n", dev->name, eoe->slave->ring_position);
   621     EC_INFO("%s stopped.\n", dev->name);
       
   622     if (!eoe->slave)
       
   623         EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
       
   624     else {
       
   625         eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
       
   626     }
   616     return 0;
   627     return 0;
   617 }
   628 }
   618 
   629 
   619 /*****************************************************************************/
   630 /*****************************************************************************/
   620 
   631