PXENV_UNDI_TRANSMIT
[PXE UNDI API]

UNDI TRANSMIT PACKET. More...


Data Structures

struct  s_PXENV_UNDI_TBD
 A transmit buffer descriptor, as pointed to by s_PXENV_UNDI_TRANSMIT::TBD. More...
struct  s_PXENV_UNDI_TRANSMIT
 Parameter block for pxenv_undi_transmit(). More...

Defines

#define PXENV_UNDI_TRANSMIT   0x0008
 PXE API function code for pxenv_undi_transmit().
#define P_UNKNOWN   0
 Media header already filled in.
#define P_IP   1
 IP protocol.
#define P_ARP   2
 ARP protocol.
#define P_RARP   3
 RARP protocol.
#define P_OTHER   4
 Other protocol.
#define XMT_DESTADDR   0x0000
 Unicast packet.
#define XMT_BROADCAST   0x0001
 Broadcast packet.
#define MAX_DATA_BLKS   8
 Maximum number of data blocks in a transmit buffer descriptor.

Typedefs

typedef struct s_PXENV_UNDI_TBD PXENV_UNDI_TBD_t
typedef struct
s_PXENV_UNDI_TRANSMIT 
PXENV_UNDI_TRANSMIT_t

Functions

PXENV_EXIT_t pxenv_undi_transmit (struct s_PXENV_UNDI_TRANSMIT *undi_transmit)


Detailed Description

UNDI TRANSMIT PACKET.

Define Documentation

#define PXENV_UNDI_TRANSMIT   0x0008

PXE API function code for pxenv_undi_transmit().

Definition at line 1060 of file pxe_api.h.

Referenced by pxe_api_call(), pxeparent_function_name(), and undinet_transmit().

#define P_UNKNOWN   0

Media header already filled in.

Definition at line 1062 of file pxe_api.h.

Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().

#define P_IP   1

IP protocol.

Definition at line 1063 of file pxe_api.h.

Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().

#define P_ARP   2

ARP protocol.

Definition at line 1064 of file pxe_api.h.

Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().

#define P_RARP   3

RARP protocol.

Definition at line 1065 of file pxe_api.h.

Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().

#define P_OTHER   4

Other protocol.

Definition at line 1066 of file pxe_api.h.

#define XMT_DESTADDR   0x0000

Unicast packet.

Definition at line 1068 of file pxe_api.h.

Referenced by pxenv_undi_isr(), and pxenv_undi_transmit().

#define XMT_BROADCAST   0x0001

Broadcast packet.

Definition at line 1069 of file pxe_api.h.

#define MAX_DATA_BLKS   8

Maximum number of data blocks in a transmit buffer descriptor.

Definition at line 1072 of file pxe_api.h.


Typedef Documentation

Definition at line 1097 of file pxe_api.h.

Definition at line 1123 of file pxe_api.h.


Function Documentation

PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT undi_transmit  ) 

Definition at line 222 of file pxe_undi.c.

References alloc_iob(), arp_protocol, copy_from_real, s_PXENV_UNDI_TBD::DataBlkCount, s_PXENV_UNDI_TBD::DataBlock, DBG2, s_PXENV_UNDI_TRANSMIT::DestAddr, free_iob(), s_PXENV_UNDI_TBD::ImmedLength, iob_put, iob_reserve, ipv4_protocol, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_broadcast, ll_protocol::ll_header_len, net_device::ll_protocol, MAX_LL_ADDR_LEN, net_protocol::name, net_protocol::net_proto, netdev_irq(), netdev_tx(), ll_protocol::ntoa, NULL, s_SEGOFF16::offset, P_ARP, P_IP, P_RARP, P_UNKNOWN, s_PXENV_UNDI_TRANSMIT::Protocol, ll_protocol::push, PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, PXENV_STATUS_OUT_OF_RESOURCES, PXENV_STATUS_SUCCESS, PXENV_STATUS_UNDI_INVALID_PARAMETER, rarp_protocol, s_SEGOFF16::segment, s_PXENV_UNDI_TRANSMIT::Status, strerror(), s_PXENV_UNDI_TRANSMIT::TBD, s_PXENV_UNDI_TBD::DataBlk::TDDataLen, undi_tx_count, s_PXENV_UNDI_TBD::Xmit, s_PXENV_UNDI_TRANSMIT::XmitFlag, and XMT_DESTADDR.

Referenced by pxe_api_call().

00223                                                     {
00224         struct s_PXENV_UNDI_TBD tbd;
00225         struct DataBlk *datablk;
00226         struct io_buffer *iobuf;
00227         struct net_protocol *net_protocol;
00228         struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
00229         char destaddr[MAX_LL_ADDR_LEN];
00230         const void *ll_dest;
00231         size_t ll_hlen = ll_protocol->ll_header_len;
00232         size_t len;
00233         unsigned int i;
00234         int rc;
00235 
00236         DBG2 ( "PXENV_UNDI_TRANSMIT" );
00237 
00238         /* Forcibly enable interrupts at this point, to work around
00239          * callers that never call PXENV_UNDI_OPEN before attempting
00240          * to use the UNDI API.
00241          */
00242         netdev_irq ( pxe_netdev, 1 );
00243 
00244         /* Identify network-layer protocol */
00245         switch ( undi_transmit->Protocol ) {
00246         case P_IP:      net_protocol = &ipv4_protocol;  break;
00247         case P_ARP:     net_protocol = &arp_protocol;   break;
00248         case P_RARP:    net_protocol = &rarp_protocol;  break;
00249         case P_UNKNOWN:
00250                 net_protocol = NULL;
00251                 ll_hlen = 0;
00252                 break;
00253         default:
00254                 DBG2 ( " %02x invalid protocol\n", undi_transmit->Protocol );
00255                 undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_PARAMETER;
00256                 return PXENV_EXIT_FAILURE;
00257         }
00258         DBG2 ( " %s", ( net_protocol ? net_protocol->name : "RAW" ) );
00259 
00260         /* Calculate total packet length */
00261         copy_from_real ( &tbd, undi_transmit->TBD.segment,
00262                          undi_transmit->TBD.offset, sizeof ( tbd ) );
00263         len = tbd.ImmedLength;
00264         DBG2 ( " %04x:%04x+%x", tbd.Xmit.segment, tbd.Xmit.offset,
00265                tbd.ImmedLength );
00266         for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) {
00267                 datablk = &tbd.DataBlock[i];
00268                 len += datablk->TDDataLen;
00269                 DBG2 ( " %04x:%04x+%x", datablk->TDDataPtr.segment,
00270                        datablk->TDDataPtr.offset, datablk->TDDataLen );
00271         }
00272 
00273         /* Allocate and fill I/O buffer */
00274         iobuf = alloc_iob ( ll_hlen + len );
00275         if ( ! iobuf ) {
00276                 DBG2 ( " could not allocate iobuf\n" );
00277                 undi_transmit->Status = PXENV_STATUS_OUT_OF_RESOURCES;
00278                 return PXENV_EXIT_FAILURE;
00279         }
00280         iob_reserve ( iobuf, ll_hlen );
00281         copy_from_real ( iob_put ( iobuf, tbd.ImmedLength ), tbd.Xmit.segment,
00282                          tbd.Xmit.offset, tbd.ImmedLength );
00283         for ( i = 0 ; i < tbd.DataBlkCount ; i++ ) {
00284                 datablk = &tbd.DataBlock[i];
00285                 copy_from_real ( iob_put ( iobuf, datablk->TDDataLen ),
00286                                  datablk->TDDataPtr.segment,
00287                                  datablk->TDDataPtr.offset,
00288                                  datablk->TDDataLen );
00289         }
00290 
00291         /* Add link-layer header, if required to do so */
00292         if ( net_protocol != NULL ) {
00293 
00294                 /* Calculate destination address */
00295                 if ( undi_transmit->XmitFlag == XMT_DESTADDR ) {
00296                         copy_from_real ( destaddr,
00297                                          undi_transmit->DestAddr.segment,
00298                                          undi_transmit->DestAddr.offset,
00299                                          ll_protocol->ll_addr_len );
00300                         ll_dest = destaddr;
00301                         DBG2 ( " DEST %s", ll_protocol->ntoa ( ll_dest ) );
00302                 } else {
00303                         ll_dest = pxe_netdev->ll_broadcast;
00304                         DBG2 ( " BCAST" );
00305                 }
00306 
00307                 /* Add link-layer header */
00308                 if ( ( rc = ll_protocol->push ( pxe_netdev, iobuf, ll_dest,
00309                                                 pxe_netdev->ll_addr,
00310                                                 net_protocol->net_proto ))!=0){
00311                         DBG2 ( " could not add link-layer header: %s\n",
00312                                strerror ( rc ) );
00313                         free_iob ( iobuf );
00314                         undi_transmit->Status = PXENV_STATUS ( rc );
00315                         return PXENV_EXIT_FAILURE;
00316                 }
00317         }
00318 
00319         /* Flag transmission as in-progress.  Do this before starting
00320          * to transmit the packet, because the ISR may trigger before
00321          * we return from netdev_tx().
00322          */
00323         undi_tx_count++;
00324 
00325         /* Transmit packet */
00326         DBG2 ( "\n" );
00327         if ( ( rc = netdev_tx ( pxe_netdev, iobuf ) ) != 0 ) {
00328                 DBG2 ( "PXENV_UNDI_TRANSMIT could not transmit: %s\n",
00329                        strerror ( rc ) );
00330                 undi_tx_count--;
00331                 undi_transmit->Status = PXENV_STATUS ( rc );
00332                 return PXENV_EXIT_FAILURE;
00333         }
00334 
00335         undi_transmit->Status = PXENV_STATUS_SUCCESS;
00336         return PXENV_EXIT_SUCCESS;
00337 }


Generated on Tue Apr 6 20:01:59 2010 for gPXE by  doxygen 1.5.7.1